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

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

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