| 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> |
| 11 | 11 |
| 12 #include <string> |
| 12 #include <utility> | 13 #include <utility> |
| 13 | 14 |
| 14 #include "base/files/file_path.h" | 15 #include "base/files/file_path.h" |
| 15 #include "base/files/file_util.h" | 16 #include "base/files/file_util.h" |
| 16 #include "base/location.h" | 17 #include "base/location.h" |
| 17 #include "base/macros.h" | 18 #include "base/macros.h" |
| 18 #include "base/memory/ptr_util.h" | 19 #include "base/memory/ptr_util.h" |
| 19 #include "base/posix/eintr_wrapper.h" | 20 #include "base/posix/eintr_wrapper.h" |
| 20 #include "base/sys_info.h" | 21 #include "base/sys_info.h" |
| 21 #include "base/task_runner_util.h" | 22 #include "base/task_runner_util.h" |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 214 // descriptor. | 215 // descriptor. |
| 215 static mojo::edk::ScopedPlatformHandle CreateSocket(); | 216 static mojo::edk::ScopedPlatformHandle CreateSocket(); |
| 216 void OnSocketCreated(mojo::edk::ScopedPlatformHandle fd); | 217 void OnSocketCreated(mojo::edk::ScopedPlatformHandle fd); |
| 217 | 218 |
| 218 // DBus callback for StartArcInstance(). | 219 // DBus callback for StartArcInstance(). |
| 219 void OnInstanceStarted(mojo::edk::ScopedPlatformHandle socket_fd, | 220 void OnInstanceStarted(mojo::edk::ScopedPlatformHandle socket_fd, |
| 220 StartArcInstanceResult result); | 221 StartArcInstanceResult result); |
| 221 | 222 |
| 222 // Synchronously accepts a connection on |socket_fd| and then processes the | 223 // Synchronously accepts a connection on |socket_fd| and then processes the |
| 223 // connected socket's file descriptor. | 224 // connected socket's file descriptor. |
| 224 static mojo::edk::ScopedPlatformHandle ConnectMojo( | 225 static mojo::ScopedMessagePipeHandle ConnectMojo( |
| 225 mojo::edk::ScopedPlatformHandle socket_fd, | 226 mojo::edk::ScopedPlatformHandle socket_fd, |
| 226 base::ScopedFD cancel_fd); | 227 base::ScopedFD cancel_fd); |
| 227 void OnMojoConnected(mojo::edk::ScopedPlatformHandle fd); | 228 void OnMojoConnected(mojo::ScopedMessagePipeHandle server_pipe); |
| 228 | 229 |
| 229 // Request to stop ARC instance via DBus. | 230 // Request to stop ARC instance via DBus. |
| 230 void StopArcInstance(); | 231 void StopArcInstance(); |
| 231 | 232 |
| 232 // chromeos::SessionManagerClient::Observer: | 233 // chromeos::SessionManagerClient::Observer: |
| 233 void ArcInstanceStopped(bool clean) override; | 234 void ArcInstanceStopped(bool clean) override; |
| 234 | 235 |
| 235 // Completes the termination procedure. | 236 // Completes the termination procedure. |
| 236 void OnStopped(ArcSessionObserver::StopReason reason); | 237 void OnStopped(ArcSessionObserver::StopReason reason); |
| 237 | 238 |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 415 } | 416 } |
| 416 | 417 |
| 417 base::PostTaskAndReplyWithResult( | 418 base::PostTaskAndReplyWithResult( |
| 418 blocking_task_runner_.get(), FROM_HERE, | 419 blocking_task_runner_.get(), FROM_HERE, |
| 419 base::Bind(&ArcSessionImpl::ConnectMojo, base::Passed(&socket_fd), | 420 base::Bind(&ArcSessionImpl::ConnectMojo, base::Passed(&socket_fd), |
| 420 base::Passed(&cancel_fd)), | 421 base::Passed(&cancel_fd)), |
| 421 base::Bind(&ArcSessionImpl::OnMojoConnected, weak_factory_.GetWeakPtr())); | 422 base::Bind(&ArcSessionImpl::OnMojoConnected, weak_factory_.GetWeakPtr())); |
| 422 } | 423 } |
| 423 | 424 |
| 424 // static | 425 // static |
| 425 mojo::edk::ScopedPlatformHandle ArcSessionImpl::ConnectMojo( | 426 mojo::ScopedMessagePipeHandle ArcSessionImpl::ConnectMojo( |
| 426 mojo::edk::ScopedPlatformHandle socket_fd, | 427 mojo::edk::ScopedPlatformHandle socket_fd, |
| 427 base::ScopedFD cancel_fd) { | 428 base::ScopedFD cancel_fd) { |
| 428 if (!WaitForSocketReadable(socket_fd.get().handle, cancel_fd.get())) { | 429 if (!WaitForSocketReadable(socket_fd.get().handle, cancel_fd.get())) { |
| 429 VLOG(1) << "Mojo connection was cancelled."; | 430 VLOG(1) << "Mojo connection was cancelled."; |
| 430 return mojo::edk::ScopedPlatformHandle(); | 431 return mojo::ScopedMessagePipeHandle(); |
| 431 } | 432 } |
| 432 | 433 |
| 433 mojo::edk::ScopedPlatformHandle scoped_fd; | 434 mojo::edk::ScopedPlatformHandle scoped_fd; |
| 434 if (!mojo::edk::ServerAcceptConnection(socket_fd.get(), &scoped_fd, | 435 if (!mojo::edk::ServerAcceptConnection(socket_fd.get(), &scoped_fd, |
| 435 /* check_peer_user = */ false) || | 436 /* check_peer_user = */ false) || |
| 436 !scoped_fd.is_valid()) { | 437 !scoped_fd.is_valid()) { |
| 437 return mojo::edk::ScopedPlatformHandle(); | 438 return mojo::ScopedMessagePipeHandle(); |
| 438 } | 439 } |
| 439 | 440 |
| 440 // Hardcode pid 0 since it is unused in mojo. | 441 // Hardcode pid 0 since it is unused in mojo. |
| 441 const base::ProcessHandle kUnusedChildProcessHandle = 0; | 442 const base::ProcessHandle kUnusedChildProcessHandle = 0; |
| 442 mojo::edk::PlatformChannelPair channel_pair; | 443 mojo::edk::PlatformChannelPair channel_pair; |
| 444 std::string child_token = mojo::edk::GenerateRandomToken(); |
| 443 mojo::edk::ChildProcessLaunched(kUnusedChildProcessHandle, | 445 mojo::edk::ChildProcessLaunched(kUnusedChildProcessHandle, |
| 444 channel_pair.PassServerHandle(), | 446 channel_pair.PassServerHandle(), child_token); |
| 445 mojo::edk::GenerateRandomToken()); | |
| 446 | 447 |
| 447 mojo::edk::ScopedPlatformHandleVectorPtr handles( | 448 mojo::edk::ScopedPlatformHandleVectorPtr handles( |
| 448 new mojo::edk::PlatformHandleVector{ | 449 new mojo::edk::PlatformHandleVector{ |
| 449 channel_pair.PassClientHandle().release()}); | 450 channel_pair.PassClientHandle().release()}); |
| 450 | 451 |
| 451 struct iovec iov = {const_cast<char*>(""), 1}; | 452 std::string token = mojo::edk::GenerateRandomToken(); |
| 453 // We need to send the length of the message as a single byte, so make sure it |
| 454 // fits. |
| 455 DCHECK_LT(token.size(), 256u); |
| 456 uint8_t message_length = static_cast<uint8_t>(token.size()); |
| 457 struct iovec iov[] = {{&message_length, sizeof(message_length)}, |
| 458 {const_cast<char*>(token.c_str()), token.size()}}; |
| 452 ssize_t result = mojo::edk::PlatformChannelSendmsgWithHandles( | 459 ssize_t result = mojo::edk::PlatformChannelSendmsgWithHandles( |
| 453 scoped_fd.get(), &iov, 1, handles->data(), handles->size()); | 460 scoped_fd.get(), iov, sizeof(iov) / sizeof(iov[0]), handles->data(), |
| 461 handles->size()); |
| 454 if (result == -1) { | 462 if (result == -1) { |
| 455 PLOG(ERROR) << "sendmsg"; | 463 PLOG(ERROR) << "sendmsg"; |
| 456 return mojo::edk::ScopedPlatformHandle(); | 464 return mojo::ScopedMessagePipeHandle(); |
| 457 } | 465 } |
| 458 | 466 |
| 459 return scoped_fd; | 467 return mojo::edk::CreateParentMessagePipe(token, child_token); |
| 460 } | 468 } |
| 461 | 469 |
| 462 void ArcSessionImpl::OnMojoConnected(mojo::edk::ScopedPlatformHandle fd) { | 470 void ArcSessionImpl::OnMojoConnected( |
| 471 mojo::ScopedMessagePipeHandle server_pipe) { |
| 463 DCHECK(thread_checker_.CalledOnValidThread()); | 472 DCHECK(thread_checker_.CalledOnValidThread()); |
| 464 | 473 |
| 465 if (state_ == State::STOPPED) { | 474 if (state_ == State::STOPPED) { |
| 466 // This is the case that error is notified via DBus before the | 475 // This is the case that error is notified via DBus before the |
| 467 // OnMojoConnected() callback is invoked. The stopping procedure has | 476 // OnMojoConnected() callback is invoked. The stopping procedure has |
| 468 // been run, so do nothing. | 477 // been run, so do nothing. |
| 469 return; | 478 return; |
| 470 } | 479 } |
| 471 | 480 |
| 472 DCHECK_EQ(state_, State::CONNECTING_MOJO); | 481 DCHECK_EQ(state_, State::CONNECTING_MOJO); |
| 473 accept_cancel_pipe_.reset(); | 482 accept_cancel_pipe_.reset(); |
| 474 | 483 |
| 475 if (stop_requested_) { | 484 if (stop_requested_) { |
| 476 StopArcInstance(); | 485 StopArcInstance(); |
| 477 return; | 486 return; |
| 478 } | 487 } |
| 479 | 488 |
| 480 if (!fd.is_valid()) { | |
| 481 LOG(ERROR) << "Invalid handle"; | |
| 482 StopArcInstance(); | |
| 483 return; | |
| 484 } | |
| 485 | |
| 486 mojo::ScopedMessagePipeHandle server_pipe = | |
| 487 mojo::edk::CreateMessagePipe(std::move(fd)); | |
| 488 if (!server_pipe.is_valid()) { | 489 if (!server_pipe.is_valid()) { |
| 489 LOG(ERROR) << "Invalid pipe"; | 490 LOG(ERROR) << "Invalid pipe"; |
| 490 StopArcInstance(); | 491 StopArcInstance(); |
| 491 return; | 492 return; |
| 492 } | 493 } |
| 493 | 494 |
| 494 mojom::ArcBridgeInstancePtr instance; | 495 mojom::ArcBridgeInstancePtr instance; |
| 495 instance.Bind(mojo::InterfacePtrInfo<mojom::ArcBridgeInstance>( | 496 instance.Bind(mojo::InterfacePtrInfo<mojom::ArcBridgeInstance>( |
| 496 std::move(server_pipe), 0u)); | 497 std::move(server_pipe), 0u)); |
| 497 arc_bridge_host_ = base::MakeUnique<ArcBridgeHostImpl>(arc_bridge_service_, | 498 arc_bridge_host_ = base::MakeUnique<ArcBridgeHostImpl>(arc_bridge_service_, |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 641 | 642 |
| 642 // static | 643 // static |
| 643 std::unique_ptr<ArcSession> ArcSession::Create( | 644 std::unique_ptr<ArcSession> ArcSession::Create( |
| 644 ArcBridgeService* arc_bridge_service, | 645 ArcBridgeService* arc_bridge_service, |
| 645 const scoped_refptr<base::TaskRunner>& blocking_task_runner) { | 646 const scoped_refptr<base::TaskRunner>& blocking_task_runner) { |
| 646 return base::MakeUnique<ArcSessionImpl>(arc_bridge_service, | 647 return base::MakeUnique<ArcSessionImpl>(arc_bridge_service, |
| 647 blocking_task_runner); | 648 blocking_task_runner); |
| 648 } | 649 } |
| 649 | 650 |
| 650 } // namespace arc | 651 } // namespace arc |
| OLD | NEW |