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 |