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. | |
Luis Héctor Chávez
2017/05/19 15:23:03
nit: OnInstanceStarted()
hidehiko
2017/05/22 08:38:06
Done.
| |
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 } | |
Luis Héctor Chávez
2017/05/19 15:23:03
nit: do you want to reset the container id here? J
hidehiko
2017/05/22 08:38:06
Done.
| |
584 | |
584 // In case that crash happens during before the Mojo channel is connected, | 585 // In case that crash happens during before the Mojo channel is connected, |
585 // unlock the BlockingPool thread. | 586 // unlock the BlockingPool thread. |
586 accept_cancel_pipe_.reset(); | 587 accept_cancel_pipe_.reset(); |
587 | 588 |
588 ArcStopReason reason; | 589 ArcStopReason reason; |
589 if (stop_requested_) { | 590 if (stop_requested_) { |
590 // If the ARC instance is stopped after its explicit request, | 591 // If the ARC instance is stopped after its explicit request, |
591 // return SHUTDOWN. | 592 // return SHUTDOWN. |
592 reason = ArcStopReason::SHUTDOWN; | 593 reason = ArcStopReason::SHUTDOWN; |
593 } else if (clean) { | 594 } else if (clean) { |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
653 | 654 |
654 // static | 655 // static |
655 std::unique_ptr<ArcSession> ArcSession::Create( | 656 std::unique_ptr<ArcSession> ArcSession::Create( |
656 ArcBridgeService* arc_bridge_service, | 657 ArcBridgeService* arc_bridge_service, |
657 const scoped_refptr<base::TaskRunner>& blocking_task_runner) { | 658 const scoped_refptr<base::TaskRunner>& blocking_task_runner) { |
658 return base::MakeUnique<ArcSessionImpl>(arc_bridge_service, | 659 return base::MakeUnique<ArcSessionImpl>(arc_bridge_service, |
659 blocking_task_runner); | 660 blocking_task_runner); |
660 } | 661 } |
661 | 662 |
662 } // namespace arc | 663 } // namespace arc |
OLD | NEW |