Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(56)

Side by Side Diff: components/arc/arc_bridge_service_impl.cc

Issue 2577373002: Refactor ArcBridgeServiceImpl part 2. (Closed)
Patch Set: Rebase Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/arc/arc_bridge_service_impl.h" 5 #include "components/arc/arc_bridge_service_impl.h"
6 6
7 #include <string> 7 #include "base/logging.h"
8 #include <utility> 8 #include "base/memory/ref_counted.h"
9 9 #include "base/task_runner.h"
10 #include "base/command_line.h"
11 #include "base/json/json_writer.h"
12 #include "base/sequenced_task_runner.h"
13 #include "base/sys_info.h"
14 #include "base/task_runner_util.h"
15 #include "base/threading/thread_task_runner_handle.h"
16 #include "base/time/time.h"
17 #include "chromeos/chromeos_switches.h"
18 #include "chromeos/dbus/dbus_method_call_status.h"
19 #include "chromeos/dbus/dbus_thread_manager.h"
20 #include "components/arc/arc_session.h" 10 #include "components/arc/arc_session.h"
21 #include "components/prefs/pref_registry_simple.h"
22 #include "components/prefs/pref_service.h"
23 11
24 namespace arc { 12 namespace arc {
25 13
26 namespace { 14 namespace {
27 15
28 constexpr base::TimeDelta kDefaultRestartDelay = 16 constexpr base::TimeDelta kDefaultRestartDelay =
29 base::TimeDelta::FromSeconds(5); 17 base::TimeDelta::FromSeconds(5);
30 18
31 } // namespace 19 } // namespace
32 20
33 ArcBridgeServiceImpl::ArcBridgeServiceImpl( 21 ArcBridgeServiceImpl::ArcBridgeServiceImpl(
34 const scoped_refptr<base::TaskRunner>& blocking_task_runner) 22 const scoped_refptr<base::TaskRunner>& blocking_task_runner)
35 : session_started_(false), 23 : restart_delay_(kDefaultRestartDelay),
36 restart_delay_(kDefaultRestartDelay),
37 factory_(base::Bind(ArcSession::Create, this, blocking_task_runner)), 24 factory_(base::Bind(ArcSession::Create, this, blocking_task_runner)),
38 weak_factory_(this) {} 25 weak_ptr_factory_(this) {}
39 26
40 ArcBridgeServiceImpl::~ArcBridgeServiceImpl() { 27 ArcBridgeServiceImpl::~ArcBridgeServiceImpl() {
28 DCHECK(CalledOnValidThread());
41 if (arc_session_) 29 if (arc_session_)
42 arc_session_->RemoveObserver(this); 30 arc_session_->RemoveObserver(this);
43 } 31 }
44 32
45 void ArcBridgeServiceImpl::RequestStart() { 33 void ArcBridgeServiceImpl::RequestStart() {
46 DCHECK(CalledOnValidThread()); 34 DCHECK(CalledOnValidThread());
47 if (session_started_) 35
36 // Consecutive RequestStart() call. Do nothing.
37 if (run_requested_)
48 return; 38 return;
39
49 VLOG(1) << "Session started"; 40 VLOG(1) << "Session started";
50 session_started_ = true; 41 run_requested_ = true;
51 PrerequisitesChanged(); 42 // Here |run_requested_| transitions from false to true. So, |restart_timer_|
43 // must be stopped (either not even started, or has been cancelled in
44 // previous RequestStop() call).
45 DCHECK(!restart_timer_.IsRunning());
46
47 if (arc_session_) {
48 // In this case, RequestStop() was called, and before |arc_session_| had
49 // finished stopping, RequestStart() was called. Do nothing in that case,
50 // since when |arc_session_| does actually stop, OnSessionStopped() will
51 // be called, where it should automatically restart.
52 DCHECK_EQ(state(), State::STOPPING);
53 } else {
54 DCHECK_EQ(state(), State::STOPPED);
55 StartArcSession();
56 }
52 } 57 }
53 58
54 void ArcBridgeServiceImpl::RequestStop() { 59 void ArcBridgeServiceImpl::RequestStop() {
55 DCHECK(CalledOnValidThread()); 60 DCHECK(CalledOnValidThread());
56 if (!session_started_) 61
62 // Consecutive RequestStop() call. Do nothing.
63 if (!run_requested_)
57 return; 64 return;
65
58 VLOG(1) << "Session ended"; 66 VLOG(1) << "Session ended";
59 session_started_ = false; 67 run_requested_ = false;
60 PrerequisitesChanged(); 68
69 if (arc_session_) {
70 // The |state_| could be either STARTING, RUNNING or STOPPING.
71 DCHECK_NE(state(), State::STOPPED);
72
73 if (state() == State::STOPPING) {
74 // STOPPING is found in the senario of "RequestStart() -> RequestStop()
75 // -> RequestStart() -> RequestStop()" case.
76 // In the first RequestStop() call, |state_| is set to STOPPING,
77 // and in the second RequestStop() finds it (so this is the second call).
78 // In that case, ArcSession::Stop() is already called, so do nothing.
79 return;
80 }
81 SetState(State::STOPPING);
82 arc_session_->Stop();
83 } else {
84 DCHECK_EQ(state(), State::STOPPED);
85 // In case restarting is in progress, cancel it.
86 restart_timer_.Stop();
87 }
61 } 88 }
62 89
63 void ArcBridgeServiceImpl::OnShutdown() { 90 void ArcBridgeServiceImpl::OnShutdown() {
64 DCHECK(CalledOnValidThread()); 91 DCHECK(CalledOnValidThread());
65 92
66 VLOG(1) << "OnShutdown"; 93 VLOG(1) << "OnShutdown";
67 session_started_ = false; 94 run_requested_ = false;
68 restart_timer_.Stop(); 95 restart_timer_.Stop();
69 if (arc_session_) { 96 if (arc_session_) {
70 if (state() != State::STOPPING) 97 if (state() != State::STOPPING)
71 SetState(State::STOPPING); 98 SetState(State::STOPPING);
72 arc_session_->OnShutdown(); 99 arc_session_->OnShutdown();
73 } 100 }
74 // ArcSession::OnShutdown() invokes OnSessionStopped() synchronously. 101 // ArcSession::OnShutdown() invokes OnSessionStopped() synchronously.
75 // In the observer method, |arc_session_| should be destroyed. 102 // In the observer method, |arc_session_| should be destroyed.
76 DCHECK(!arc_session_); 103 DCHECK(!arc_session_);
77 } 104 }
78 105
79 void ArcBridgeServiceImpl::SetArcSessionFactoryForTesting( 106 void ArcBridgeServiceImpl::SetArcSessionFactoryForTesting(
80 const ArcSessionFactory& factory) { 107 const ArcSessionFactory& factory) {
81 DCHECK(!factory.is_null()); 108 DCHECK(!factory.is_null());
109 DCHECK_EQ(state(), State::STOPPED);
110 DCHECK(!arc_session_);
111 DCHECK(!restart_timer_.IsRunning());
82 factory_ = factory; 112 factory_ = factory;
83 } 113 }
84 114
85 void ArcBridgeServiceImpl::SetRestartDelayForTesting( 115 void ArcBridgeServiceImpl::SetRestartDelayForTesting(
86 const base::TimeDelta& restart_delay) { 116 const base::TimeDelta& restart_delay) {
87 DCHECK_EQ(state(), State::STOPPED); 117 DCHECK_EQ(state(), State::STOPPED);
88 DCHECK(!arc_session_); 118 DCHECK(!arc_session_);
89 DCHECK(!restart_timer_.IsRunning()); 119 DCHECK(!restart_timer_.IsRunning());
90 restart_delay_ = restart_delay; 120 restart_delay_ = restart_delay;
91 } 121 }
92 122
93 void ArcBridgeServiceImpl::PrerequisitesChanged() {
94 DCHECK(CalledOnValidThread());
95 VLOG(1) << "Prerequisites changed. "
96 << "state=" << static_cast<uint32_t>(state())
97 << ", session_started=" << session_started_;
98 if (state() == State::STOPPED) {
99 if (!session_started_) {
100 // We were explicitly asked to stop, so do not restart.
101 restart_timer_.Stop();
102 return;
103 }
104 DCHECK(!restart_timer_.IsRunning());
105 VLOG(0) << "Prerequisites met, starting ARC";
106 StartArcSession();
107 } else {
108 DCHECK(!restart_timer_.IsRunning());
109 if (session_started_)
110 return;
111 VLOG(0) << "Prerequisites stopped being met, stopping ARC";
112 StopInstance();
113 }
114 }
115
116 void ArcBridgeServiceImpl::StartArcSession() { 123 void ArcBridgeServiceImpl::StartArcSession() {
117 DCHECK(CalledOnValidThread()); 124 DCHECK(CalledOnValidThread());
118 DCHECK_EQ(state(), State::STOPPED); 125 DCHECK_EQ(state(), State::STOPPED);
119 DCHECK(!arc_session_); 126 DCHECK(!arc_session_);
120 DCHECK(!restart_timer_.IsRunning()); 127 DCHECK(!restart_timer_.IsRunning());
121 128
122 VLOG(1) << "Starting ARC instance"; 129 VLOG(1) << "Starting ARC instance";
123 SetStopReason(StopReason::SHUTDOWN); 130 SetStopReason(StopReason::SHUTDOWN);
124 arc_session_ = factory_.Run(); 131 arc_session_ = factory_.Run();
125 arc_session_->AddObserver(this); 132 arc_session_->AddObserver(this);
126 SetState(State::CONNECTING); 133 SetState(State::STARTING);
127 arc_session_->Start(); 134 arc_session_->Start();
128 } 135 }
129 136
130 void ArcBridgeServiceImpl::StopInstance() {
131 DCHECK(CalledOnValidThread());
132 DCHECK_NE(state(), State::STOPPED);
133 DCHECK(!restart_timer_.IsRunning());
134
135 if (state() == State::STOPPING) {
136 VLOG(1) << "StopInstance() called when ARC is not running";
137 return;
138 }
139
140 VLOG(1) << "Stopping ARC";
141 DCHECK(arc_session_.get());
142 SetState(State::STOPPING);
143
144 // Note: this can call OnStopped() internally as a callback.
145 arc_session_->Stop();
146 }
147
148 void ArcBridgeServiceImpl::OnSessionReady() { 137 void ArcBridgeServiceImpl::OnSessionReady() {
149 DCHECK(CalledOnValidThread()); 138 DCHECK(CalledOnValidThread());
150 if (state() != State::CONNECTING) { 139 DCHECK_EQ(state(), State::STARTING);
151 VLOG(1) << "StopInstance() called while connecting"; 140 DCHECK(arc_session_);
152 return; 141 DCHECK(!restart_timer_.IsRunning());
153 }
154 142
155 VLOG(0) << "ARC ready"; 143 VLOG(0) << "ARC ready";
156 SetState(State::READY); 144 SetState(State::RUNNING);
157 } 145 }
158 146
159 void ArcBridgeServiceImpl::OnSessionStopped(StopReason stop_reason) { 147 void ArcBridgeServiceImpl::OnSessionStopped(StopReason stop_reason) {
160 DCHECK(CalledOnValidThread()); 148 DCHECK(CalledOnValidThread());
149 DCHECK_NE(state(), State::STOPPED);
150 DCHECK(arc_session_);
161 DCHECK(!restart_timer_.IsRunning()); 151 DCHECK(!restart_timer_.IsRunning());
162 152
163 VLOG(0) << "ARC stopped: " << stop_reason; 153 VLOG(0) << "ARC stopped: " << stop_reason;
164 arc_session_->RemoveObserver(this); 154 arc_session_->RemoveObserver(this);
165 arc_session_.reset(); 155 arc_session_.reset();
166 156
167 // If READY, ARC instance unexpectedly crashed so we need to restart it 157 // If RUNNING, ARC instance unexpectedly crashed so we need to restart it
168 // automatically. 158 // automatically.
169 // If STOPPING, at least once RequestStop() is called. If |session_started_| 159 // If STOPPING, at least once RequestStop() is called. If |session_started_|
170 // is true, RequestStart() is following so schedule to restart ARC session. 160 // is true, RequestStart() is following so schedule to restart ARC session.
171 // Otherwise, do nothing. 161 // Otherwise, do nothing.
172 // If CONNECTING, ARC instance has not been booted properly, so do not 162 // If STARTING, ARC instance has not been booted properly, so do not
173 // restart it automatically. 163 // restart it automatically.
174 if (state() == State::READY || 164 if (state() == State::RUNNING ||
175 (state() == State::STOPPING && session_started_)) { 165 (state() == State::STOPPING && run_requested_)) {
176 // This check is for READY case. In READY case |session_started_| should be 166 // This check is for READY case. In RUNNING case |run_requested_| should
177 // always true, because if once RequestStop() is called, the state() will 167 // be always true, because if once RequestStop() is called, the state()
178 // be set to STOPPING. 168 // will be set to STOPPING.
179 DCHECK(session_started_); 169 DCHECK(run_requested_);
180 170
181 // There was a previous invocation and it crashed for some reason. Try 171 // There was a previous invocation and it crashed for some reason. Try
182 // starting ARC instance later again. 172 // starting ARC instance later again.
183 // Note that even |restart_delay_| is 0 (for testing), it needs to 173 // Note that even |restart_delay_| is 0 (for testing), it needs to
184 // PostTask, because observer callback may call RequestStart()/Stop(), 174 // PostTask, because observer callback may call RequestStart()/Stop(),
185 // which can change restarting. 175 // which can change restarting.
186 VLOG(0) << "ARC restarting"; 176 VLOG(0) << "ARC restarting";
187 restart_timer_.Start(FROM_HERE, restart_delay_, 177 restart_timer_.Start(FROM_HERE, restart_delay_,
188 base::Bind(&ArcBridgeServiceImpl::StartArcSession, 178 base::Bind(&ArcBridgeServiceImpl::StartArcSession,
189 weak_factory_.GetWeakPtr())); 179 weak_ptr_factory_.GetWeakPtr()));
190 } 180 }
191 181
192 // TODO(hidehiko): Consider to let observers know whether there is scheduled 182 // TODO(hidehiko): Consider to let observers know whether there is scheduled
193 // restarting event, or not. 183 // restarting event, or not.
194 SetStopReason(stop_reason); 184 SetStopReason(stop_reason);
195 SetState(State::STOPPED); 185 SetState(State::STOPPED);
196 } 186 }
197 187
198 } // namespace arc 188 } // namespace arc
OLDNEW
« no previous file with comments | « components/arc/arc_bridge_service_impl.h ('k') | components/arc/test/fake_arc_bridge_service.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698