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

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

Issue 2194193002: Fix ArcBridgeBootstrap race issues. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase. Created 4 years, 2 months 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/message_loop/message_loop.h" 12 #include "base/message_loop/message_loop.h"
13 #include "base/sequenced_task_runner.h" 13 #include "base/sequenced_task_runner.h"
14 #include "base/sys_info.h" 14 #include "base/sys_info.h"
15 #include "base/task_runner_util.h" 15 #include "base/task_runner_util.h"
16 #include "base/threading/thread_task_runner_handle.h" 16 #include "base/threading/thread_task_runner_handle.h"
17 #include "base/time/time.h" 17 #include "base/time/time.h"
18 #include "chromeos/chromeos_switches.h" 18 #include "chromeos/chromeos_switches.h"
19 #include "chromeos/dbus/dbus_method_call_status.h" 19 #include "chromeos/dbus/dbus_method_call_status.h"
20 #include "chromeos/dbus/dbus_thread_manager.h" 20 #include "chromeos/dbus/dbus_thread_manager.h"
21 #include "chromeos/dbus/session_manager_client.h"
22 #include "components/arc/arc_bridge_host_impl.h" 21 #include "components/arc/arc_bridge_host_impl.h"
23 #include "components/prefs/pref_registry_simple.h" 22 #include "components/prefs/pref_registry_simple.h"
24 #include "components/prefs/pref_service.h" 23 #include "components/prefs/pref_service.h"
25 24
26 namespace arc { 25 namespace arc {
27 26
28 extern ArcBridgeService* g_arc_bridge_service; 27 extern ArcBridgeService* g_arc_bridge_service;
29 28
30 namespace { 29 namespace {
31 constexpr int64_t kReconnectDelayInSeconds = 5; 30 constexpr int64_t kReconnectDelayInSeconds = 5;
32 } // namespace 31 } // namespace
33 32
34 ArcBridgeServiceImpl::ArcBridgeServiceImpl( 33 ArcBridgeServiceImpl::ArcBridgeServiceImpl()
35 std::unique_ptr<ArcBridgeBootstrap> bootstrap) 34 : session_started_(false),
36 : bootstrap_(std::move(bootstrap)), 35 factory_(base::Bind(ArcBridgeBootstrap::Create)),
37 session_started_(false),
38 weak_factory_(this) { 36 weak_factory_(this) {
39 DCHECK(!g_arc_bridge_service); 37 DCHECK(!g_arc_bridge_service);
40 g_arc_bridge_service = this; 38 g_arc_bridge_service = this;
41 bootstrap_->set_delegate(this);
42 } 39 }
43 40
44 ArcBridgeServiceImpl::~ArcBridgeServiceImpl() { 41 ArcBridgeServiceImpl::~ArcBridgeServiceImpl() {
45 DCHECK(g_arc_bridge_service == this); 42 DCHECK(g_arc_bridge_service == this);
46 g_arc_bridge_service = nullptr; 43 g_arc_bridge_service = nullptr;
47 } 44 }
48 45
49 void ArcBridgeServiceImpl::HandleStartup() { 46 void ArcBridgeServiceImpl::HandleStartup() {
50 DCHECK(CalledOnValidThread()); 47 DCHECK(CalledOnValidThread());
51 if (session_started_) 48 if (session_started_)
52 return; 49 return;
53 VLOG(1) << "Session started"; 50 VLOG(1) << "Session started";
54 session_started_ = true; 51 session_started_ = true;
55 PrerequisitesChanged(); 52 PrerequisitesChanged();
56 } 53 }
57 54
58 void ArcBridgeServiceImpl::Shutdown() { 55 void ArcBridgeServiceImpl::Shutdown() {
59 DCHECK(CalledOnValidThread()); 56 DCHECK(CalledOnValidThread());
60 if (!session_started_) 57 if (!session_started_)
61 return; 58 return;
62 VLOG(1) << "Session ended"; 59 VLOG(1) << "Session ended";
63 session_started_ = false; 60 session_started_ = false;
64 PrerequisitesChanged(); 61 PrerequisitesChanged();
65 } 62 }
66 63
64 void ArcBridgeServiceImpl::SetArcBridgeBootstrapFactoryForTesting(
65 const ArcBridgeBootstrapFactory& factory) {
66 DCHECK(!factory.is_null());
67 factory_ = factory;
68 }
69
70
67 void ArcBridgeServiceImpl::DisableReconnectDelayForTesting() { 71 void ArcBridgeServiceImpl::DisableReconnectDelayForTesting() {
68 use_delay_before_reconnecting_ = false; 72 use_delay_before_reconnecting_ = false;
69 } 73 }
70 74
71 void ArcBridgeServiceImpl::PrerequisitesChanged() { 75 void ArcBridgeServiceImpl::PrerequisitesChanged() {
72 DCHECK(CalledOnValidThread()); 76 DCHECK(CalledOnValidThread());
73 VLOG(1) << "Prerequisites changed. " 77 VLOG(1) << "Prerequisites changed. "
74 << "state=" << static_cast<uint32_t>(state()) 78 << "state=" << static_cast<uint32_t>(state())
75 << ", session_started=" << session_started_; 79 << ", session_started=" << session_started_;
76 if (state() == State::STOPPED) { 80 if (state() == State::STOPPED) {
77 if (!session_started_) 81 if (!session_started_)
78 return; 82 return;
79 VLOG(0) << "Prerequisites met, starting ARC"; 83 VLOG(0) << "Prerequisites met, starting ARC";
80 SetStopReason(StopReason::SHUTDOWN); 84 SetStopReason(StopReason::SHUTDOWN);
85
81 SetState(State::CONNECTING); 86 SetState(State::CONNECTING);
87 bootstrap_ = factory_.Run();
88 bootstrap_->set_delegate(this);
82 bootstrap_->Start(); 89 bootstrap_->Start();
83 } else { 90 } else {
84 if (session_started_) 91 if (session_started_)
85 return; 92 return;
86 VLOG(0) << "Prerequisites stopped being met, stopping ARC"; 93 VLOG(0) << "Prerequisites stopped being met, stopping ARC";
87 StopInstance(); 94 StopInstance();
88 } 95 }
89 } 96 }
90 97
91 void ArcBridgeServiceImpl::StopInstance() { 98 void ArcBridgeServiceImpl::StopInstance() {
92 DCHECK(CalledOnValidThread()); 99 DCHECK(CalledOnValidThread());
93 if (state() == State::STOPPED || state() == State::STOPPING) { 100 if (state() == State::STOPPED || state() == State::STOPPING) {
94 VLOG(1) << "StopInstance() called when ARC is not running"; 101 VLOG(1) << "StopInstance() called when ARC is not running";
95 return; 102 return;
96 } 103 }
97 104
105 // We were explicitly asked to stop, so do not reconnect.
106 reconnect_ = false;
107
98 VLOG(1) << "Stopping ARC"; 108 VLOG(1) << "Stopping ARC";
109 DCHECK(bootstrap_.get());
99 SetState(State::STOPPING); 110 SetState(State::STOPPING);
100 arc_bridge_host_.reset(); 111 arc_bridge_host_.reset();
112
113 // Note: this can call OnStopped() internally as a callback.
101 bootstrap_->Stop(); 114 bootstrap_->Stop();
102
103 // We were explicitly asked to stop, so do not reconnect.
104 reconnect_ = false;
105 } 115 }
106 116
107 void ArcBridgeServiceImpl::OnConnectionEstablished( 117 void ArcBridgeServiceImpl::OnConnectionEstablished(
108 mojom::ArcBridgeInstancePtr instance) { 118 mojom::ArcBridgeInstancePtr instance) {
109 DCHECK(CalledOnValidThread()); 119 DCHECK(CalledOnValidThread());
110 if (state() != State::CONNECTING) { 120 if (state() != State::CONNECTING) {
111 VLOG(1) << "StopInstance() called while connecting"; 121 VLOG(1) << "StopInstance() called while connecting";
112 return; 122 return;
113 } 123 }
114 124
115 arc_bridge_host_.reset(new ArcBridgeHostImpl(std::move(instance))); 125 arc_bridge_host_.reset(new ArcBridgeHostImpl(std::move(instance)));
116 126
117 // The container can be considered to have been successfully launched, so 127 // The container can be considered to have been successfully launched, so
118 // restart if the connection goes down without being requested. 128 // restart if the connection goes down without being requested.
119 reconnect_ = true; 129 reconnect_ = true;
120 VLOG(0) << "ARC ready"; 130 VLOG(0) << "ARC ready";
121 SetState(State::READY); 131 SetState(State::READY);
122 } 132 }
123 133
124 void ArcBridgeServiceImpl::OnStopped(StopReason stop_reason) { 134 void ArcBridgeServiceImpl::OnStopped(StopReason stop_reason) {
125 DCHECK(CalledOnValidThread()); 135 DCHECK(CalledOnValidThread());
136 VLOG(0) << "ARC stopped: " << stop_reason;
126 arc_bridge_host_.reset(); 137 arc_bridge_host_.reset();
138 bootstrap_.reset();
127 SetStopReason(stop_reason); 139 SetStopReason(stop_reason);
128 SetState(State::STOPPED); 140 SetState(State::STOPPED);
129 VLOG(0) << "ARC stopped";
130 141
131 if (reconnect_) { 142 if (reconnect_) {
132 // There was a previous invocation and it crashed for some reason. Try 143 // There was a previous invocation and it crashed for some reason. Try
133 // starting the container again. 144 // starting the container again.
134 reconnect_ = false; 145 reconnect_ = false;
135 VLOG(0) << "ARC reconnecting"; 146 VLOG(0) << "ARC reconnecting";
136 if (use_delay_before_reconnecting_) { 147 if (use_delay_before_reconnecting_) {
137 // Instead of immediately trying to restart the container, give it some 148 // Instead of immediately trying to restart the container, give it some
138 // time to finish tearing down in case it is still in the process of 149 // time to finish tearing down in case it is still in the process of
139 // stopping. 150 // stopping.
140 base::MessageLoop::current()->task_runner()->PostDelayedTask( 151 base::MessageLoop::current()->task_runner()->PostDelayedTask(
141 FROM_HERE, base::Bind(&ArcBridgeServiceImpl::PrerequisitesChanged, 152 FROM_HERE, base::Bind(&ArcBridgeServiceImpl::PrerequisitesChanged,
142 weak_factory_.GetWeakPtr()), 153 weak_factory_.GetWeakPtr()),
143 base::TimeDelta::FromSeconds(kReconnectDelayInSeconds)); 154 base::TimeDelta::FromSeconds(kReconnectDelayInSeconds));
144 } else { 155 } else {
145 // Restart immediately. 156 // Restart immediately.
146 PrerequisitesChanged(); 157 PrerequisitesChanged();
147 } 158 }
148 } 159 }
149 } 160 }
150 161
151 } // namespace arc 162 } // 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