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_bridge_bootstrap.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" |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 99 VLOG(1) << "Stop() was called during ConnectMojo()"; | 99 VLOG(1) << "Stop() was called during ConnectMojo()"; |
| 100 return false; | 100 return false; |
| 101 } | 101 } |
| 102 | 102 |
| 103 DCHECK(fds[0].revents); | 103 DCHECK(fds[0].revents); |
| 104 return true; | 104 return true; |
| 105 } | 105 } |
| 106 | 106 |
| 107 // TODO(hidehiko): Refactor more to make this class unittest-able, for at least | 107 // TODO(hidehiko): Refactor more to make this class unittest-able, for at least |
| 108 // state-machine part. | 108 // state-machine part. |
| 109 class ArcBridgeBootstrapImpl : public ArcBridgeBootstrap, | 109 class ArcSessionImpl : public ArcSession, |
| 110 public chromeos::SessionManagerClient::Observer { | 110 public chromeos::SessionManagerClient::Observer { |
| 111 public: | 111 public: |
| 112 // The possible states of the bootstrap connection. In the normal flow, | 112 // The possible states of the bootstrap connection. In the normal flow, |
|
Luis Héctor Chávez
2016/10/18 00:24:57
nit: s/bootstrap connection/session/?
hidehiko
2016/10/18 05:27:45
Done.
| |
| 113 // the state changes in the following sequence: | 113 // the state changes in the following sequence: |
| 114 // | 114 // |
| 115 // NOT_STARTED | 115 // NOT_STARTED |
| 116 // Start() -> | 116 // Start() -> |
| 117 // CREATING_SOCKET | 117 // CREATING_SOCKET |
| 118 // CreateSocket() -> OnSocketCreated() -> | 118 // CreateSocket() -> OnSocketCreated() -> |
| 119 // STARTING_INSTANCE | 119 // STARTING_INSTANCE |
| 120 // -> OnInstanceStarted() -> | 120 // -> OnInstanceStarted() -> |
| 121 // CONNECTING_MOJO | 121 // CONNECTING_MOJO |
| 122 // ConnectMojo() -> OnMojoConnected() -> | 122 // ConnectMojo() -> OnMojoConnected() -> |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 192 // The instance has started. Waiting for it to connect to the IPC bridge. | 192 // The instance has started. Waiting for it to connect to the IPC bridge. |
| 193 CONNECTING_MOJO, | 193 CONNECTING_MOJO, |
| 194 | 194 |
| 195 // The instance is fully set up. | 195 // The instance is fully set up. |
| 196 RUNNING, | 196 RUNNING, |
| 197 | 197 |
| 198 // ARC is terminated. | 198 // ARC is terminated. |
| 199 STOPPED, | 199 STOPPED, |
| 200 }; | 200 }; |
| 201 | 201 |
| 202 ArcBridgeBootstrapImpl(); | 202 ArcSessionImpl(); |
| 203 ~ArcBridgeBootstrapImpl() override; | 203 ~ArcSessionImpl() override; |
| 204 | 204 |
| 205 // ArcBridgeBootstrap: | 205 // ArcSession overrides: |
| 206 void Start() override; | 206 void Start() override; |
| 207 void Stop() override; | 207 void Stop() override; |
| 208 | 208 |
| 209 private: | 209 private: |
| 210 // Creates the UNIX socket on the bootstrap thread and then processes its | 210 // Creates the UNIX socket on a worker pool and then processes its file |
| 211 // file 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 // The state of the bootstrap connection. | 234 // The state of the session. |
| 235 State state_ = State::NOT_STARTED; | 235 State state_ = State::NOT_STARTED; |
| 236 | 236 |
| 237 // When Stop() is called, this flag is set. | 237 // When Stop() is called, this flag is set. |
| 238 bool stop_requested_ = false; | 238 bool stop_requested_ = false; |
| 239 | 239 |
| 240 // In CONNECTING_MOJO state, this is set to the write side of the pipe | 240 // In CONNECTING_MOJO state, this is set to the write side of the pipe |
| 241 // to notify cancelling of the procedure. | 241 // to notify cancelling of the procedure. |
| 242 base::ScopedFD accept_cancel_pipe_; | 242 base::ScopedFD accept_cancel_pipe_; |
| 243 | 243 |
| 244 // Mojo endpoint. | 244 // Mojo endpoint. |
| 245 std::unique_ptr<mojom::ArcBridgeHost> arc_bridge_host_; | 245 std::unique_ptr<mojom::ArcBridgeHost> arc_bridge_host_; |
| 246 | 246 |
| 247 base::ThreadChecker thread_checker_; | 247 base::ThreadChecker thread_checker_; |
| 248 | 248 |
| 249 // WeakPtrFactory to use callbacks. | 249 // WeakPtrFactory to use callbacks. |
| 250 base::WeakPtrFactory<ArcBridgeBootstrapImpl> weak_factory_; | 250 base::WeakPtrFactory<ArcSessionImpl> weak_factory_; |
| 251 | 251 |
| 252 private: | 252 private: |
| 253 DISALLOW_COPY_AND_ASSIGN(ArcBridgeBootstrapImpl); | 253 DISALLOW_COPY_AND_ASSIGN(ArcSessionImpl); |
| 254 }; | 254 }; |
| 255 | 255 |
| 256 ArcBridgeBootstrapImpl::ArcBridgeBootstrapImpl() | 256 ArcSessionImpl::ArcSessionImpl() : weak_factory_(this) { |
| 257 : weak_factory_(this) { | |
| 258 chromeos::SessionManagerClient* client = GetSessionManagerClient(); | 257 chromeos::SessionManagerClient* client = GetSessionManagerClient(); |
| 259 if (client == nullptr) | 258 if (client == nullptr) |
| 260 return; | 259 return; |
| 261 client->AddObserver(this); | 260 client->AddObserver(this); |
| 262 } | 261 } |
| 263 | 262 |
| 264 ArcBridgeBootstrapImpl::~ArcBridgeBootstrapImpl() { | 263 ArcSessionImpl::~ArcSessionImpl() { |
| 265 DCHECK(thread_checker_.CalledOnValidThread()); | 264 DCHECK(thread_checker_.CalledOnValidThread()); |
| 266 // TODO(hidehiko): CHECK if |state_| is in NOT_STARTED or STOPPED. | 265 // TODO(hidehiko): CHECK if |state_| is in NOT_STARTED or STOPPED. |
| 267 // Currently, specifically on shutdown, the state_ can be any value. | 266 // Currently, specifically on shutdown, the state_ can be any value. |
| 268 chromeos::SessionManagerClient* client = GetSessionManagerClient(); | 267 chromeos::SessionManagerClient* client = GetSessionManagerClient(); |
| 269 if (client == nullptr) | 268 if (client == nullptr) |
| 270 return; | 269 return; |
| 271 client->RemoveObserver(this); | 270 client->RemoveObserver(this); |
| 272 } | 271 } |
| 273 | 272 |
| 274 void ArcBridgeBootstrapImpl::Start() { | 273 void ArcSessionImpl::Start() { |
| 275 DCHECK(thread_checker_.CalledOnValidThread()); | 274 DCHECK(thread_checker_.CalledOnValidThread()); |
| 276 DCHECK_EQ(state_, State::NOT_STARTED); | 275 DCHECK_EQ(state_, State::NOT_STARTED); |
| 277 VLOG(2) << "Starting ARC session."; | 276 VLOG(2) << "Starting ARC session."; |
| 278 VLOG(2) << "Creating socket..."; | 277 VLOG(2) << "Creating socket..."; |
| 279 | 278 |
| 280 state_ = State::CREATING_SOCKET; | 279 state_ = State::CREATING_SOCKET; |
| 281 base::PostTaskAndReplyWithResult( | 280 base::PostTaskAndReplyWithResult( |
| 282 base::WorkerPool::GetTaskRunner(true).get(), FROM_HERE, | 281 base::WorkerPool::GetTaskRunner(true).get(), FROM_HERE, |
| 283 base::Bind(&ArcBridgeBootstrapImpl::CreateSocket), | 282 base::Bind(&ArcSessionImpl::CreateSocket), |
| 284 base::Bind(&ArcBridgeBootstrapImpl::OnSocketCreated, | 283 base::Bind(&ArcSessionImpl::OnSocketCreated, weak_factory_.GetWeakPtr())); |
| 285 weak_factory_.GetWeakPtr())); | |
| 286 } | 284 } |
| 287 | 285 |
| 288 // static | 286 // static |
| 289 base::ScopedFD ArcBridgeBootstrapImpl::CreateSocket() { | 287 base::ScopedFD ArcSessionImpl::CreateSocket() { |
| 290 base::FilePath socket_path(kArcBridgeSocketPath); | 288 base::FilePath socket_path(kArcBridgeSocketPath); |
| 291 | 289 |
| 292 int raw_fd = -1; | 290 int raw_fd = -1; |
| 293 if (!IPC::CreateServerUnixDomainSocket(socket_path, &raw_fd)) | 291 if (!IPC::CreateServerUnixDomainSocket(socket_path, &raw_fd)) |
| 294 return base::ScopedFD(); | 292 return base::ScopedFD(); |
| 295 base::ScopedFD socket_fd(raw_fd); | 293 base::ScopedFD socket_fd(raw_fd); |
| 296 | 294 |
| 297 // Change permissions on the socket. | 295 // Change permissions on the socket. |
| 298 struct group arc_bridge_group; | 296 struct group arc_bridge_group; |
| 299 struct group* arc_bridge_group_res = nullptr; | 297 struct group* arc_bridge_group_res = nullptr; |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 316 } | 314 } |
| 317 | 315 |
| 318 if (!base::SetPosixFilePermissions(socket_path, 0660)) { | 316 if (!base::SetPosixFilePermissions(socket_path, 0660)) { |
| 319 PLOG(ERROR) << "Could not set permissions: " << socket_path.value(); | 317 PLOG(ERROR) << "Could not set permissions: " << socket_path.value(); |
| 320 return base::ScopedFD(); | 318 return base::ScopedFD(); |
| 321 } | 319 } |
| 322 | 320 |
| 323 return socket_fd; | 321 return socket_fd; |
| 324 } | 322 } |
| 325 | 323 |
| 326 void ArcBridgeBootstrapImpl::OnSocketCreated(base::ScopedFD socket_fd) { | 324 void ArcSessionImpl::OnSocketCreated(base::ScopedFD socket_fd) { |
| 327 DCHECK(thread_checker_.CalledOnValidThread()); | 325 DCHECK(thread_checker_.CalledOnValidThread()); |
| 328 DCHECK_EQ(state_, State::CREATING_SOCKET); | 326 DCHECK_EQ(state_, State::CREATING_SOCKET); |
| 329 | 327 |
| 330 if (stop_requested_) { | 328 if (stop_requested_) { |
| 331 VLOG(1) << "Stop() called while connecting"; | 329 VLOG(1) << "Stop() called while connecting"; |
| 332 OnStopped(ArcBridgeService::StopReason::SHUTDOWN); | 330 OnStopped(ArcBridgeService::StopReason::SHUTDOWN); |
| 333 return; | 331 return; |
| 334 } | 332 } |
| 335 | 333 |
| 336 if (!socket_fd.is_valid()) { | 334 if (!socket_fd.is_valid()) { |
| 337 LOG(ERROR) << "ARC: Error creating socket"; | 335 LOG(ERROR) << "ARC: Error creating socket"; |
| 338 OnStopped(ArcBridgeService::StopReason::GENERIC_BOOT_FAILURE); | 336 OnStopped(ArcBridgeService::StopReason::GENERIC_BOOT_FAILURE); |
| 339 return; | 337 return; |
| 340 } | 338 } |
| 341 | 339 |
| 342 VLOG(2) << "Socket is created. Starting ARC instance..."; | 340 VLOG(2) << "Socket is created. Starting ARC instance..."; |
| 343 state_ = State::STARTING_INSTANCE; | 341 state_ = State::STARTING_INSTANCE; |
| 344 user_manager::UserManager* user_manager = user_manager::UserManager::Get(); | 342 user_manager::UserManager* user_manager = user_manager::UserManager::Get(); |
| 345 DCHECK(user_manager->GetPrimaryUser()); | 343 DCHECK(user_manager->GetPrimaryUser()); |
| 346 const cryptohome::Identification cryptohome_id( | 344 const cryptohome::Identification cryptohome_id( |
| 347 user_manager->GetPrimaryUser()->GetAccountId()); | 345 user_manager->GetPrimaryUser()->GetAccountId()); |
| 348 | 346 |
| 349 bool disable_boot_completed_broadcast = | 347 bool disable_boot_completed_broadcast = |
| 350 !base::FeatureList::IsEnabled(arc::kBootCompletedBroadcastFeature); | 348 !base::FeatureList::IsEnabled(arc::kBootCompletedBroadcastFeature); |
| 351 | 349 |
| 352 chromeos::SessionManagerClient* session_manager_client = | 350 chromeos::SessionManagerClient* session_manager_client = |
| 353 chromeos::DBusThreadManager::Get()->GetSessionManagerClient(); | 351 chromeos::DBusThreadManager::Get()->GetSessionManagerClient(); |
| 354 session_manager_client->StartArcInstance( | 352 session_manager_client->StartArcInstance( |
| 355 cryptohome_id, | 353 cryptohome_id, disable_boot_completed_broadcast, |
| 356 disable_boot_completed_broadcast, | 354 base::Bind(&ArcSessionImpl::OnInstanceStarted, weak_factory_.GetWeakPtr(), |
| 357 base::Bind(&ArcBridgeBootstrapImpl::OnInstanceStarted, | 355 base::Passed(&socket_fd))); |
| 358 weak_factory_.GetWeakPtr(), base::Passed(&socket_fd))); | |
| 359 } | 356 } |
| 360 | 357 |
| 361 void ArcBridgeBootstrapImpl::OnInstanceStarted(base::ScopedFD socket_fd, | 358 void ArcSessionImpl::OnInstanceStarted(base::ScopedFD socket_fd, |
| 362 StartArcInstanceResult result) { | 359 StartArcInstanceResult result) { |
| 363 DCHECK(thread_checker_.CalledOnValidThread()); | 360 DCHECK(thread_checker_.CalledOnValidThread()); |
| 364 if (state_ == State::STOPPED) { | 361 if (state_ == State::STOPPED) { |
| 365 // This is the case that error is notified via DBus before the | 362 // This is the case that error is notified via DBus before the |
| 366 // OnInstanceStarted() callback is invoked. The stopping procedure has | 363 // OnInstanceStarted() callback is invoked. The stopping procedure has |
| 367 // been run, so do nothing. | 364 // been run, so do nothing. |
| 368 return; | 365 return; |
| 369 } | 366 } |
| 370 | 367 |
| 371 DCHECK_EQ(state_, State::STARTING_INSTANCE); | 368 DCHECK_EQ(state_, State::STARTING_INSTANCE); |
| 372 | 369 |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 394 // Prepare a pipe so that AcceptInstanceConnection can be interrupted on | 391 // Prepare a pipe so that AcceptInstanceConnection can be interrupted on |
| 395 // Stop(). | 392 // Stop(). |
| 396 base::ScopedFD cancel_fd; | 393 base::ScopedFD cancel_fd; |
| 397 if (!CreatePipe(&cancel_fd, &accept_cancel_pipe_)) { | 394 if (!CreatePipe(&cancel_fd, &accept_cancel_pipe_)) { |
| 398 OnStopped(ArcBridgeService::StopReason::GENERIC_BOOT_FAILURE); | 395 OnStopped(ArcBridgeService::StopReason::GENERIC_BOOT_FAILURE); |
| 399 return; | 396 return; |
| 400 } | 397 } |
| 401 | 398 |
| 402 base::PostTaskAndReplyWithResult( | 399 base::PostTaskAndReplyWithResult( |
| 403 base::WorkerPool::GetTaskRunner(true).get(), FROM_HERE, | 400 base::WorkerPool::GetTaskRunner(true).get(), FROM_HERE, |
| 404 base::Bind(&ArcBridgeBootstrapImpl::ConnectMojo, base::Passed(&socket_fd), | 401 base::Bind(&ArcSessionImpl::ConnectMojo, base::Passed(&socket_fd), |
| 405 base::Passed(&cancel_fd)), | 402 base::Passed(&cancel_fd)), |
| 406 base::Bind(&ArcBridgeBootstrapImpl::OnMojoConnected, | 403 base::Bind(&ArcSessionImpl::OnMojoConnected, weak_factory_.GetWeakPtr())); |
| 407 weak_factory_.GetWeakPtr())); | |
| 408 } | 404 } |
| 409 | 405 |
| 410 // static | 406 // static |
| 411 base::ScopedFD ArcBridgeBootstrapImpl::ConnectMojo(base::ScopedFD socket_fd, | 407 base::ScopedFD ArcSessionImpl::ConnectMojo(base::ScopedFD socket_fd, |
| 412 base::ScopedFD cancel_fd) { | 408 base::ScopedFD cancel_fd) { |
| 413 if (!WaitForSocketReadable(socket_fd.get(), cancel_fd.get())) { | 409 if (!WaitForSocketReadable(socket_fd.get(), cancel_fd.get())) { |
| 414 VLOG(1) << "Mojo connection was cancelled."; | 410 VLOG(1) << "Mojo connection was cancelled."; |
| 415 return base::ScopedFD(); | 411 return base::ScopedFD(); |
| 416 } | 412 } |
| 417 | 413 |
| 418 int raw_fd = -1; | 414 int raw_fd = -1; |
| 419 if (!IPC::ServerOnConnect(socket_fd.get(), &raw_fd)) { | 415 if (!IPC::ServerOnConnect(socket_fd.get(), &raw_fd)) { |
| 420 return base::ScopedFD(); | 416 return base::ScopedFD(); |
| 421 } | 417 } |
| 422 base::ScopedFD scoped_fd(raw_fd); | 418 base::ScopedFD scoped_fd(raw_fd); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 437 mojo::edk::PlatformHandle(scoped_fd.get()), &iov, 1, handles->data(), | 433 mojo::edk::PlatformHandle(scoped_fd.get()), &iov, 1, handles->data(), |
| 438 handles->size()); | 434 handles->size()); |
| 439 if (result == -1) { | 435 if (result == -1) { |
| 440 PLOG(ERROR) << "sendmsg"; | 436 PLOG(ERROR) << "sendmsg"; |
| 441 return base::ScopedFD(); | 437 return base::ScopedFD(); |
| 442 } | 438 } |
| 443 | 439 |
| 444 return scoped_fd; | 440 return scoped_fd; |
| 445 } | 441 } |
| 446 | 442 |
| 447 void ArcBridgeBootstrapImpl::OnMojoConnected(base::ScopedFD fd) { | 443 void ArcSessionImpl::OnMojoConnected(base::ScopedFD fd) { |
| 448 DCHECK(thread_checker_.CalledOnValidThread()); | 444 DCHECK(thread_checker_.CalledOnValidThread()); |
| 449 | 445 |
| 450 if (state_ == State::STOPPED) { | 446 if (state_ == State::STOPPED) { |
| 451 // This is the case that error is notified via DBus before the | 447 // This is the case that error is notified via DBus before the |
| 452 // OnMojoConnected() callback is invoked. The stopping procedure has | 448 // OnMojoConnected() callback is invoked. The stopping procedure has |
| 453 // been run, so do nothing. | 449 // been run, so do nothing. |
| 454 return; | 450 return; |
| 455 } | 451 } |
| 456 | 452 |
| 457 DCHECK_EQ(state_, State::CONNECTING_MOJO); | 453 DCHECK_EQ(state_, State::CONNECTING_MOJO); |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 480 instance.Bind(mojo::InterfacePtrInfo<mojom::ArcBridgeInstance>( | 476 instance.Bind(mojo::InterfacePtrInfo<mojom::ArcBridgeInstance>( |
| 481 std::move(server_pipe), 0u)); | 477 std::move(server_pipe), 0u)); |
| 482 arc_bridge_host_.reset(new ArcBridgeHostImpl(std::move(instance))); | 478 arc_bridge_host_.reset(new ArcBridgeHostImpl(std::move(instance))); |
| 483 | 479 |
| 484 VLOG(2) << "Mojo is connected. ARC is running."; | 480 VLOG(2) << "Mojo is connected. ARC is running."; |
| 485 state_ = State::RUNNING; | 481 state_ = State::RUNNING; |
| 486 for (auto& observer : observer_list_) | 482 for (auto& observer : observer_list_) |
| 487 observer.OnReady(); | 483 observer.OnReady(); |
| 488 } | 484 } |
| 489 | 485 |
| 490 void ArcBridgeBootstrapImpl::Stop() { | 486 void ArcSessionImpl::Stop() { |
| 491 DCHECK(thread_checker_.CalledOnValidThread()); | 487 DCHECK(thread_checker_.CalledOnValidThread()); |
| 492 VLOG(2) << "Stopping ARC session is requested."; | 488 VLOG(2) << "Stopping ARC session is requested."; |
| 493 | 489 |
| 494 // For second time or later, just do nothing. | 490 // For second time or later, just do nothing. |
| 495 // It is already in the stopping phase. | 491 // It is already in the stopping phase. |
| 496 if (stop_requested_) | 492 if (stop_requested_) |
| 497 return; | 493 return; |
| 498 | 494 |
| 499 stop_requested_ = true; | 495 stop_requested_ = true; |
| 500 arc_bridge_host_.reset(); | 496 arc_bridge_host_.reset(); |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 529 // Now ARC instance is running. Request to stop it. | 525 // Now ARC instance is running. Request to stop it. |
| 530 StopArcInstance(); | 526 StopArcInstance(); |
| 531 return; | 527 return; |
| 532 | 528 |
| 533 case State::STOPPED: | 529 case State::STOPPED: |
| 534 // The instance is already stopped. Do nothing. | 530 // The instance is already stopped. Do nothing. |
| 535 return; | 531 return; |
| 536 } | 532 } |
| 537 } | 533 } |
| 538 | 534 |
| 539 void ArcBridgeBootstrapImpl::StopArcInstance() { | 535 void ArcSessionImpl::StopArcInstance() { |
| 540 DCHECK(thread_checker_.CalledOnValidThread()); | 536 DCHECK(thread_checker_.CalledOnValidThread()); |
| 541 DCHECK(state_ == State::STARTING_INSTANCE || | 537 DCHECK(state_ == State::STARTING_INSTANCE || |
| 542 state_ == State::CONNECTING_MOJO || state_ == State::RUNNING); | 538 state_ == State::CONNECTING_MOJO || state_ == State::RUNNING); |
| 543 | 539 |
| 544 // Notification will arrive through ArcInstanceStopped(). | 540 // Notification will arrive through ArcInstanceStopped(). |
| 545 VLOG(2) << "Requesting to stop ARC instance"; | 541 VLOG(2) << "Requesting to stop ARC instance"; |
| 546 chromeos::SessionManagerClient* session_manager_client = | 542 chromeos::SessionManagerClient* session_manager_client = |
| 547 chromeos::DBusThreadManager::Get()->GetSessionManagerClient(); | 543 chromeos::DBusThreadManager::Get()->GetSessionManagerClient(); |
| 548 session_manager_client->StopArcInstance( | 544 session_manager_client->StopArcInstance( |
| 549 base::Bind(&DoNothingInstanceStopped)); | 545 base::Bind(&DoNothingInstanceStopped)); |
| 550 } | 546 } |
| 551 | 547 |
| 552 void ArcBridgeBootstrapImpl::ArcInstanceStopped(bool clean) { | 548 void ArcSessionImpl::ArcInstanceStopped(bool clean) { |
| 553 DCHECK(thread_checker_.CalledOnValidThread()); | 549 DCHECK(thread_checker_.CalledOnValidThread()); |
| 554 VLOG(1) << "Notified that ARC instance is stopped " | 550 VLOG(1) << "Notified that ARC instance is stopped " |
| 555 << (clean ? "cleanly" : "uncleanly"); | 551 << (clean ? "cleanly" : "uncleanly"); |
| 556 | 552 |
| 557 // In case that crash happens during before the Mojo channel is connected, | 553 // In case that crash happens during before the Mojo channel is connected, |
| 558 // unlock the WorkerPool thread. | 554 // unlock the WorkerPool thread. |
| 559 accept_cancel_pipe_.reset(); | 555 accept_cancel_pipe_.reset(); |
| 560 | 556 |
| 561 ArcBridgeService::StopReason reason; | 557 ArcBridgeService::StopReason reason; |
| 562 if (stop_requested_) { | 558 if (stop_requested_) { |
| 563 // If the ARC instance is stopped after its explicit request, | 559 // If the ARC instance is stopped after its explicit request, |
| 564 // return SHUTDOWN. | 560 // return SHUTDOWN. |
| 565 reason = ArcBridgeService::StopReason::SHUTDOWN; | 561 reason = ArcBridgeService::StopReason::SHUTDOWN; |
| 566 } else if (clean) { | 562 } else if (clean) { |
| 567 // If the ARC instance is stopped, but it is not explicitly requested, | 563 // If the ARC instance is stopped, but it is not explicitly requested, |
| 568 // then this is triggered by some failure during the starting procedure. | 564 // then this is triggered by some failure during the starting procedure. |
| 569 // Return GENERIC_BOOT_FAILURE for the case. | 565 // Return GENERIC_BOOT_FAILURE for the case. |
| 570 reason = ArcBridgeService::StopReason::GENERIC_BOOT_FAILURE; | 566 reason = ArcBridgeService::StopReason::GENERIC_BOOT_FAILURE; |
| 571 } else { | 567 } else { |
| 572 // Otherwise, this is caused by CRASH occured inside of the ARC instance. | 568 // Otherwise, this is caused by CRASH occured inside of the ARC instance. |
| 573 reason = ArcBridgeService::StopReason::CRASH; | 569 reason = ArcBridgeService::StopReason::CRASH; |
| 574 } | 570 } |
| 575 OnStopped(reason); | 571 OnStopped(reason); |
| 576 } | 572 } |
| 577 | 573 |
| 578 void ArcBridgeBootstrapImpl::OnStopped(ArcBridgeService::StopReason reason) { | 574 void ArcSessionImpl::OnStopped(ArcBridgeService::StopReason reason) { |
| 579 DCHECK(thread_checker_.CalledOnValidThread()); | 575 DCHECK(thread_checker_.CalledOnValidThread()); |
| 580 // OnStopped() should be called once per instance. | 576 // OnStopped() should be called once per instance. |
| 581 DCHECK_NE(state_, State::STOPPED); | 577 DCHECK_NE(state_, State::STOPPED); |
| 582 VLOG(2) << "ARC session is stopped."; | 578 VLOG(2) << "ARC session is stopped."; |
| 583 arc_bridge_host_.reset(); | 579 arc_bridge_host_.reset(); |
| 584 state_ = State::STOPPED; | 580 state_ = State::STOPPED; |
| 585 for (auto& observer : observer_list_) | 581 for (auto& observer : observer_list_) |
| 586 observer.OnStopped(reason); | 582 observer.OnStopped(reason); |
| 587 } | 583 } |
| 588 | 584 |
| 589 } // namespace | 585 } // namespace |
| 590 | 586 |
| 591 ArcBridgeBootstrap::ArcBridgeBootstrap() = default; | 587 ArcSession::ArcSession() = default; |
| 592 ArcBridgeBootstrap::~ArcBridgeBootstrap() = default; | 588 ArcSession::~ArcSession() = default; |
| 593 | 589 |
| 594 void ArcBridgeBootstrap::AddObserver(Observer* observer) { | 590 void ArcSession::AddObserver(Observer* observer) { |
| 595 observer_list_.AddObserver(observer); | 591 observer_list_.AddObserver(observer); |
| 596 } | 592 } |
| 597 | 593 |
| 598 void ArcBridgeBootstrap::RemoveObserver(Observer* observer) { | 594 void ArcSession::RemoveObserver(Observer* observer) { |
| 599 observer_list_.RemoveObserver(observer); | 595 observer_list_.RemoveObserver(observer); |
| 600 } | 596 } |
| 601 | 597 |
| 602 // static | 598 // static |
| 603 std::unique_ptr<ArcBridgeBootstrap> ArcBridgeBootstrap::Create() { | 599 std::unique_ptr<ArcSession> ArcSession::Create() { |
| 604 return base::MakeUnique<ArcBridgeBootstrapImpl>(); | 600 return base::MakeUnique<ArcSessionImpl>(); |
| 605 } | 601 } |
| 606 | 602 |
| 607 } // namespace arc | 603 } // namespace arc |
| OLD | NEW |