| 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> |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 void OnShutdown() override; | 212 void OnShutdown() override; |
| 213 | 213 |
| 214 private: | 214 private: |
| 215 // Creates the UNIX socket on a worker pool and then processes its file | 215 // Creates the UNIX socket on a worker pool and then processes its file |
| 216 // descriptor. | 216 // descriptor. |
| 217 static mojo::edk::ScopedPlatformHandle CreateSocket(); | 217 static mojo::edk::ScopedPlatformHandle CreateSocket(); |
| 218 void OnSocketCreated(mojo::edk::ScopedPlatformHandle fd); | 218 void OnSocketCreated(mojo::edk::ScopedPlatformHandle fd); |
| 219 | 219 |
| 220 // DBus callback for StartArcInstance(). | 220 // DBus callback for StartArcInstance(). |
| 221 void OnInstanceStarted(mojo::edk::ScopedPlatformHandle socket_fd, | 221 void OnInstanceStarted(mojo::edk::ScopedPlatformHandle socket_fd, |
| 222 StartArcInstanceResult result); | 222 StartArcInstanceResult result, |
| 223 const std::string& container_instance_id); |
| 223 | 224 |
| 224 // Synchronously accepts a connection on |socket_fd| and then processes the | 225 // Synchronously accepts a connection on |socket_fd| and then processes the |
| 225 // connected socket's file descriptor. | 226 // connected socket's file descriptor. |
| 226 static mojo::ScopedMessagePipeHandle ConnectMojo( | 227 static mojo::ScopedMessagePipeHandle ConnectMojo( |
| 227 mojo::edk::ScopedPlatformHandle socket_fd, | 228 mojo::edk::ScopedPlatformHandle socket_fd, |
| 228 base::ScopedFD cancel_fd); | 229 base::ScopedFD cancel_fd); |
| 229 void OnMojoConnected(mojo::ScopedMessagePipeHandle server_pipe); | 230 void OnMojoConnected(mojo::ScopedMessagePipeHandle server_pipe); |
| 230 | 231 |
| 231 // Request to stop ARC instance via DBus. | 232 // Request to stop ARC instance via DBus. |
| 232 void StopArcInstance(); | 233 void StopArcInstance(); |
| 233 | 234 |
| 234 // chromeos::SessionManagerClient::Observer: | 235 // chromeos::SessionManagerClient::Observer: |
| 235 void ArcInstanceStopped(bool clean) override; | 236 void ArcInstanceStopped(bool clean, |
| 237 const std::string& container_instance_id) override; |
| 236 | 238 |
| 237 // Completes the termination procedure. | 239 // Completes the termination procedure. |
| 238 void OnStopped(ArcStopReason reason); | 240 void OnStopped(ArcStopReason reason); |
| 239 | 241 |
| 240 // Checks whether a function runs on the thread where the instance is | 242 // Checks whether a function runs on the thread where the instance is |
| 241 // created. | 243 // created. |
| 242 base::ThreadChecker thread_checker_; | 244 base::ThreadChecker thread_checker_; |
| 243 | 245 |
| 244 // Owned by ArcServiceManager. | 246 // Owned by ArcServiceManager. |
| 245 ArcBridgeService* const arc_bridge_service_; | 247 ArcBridgeService* const arc_bridge_service_; |
| 246 | 248 |
| 247 // Task runner to run a blocking tasks. | 249 // Task runner to run a blocking tasks. |
| 248 scoped_refptr<base::TaskRunner> blocking_task_runner_; | 250 scoped_refptr<base::TaskRunner> blocking_task_runner_; |
| 249 | 251 |
| 250 // The state of the session. | 252 // The state of the session. |
| 251 State state_ = State::NOT_STARTED; | 253 State state_ = State::NOT_STARTED; |
| 252 | 254 |
| 253 // When Stop() is called, this flag is set. | 255 // When Stop() is called, this flag is set. |
| 254 bool stop_requested_ = false; | 256 bool stop_requested_ = false; |
| 255 | 257 |
| 258 // Container instance id passed from session_manager. |
| 259 // Should be available only after OnInstanceStarted(). |
| 260 std::string container_instance_id_; |
| 261 |
| 256 // In CONNECTING_MOJO state, this is set to the write side of the pipe | 262 // In CONNECTING_MOJO state, this is set to the write side of the pipe |
| 257 // to notify cancelling of the procedure. | 263 // to notify cancelling of the procedure. |
| 258 base::ScopedFD accept_cancel_pipe_; | 264 base::ScopedFD accept_cancel_pipe_; |
| 259 | 265 |
| 260 // Mojo endpoint. | 266 // Mojo endpoint. |
| 261 std::unique_ptr<mojom::ArcBridgeHost> arc_bridge_host_; | 267 std::unique_ptr<mojom::ArcBridgeHost> arc_bridge_host_; |
| 262 | 268 |
| 263 // WeakPtrFactory to use callbacks. | 269 // WeakPtrFactory to use callbacks. |
| 264 base::WeakPtrFactory<ArcSessionImpl> weak_factory_; | 270 base::WeakPtrFactory<ArcSessionImpl> weak_factory_; |
| 265 | 271 |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 374 chromeos::SessionManagerClient* session_manager_client = | 380 chromeos::SessionManagerClient* session_manager_client = |
| 375 chromeos::DBusThreadManager::Get()->GetSessionManagerClient(); | 381 chromeos::DBusThreadManager::Get()->GetSessionManagerClient(); |
| 376 session_manager_client->StartArcInstance( | 382 session_manager_client->StartArcInstance( |
| 377 cryptohome_id, disable_boot_completed_broadcast, enable_vendor_privileged, | 383 cryptohome_id, disable_boot_completed_broadcast, enable_vendor_privileged, |
| 378 base::Bind(&ArcSessionImpl::OnInstanceStarted, weak_factory_.GetWeakPtr(), | 384 base::Bind(&ArcSessionImpl::OnInstanceStarted, weak_factory_.GetWeakPtr(), |
| 379 base::Passed(&socket_fd))); | 385 base::Passed(&socket_fd))); |
| 380 } | 386 } |
| 381 | 387 |
| 382 void ArcSessionImpl::OnInstanceStarted( | 388 void ArcSessionImpl::OnInstanceStarted( |
| 383 mojo::edk::ScopedPlatformHandle socket_fd, | 389 mojo::edk::ScopedPlatformHandle socket_fd, |
| 384 StartArcInstanceResult result) { | 390 StartArcInstanceResult result, |
| 391 const std::string& container_instance_id) { |
| 385 DCHECK(thread_checker_.CalledOnValidThread()); | 392 DCHECK(thread_checker_.CalledOnValidThread()); |
| 386 if (state_ == State::STOPPED) { | |
| 387 // This is the case that error is notified via DBus before the | |
| 388 // OnInstanceStarted() callback is invoked. The stopping procedure has | |
| 389 // been run, so do nothing. | |
| 390 return; | |
| 391 } | |
| 392 | |
| 393 DCHECK_EQ(state_, State::STARTING_INSTANCE); | 393 DCHECK_EQ(state_, State::STARTING_INSTANCE); |
| 394 container_instance_id_ = container_instance_id; |
| 394 | 395 |
| 395 if (stop_requested_) { | 396 if (stop_requested_) { |
| 396 if (result == StartArcInstanceResult::SUCCESS) { | 397 if (result == StartArcInstanceResult::SUCCESS) { |
| 397 // The ARC instance has started to run. Request to stop. | 398 // The ARC instance has started to run. Request to stop. |
| 398 StopArcInstance(); | 399 StopArcInstance(); |
| 399 return; | 400 return; |
| 400 } | 401 } |
| 401 OnStopped(ArcStopReason::SHUTDOWN); | 402 OnStopped(ArcStopReason::SHUTDOWN); |
| 402 return; | 403 return; |
| 403 } | 404 } |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 474 PLOG(ERROR) << "sendmsg"; | 475 PLOG(ERROR) << "sendmsg"; |
| 475 return mojo::ScopedMessagePipeHandle(); | 476 return mojo::ScopedMessagePipeHandle(); |
| 476 } | 477 } |
| 477 | 478 |
| 478 return pipe; | 479 return pipe; |
| 479 } | 480 } |
| 480 | 481 |
| 481 void ArcSessionImpl::OnMojoConnected( | 482 void ArcSessionImpl::OnMojoConnected( |
| 482 mojo::ScopedMessagePipeHandle server_pipe) { | 483 mojo::ScopedMessagePipeHandle server_pipe) { |
| 483 DCHECK(thread_checker_.CalledOnValidThread()); | 484 DCHECK(thread_checker_.CalledOnValidThread()); |
| 484 | |
| 485 if (state_ == State::STOPPED) { | |
| 486 // This is the case that error is notified via DBus before the | |
| 487 // OnMojoConnected() callback is invoked. The stopping procedure has | |
| 488 // been run, so do nothing. | |
| 489 return; | |
| 490 } | |
| 491 | |
| 492 DCHECK_EQ(state_, State::CONNECTING_MOJO); | 485 DCHECK_EQ(state_, State::CONNECTING_MOJO); |
| 493 accept_cancel_pipe_.reset(); | 486 accept_cancel_pipe_.reset(); |
| 494 | 487 |
| 495 if (stop_requested_) { | 488 if (stop_requested_) { |
| 496 StopArcInstance(); | 489 StopArcInstance(); |
| 497 return; | 490 return; |
| 498 } | 491 } |
| 499 | 492 |
| 500 if (!server_pipe.is_valid()) { | 493 if (!server_pipe.is_valid()) { |
| 501 LOG(ERROR) << "Invalid pipe"; | 494 LOG(ERROR) << "Invalid pipe"; |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 569 state_ == State::CONNECTING_MOJO || state_ == State::RUNNING); | 562 state_ == State::CONNECTING_MOJO || state_ == State::RUNNING); |
| 570 | 563 |
| 571 // Notification will arrive through ArcInstanceStopped(). | 564 // Notification will arrive through ArcInstanceStopped(). |
| 572 VLOG(2) << "Requesting to stop ARC instance"; | 565 VLOG(2) << "Requesting to stop ARC instance"; |
| 573 chromeos::SessionManagerClient* session_manager_client = | 566 chromeos::SessionManagerClient* session_manager_client = |
| 574 chromeos::DBusThreadManager::Get()->GetSessionManagerClient(); | 567 chromeos::DBusThreadManager::Get()->GetSessionManagerClient(); |
| 575 session_manager_client->StopArcInstance( | 568 session_manager_client->StopArcInstance( |
| 576 base::Bind(&DoNothingInstanceStopped)); | 569 base::Bind(&DoNothingInstanceStopped)); |
| 577 } | 570 } |
| 578 | 571 |
| 579 void ArcSessionImpl::ArcInstanceStopped(bool clean) { | 572 void ArcSessionImpl::ArcInstanceStopped( |
| 573 bool clean, |
| 574 const std::string& container_instance_id) { |
| 580 DCHECK(thread_checker_.CalledOnValidThread()); | 575 DCHECK(thread_checker_.CalledOnValidThread()); |
| 581 VLOG(1) << "Notified that ARC instance is stopped " | 576 VLOG(1) << "Notified that ARC instance is stopped " |
| 582 << (clean ? "cleanly" : "uncleanly"); | 577 << (clean ? "cleanly" : "uncleanly"); |
| 583 | 578 |
| 579 if (container_instance_id != container_instance_id_) { |
| 580 VLOG(1) << "Container instance id mismatch. Do nothing." |
| 581 << container_instance_id << " vs " << container_instance_id_; |
| 582 return; |
| 583 } |
| 584 |
| 585 // Release |container_instance_id_| to avoid duplicate invocation situation. |
| 586 container_instance_id_.clear(); |
| 587 |
| 584 // In case that crash happens during before the Mojo channel is connected, | 588 // In case that crash happens during before the Mojo channel is connected, |
| 585 // unlock the BlockingPool thread. | 589 // unlock the BlockingPool thread. |
| 586 accept_cancel_pipe_.reset(); | 590 accept_cancel_pipe_.reset(); |
| 587 | 591 |
| 588 ArcStopReason reason; | 592 ArcStopReason reason; |
| 589 if (stop_requested_) { | 593 if (stop_requested_) { |
| 590 // If the ARC instance is stopped after its explicit request, | 594 // If the ARC instance is stopped after its explicit request, |
| 591 // return SHUTDOWN. | 595 // return SHUTDOWN. |
| 592 reason = ArcStopReason::SHUTDOWN; | 596 reason = ArcStopReason::SHUTDOWN; |
| 593 } else if (clean) { | 597 } else if (clean) { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 653 | 657 |
| 654 // static | 658 // static |
| 655 std::unique_ptr<ArcSession> ArcSession::Create( | 659 std::unique_ptr<ArcSession> ArcSession::Create( |
| 656 ArcBridgeService* arc_bridge_service, | 660 ArcBridgeService* arc_bridge_service, |
| 657 const scoped_refptr<base::TaskRunner>& blocking_task_runner) { | 661 const scoped_refptr<base::TaskRunner>& blocking_task_runner) { |
| 658 return base::MakeUnique<ArcSessionImpl>(arc_bridge_service, | 662 return base::MakeUnique<ArcSessionImpl>(arc_bridge_service, |
| 659 blocking_task_runner); | 663 blocking_task_runner); |
| 660 } | 664 } |
| 661 | 665 |
| 662 } // namespace arc | 666 } // namespace arc |
| OLD | NEW |