drivefs_bootstrap.cc 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. // Copyright 2018 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "ash/components/drivefs/drivefs_bootstrap.h"
  5. #include <utility>
  6. #include "ash/components/drivefs/mojom/drivefs.mojom.h"
  7. #include "base/bind.h"
  8. #include "chromeos/components/mojo_bootstrap/pending_connection_manager.h"
  9. #include "mojo/public/cpp/bindings/receiver.h"
  10. #include "mojo/public/cpp/bindings/remote.h"
  11. #include "mojo/public/cpp/platform/platform_channel_endpoint.h"
  12. #include "mojo/public/cpp/system/invitation.h"
  13. namespace drivefs {
  14. DriveFsBootstrapListener::DriveFsBootstrapListener()
  15. : bootstrap_(invitation_.AttachMessagePipe("drivefs-bootstrap"),
  16. mojom::DriveFsBootstrap::Version_),
  17. pending_token_(base::UnguessableToken::Create()) {
  18. mojo_bootstrap::PendingConnectionManager::Get().ExpectOpenIpcChannel(
  19. pending_token_,
  20. base::BindOnce(&DriveFsBootstrapListener::AcceptMojoConnection,
  21. base::Unretained(this)));
  22. }
  23. DriveFsBootstrapListener::~DriveFsBootstrapListener() {
  24. if (pending_token_) {
  25. mojo_bootstrap::PendingConnectionManager::Get()
  26. .CancelExpectedOpenIpcChannel(pending_token_);
  27. pending_token_ = {};
  28. }
  29. }
  30. mojo::PendingRemote<mojom::DriveFsBootstrap>
  31. DriveFsBootstrapListener::bootstrap() {
  32. return std::move(bootstrap_);
  33. }
  34. void DriveFsBootstrapListener::AcceptMojoConnection(base::ScopedFD handle) {
  35. DCHECK(pending_token_);
  36. pending_token_ = {};
  37. connected_ = true;
  38. SendInvitationOverPipe(std::move(handle));
  39. }
  40. void DriveFsBootstrapListener::SendInvitationOverPipe(base::ScopedFD handle) {
  41. mojo::OutgoingInvitation::Send(
  42. std::move(invitation_), base::kNullProcessHandle,
  43. mojo::PlatformChannelEndpoint(mojo::PlatformHandle(std::move(handle))));
  44. }
  45. class DriveFsConnectionImpl : public DriveFsConnection {
  46. public:
  47. DriveFsConnectionImpl(
  48. std::unique_ptr<DriveFsBootstrapListener> bootstrap_listener,
  49. mojom::DriveFsConfigurationPtr config)
  50. : bootstrap_listener_(std::move(bootstrap_listener)),
  51. config_(std::move(config)) {}
  52. DriveFsConnectionImpl(const DriveFsConnectionImpl&) = delete;
  53. DriveFsConnectionImpl& operator=(const DriveFsConnectionImpl&) = delete;
  54. ~DriveFsConnectionImpl() override = default;
  55. base::UnguessableToken Connect(mojom::DriveFsDelegate* delegate,
  56. base::OnceClosure on_disconnected) override {
  57. delegate_receiver_ =
  58. std::make_unique<mojo::Receiver<mojom::DriveFsDelegate>>(delegate);
  59. on_disconnected_ = std::move(on_disconnected);
  60. auto bootstrap =
  61. mojo::Remote<mojom::DriveFsBootstrap>(bootstrap_listener_->bootstrap());
  62. auto token = bootstrap_listener_->pending_token();
  63. bootstrap->Init(std::move(config_), drivefs_.BindNewPipeAndPassReceiver(),
  64. delegate_receiver_->BindNewPipeAndPassRemote());
  65. delegate_receiver_->set_disconnect_handler(base::BindOnce(
  66. &DriveFsConnectionImpl::OnMojoConnectionError, base::Unretained(this)));
  67. drivefs_.set_disconnect_handler(base::BindOnce(
  68. &DriveFsConnectionImpl::OnMojoConnectionError, base::Unretained(this)));
  69. return token;
  70. }
  71. mojom::DriveFs& GetDriveFs() override {
  72. CHECK(drivefs_);
  73. return *drivefs_;
  74. }
  75. private:
  76. void OnMojoConnectionError() {
  77. if (on_disconnected_ && bootstrap_listener_->is_connected()) {
  78. std::move(on_disconnected_).Run();
  79. }
  80. }
  81. const std::unique_ptr<DriveFsBootstrapListener> bootstrap_listener_;
  82. mojom::DriveFsConfigurationPtr config_;
  83. std::unique_ptr<mojo::Receiver<mojom::DriveFsDelegate>> delegate_receiver_;
  84. mojo::Remote<mojom::DriveFs> drivefs_;
  85. base::OnceClosure on_disconnected_;
  86. };
  87. std::unique_ptr<DriveFsConnection> DriveFsConnection::Create(
  88. std::unique_ptr<DriveFsBootstrapListener> bootstrap_listener,
  89. mojom::DriveFsConfigurationPtr config) {
  90. return std::make_unique<DriveFsConnectionImpl>(std::move(bootstrap_listener),
  91. std::move(config));
  92. }
  93. } // namespace drivefs