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

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

Issue 2577373002: Refactor ArcBridgeServiceImpl part 2. (Closed)
Patch Set: 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 namespace { 13 namespace {
26 14
27 constexpr base::TimeDelta kDefaultRestartDelay = 15 constexpr base::TimeDelta kDefaultRestartDelay =
28 base::TimeDelta::FromSeconds(5); 16 base::TimeDelta::FromSeconds(5);
29 17
30 } // namespace 18 } // namespace
31 19
32 ArcBridgeServiceImpl::ArcBridgeServiceImpl( 20 ArcBridgeServiceImpl::ArcBridgeServiceImpl(
33 const scoped_refptr<base::TaskRunner>& blocking_task_runner) 21 const scoped_refptr<base::TaskRunner>& blocking_task_runner)
34 : session_started_(false), 22 : restart_delay_(kDefaultRestartDelay),
35 restart_delay_(kDefaultRestartDelay),
36 factory_(base::Bind(ArcSession::Create, this, blocking_task_runner)), 23 factory_(base::Bind(ArcSession::Create, this, blocking_task_runner)),
37 weak_factory_(this) {} 24 weak_ptr_factory_(this) {}
38 25
39 ArcBridgeServiceImpl::~ArcBridgeServiceImpl() { 26 ArcBridgeServiceImpl::~ArcBridgeServiceImpl() {
27 DCHECK(CalledOnValidThread());
40 if (arc_session_) 28 if (arc_session_)
41 arc_session_->RemoveObserver(this); 29 arc_session_->RemoveObserver(this);
42 } 30 }
43 31
44 void ArcBridgeServiceImpl::RequestStart() { 32 void ArcBridgeServiceImpl::RequestStart() {
45 DCHECK(CalledOnValidThread()); 33 DCHECK(CalledOnValidThread());
46 if (session_started_) 34
35 // Consecutive RequestStart() call. Do nothing.
36 if (running_)
47 return; 37 return;
38
48 VLOG(1) << "Session started"; 39 VLOG(1) << "Session started";
49 session_started_ = true; 40 running_ = true;
50 PrerequisitesChanged(); 41 // Here the |running_| becomes false to true. So, |restart_timer_| must be
Luis Héctor Chávez 2016/12/16 23:20:12 nit: "Here |running_| transitions from false to tr
hidehiko 2016/12/19 08:05:11 Done.
42 // stopped (either not even started, or has been cancelled in previous
43 // RequestStop() call).
44 DCHECK(!restart_timer_.IsRunning());
45
46 if (arc_session_) {
47 // This case, a client calls RequestStop() in advance, then soon
Luis Héctor Chávez 2016/12/16 23:20:12 nit: "In this case, RequestStop() was called, and
hidehiko 2016/12/19 08:05:11 Done.
48 // RequestStart(). In such a case, |arc_session_| must be requested
49 // to stop already. Then, do nothing now, and later in OnSessionStopped(),
50 // restarting should be handled.
51 DCHECK_EQ(state(), State::STOPPING);
52 } else {
53 DCHECK_EQ(state(), State::STOPPED);
54 StartArcSession();
55 }
51 } 56 }
52 57
53 void ArcBridgeServiceImpl::RequestStop() { 58 void ArcBridgeServiceImpl::RequestStop() {
54 DCHECK(CalledOnValidThread()); 59 DCHECK(CalledOnValidThread());
55 if (!session_started_) 60
61 // Consecutive RequestStop() call. Do nothing.
62 if (!running_)
56 return; 63 return;
64
57 VLOG(1) << "Session ended"; 65 VLOG(1) << "Session ended";
58 session_started_ = false; 66 running_ = false;
59 PrerequisitesChanged(); 67
68 if (arc_session_) {
69 // The |state_| could be either STARTING, RUNNING or STOPPING.
70 DCHECK_NE(state(), State::STOPPED);
71
72 // STOPPING is found in the senario of "RequestStart() -> RequestStop()
73 // -> RequestStart() -> RequestStop()" case.
74 // In the first RequestStop() call, |state_| is set to STOPPING,
75 // and in the second RequestStop() finds it (so this is the second call).
76 // In that case, ArcSession::Stop() is already called, so do nothing.
77 if (state() != State::STOPPING) {
Luis Héctor Chávez 2016/12/16 23:20:12 nit: if (state() == State::STOPPING) { // STOPP
hidehiko 2016/12/19 08:05:11 Done.
78 SetState(State::STOPPING);
79 arc_session_->Stop();
80 }
81 } else {
82 DCHECK_EQ(state(), State::STOPPED);
83 // In case restarting is in progress, cancel it.
84 restart_timer_.Stop();
85 }
60 } 86 }
61 87
62 void ArcBridgeServiceImpl::OnShutdown() { 88 void ArcBridgeServiceImpl::OnShutdown() {
63 DCHECK(CalledOnValidThread()); 89 DCHECK(CalledOnValidThread());
64 90
65 VLOG(1) << "OnShutdown"; 91 VLOG(1) << "OnShutdown";
66 session_started_ = false; 92 running_ = false;
67 restart_timer_.Stop(); 93 restart_timer_.Stop();
68 if (arc_session_) 94 if (arc_session_)
69 arc_session_->OnShutdown(); 95 arc_session_->OnShutdown();
70 // ArcSession::OnShutdown() invokes OnSessionStopped() synchronously. 96 // ArcSession::OnShutdown() invokes OnSessionStopped() synchronously.
71 // In the observer method, |arc_session_| should be destroyed. 97 // In the observer method, |arc_session_| should be destroyed.
72 DCHECK(!arc_session_); 98 DCHECK(!arc_session_);
73 } 99 }
74 100
75 void ArcBridgeServiceImpl::SetArcSessionFactoryForTesting( 101 void ArcBridgeServiceImpl::SetArcSessionFactoryForTesting(
76 const ArcSessionFactory& factory) { 102 const ArcSessionFactory& factory) {
77 DCHECK(!factory.is_null()); 103 DCHECK(!factory.is_null());
104 DCHECK_EQ(state(), State::STOPPED);
105 DCHECK(!arc_session_);
106 DCHECK(!restart_timer_.IsRunning());
78 factory_ = factory; 107 factory_ = factory;
79 } 108 }
80 109
81 void ArcBridgeServiceImpl::SetRestartDelayForTesting( 110 void ArcBridgeServiceImpl::SetRestartDelayForTesting(
82 const base::TimeDelta& restart_delay) { 111 const base::TimeDelta& restart_delay) {
83 DCHECK_EQ(state(), State::STOPPED); 112 DCHECK_EQ(state(), State::STOPPED);
84 DCHECK(!arc_session_); 113 DCHECK(!arc_session_);
85 DCHECK(!restart_timer_.IsRunning()); 114 DCHECK(!restart_timer_.IsRunning());
86 restart_delay_ = restart_delay; 115 restart_delay_ = restart_delay;
87 } 116 }
88 117
89 void ArcBridgeServiceImpl::PrerequisitesChanged() {
90 DCHECK(CalledOnValidThread());
91 VLOG(1) << "Prerequisites changed. "
92 << "state=" << static_cast<uint32_t>(state())
93 << ", session_started=" << session_started_;
94 if (state() == State::STOPPED) {
95 if (!session_started_) {
96 // We were explicitly asked to stop, so do not restart.
97 restart_timer_.Stop();
98 return;
99 }
100 DCHECK(!restart_timer_.IsRunning());
101 VLOG(0) << "Prerequisites met, starting ARC";
102 StartArcSession();
103 } else {
104 DCHECK(!restart_timer_.IsRunning());
105 if (session_started_)
106 return;
107 VLOG(0) << "Prerequisites stopped being met, stopping ARC";
108 StopInstance();
109 }
110 }
111
112 void ArcBridgeServiceImpl::StartArcSession() { 118 void ArcBridgeServiceImpl::StartArcSession() {
113 DCHECK(CalledOnValidThread()); 119 DCHECK(CalledOnValidThread());
114 DCHECK_EQ(state(), State::STOPPED); 120 DCHECK_EQ(state(), State::STOPPED);
115 DCHECK(!arc_session_); 121 DCHECK(!arc_session_);
116 DCHECK(!restart_timer_.IsRunning()); 122 DCHECK(!restart_timer_.IsRunning());
117 123
118 VLOG(1) << "Starting ARC instance"; 124 VLOG(1) << "Starting ARC instance";
119 SetStopReason(StopReason::SHUTDOWN); 125 SetStopReason(StopReason::SHUTDOWN);
120 arc_session_ = factory_.Run(); 126 arc_session_ = factory_.Run();
121 arc_session_->AddObserver(this); 127 arc_session_->AddObserver(this);
122 SetState(State::CONNECTING); 128 SetState(State::STARTING);
123 arc_session_->Start(); 129 arc_session_->Start();
124 } 130 }
125 131
126 void ArcBridgeServiceImpl::StopInstance() {
127 DCHECK(CalledOnValidThread());
128 DCHECK_NE(state(), State::STOPPED);
129 DCHECK(!restart_timer_.IsRunning());
130
131 if (state() == State::STOPPING) {
132 VLOG(1) << "StopInstance() called when ARC is not running";
133 return;
134 }
135
136 VLOG(1) << "Stopping ARC";
137 DCHECK(arc_session_.get());
138 SetState(State::STOPPING);
139
140 // Note: this can call OnStopped() internally as a callback.
141 arc_session_->Stop();
142 }
143
144 void ArcBridgeServiceImpl::OnSessionReady() { 132 void ArcBridgeServiceImpl::OnSessionReady() {
145 DCHECK(CalledOnValidThread()); 133 DCHECK(CalledOnValidThread());
146 if (state() != State::CONNECTING) { 134 DCHECK_EQ(state(), State::STARTING);
147 VLOG(1) << "StopInstance() called while connecting"; 135 DCHECK(arc_session_);
148 return; 136 DCHECK(!restart_timer_.IsRunning());
149 }
150 137
151 VLOG(0) << "ARC ready"; 138 VLOG(0) << "ARC ready";
152 SetState(State::READY); 139 SetState(State::RUNNING);
153 } 140 }
154 141
155 void ArcBridgeServiceImpl::OnSessionStopped(StopReason stop_reason) { 142 void ArcBridgeServiceImpl::OnSessionStopped(StopReason stop_reason) {
156 DCHECK(CalledOnValidThread()); 143 DCHECK(CalledOnValidThread());
144 DCHECK_NE(state(), State::STOPPED);
145 DCHECK(arc_session_);
157 DCHECK(!restart_timer_.IsRunning()); 146 DCHECK(!restart_timer_.IsRunning());
158 147
159 VLOG(0) << "ARC stopped: " << stop_reason; 148 VLOG(0) << "ARC stopped: " << stop_reason;
160 arc_session_->RemoveObserver(this); 149 arc_session_->RemoveObserver(this);
161 arc_session_.reset(); 150 arc_session_.reset();
162 151
163 // If READY, ARC instance is unexpectedly crashed so we need to restart it 152 // If READY, ARC instance is unexpectedly crashed so we need to restart it
164 // automatically. If STOPPING, it is the result of consecutive RequestStop() 153 // automatically. If STOPPING, it is the result of consecutive RequestStop()
165 // followed by RequestStart() invocation. 154 // followed by RequestStart() invocation.
166 // If CONNECTING, ARC instance has not been booted properly, so do not 155 // If CONNECTING, ARC instance has not been booted properly, so do not
Luis Héctor Chávez 2016/12/16 23:20:12 STARTING?
hidehiko 2016/12/19 08:05:11 Done.
167 // restart it automatically. 156 // restart it automatically.
168 if (session_started_ && 157 if (running_ && (state() == State::RUNNING || state() == State::STOPPING)) {
169 (state() == State::READY || state() == State::STOPPING)) {
170 // There was a previous invocation and it crashed for some reason. Try 158 // There was a previous invocation and it crashed for some reason. Try
171 // starting ARC instance later again. 159 // starting ARC instance later again.
172 // Note that even |restart_delay_| is 0 (for testing), it needs to 160 // Note that even |restart_delay_| is 0 (for testing), it needs to
173 // PostTask, because observer callback may call RequestStart()/Stop(), 161 // PostTask, because observer callback may call RequestStart()/Stop(),
174 // which can change restarting. 162 // which can change restarting.
175 VLOG(0) << "ARC restarting"; 163 VLOG(0) << "ARC restarting";
176 restart_timer_.Start(FROM_HERE, restart_delay_, 164 restart_timer_.Start(FROM_HERE, restart_delay_,
177 base::Bind(&ArcBridgeServiceImpl::StartArcSession, 165 base::Bind(&ArcBridgeServiceImpl::StartArcSession,
178 weak_factory_.GetWeakPtr())); 166 weak_ptr_factory_.GetWeakPtr()));
179 } 167 }
180 168
181 SetStopReason(stop_reason); 169 SetStopReason(stop_reason);
182 SetState(State::STOPPED); 170 SetState(State::STOPPED);
183 } 171 }
184 172
185 } // namespace arc 173 } // namespace arc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698