Chromium Code Reviews| OLD | NEW |
|---|---|
| 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_session.h" | 5 #include "components/arc/arc_session.h" |
| 6 | 6 |
| 7 #include <fcntl.h> | 7 #include <fcntl.h> |
| 8 #include <grp.h> | 8 #include <grp.h> |
| 9 #include <poll.h> | 9 #include <poll.h> |
| 10 #include <unistd.h> | 10 #include <unistd.h> |
| 11 | 11 |
| 12 #include <utility> | 12 #include <utility> |
| 13 | 13 |
| 14 #include "base/files/file_path.h" | 14 #include "base/files/file_path.h" |
| 15 #include "base/files/file_util.h" | 15 #include "base/files/file_util.h" |
| 16 #include "base/location.h" | 16 #include "base/location.h" |
| 17 #include "base/macros.h" | 17 #include "base/macros.h" |
| 18 #include "base/memory/ptr_util.h" | 18 #include "base/memory/ptr_util.h" |
| 19 #include "base/posix/eintr_wrapper.h" | 19 #include "base/posix/eintr_wrapper.h" |
| 20 #include "base/sys_info.h" | 20 #include "base/sys_info.h" |
| 21 #include "base/task_runner_util.h" | 21 #include "base/task_runner_util.h" |
| 22 #include "base/threading/thread_checker.h" | 22 #include "base/threading/thread_checker.h" |
| 23 #include "base/threading/thread_task_runner_handle.h" | 23 #include "base/threading/thread_task_runner_handle.h" |
| 24 #include "base/threading/worker_pool.h" | |
| 25 #include "chromeos/cryptohome/cryptohome_parameters.h" | 24 #include "chromeos/cryptohome/cryptohome_parameters.h" |
| 26 #include "chromeos/dbus/dbus_method_call_status.h" | 25 #include "chromeos/dbus/dbus_method_call_status.h" |
| 27 #include "chromeos/dbus/dbus_thread_manager.h" | 26 #include "chromeos/dbus/dbus_thread_manager.h" |
| 28 #include "chromeos/dbus/session_manager_client.h" | 27 #include "chromeos/dbus/session_manager_client.h" |
| 29 #include "components/arc/arc_bridge_host_impl.h" | 28 #include "components/arc/arc_bridge_host_impl.h" |
| 30 #include "components/arc/arc_features.h" | 29 #include "components/arc/arc_features.h" |
| 31 #include "components/user_manager/user_manager.h" | 30 #include "components/user_manager/user_manager.h" |
| 32 #include "ipc/unix_domain_socket_util.h" | 31 #include "ipc/unix_domain_socket_util.h" |
| 33 #include "mojo/edk/embedder/embedder.h" | 32 #include "mojo/edk/embedder/embedder.h" |
| 34 #include "mojo/edk/embedder/platform_channel_pair.h" | 33 #include "mojo/edk/embedder/platform_channel_pair.h" |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 125 // At any state, Stop() can be called. It does not immediately stop the | 124 // At any state, Stop() can be called. It does not immediately stop the |
| 126 // instance, but will eventually stop it. | 125 // instance, but will eventually stop it. |
| 127 // The actual stop will be notified via Observer::OnStopped(). | 126 // The actual stop will be notified via Observer::OnStopped(). |
| 128 // | 127 // |
| 129 // When Stop() is called, it makes various behavior based on the current | 128 // When Stop() is called, it makes various behavior based on the current |
| 130 // phase. | 129 // phase. |
| 131 // | 130 // |
| 132 // NOT_STARTED: | 131 // NOT_STARTED: |
| 133 // Do nothing. Immediately transition to the STOPPED state. | 132 // Do nothing. Immediately transition to the STOPPED state. |
| 134 // CREATING_SOCKET: | 133 // CREATING_SOCKET: |
| 135 // The main task of the phase runs on WorkerPool thread. So, Stop() just | 134 // The main task of the phase runs on BlockingPool thread. So, Stop() just |
| 136 // sets the flag and return. On the main task completion, a callback | 135 // sets the flag and return. On the main task completion, a callback |
| 137 // will run on the main (practically UI) thread, and the flag is checked | 136 // will run on the main (practically UI) thread, and the flag is checked |
| 138 // at the beginning of them. This should work under the assumption that | 137 // at the beginning of them. This should work under the assumption that |
| 139 // the main tasks do not block indefinitely. | 138 // the main tasks do not block indefinitely. |
| 140 // STARTING_INSTANCE: | 139 // STARTING_INSTANCE: |
| 141 // The ARC instance is starting via SessionManager. So, similar to | 140 // The ARC instance is starting via SessionManager. So, similar to |
| 142 // CREATING_SOCKET case, Stop() just sets the flag and return. In its | 141 // CREATING_SOCKET case, Stop() just sets the flag and return. In its |
| 143 // callback, it checks if ARC instance is successfully started or not. | 142 // callback, it checks if ARC instance is successfully started or not. |
| 144 // In case of success, a request to stop the ARC instance is sent to | 143 // In case of success, a request to stop the ARC instance is sent to |
| 145 // SessionManager. Its completion will be notified via ArcInstanceStopped. | 144 // SessionManager. Its completion will be notified via ArcInstanceStopped. |
| 146 // Otherwise, it just turns into STOPPED state. | 145 // Otherwise, it just turns into STOPPED state. |
| 147 // CONNECTING_MOJO: | 146 // CONNECTING_MOJO: |
| 148 // The main task runs on WorkerPool thread, but it is blocking call. | 147 // The main task runs on BlockingPool thread, but it is blocking call. |
| 149 // So, Stop() sends a request to cancel the blocking by closing the pipe | 148 // So, Stop() sends a request to cancel the blocking by closing the pipe |
| 150 // whose read side is also polled. Then, in its callback, similar to | 149 // whose read side is also polled. Then, in its callback, similar to |
| 151 // STARTING_INSTANCE, a request to stop the ARC instance is sent to | 150 // STARTING_INSTANCE, a request to stop the ARC instance is sent to |
| 152 // SessionManager, and ArcInstanceStopped handles remaining procedure. | 151 // SessionManager, and ArcInstanceStopped handles remaining procedure. |
| 153 // RUNNING: | 152 // RUNNING: |
| 154 // There is no more callback which runs on normal flow, so Stop() requests | 153 // There is no more callback which runs on normal flow, so Stop() requests |
| 155 // to stop the ARC instance via SessionManager. | 154 // to stop the ARC instance via SessionManager. |
| 156 // | 155 // |
| 157 // Another trigger to change the state coming from outside of this class | 156 // Another trigger to change the state coming from outside of this class |
| 158 // is an event ArcInstanceStopped() sent from SessionManager, when ARC | 157 // is an event ArcInstanceStopped() sent from SessionManager, when ARC |
| 159 // instace unexpectedly terminates. ArcInstanceStopped() turns the state into | 158 // instace unexpectedly terminates. ArcInstanceStopped() turns the state into |
| 160 // STOPPED immediately. | 159 // STOPPED immediately. |
| 161 // This happens only when STARTING_INSTANCE, CONNECTING_MOJO or RUNNING | 160 // This happens only when STARTING_INSTANCE, CONNECTING_MOJO or RUNNING |
| 162 // state. | 161 // state. |
| 163 // | 162 // |
| 164 // STARTING_INSTANCE: | 163 // STARTING_INSTANCE: |
| 165 // In OnInstanceStarted(), |state_| is checked at the beginning. If it is | 164 // In OnInstanceStarted(), |state_| is checked at the beginning. If it is |
| 166 // STOPPED, then ArcInstanceStopped() is called. Do nothing in that case. | 165 // STOPPED, then ArcInstanceStopped() is called. Do nothing in that case. |
| 167 // CONNECTING_MOJO: | 166 // CONNECTING_MOJO: |
| 168 // Similar to Stop() case above, ArcInstanceStopped() also notifies to | 167 // Similar to Stop() case above, ArcInstanceStopped() also notifies to |
| 169 // WorkerPool() thread to cancel it to unblock the thread. In | 168 // BlockingPool thread to cancel it to unblock the thread. In |
| 170 // OnMojoConnected(), similar to OnInstanceStarted(), check if |state_| is | 169 // OnMojoConnected(), similar to OnInstanceStarted(), check if |state_| is |
| 171 // STOPPED, then do nothing. | 170 // STOPPED, then do nothing. |
| 172 // RUNNING: | 171 // RUNNING: |
| 173 // It is not necessary to do anything special here. | 172 // It is not necessary to do anything special here. |
| 174 // | 173 // |
| 175 // In NOT_STARTED or STOPPED state, the instance can be safely destructed. | 174 // In NOT_STARTED or STOPPED state, the instance can be safely destructed. |
| 176 // Specifically, in STOPPED state, there may be inflight operations or | 175 // Specifically, in STOPPED state, there may be inflight operations or |
| 177 // pending callbacks. Though, what they do is just do-nothing conceptually | 176 // pending callbacks. Though, what they do is just do-nothing conceptually |
| 178 // and they can be safely ignored. | 177 // and they can be safely ignored. |
| 179 // | 178 // |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 192 // The instance has started. Waiting for it to connect to the IPC bridge. | 191 // The instance has started. Waiting for it to connect to the IPC bridge. |
| 193 CONNECTING_MOJO, | 192 CONNECTING_MOJO, |
| 194 | 193 |
| 195 // The instance is fully set up. | 194 // The instance is fully set up. |
| 196 RUNNING, | 195 RUNNING, |
| 197 | 196 |
| 198 // ARC is terminated. | 197 // ARC is terminated. |
| 199 STOPPED, | 198 STOPPED, |
| 200 }; | 199 }; |
| 201 | 200 |
| 202 ArcSessionImpl(); | 201 explicit ArcSessionImpl(scoped_refptr<base::TaskRunner> blocking_task_runner); |
|
Luis Héctor Chávez
2016/10/21 00:43:41
nit: const scoped_refptr<...>&
hidehiko
2016/10/21 04:34:03
Done.
| |
| 203 ~ArcSessionImpl() override; | 202 ~ArcSessionImpl() override; |
| 204 | 203 |
| 205 // ArcSession overrides: | 204 // ArcSession overrides: |
| 206 void Start() override; | 205 void Start() override; |
| 207 void Stop() override; | 206 void Stop() override; |
| 207 void OnShutdown() override; | |
| 208 | 208 |
| 209 private: | 209 private: |
| 210 // Creates the UNIX socket on a worker pool and then processes its file | 210 // Creates the UNIX socket on a worker pool and then processes its file |
| 211 // descriptor. | 211 // descriptor. |
| 212 static base::ScopedFD CreateSocket(); | 212 static base::ScopedFD CreateSocket(); |
| 213 void OnSocketCreated(base::ScopedFD fd); | 213 void OnSocketCreated(base::ScopedFD fd); |
| 214 | 214 |
| 215 // DBus callback for StartArcInstance(). | 215 // DBus callback for StartArcInstance(). |
| 216 void OnInstanceStarted(base::ScopedFD socket_fd, | 216 void OnInstanceStarted(base::ScopedFD socket_fd, |
| 217 StartArcInstanceResult result); | 217 StartArcInstanceResult result); |
| 218 | 218 |
| 219 // Synchronously accepts a connection on |socket_fd| and then processes the | 219 // Synchronously accepts a connection on |socket_fd| and then processes the |
| 220 // connected socket's file descriptor. | 220 // connected socket's file descriptor. |
| 221 static base::ScopedFD ConnectMojo(base::ScopedFD socket_fd, | 221 static base::ScopedFD ConnectMojo(base::ScopedFD socket_fd, |
| 222 base::ScopedFD cancel_fd); | 222 base::ScopedFD cancel_fd); |
| 223 void OnMojoConnected(base::ScopedFD fd); | 223 void OnMojoConnected(base::ScopedFD fd); |
| 224 | 224 |
| 225 // Request to stop ARC instance via DBus. | 225 // Request to stop ARC instance via DBus. |
| 226 void StopArcInstance(); | 226 void StopArcInstance(); |
| 227 | 227 |
| 228 // chromeos::SessionManagerClient::Observer: | 228 // chromeos::SessionManagerClient::Observer: |
| 229 void ArcInstanceStopped(bool clean) override; | 229 void ArcInstanceStopped(bool clean) override; |
| 230 | 230 |
| 231 // Completes the termination procedure. | 231 // Completes the termination procedure. |
| 232 void OnStopped(ArcBridgeService::StopReason reason); | 232 void OnStopped(ArcBridgeService::StopReason reason); |
| 233 | 233 |
| 234 // Checks whether a function runs on the thread where the instance is | |
| 235 // created. | |
| 236 base::ThreadChecker thread_checker_; | |
| 237 | |
| 238 // Task runner to run a blocking tasks. | |
| 239 scoped_refptr<base::TaskRunner> blocking_task_runner_; | |
| 240 | |
| 234 // The state of the session. | 241 // The state of the session. |
| 235 State state_ = State::NOT_STARTED; | 242 State state_ = State::NOT_STARTED; |
| 236 | 243 |
| 237 // When Stop() is called, this flag is set. | 244 // When Stop() is called, this flag is set. |
| 238 bool stop_requested_ = false; | 245 bool stop_requested_ = false; |
| 239 | 246 |
| 240 // In CONNECTING_MOJO state, this is set to the write side of the pipe | 247 // In CONNECTING_MOJO state, this is set to the write side of the pipe |
| 241 // to notify cancelling of the procedure. | 248 // to notify cancelling of the procedure. |
| 242 base::ScopedFD accept_cancel_pipe_; | 249 base::ScopedFD accept_cancel_pipe_; |
| 243 | 250 |
| 244 // Mojo endpoint. | 251 // Mojo endpoint. |
| 245 std::unique_ptr<mojom::ArcBridgeHost> arc_bridge_host_; | 252 std::unique_ptr<mojom::ArcBridgeHost> arc_bridge_host_; |
| 246 | 253 |
| 247 base::ThreadChecker thread_checker_; | |
| 248 | |
| 249 // WeakPtrFactory to use callbacks. | 254 // WeakPtrFactory to use callbacks. |
| 250 base::WeakPtrFactory<ArcSessionImpl> weak_factory_; | 255 base::WeakPtrFactory<ArcSessionImpl> weak_factory_; |
| 251 | 256 |
| 252 private: | 257 private: |
| 253 DISALLOW_COPY_AND_ASSIGN(ArcSessionImpl); | 258 DISALLOW_COPY_AND_ASSIGN(ArcSessionImpl); |
| 254 }; | 259 }; |
| 255 | 260 |
| 256 ArcSessionImpl::ArcSessionImpl() : weak_factory_(this) { | 261 ArcSessionImpl::ArcSessionImpl( |
| 262 scoped_refptr<base::TaskRunner> blocking_task_runner) | |
| 263 : blocking_task_runner_(blocking_task_runner), weak_factory_(this) { | |
| 257 chromeos::SessionManagerClient* client = GetSessionManagerClient(); | 264 chromeos::SessionManagerClient* client = GetSessionManagerClient(); |
| 258 if (client == nullptr) | 265 if (client == nullptr) |
| 259 return; | 266 return; |
| 260 client->AddObserver(this); | 267 client->AddObserver(this); |
| 261 } | 268 } |
| 262 | 269 |
| 263 ArcSessionImpl::~ArcSessionImpl() { | 270 ArcSessionImpl::~ArcSessionImpl() { |
| 264 DCHECK(thread_checker_.CalledOnValidThread()); | 271 DCHECK(thread_checker_.CalledOnValidThread()); |
| 265 // TODO(hidehiko): CHECK if |state_| is in NOT_STARTED or STOPPED. | 272 DCHECK(state_ == State::NOT_STARTED || state_ == State::STOPPED); |
| 266 // Currently, specifically on shutdown, the state_ can be any value. | |
| 267 chromeos::SessionManagerClient* client = GetSessionManagerClient(); | 273 chromeos::SessionManagerClient* client = GetSessionManagerClient(); |
| 268 if (client == nullptr) | 274 if (client == nullptr) |
| 269 return; | 275 return; |
| 270 client->RemoveObserver(this); | 276 client->RemoveObserver(this); |
| 271 } | 277 } |
| 272 | 278 |
| 273 void ArcSessionImpl::Start() { | 279 void ArcSessionImpl::Start() { |
| 274 DCHECK(thread_checker_.CalledOnValidThread()); | 280 DCHECK(thread_checker_.CalledOnValidThread()); |
| 275 DCHECK_EQ(state_, State::NOT_STARTED); | 281 DCHECK_EQ(state_, State::NOT_STARTED); |
| 276 VLOG(2) << "Starting ARC session."; | 282 VLOG(2) << "Starting ARC session."; |
| 277 VLOG(2) << "Creating socket..."; | 283 VLOG(2) << "Creating socket..."; |
| 278 | 284 |
| 279 state_ = State::CREATING_SOCKET; | 285 state_ = State::CREATING_SOCKET; |
| 280 base::PostTaskAndReplyWithResult( | 286 base::PostTaskAndReplyWithResult( |
| 281 base::WorkerPool::GetTaskRunner(true).get(), FROM_HERE, | 287 blocking_task_runner_.get(), FROM_HERE, |
| 282 base::Bind(&ArcSessionImpl::CreateSocket), | 288 base::Bind(&ArcSessionImpl::CreateSocket), |
| 283 base::Bind(&ArcSessionImpl::OnSocketCreated, weak_factory_.GetWeakPtr())); | 289 base::Bind(&ArcSessionImpl::OnSocketCreated, weak_factory_.GetWeakPtr())); |
| 284 } | 290 } |
| 285 | 291 |
| 286 // static | 292 // static |
| 287 base::ScopedFD ArcSessionImpl::CreateSocket() { | 293 base::ScopedFD ArcSessionImpl::CreateSocket() { |
| 288 base::FilePath socket_path(kArcBridgeSocketPath); | 294 base::FilePath socket_path(kArcBridgeSocketPath); |
| 289 | 295 |
| 290 int raw_fd = -1; | 296 int raw_fd = -1; |
| 291 if (!IPC::CreateServerUnixDomainSocket(socket_path, &raw_fd)) | 297 if (!IPC::CreateServerUnixDomainSocket(socket_path, &raw_fd)) |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 390 | 396 |
| 391 // Prepare a pipe so that AcceptInstanceConnection can be interrupted on | 397 // Prepare a pipe so that AcceptInstanceConnection can be interrupted on |
| 392 // Stop(). | 398 // Stop(). |
| 393 base::ScopedFD cancel_fd; | 399 base::ScopedFD cancel_fd; |
| 394 if (!CreatePipe(&cancel_fd, &accept_cancel_pipe_)) { | 400 if (!CreatePipe(&cancel_fd, &accept_cancel_pipe_)) { |
| 395 OnStopped(ArcBridgeService::StopReason::GENERIC_BOOT_FAILURE); | 401 OnStopped(ArcBridgeService::StopReason::GENERIC_BOOT_FAILURE); |
| 396 return; | 402 return; |
| 397 } | 403 } |
| 398 | 404 |
| 399 base::PostTaskAndReplyWithResult( | 405 base::PostTaskAndReplyWithResult( |
| 400 base::WorkerPool::GetTaskRunner(true).get(), FROM_HERE, | 406 blocking_task_runner_.get(), FROM_HERE, |
| 401 base::Bind(&ArcSessionImpl::ConnectMojo, base::Passed(&socket_fd), | 407 base::Bind(&ArcSessionImpl::ConnectMojo, base::Passed(&socket_fd), |
| 402 base::Passed(&cancel_fd)), | 408 base::Passed(&cancel_fd)), |
| 403 base::Bind(&ArcSessionImpl::OnMojoConnected, weak_factory_.GetWeakPtr())); | 409 base::Bind(&ArcSessionImpl::OnMojoConnected, weak_factory_.GetWeakPtr())); |
| 404 } | 410 } |
| 405 | 411 |
| 406 // static | 412 // static |
| 407 base::ScopedFD ArcSessionImpl::ConnectMojo(base::ScopedFD socket_fd, | 413 base::ScopedFD ArcSessionImpl::ConnectMojo(base::ScopedFD socket_fd, |
| 408 base::ScopedFD cancel_fd) { | 414 base::ScopedFD cancel_fd) { |
| 409 if (!WaitForSocketReadable(socket_fd.get(), cancel_fd.get())) { | 415 if (!WaitForSocketReadable(socket_fd.get(), cancel_fd.get())) { |
| 410 VLOG(1) << "Mojo connection was cancelled."; | 416 VLOG(1) << "Mojo connection was cancelled."; |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 507 // On Chrome shutdown, it is not the case because the message loop is | 513 // On Chrome shutdown, it is not the case because the message loop is |
| 508 // already stopped here. Practically, it is not a problem because; | 514 // already stopped here. Practically, it is not a problem because; |
| 509 // - On socket creating, it is ok to simply ignore such cases, | 515 // - On socket creating, it is ok to simply ignore such cases, |
| 510 // because we no-longer continue the bootstrap procedure. | 516 // because we no-longer continue the bootstrap procedure. |
| 511 // - On starting instance, the container instance can be leaked. | 517 // - On starting instance, the container instance can be leaked. |
| 512 // Practically it is not problematic because the session manager will | 518 // Practically it is not problematic because the session manager will |
| 513 // clean it up. | 519 // clean it up. |
| 514 return; | 520 return; |
| 515 | 521 |
| 516 case State::CONNECTING_MOJO: | 522 case State::CONNECTING_MOJO: |
| 517 // Mojo connection is being waited on a WorkerPool thread. | 523 // Mojo connection is being waited on a BlockingPool thread. |
| 518 // Request to cancel it. Following stopping procedure will run | 524 // Request to cancel it. Following stopping procedure will run |
| 519 // in its callback. | 525 // in its callback. |
| 520 DCHECK(accept_cancel_pipe_.get()); | |
|
hidehiko
2016/10/20 10:09:08
Note: I found that there is a case that this is tr
Luis Héctor Chávez
2016/10/21 00:43:41
Acknowledged.
| |
| 521 accept_cancel_pipe_.reset(); | 526 accept_cancel_pipe_.reset(); |
| 522 return; | 527 return; |
| 523 | 528 |
| 524 case State::RUNNING: | 529 case State::RUNNING: |
| 525 // Now ARC instance is running. Request to stop it. | 530 // Now ARC instance is running. Request to stop it. |
| 526 StopArcInstance(); | 531 StopArcInstance(); |
| 527 return; | 532 return; |
| 528 | 533 |
| 529 case State::STOPPED: | 534 case State::STOPPED: |
| 530 // The instance is already stopped. Do nothing. | 535 // The instance is already stopped. Do nothing. |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 544 session_manager_client->StopArcInstance( | 549 session_manager_client->StopArcInstance( |
| 545 base::Bind(&DoNothingInstanceStopped)); | 550 base::Bind(&DoNothingInstanceStopped)); |
| 546 } | 551 } |
| 547 | 552 |
| 548 void ArcSessionImpl::ArcInstanceStopped(bool clean) { | 553 void ArcSessionImpl::ArcInstanceStopped(bool clean) { |
| 549 DCHECK(thread_checker_.CalledOnValidThread()); | 554 DCHECK(thread_checker_.CalledOnValidThread()); |
| 550 VLOG(1) << "Notified that ARC instance is stopped " | 555 VLOG(1) << "Notified that ARC instance is stopped " |
| 551 << (clean ? "cleanly" : "uncleanly"); | 556 << (clean ? "cleanly" : "uncleanly"); |
| 552 | 557 |
| 553 // In case that crash happens during before the Mojo channel is connected, | 558 // In case that crash happens during before the Mojo channel is connected, |
| 554 // unlock the WorkerPool thread. | 559 // unlock the BlockingPool thread. |
| 555 accept_cancel_pipe_.reset(); | 560 accept_cancel_pipe_.reset(); |
| 556 | 561 |
| 557 ArcBridgeService::StopReason reason; | 562 ArcBridgeService::StopReason reason; |
| 558 if (stop_requested_) { | 563 if (stop_requested_) { |
| 559 // If the ARC instance is stopped after its explicit request, | 564 // If the ARC instance is stopped after its explicit request, |
| 560 // return SHUTDOWN. | 565 // return SHUTDOWN. |
| 561 reason = ArcBridgeService::StopReason::SHUTDOWN; | 566 reason = ArcBridgeService::StopReason::SHUTDOWN; |
| 562 } else if (clean) { | 567 } else if (clean) { |
| 563 // If the ARC instance is stopped, but it is not explicitly requested, | 568 // If the ARC instance is stopped, but it is not explicitly requested, |
| 564 // then this is triggered by some failure during the starting procedure. | 569 // then this is triggered by some failure during the starting procedure. |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 575 DCHECK(thread_checker_.CalledOnValidThread()); | 580 DCHECK(thread_checker_.CalledOnValidThread()); |
| 576 // OnStopped() should be called once per instance. | 581 // OnStopped() should be called once per instance. |
| 577 DCHECK_NE(state_, State::STOPPED); | 582 DCHECK_NE(state_, State::STOPPED); |
| 578 VLOG(2) << "ARC session is stopped."; | 583 VLOG(2) << "ARC session is stopped."; |
| 579 arc_bridge_host_.reset(); | 584 arc_bridge_host_.reset(); |
| 580 state_ = State::STOPPED; | 585 state_ = State::STOPPED; |
| 581 for (auto& observer : observer_list_) | 586 for (auto& observer : observer_list_) |
| 582 observer.OnStopped(reason); | 587 observer.OnStopped(reason); |
| 583 } | 588 } |
| 584 | 589 |
| 590 void ArcSessionImpl::OnShutdown() { | |
| 591 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 592 stop_requested_ = true; | |
| 593 if (state_ == State::STOPPED) | |
| 594 return; | |
| 595 | |
| 596 // Here, the message loop is already stopped, and the Chrome will be soon | |
| 597 // shutdown. Thus, it is not necessary to take care about restarting case. | |
| 598 // If ArcSession is waiting for mojo connection, cancels it. The BlockingPool | |
| 599 // will be joined later. | |
| 600 accept_cancel_pipe_.reset(); | |
| 601 | |
| 602 // After Chrome's shutdown, SessionManager shuts down the ARC instance, | |
|
Luis Héctor Chávez
2016/10/21 00:43:41
I'd still want this code to be robust by itself an
hidehiko
2016/10/21 04:34:03
Could you tell me what more robustness do you want
Luis Héctor Chávez
2016/10/21 06:34:20
We can rely on SessionManager's _current_ behavior
hashimoto
2016/10/21 07:20:27
IIUC unclean shutdown is also covered by SessionMa
Luis Héctor Chávez
2016/10/21 07:53:43
Oh that was unintentional :/ we should swap the ti
| |
| 603 // so we do not need to worry about it here. | |
| 604 // Directly set to the STOPPED stateby OnStopped(). Note that callsing | |
|
Luis Héctor Chávez
2016/10/21 00:43:41
nit: s/callsing/calling/
hidehiko
2016/10/21 04:34:03
Done.
| |
| 605 // StopArcInstance() may not work well. At least, because the UI thread is | |
| 606 // already stopped here, ArcInstanceStopped() callback cannot be invoked. | |
| 607 OnStopped(ArcBridgeService::StopReason::SHUTDOWN); | |
| 608 } | |
| 609 | |
| 585 } // namespace | 610 } // namespace |
| 586 | 611 |
| 587 ArcSession::ArcSession() = default; | 612 ArcSession::ArcSession() = default; |
| 588 ArcSession::~ArcSession() = default; | 613 ArcSession::~ArcSession() = default; |
| 589 | 614 |
| 590 void ArcSession::AddObserver(Observer* observer) { | 615 void ArcSession::AddObserver(Observer* observer) { |
| 591 observer_list_.AddObserver(observer); | 616 observer_list_.AddObserver(observer); |
| 592 } | 617 } |
| 593 | 618 |
| 594 void ArcSession::RemoveObserver(Observer* observer) { | 619 void ArcSession::RemoveObserver(Observer* observer) { |
| 595 observer_list_.RemoveObserver(observer); | 620 observer_list_.RemoveObserver(observer); |
| 596 } | 621 } |
| 597 | 622 |
| 598 // static | 623 // static |
| 599 std::unique_ptr<ArcSession> ArcSession::Create() { | 624 std::unique_ptr<ArcSession> ArcSession::Create( |
| 600 return base::MakeUnique<ArcSessionImpl>(); | 625 scoped_refptr<base::TaskRunner> blocking_task_runner) { |
| 626 return base::MakeUnique<ArcSessionImpl>(blocking_task_runner); | |
| 601 } | 627 } |
| 602 | 628 |
| 603 } // namespace arc | 629 } // namespace arc |
| OLD | NEW |