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