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_bridge_bootstrap.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" | 24 #include "base/threading/worker_pool.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_features.h" | 30 #include "components/arc/arc_features.h" |
30 #include "components/user_manager/user_manager.h" | 31 #include "components/user_manager/user_manager.h" |
31 #include "ipc/unix_domain_socket_util.h" | 32 #include "ipc/unix_domain_socket_util.h" |
32 #include "mojo/edk/embedder/embedder.h" | 33 #include "mojo/edk/embedder/embedder.h" |
33 #include "mojo/edk/embedder/platform_channel_pair.h" | 34 #include "mojo/edk/embedder/platform_channel_pair.h" |
34 #include "mojo/edk/embedder/platform_channel_utils_posix.h" | 35 #include "mojo/edk/embedder/platform_channel_utils_posix.h" |
35 #include "mojo/edk/embedder/platform_handle_vector.h" | 36 #include "mojo/edk/embedder/platform_handle_vector.h" |
36 #include "mojo/edk/embedder/scoped_platform_handle.h" | 37 #include "mojo/edk/embedder/scoped_platform_handle.h" |
37 #include "mojo/public/cpp/bindings/binding.h" | 38 #include "mojo/public/cpp/bindings/binding.h" |
38 | 39 |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 // CREATING_SOCKET | 120 // CREATING_SOCKET |
120 // CreateSocket() -> OnSocketCreated() -> | 121 // CreateSocket() -> OnSocketCreated() -> |
121 // STARTING_INSTANCE | 122 // STARTING_INSTANCE |
122 // -> OnInstanceStarted() -> | 123 // -> OnInstanceStarted() -> |
123 // CONNECTING_MOJO | 124 // CONNECTING_MOJO |
124 // ConnectMojo() -> OnMojoConnected() -> | 125 // ConnectMojo() -> OnMojoConnected() -> |
125 // RUNNING | 126 // RUNNING |
126 // | 127 // |
127 // At any state, Stop() can be called. It does not immediately stop the | 128 // At any state, Stop() can be called. It does not immediately stop the |
128 // instance, but will eventually stop it. | 129 // instance, but will eventually stop it. |
129 // The actual stop will be notified via OnStopped() of the |delegate_|. | 130 // The actual stop will be notified via Observer::OnStopped(). |
130 // | 131 // |
131 // When Stop() is called, it makes various behavior based on the current | 132 // When Stop() is called, it makes various behavior based on the current |
132 // phase. | 133 // phase. |
133 // | 134 // |
134 // NOT_STARTED: | 135 // NOT_STARTED: |
135 // Do nothing. Immediately transition to the STOPPED state. | 136 // Do nothing. Immediately transition to the STOPPED state. |
136 // CHECKING_DISK_SPACE, CREATING_SOCKET: | 137 // CHECKING_DISK_SPACE, CREATING_SOCKET: |
137 // The main task of those phases runs on WorkerPool thread. So, Stop() | 138 // The main task of those phases runs on WorkerPool thread. So, Stop() |
138 // just sets the flag and return. On the main task completion, a callback | 139 // just sets the flag and return. On the main task completion, a callback |
139 // will run on the main (practically UI) thread, and the flag is checked | 140 // will run on the main (practically UI) thread, and the flag is checked |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
241 // The state of the bootstrap connection. | 242 // The state of the bootstrap connection. |
242 State state_ = State::NOT_STARTED; | 243 State state_ = State::NOT_STARTED; |
243 | 244 |
244 // When Stop() is called, this flag is set. | 245 // When Stop() is called, this flag is set. |
245 bool stop_requested_ = false; | 246 bool stop_requested_ = false; |
246 | 247 |
247 // In CONNECTING_MOJO state, this is set to the write side of the pipe | 248 // In CONNECTING_MOJO state, this is set to the write side of the pipe |
248 // to notify cancelling of the procedure. | 249 // to notify cancelling of the procedure. |
249 base::ScopedFD accept_cancel_pipe_; | 250 base::ScopedFD accept_cancel_pipe_; |
250 | 251 |
| 252 // Mojo endpoint. |
| 253 std::unique_ptr<mojom::ArcBridgeHost> arc_bridge_host_; |
| 254 |
251 base::ThreadChecker thread_checker_; | 255 base::ThreadChecker thread_checker_; |
252 | 256 |
253 // WeakPtrFactory to use callbacks. | 257 // WeakPtrFactory to use callbacks. |
254 base::WeakPtrFactory<ArcBridgeBootstrapImpl> weak_factory_; | 258 base::WeakPtrFactory<ArcBridgeBootstrapImpl> weak_factory_; |
255 | 259 |
256 private: | 260 private: |
257 DISALLOW_COPY_AND_ASSIGN(ArcBridgeBootstrapImpl); | 261 DISALLOW_COPY_AND_ASSIGN(ArcBridgeBootstrapImpl); |
258 }; | 262 }; |
259 | 263 |
260 ArcBridgeBootstrapImpl::ArcBridgeBootstrapImpl() | 264 ArcBridgeBootstrapImpl::ArcBridgeBootstrapImpl() |
261 : weak_factory_(this) { | 265 : weak_factory_(this) { |
262 chromeos::SessionManagerClient* client = GetSessionManagerClient(); | 266 chromeos::SessionManagerClient* client = GetSessionManagerClient(); |
263 if (client == nullptr) | 267 if (client == nullptr) |
264 return; | 268 return; |
265 client->AddObserver(this); | 269 client->AddObserver(this); |
266 } | 270 } |
267 | 271 |
268 ArcBridgeBootstrapImpl::~ArcBridgeBootstrapImpl() { | 272 ArcBridgeBootstrapImpl::~ArcBridgeBootstrapImpl() { |
269 DCHECK(thread_checker_.CalledOnValidThread()); | 273 DCHECK(thread_checker_.CalledOnValidThread()); |
270 // TODO(hidehiko): CHECK if |state_| is in NOT_STARTED or STOPPED. | 274 // TODO(hidehiko): CHECK if |state_| is in NOT_STARTED or STOPPED. |
271 // Currently, specifically on shutdown, the state_ can be any value. | 275 // Currently, specifically on shutdown, the state_ can be any value. |
272 chromeos::SessionManagerClient* client = GetSessionManagerClient(); | 276 chromeos::SessionManagerClient* client = GetSessionManagerClient(); |
273 if (client == nullptr) | 277 if (client == nullptr) |
274 return; | 278 return; |
275 client->RemoveObserver(this); | 279 client->RemoveObserver(this); |
276 } | 280 } |
277 | 281 |
278 void ArcBridgeBootstrapImpl::Start() { | 282 void ArcBridgeBootstrapImpl::Start() { |
279 DCHECK(thread_checker_.CalledOnValidThread()); | 283 DCHECK(thread_checker_.CalledOnValidThread()); |
280 DCHECK(delegate_); | |
281 DCHECK_EQ(state_, State::NOT_STARTED); | 284 DCHECK_EQ(state_, State::NOT_STARTED); |
282 VLOG(2) << "Starting ARC session."; | 285 VLOG(2) << "Starting ARC session."; |
283 VLOG(2) << "Checking disk space..."; | 286 VLOG(2) << "Checking disk space..."; |
284 state_ = State::CHECKING_DISK_SPACE; | 287 state_ = State::CHECKING_DISK_SPACE; |
285 | 288 |
286 // TODO(crbug.com/628124): Move disk space checking logic to session_manager. | 289 // TODO(crbug.com/628124): Move disk space checking logic to session_manager. |
287 base::PostTaskAndReplyWithResult( | 290 base::PostTaskAndReplyWithResult( |
288 base::WorkerPool::GetTaskRunner(true).get(), FROM_HERE, | 291 base::WorkerPool::GetTaskRunner(true).get(), FROM_HERE, |
289 base::Bind(&base::SysInfo::AmountOfFreeDiskSpace, | 292 base::Bind(&base::SysInfo::AmountOfFreeDiskSpace, |
290 base::FilePath(kDiskCheckPath)), | 293 base::FilePath(kDiskCheckPath)), |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
507 mojo::edk::ScopedPlatformHandle(mojo::edk::PlatformHandle(fd.release()))); | 510 mojo::edk::ScopedPlatformHandle(mojo::edk::PlatformHandle(fd.release()))); |
508 if (!server_pipe.is_valid()) { | 511 if (!server_pipe.is_valid()) { |
509 LOG(ERROR) << "Invalid pipe"; | 512 LOG(ERROR) << "Invalid pipe"; |
510 StopArcInstance(); | 513 StopArcInstance(); |
511 return; | 514 return; |
512 } | 515 } |
513 | 516 |
514 mojom::ArcBridgeInstancePtr instance; | 517 mojom::ArcBridgeInstancePtr instance; |
515 instance.Bind(mojo::InterfacePtrInfo<mojom::ArcBridgeInstance>( | 518 instance.Bind(mojo::InterfacePtrInfo<mojom::ArcBridgeInstance>( |
516 std::move(server_pipe), 0u)); | 519 std::move(server_pipe), 0u)); |
517 // TODO(hidehiko): Move to creating ArcBridgeHost here to fix the twisted | 520 arc_bridge_host_.reset(new ArcBridgeHostImpl(std::move(instance))); |
518 // state change. | |
519 | 521 |
520 VLOG(2) << "Mojo is connected. ARC is running."; | 522 VLOG(2) << "Mojo is connected. ARC is running."; |
521 state_ = State::RUNNING; | 523 state_ = State::RUNNING; |
522 delegate_->OnConnectionEstablished(std::move(instance)); | 524 FOR_EACH_OBSERVER(ArcBridgeBootstrap::Observer, observer_list_, OnReady()); |
523 } | 525 } |
524 | 526 |
525 void ArcBridgeBootstrapImpl::Stop() { | 527 void ArcBridgeBootstrapImpl::Stop() { |
526 DCHECK(thread_checker_.CalledOnValidThread()); | 528 DCHECK(thread_checker_.CalledOnValidThread()); |
527 DCHECK(delegate_); | |
528 VLOG(2) << "Stopping ARC session is requested."; | 529 VLOG(2) << "Stopping ARC session is requested."; |
529 | 530 |
530 // For second time or later, just do nothing. | 531 // For second time or later, just do nothing. |
531 // It is already in the stopping phase. | 532 // It is already in the stopping phase. |
532 if (stop_requested_) | 533 if (stop_requested_) |
533 return; | 534 return; |
534 | 535 |
535 stop_requested_ = true; | 536 stop_requested_ = true; |
| 537 arc_bridge_host_.reset(); |
536 switch (state_) { | 538 switch (state_) { |
537 case State::NOT_STARTED: | 539 case State::NOT_STARTED: |
538 OnStopped(ArcBridgeService::StopReason::SHUTDOWN); | 540 OnStopped(ArcBridgeService::StopReason::SHUTDOWN); |
539 return; | 541 return; |
540 | 542 |
541 case State::CHECKING_DISK_SPACE: | 543 case State::CHECKING_DISK_SPACE: |
542 case State::CREATING_SOCKET: | 544 case State::CREATING_SOCKET: |
543 case State::STARTING_INSTANCE: | 545 case State::STARTING_INSTANCE: |
544 // Before starting the ARC instance, we do nothing here. | 546 // Before starting the ARC instance, we do nothing here. |
545 // At some point, a callback will be invoked on UI thread, | 547 // At some point, a callback will be invoked on UI thread, |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
610 reason = ArcBridgeService::StopReason::CRASH; | 612 reason = ArcBridgeService::StopReason::CRASH; |
611 } | 613 } |
612 OnStopped(reason); | 614 OnStopped(reason); |
613 } | 615 } |
614 | 616 |
615 void ArcBridgeBootstrapImpl::OnStopped(ArcBridgeService::StopReason reason) { | 617 void ArcBridgeBootstrapImpl::OnStopped(ArcBridgeService::StopReason reason) { |
616 DCHECK(thread_checker_.CalledOnValidThread()); | 618 DCHECK(thread_checker_.CalledOnValidThread()); |
617 // OnStopped() should be called once per instance. | 619 // OnStopped() should be called once per instance. |
618 DCHECK_NE(state_, State::STOPPED); | 620 DCHECK_NE(state_, State::STOPPED); |
619 VLOG(2) << "ARC session is stopped."; | 621 VLOG(2) << "ARC session is stopped."; |
| 622 arc_bridge_host_.reset(); |
620 state_ = State::STOPPED; | 623 state_ = State::STOPPED; |
621 delegate_->OnStopped(reason); | 624 FOR_EACH_OBSERVER(ArcBridgeBootstrap::Observer, observer_list_, |
| 625 OnStopped(reason)); |
622 } | 626 } |
623 | 627 |
624 } // namespace | 628 } // namespace |
625 | 629 |
| 630 ArcBridgeBootstrap::ArcBridgeBootstrap() = default; |
| 631 ArcBridgeBootstrap::~ArcBridgeBootstrap() = default; |
| 632 |
| 633 void ArcBridgeBootstrap::AddObserver(Observer* observer) { |
| 634 observer_list_.AddObserver(observer); |
| 635 } |
| 636 |
| 637 void ArcBridgeBootstrap::RemoveObserver(Observer* observer) { |
| 638 observer_list_.RemoveObserver(observer); |
| 639 } |
| 640 |
626 // static | 641 // static |
627 std::unique_ptr<ArcBridgeBootstrap> ArcBridgeBootstrap::Create() { | 642 std::unique_ptr<ArcBridgeBootstrap> ArcBridgeBootstrap::Create() { |
628 return base::MakeUnique<ArcBridgeBootstrapImpl>(); | 643 return base::MakeUnique<ArcBridgeBootstrapImpl>(); |
629 } | 644 } |
630 | 645 |
631 } // namespace arc | 646 } // namespace arc |
OLD | NEW |