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

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

Issue 2720303002: Do nothing on OnSessionStopped if ARC is being restarted. (Closed)
Patch Set: Address comments. Created 3 years, 9 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_session.h ('k') | components/arc/arc_session_observer.h » ('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_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 10 matching lines...) Expand all
21 #include "base/sys_info.h" 21 #include "base/sys_info.h"
22 #include "base/task_runner_util.h" 22 #include "base/task_runner_util.h"
23 #include "base/threading/thread_checker.h" 23 #include "base/threading/thread_checker.h"
24 #include "base/threading/thread_task_runner_handle.h" 24 #include "base/threading/thread_task_runner_handle.h"
25 #include "chromeos/cryptohome/cryptohome_parameters.h" 25 #include "chromeos/cryptohome/cryptohome_parameters.h"
26 #include "chromeos/dbus/dbus_method_call_status.h" 26 #include "chromeos/dbus/dbus_method_call_status.h"
27 #include "chromeos/dbus/dbus_thread_manager.h" 27 #include "chromeos/dbus/dbus_thread_manager.h"
28 #include "chromeos/dbus/session_manager_client.h" 28 #include "chromeos/dbus/session_manager_client.h"
29 #include "components/arc/arc_bridge_host_impl.h" 29 #include "components/arc/arc_bridge_host_impl.h"
30 #include "components/arc/arc_features.h" 30 #include "components/arc/arc_features.h"
31 #include "components/arc/arc_session_observer.h"
32 #include "components/user_manager/user_manager.h" 31 #include "components/user_manager/user_manager.h"
33 #include "mojo/edk/embedder/embedder.h" 32 #include "mojo/edk/embedder/embedder.h"
34 #include "mojo/edk/embedder/named_platform_handle.h" 33 #include "mojo/edk/embedder/named_platform_handle.h"
35 #include "mojo/edk/embedder/named_platform_handle_utils.h" 34 #include "mojo/edk/embedder/named_platform_handle_utils.h"
36 #include "mojo/edk/embedder/pending_process_connection.h" 35 #include "mojo/edk/embedder/pending_process_connection.h"
37 #include "mojo/edk/embedder/platform_channel_pair.h" 36 #include "mojo/edk/embedder/platform_channel_pair.h"
38 #include "mojo/edk/embedder/platform_channel_utils_posix.h" 37 #include "mojo/edk/embedder/platform_channel_utils_posix.h"
39 #include "mojo/edk/embedder/platform_handle_vector.h" 38 #include "mojo/edk/embedder/platform_handle_vector.h"
40 #include "mojo/edk/embedder/scoped_platform_handle.h" 39 #include "mojo/edk/embedder/scoped_platform_handle.h"
41 #include "mojo/public/cpp/bindings/binding.h" 40 #include "mojo/public/cpp/bindings/binding.h"
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 // CREATING_SOCKET 119 // CREATING_SOCKET
121 // CreateSocket() -> OnSocketCreated() -> 120 // CreateSocket() -> OnSocketCreated() ->
122 // STARTING_INSTANCE 121 // STARTING_INSTANCE
123 // -> OnInstanceStarted() -> 122 // -> OnInstanceStarted() ->
124 // CONNECTING_MOJO 123 // CONNECTING_MOJO
125 // ConnectMojo() -> OnMojoConnected() -> 124 // ConnectMojo() -> OnMojoConnected() ->
126 // RUNNING 125 // RUNNING
127 // 126 //
128 // At any state, Stop() can be called. It does not immediately stop the 127 // At any state, Stop() can be called. It does not immediately stop the
129 // instance, but will eventually stop it. 128 // instance, but will eventually stop it.
130 // The actual stop will be notified via ArcSessionObserver::OnStopped(). 129 // The actual stop will be notified via ArcSession::Observer::OnStopped().
131 // 130 //
132 // When Stop() is called, it makes various behavior based on the current 131 // When Stop() is called, it makes various behavior based on the current
133 // phase. 132 // phase.
134 // 133 //
135 // NOT_STARTED: 134 // NOT_STARTED:
136 // Do nothing. Immediately transition to the STOPPED state. 135 // Do nothing. Immediately transition to the STOPPED state.
137 // CREATING_SOCKET: 136 // CREATING_SOCKET:
138 // The main task of the phase runs on BlockingPool thread. So, Stop() just 137 // The main task of the phase runs on BlockingPool thread. So, Stop() just
139 // sets the flag and return. On the main task completion, a callback 138 // sets the flag and return. On the main task completion, a callback
140 // will run on the main (practically UI) thread, and the flag is checked 139 // will run on the main (practically UI) thread, and the flag is checked
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 base::ScopedFD cancel_fd); 227 base::ScopedFD cancel_fd);
229 void OnMojoConnected(mojo::ScopedMessagePipeHandle server_pipe); 228 void OnMojoConnected(mojo::ScopedMessagePipeHandle server_pipe);
230 229
231 // Request to stop ARC instance via DBus. 230 // Request to stop ARC instance via DBus.
232 void StopArcInstance(); 231 void StopArcInstance();
233 232
234 // chromeos::SessionManagerClient::Observer: 233 // chromeos::SessionManagerClient::Observer:
235 void ArcInstanceStopped(bool clean) override; 234 void ArcInstanceStopped(bool clean) override;
236 235
237 // Completes the termination procedure. 236 // Completes the termination procedure.
238 void OnStopped(ArcSessionObserver::StopReason reason); 237 void OnStopped(ArcStopReason reason);
239 238
240 // Checks whether a function runs on the thread where the instance is 239 // Checks whether a function runs on the thread where the instance is
241 // created. 240 // created.
242 base::ThreadChecker thread_checker_; 241 base::ThreadChecker thread_checker_;
243 242
244 // Owned by ArcServiceManager. 243 // Owned by ArcServiceManager.
245 ArcBridgeService* const arc_bridge_service_; 244 ArcBridgeService* const arc_bridge_service_;
246 245
247 // Task runner to run a blocking tasks. 246 // Task runner to run a blocking tasks.
248 scoped_refptr<base::TaskRunner> blocking_task_runner_; 247 scoped_refptr<base::TaskRunner> blocking_task_runner_;
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 return socket_fd; 338 return socket_fd;
340 } 339 }
341 340
342 void ArcSessionImpl::OnSocketCreated( 341 void ArcSessionImpl::OnSocketCreated(
343 mojo::edk::ScopedPlatformHandle socket_fd) { 342 mojo::edk::ScopedPlatformHandle socket_fd) {
344 DCHECK(thread_checker_.CalledOnValidThread()); 343 DCHECK(thread_checker_.CalledOnValidThread());
345 DCHECK_EQ(state_, State::CREATING_SOCKET); 344 DCHECK_EQ(state_, State::CREATING_SOCKET);
346 345
347 if (stop_requested_) { 346 if (stop_requested_) {
348 VLOG(1) << "Stop() called while connecting"; 347 VLOG(1) << "Stop() called while connecting";
349 OnStopped(ArcSessionObserver::StopReason::SHUTDOWN); 348 OnStopped(ArcStopReason::SHUTDOWN);
350 return; 349 return;
351 } 350 }
352 351
353 if (!socket_fd.is_valid()) { 352 if (!socket_fd.is_valid()) {
354 LOG(ERROR) << "ARC: Error creating socket"; 353 LOG(ERROR) << "ARC: Error creating socket";
355 OnStopped(ArcSessionObserver::StopReason::GENERIC_BOOT_FAILURE); 354 OnStopped(ArcStopReason::GENERIC_BOOT_FAILURE);
356 return; 355 return;
357 } 356 }
358 357
359 VLOG(2) << "Socket is created. Starting ARC instance..."; 358 VLOG(2) << "Socket is created. Starting ARC instance...";
360 state_ = State::STARTING_INSTANCE; 359 state_ = State::STARTING_INSTANCE;
361 user_manager::UserManager* user_manager = user_manager::UserManager::Get(); 360 user_manager::UserManager* user_manager = user_manager::UserManager::Get();
362 DCHECK(user_manager->GetPrimaryUser()); 361 DCHECK(user_manager->GetPrimaryUser());
363 const cryptohome::Identification cryptohome_id( 362 const cryptohome::Identification cryptohome_id(
364 user_manager->GetPrimaryUser()->GetAccountId()); 363 user_manager->GetPrimaryUser()->GetAccountId());
365 364
(...skipping 20 matching lines...) Expand all
386 } 385 }
387 386
388 DCHECK_EQ(state_, State::STARTING_INSTANCE); 387 DCHECK_EQ(state_, State::STARTING_INSTANCE);
389 388
390 if (stop_requested_) { 389 if (stop_requested_) {
391 if (result == StartArcInstanceResult::SUCCESS) { 390 if (result == StartArcInstanceResult::SUCCESS) {
392 // The ARC instance has started to run. Request to stop. 391 // The ARC instance has started to run. Request to stop.
393 StopArcInstance(); 392 StopArcInstance();
394 return; 393 return;
395 } 394 }
396 OnStopped(ArcSessionObserver::StopReason::SHUTDOWN); 395 OnStopped(ArcStopReason::SHUTDOWN);
397 return; 396 return;
398 } 397 }
399 398
400 if (result != StartArcInstanceResult::SUCCESS) { 399 if (result != StartArcInstanceResult::SUCCESS) {
401 LOG(ERROR) << "Failed to start ARC instance"; 400 LOG(ERROR) << "Failed to start ARC instance";
402 OnStopped(result == StartArcInstanceResult::LOW_FREE_DISK_SPACE 401 OnStopped(result == StartArcInstanceResult::LOW_FREE_DISK_SPACE
403 ? ArcSessionObserver::StopReason::LOW_DISK_SPACE 402 ? ArcStopReason::LOW_DISK_SPACE
404 : ArcSessionObserver::StopReason::GENERIC_BOOT_FAILURE); 403 : ArcStopReason::GENERIC_BOOT_FAILURE);
405 return; 404 return;
406 } 405 }
407 406
408 VLOG(2) << "ARC instance is successfully started. Connecting Mojo..."; 407 VLOG(2) << "ARC instance is successfully started. Connecting Mojo...";
409 state_ = State::CONNECTING_MOJO; 408 state_ = State::CONNECTING_MOJO;
410 409
411 // Prepare a pipe so that AcceptInstanceConnection can be interrupted on 410 // Prepare a pipe so that AcceptInstanceConnection can be interrupted on
412 // Stop(). 411 // Stop().
413 base::ScopedFD cancel_fd; 412 base::ScopedFD cancel_fd;
414 if (!CreatePipe(&cancel_fd, &accept_cancel_pipe_)) { 413 if (!CreatePipe(&cancel_fd, &accept_cancel_pipe_)) {
415 OnStopped(ArcSessionObserver::StopReason::GENERIC_BOOT_FAILURE); 414 OnStopped(ArcStopReason::GENERIC_BOOT_FAILURE);
416 return; 415 return;
417 } 416 }
418 417
419 base::PostTaskAndReplyWithResult( 418 base::PostTaskAndReplyWithResult(
420 blocking_task_runner_.get(), FROM_HERE, 419 blocking_task_runner_.get(), FROM_HERE,
421 base::Bind(&ArcSessionImpl::ConnectMojo, base::Passed(&socket_fd), 420 base::Bind(&ArcSessionImpl::ConnectMojo, base::Passed(&socket_fd),
422 base::Passed(&cancel_fd)), 421 base::Passed(&cancel_fd)),
423 base::Bind(&ArcSessionImpl::OnMojoConnected, weak_factory_.GetWeakPtr())); 422 base::Bind(&ArcSessionImpl::OnMojoConnected, weak_factory_.GetWeakPtr()));
424 } 423 }
425 424
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 511
513 // For second time or later, just do nothing. 512 // For second time or later, just do nothing.
514 // It is already in the stopping phase. 513 // It is already in the stopping phase.
515 if (stop_requested_) 514 if (stop_requested_)
516 return; 515 return;
517 516
518 stop_requested_ = true; 517 stop_requested_ = true;
519 arc_bridge_host_.reset(); 518 arc_bridge_host_.reset();
520 switch (state_) { 519 switch (state_) {
521 case State::NOT_STARTED: 520 case State::NOT_STARTED:
522 OnStopped(ArcSessionObserver::StopReason::SHUTDOWN); 521 OnStopped(ArcStopReason::SHUTDOWN);
523 return; 522 return;
524 523
525 case State::CREATING_SOCKET: 524 case State::CREATING_SOCKET:
526 case State::STARTING_INSTANCE: 525 case State::STARTING_INSTANCE:
527 // Before starting the ARC instance, we do nothing here. 526 // Before starting the ARC instance, we do nothing here.
528 // At some point, a callback will be invoked on UI thread, 527 // At some point, a callback will be invoked on UI thread,
529 // and stopping procedure will be run there. 528 // and stopping procedure will be run there.
530 // On Chrome shutdown, it is not the case because the message loop is 529 // On Chrome shutdown, it is not the case because the message loop is
531 // already stopped here. Practically, it is not a problem because; 530 // already stopped here. Practically, it is not a problem because;
532 // - On socket creating, it is ok to simply ignore such cases, 531 // - On socket creating, it is ok to simply ignore such cases,
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
569 568
570 void ArcSessionImpl::ArcInstanceStopped(bool clean) { 569 void ArcSessionImpl::ArcInstanceStopped(bool clean) {
571 DCHECK(thread_checker_.CalledOnValidThread()); 570 DCHECK(thread_checker_.CalledOnValidThread());
572 VLOG(1) << "Notified that ARC instance is stopped " 571 VLOG(1) << "Notified that ARC instance is stopped "
573 << (clean ? "cleanly" : "uncleanly"); 572 << (clean ? "cleanly" : "uncleanly");
574 573
575 // In case that crash happens during before the Mojo channel is connected, 574 // In case that crash happens during before the Mojo channel is connected,
576 // unlock the BlockingPool thread. 575 // unlock the BlockingPool thread.
577 accept_cancel_pipe_.reset(); 576 accept_cancel_pipe_.reset();
578 577
579 ArcSessionObserver::StopReason reason; 578 ArcStopReason reason;
580 if (stop_requested_) { 579 if (stop_requested_) {
581 // If the ARC instance is stopped after its explicit request, 580 // If the ARC instance is stopped after its explicit request,
582 // return SHUTDOWN. 581 // return SHUTDOWN.
583 reason = ArcSessionObserver::StopReason::SHUTDOWN; 582 reason = ArcStopReason::SHUTDOWN;
584 } else if (clean) { 583 } else if (clean) {
585 // If the ARC instance is stopped, but it is not explicitly requested, 584 // If the ARC instance is stopped, but it is not explicitly requested,
586 // then this is triggered by some failure during the starting procedure. 585 // then this is triggered by some failure during the starting procedure.
587 // Return GENERIC_BOOT_FAILURE for the case. 586 // Return GENERIC_BOOT_FAILURE for the case.
588 reason = ArcSessionObserver::StopReason::GENERIC_BOOT_FAILURE; 587 reason = ArcStopReason::GENERIC_BOOT_FAILURE;
589 } else { 588 } else {
590 // Otherwise, this is caused by CRASH occured inside of the ARC instance. 589 // Otherwise, this is caused by CRASH occured inside of the ARC instance.
591 reason = ArcSessionObserver::StopReason::CRASH; 590 reason = ArcStopReason::CRASH;
592 } 591 }
593 OnStopped(reason); 592 OnStopped(reason);
594 } 593 }
595 594
596 void ArcSessionImpl::OnStopped(ArcSessionObserver::StopReason reason) { 595 void ArcSessionImpl::OnStopped(ArcStopReason reason) {
597 DCHECK(thread_checker_.CalledOnValidThread()); 596 DCHECK(thread_checker_.CalledOnValidThread());
598 // OnStopped() should be called once per instance. 597 // OnStopped() should be called once per instance.
599 DCHECK_NE(state_, State::STOPPED); 598 DCHECK_NE(state_, State::STOPPED);
600 VLOG(2) << "ARC session is stopped."; 599 VLOG(2) << "ARC session is stopped.";
601 arc_bridge_host_.reset(); 600 arc_bridge_host_.reset();
602 state_ = State::STOPPED; 601 state_ = State::STOPPED;
603 for (auto& observer : observer_list_) 602 for (auto& observer : observer_list_)
604 observer.OnSessionStopped(reason); 603 observer.OnSessionStopped(reason);
605 } 604 }
606 605
(...skipping 12 matching lines...) Expand all
619 // Stops the ARC instance to let it graceful shutdown. 618 // Stops the ARC instance to let it graceful shutdown.
620 // Note that this may fail if ARC container is not actually running, but 619 // Note that this may fail if ARC container is not actually running, but
621 // ignore an error as described below. 620 // ignore an error as described below.
622 if (state_ == State::STARTING_INSTANCE || 621 if (state_ == State::STARTING_INSTANCE ||
623 state_ == State::CONNECTING_MOJO || state_ == State::RUNNING) 622 state_ == State::CONNECTING_MOJO || state_ == State::RUNNING)
624 StopArcInstance(); 623 StopArcInstance();
625 624
626 // Directly set to the STOPPED stateby OnStopped(). Note that calling 625 // Directly set to the STOPPED stateby OnStopped(). Note that calling
627 // StopArcInstance() may not work well. At least, because the UI thread is 626 // StopArcInstance() may not work well. At least, because the UI thread is
628 // already stopped here, ArcInstanceStopped() callback cannot be invoked. 627 // already stopped here, ArcInstanceStopped() callback cannot be invoked.
629 OnStopped(ArcSessionObserver::StopReason::SHUTDOWN); 628 OnStopped(ArcStopReason::SHUTDOWN);
630 } 629 }
631 630
632 } // namespace 631 } // namespace
633 632
634 ArcSession::ArcSession() = default; 633 ArcSession::ArcSession() = default;
635 ArcSession::~ArcSession() = default; 634 ArcSession::~ArcSession() = default;
636 635
637 void ArcSession::AddObserver(ArcSessionObserver* observer) { 636 void ArcSession::AddObserver(Observer* observer) {
638 observer_list_.AddObserver(observer); 637 observer_list_.AddObserver(observer);
639 } 638 }
640 639
641 void ArcSession::RemoveObserver(ArcSessionObserver* observer) { 640 void ArcSession::RemoveObserver(Observer* observer) {
642 observer_list_.RemoveObserver(observer); 641 observer_list_.RemoveObserver(observer);
643 } 642 }
644 643
645 // static 644 // static
646 std::unique_ptr<ArcSession> ArcSession::Create( 645 std::unique_ptr<ArcSession> ArcSession::Create(
647 ArcBridgeService* arc_bridge_service, 646 ArcBridgeService* arc_bridge_service,
648 const scoped_refptr<base::TaskRunner>& blocking_task_runner) { 647 const scoped_refptr<base::TaskRunner>& blocking_task_runner) {
649 return base::MakeUnique<ArcSessionImpl>(arc_bridge_service, 648 return base::MakeUnique<ArcSessionImpl>(arc_bridge_service,
650 blocking_task_runner); 649 blocking_task_runner);
651 } 650 }
652 651
653 } // namespace arc 652 } // namespace arc
OLDNEW
« no previous file with comments | « components/arc/arc_session.h ('k') | components/arc/arc_session_observer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698