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

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

Issue 2582003002: Refactor ArcBridgeServiceImpl part 1. (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
« no previous file with comments | « components/arc/arc_bridge_service_impl.h ('k') | components/arc/arc_bridge_service_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <string>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/json/json_writer.h" 11 #include "base/json/json_writer.h"
12 #include "base/sequenced_task_runner.h" 12 #include "base/sequenced_task_runner.h"
13 #include "base/sys_info.h" 13 #include "base/sys_info.h"
14 #include "base/task_runner_util.h" 14 #include "base/task_runner_util.h"
15 #include "base/threading/thread_task_runner_handle.h" 15 #include "base/threading/thread_task_runner_handle.h"
16 #include "base/time/time.h" 16 #include "base/time/time.h"
17 #include "chromeos/chromeos_switches.h" 17 #include "chromeos/chromeos_switches.h"
18 #include "chromeos/dbus/dbus_method_call_status.h" 18 #include "chromeos/dbus/dbus_method_call_status.h"
19 #include "chromeos/dbus/dbus_thread_manager.h" 19 #include "chromeos/dbus/dbus_thread_manager.h"
20 #include "components/arc/arc_session.h" 20 #include "components/arc/arc_session.h"
21 #include "components/prefs/pref_registry_simple.h" 21 #include "components/prefs/pref_registry_simple.h"
22 #include "components/prefs/pref_service.h" 22 #include "components/prefs/pref_service.h"
23 23
24 namespace arc { 24 namespace arc {
25 namespace { 25 namespace {
Luis Héctor Chávez 2016/12/16 23:02:13 nit: maybe add a newline before for consistency?
hidehiko 2016/12/19 07:41:21 Done.
26 constexpr int64_t kReconnectDelayInSeconds = 5; 26
27 constexpr base::TimeDelta kDefaultRestartDelay =
28 base::TimeDelta::FromSeconds(5);
29
27 } // namespace 30 } // namespace
28 31
29 ArcBridgeServiceImpl::ArcBridgeServiceImpl( 32 ArcBridgeServiceImpl::ArcBridgeServiceImpl(
30 const scoped_refptr<base::TaskRunner>& blocking_task_runner) 33 const scoped_refptr<base::TaskRunner>& blocking_task_runner)
31 : session_started_(false), 34 : session_started_(false),
35 restart_delay_(kDefaultRestartDelay),
32 factory_(base::Bind(ArcSession::Create, this, blocking_task_runner)), 36 factory_(base::Bind(ArcSession::Create, this, blocking_task_runner)),
33 weak_factory_(this) {} 37 weak_factory_(this) {}
34 38
35 ArcBridgeServiceImpl::~ArcBridgeServiceImpl() { 39 ArcBridgeServiceImpl::~ArcBridgeServiceImpl() {
36 if (arc_session_) 40 if (arc_session_)
37 arc_session_->RemoveObserver(this); 41 arc_session_->RemoveObserver(this);
38 } 42 }
39 43
40 void ArcBridgeServiceImpl::RequestStart() { 44 void ArcBridgeServiceImpl::RequestStart() {
41 DCHECK(CalledOnValidThread()); 45 DCHECK(CalledOnValidThread());
42 if (session_started_) 46 if (session_started_)
43 return; 47 return;
44 VLOG(1) << "Session started"; 48 VLOG(1) << "Session started";
45 session_started_ = true; 49 session_started_ = true;
46 PrerequisitesChanged(); 50 PrerequisitesChanged();
47 } 51 }
48 52
49 void ArcBridgeServiceImpl::RequestStop() { 53 void ArcBridgeServiceImpl::RequestStop() {
50 DCHECK(CalledOnValidThread()); 54 DCHECK(CalledOnValidThread());
51 if (!session_started_) 55 if (!session_started_)
52 return; 56 return;
53 VLOG(1) << "Session ended"; 57 VLOG(1) << "Session ended";
54 session_started_ = false; 58 session_started_ = false;
55 PrerequisitesChanged(); 59 PrerequisitesChanged();
56 } 60 }
57 61
58 void ArcBridgeServiceImpl::OnShutdown() { 62 void ArcBridgeServiceImpl::OnShutdown() {
59 DCHECK(CalledOnValidThread()); 63 DCHECK(CalledOnValidThread());
64
60 VLOG(1) << "OnShutdown"; 65 VLOG(1) << "OnShutdown";
61 if (!session_started_)
62 return;
63 session_started_ = false; 66 session_started_ = false;
64 reconnect_ = false; 67 restart_timer_.Stop();
65 if (arc_session_) 68 if (arc_session_)
66 arc_session_->OnShutdown(); 69 arc_session_->OnShutdown();
70 // ArcSession::OnShutdown() invokes OnSessionStopped() synchronously.
71 // In the observer method, |arc_session_| should be destroyed.
72 DCHECK(!arc_session_);
67 } 73 }
68 74
69 void ArcBridgeServiceImpl::SetArcSessionFactoryForTesting( 75 void ArcBridgeServiceImpl::SetArcSessionFactoryForTesting(
70 const ArcSessionFactory& factory) { 76 const ArcSessionFactory& factory) {
71 DCHECK(!factory.is_null()); 77 DCHECK(!factory.is_null());
72 factory_ = factory; 78 factory_ = factory;
73 } 79 }
74 80
75 void ArcBridgeServiceImpl::DisableReconnectDelayForTesting() { 81 void ArcBridgeServiceImpl::SetRestartDelayForTesting(
76 use_delay_before_reconnecting_ = false; 82 const base::TimeDelta& restart_delay) {
83 DCHECK_EQ(state(), State::STOPPED);
84 DCHECK(!arc_session_);
85 DCHECK(!restart_timer_.IsRunning());
86 restart_delay_ = restart_delay;
77 } 87 }
78 88
79 void ArcBridgeServiceImpl::PrerequisitesChanged() { 89 void ArcBridgeServiceImpl::PrerequisitesChanged() {
Luis Héctor Chávez 2016/12/16 23:02:13 Now that you've removed the third caller of Prereq
Luis Héctor Chávez 2016/12/16 23:06:35 Nevermind about this, I just saw your second patch
hidehiko 2016/12/19 07:41:21 Yes. Let me work on it in the following CL.
80 DCHECK(CalledOnValidThread()); 90 DCHECK(CalledOnValidThread());
81 VLOG(1) << "Prerequisites changed. " 91 VLOG(1) << "Prerequisites changed. "
82 << "state=" << static_cast<uint32_t>(state()) 92 << "state=" << static_cast<uint32_t>(state())
83 << ", session_started=" << session_started_; 93 << ", session_started=" << session_started_;
84 if (state() == State::STOPPED) { 94 if (state() == State::STOPPED) {
85 if (!session_started_) 95 if (!session_started_) {
96 // We were explicitly asked to stop, so do not restart.
97 restart_timer_.Stop();
Luis Héctor Chávez 2016/12/16 23:02:13 How about you move this to L96-97 to RequestStop()
hidehiko 2016/12/19 07:41:21 If this is not a big problem, can I keep this in t
86 return; 98 return;
99 }
100 DCHECK(!restart_timer_.IsRunning());
Luis Héctor Chávez 2016/12/16 23:02:13 Both branches check for this. Move to after L93?
hidehiko 2016/12/19 07:41:21 Similar to above, can I address this in the follow
87 VLOG(0) << "Prerequisites met, starting ARC"; 101 VLOG(0) << "Prerequisites met, starting ARC";
88 SetStopReason(StopReason::SHUTDOWN); 102 StartArcSession();
89
90 if (arc_session_)
91 arc_session_->RemoveObserver(this);
92
93 SetState(State::CONNECTING);
94 arc_session_ = factory_.Run();
95 arc_session_->AddObserver(this);
96 arc_session_->Start();
97 } else { 103 } else {
104 DCHECK(!restart_timer_.IsRunning());
98 if (session_started_) 105 if (session_started_)
99 return; 106 return;
100 VLOG(0) << "Prerequisites stopped being met, stopping ARC"; 107 VLOG(0) << "Prerequisites stopped being met, stopping ARC";
101 StopInstance(); 108 StopInstance();
102 } 109 }
103 } 110 }
104 111
112 void ArcBridgeServiceImpl::StartArcSession() {
113 DCHECK(CalledOnValidThread());
114 DCHECK_EQ(state(), State::STOPPED);
115 DCHECK(!arc_session_);
116 DCHECK(!restart_timer_.IsRunning());
117
118 VLOG(1) << "Starting ARC instance";
119 SetStopReason(StopReason::SHUTDOWN);
120 arc_session_ = factory_.Run();
121 arc_session_->AddObserver(this);
122 SetState(State::CONNECTING);
123 arc_session_->Start();
124 }
125
105 void ArcBridgeServiceImpl::StopInstance() { 126 void ArcBridgeServiceImpl::StopInstance() {
106 DCHECK(CalledOnValidThread()); 127 DCHECK(CalledOnValidThread());
107 if (state() == State::STOPPED || state() == State::STOPPING) { 128 DCHECK_NE(state(), State::STOPPED);
129 DCHECK(!restart_timer_.IsRunning());
130
131 if (state() == State::STOPPING) {
108 VLOG(1) << "StopInstance() called when ARC is not running"; 132 VLOG(1) << "StopInstance() called when ARC is not running";
109 return; 133 return;
110 } 134 }
111 135
112 // We were explicitly asked to stop, so do not reconnect.
113 reconnect_ = false;
114
115 VLOG(1) << "Stopping ARC"; 136 VLOG(1) << "Stopping ARC";
116 DCHECK(arc_session_.get()); 137 DCHECK(arc_session_.get());
117 SetState(State::STOPPING); 138 SetState(State::STOPPING);
118 139
119 // Note: this can call OnStopped() internally as a callback. 140 // Note: this can call OnStopped() internally as a callback.
120 arc_session_->Stop(); 141 arc_session_->Stop();
121 } 142 }
122 143
123 void ArcBridgeServiceImpl::OnSessionReady() { 144 void ArcBridgeServiceImpl::OnSessionReady() {
124 DCHECK(CalledOnValidThread()); 145 DCHECK(CalledOnValidThread());
125 if (state() != State::CONNECTING) { 146 if (state() != State::CONNECTING) {
126 VLOG(1) << "StopInstance() called while connecting"; 147 VLOG(1) << "StopInstance() called while connecting";
127 return; 148 return;
128 } 149 }
129 150
130 // The container can be considered to have been successfully launched, so
131 // restart if the connection goes down without being requested.
132 reconnect_ = true;
133 VLOG(0) << "ARC ready"; 151 VLOG(0) << "ARC ready";
134 SetState(State::READY); 152 SetState(State::READY);
135 } 153 }
136 154
137 void ArcBridgeServiceImpl::OnSessionStopped(StopReason stop_reason) { 155 void ArcBridgeServiceImpl::OnSessionStopped(StopReason stop_reason) {
138 DCHECK(CalledOnValidThread()); 156 DCHECK(CalledOnValidThread());
157 DCHECK(!restart_timer_.IsRunning());
158
139 VLOG(0) << "ARC stopped: " << stop_reason; 159 VLOG(0) << "ARC stopped: " << stop_reason;
140 arc_session_->RemoveObserver(this); 160 arc_session_->RemoveObserver(this);
141 arc_session_.reset(); 161 arc_session_.reset();
162
163 // If READY, ARC instance is unexpectedly crashed so we need to restart it
Luis Héctor Chávez 2016/12/16 23:02:13 nit: "ARC instance unexpectedly crashed".
hidehiko 2016/12/19 07:41:21 Done.
164 // automatically. If STOPPING, it is the result of consecutive RequestStop()
165 // followed by RequestStart() invocation.
166 // If CONNECTING, ARC instance has not been booted properly, so do not
167 // restart it automatically.
168 if (session_started_ &&
Luis Héctor Chávez 2016/12/16 23:02:13 In the same spirit as we did reset |reconnect_|, s
hidehiko 2016/12/19 07:41:21 IIUC, unlike |reconnect_|, |session_started_| shou
Luis Héctor Chávez 2016/12/19 22:23:38 I like the proposed condition much better, since i
hidehiko 2016/12/20 13:38:02 Sure, done. Just in case, could you take another l
169 (state() == State::READY || state() == State::STOPPING)) {
170 // There was a previous invocation and it crashed for some reason. Try
171 // starting ARC instance later again.
172 // Note that even |restart_delay_| is 0 (for testing), it needs to
173 // PostTask, because observer callback may call RequestStart()/Stop(),
174 // which can change restarting.
175 VLOG(0) << "ARC restarting";
176 restart_timer_.Start(FROM_HERE, restart_delay_,
177 base::Bind(&ArcBridgeServiceImpl::StartArcSession,
178 weak_factory_.GetWeakPtr()));
179 }
180
142 SetStopReason(stop_reason); 181 SetStopReason(stop_reason);
143 SetState(State::STOPPED); 182 SetState(State::STOPPED);
144
145 if (reconnect_) {
146 // There was a previous invocation and it crashed for some reason. Try
147 // starting the container again.
148 reconnect_ = false;
149 VLOG(0) << "ARC reconnecting";
150 if (use_delay_before_reconnecting_) {
151 // Instead of immediately trying to restart the container, give it some
152 // time to finish tearing down in case it is still in the process of
153 // stopping.
154 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
155 FROM_HERE, base::Bind(&ArcBridgeServiceImpl::PrerequisitesChanged,
156 weak_factory_.GetWeakPtr()),
157 base::TimeDelta::FromSeconds(kReconnectDelayInSeconds));
158 } else {
159 // Restart immediately.
160 PrerequisitesChanged();
161 }
162 }
163 } 183 }
164 184
165 } // namespace arc 185 } // namespace arc
OLDNEW
« no previous file with comments | « components/arc/arc_bridge_service_impl.h ('k') | components/arc/arc_bridge_service_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698