morrita@chromium.org | 15996aa | 2014-08-05 08:44:17 +0900 | [diff] [blame] | 1 | // Copyright 2014 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 | |
| 5 | #ifndef IPC_IPC_MESSAGE_PIPE_READER_H_ |
| 6 | #define IPC_IPC_MESSAGE_PIPE_READER_H_ |
| 7 | |
avi | 42ebda4 | 2015-12-22 11:39:04 +0900 | [diff] [blame] | 8 | #include <stdint.h> |
| 9 | |
dcheng | 0bdf377 | 2015-11-19 16:00:20 +0900 | [diff] [blame] | 10 | #include <memory> |
morrita@chromium.org | 15996aa | 2014-08-05 08:44:17 +0900 | [diff] [blame] | 11 | #include <vector> |
| 12 | |
amistry | 5dfb9c2 | 2015-09-03 03:04:22 +0900 | [diff] [blame] | 13 | #include "base/atomicops.h" |
morrita | 1f42dc6 | 2014-11-26 08:35:57 +0900 | [diff] [blame] | 14 | #include "base/compiler_specific.h" |
avi | 42ebda4 | 2015-12-22 11:39:04 +0900 | [diff] [blame] | 15 | #include "base/macros.h" |
rockot | a01dbc7 | 2016-07-23 06:18:07 +0900 | [diff] [blame] | 16 | #include "base/process/process_handle.h" |
amistry | 5dfb9c2 | 2015-09-03 03:04:22 +0900 | [diff] [blame] | 17 | #include "base/threading/thread_checker.h" |
amistry | 6555e69 | 2016-06-23 16:52:37 +0900 | [diff] [blame] | 18 | #include "ipc/ipc.mojom.h" |
rockot | a6edf83 | 2016-07-14 09:34:11 +0900 | [diff] [blame] | 19 | #include "ipc/ipc_export.h" |
morrita | 1f42dc6 | 2014-11-26 08:35:57 +0900 | [diff] [blame] | 20 | #include "ipc/ipc_message.h" |
sammc | 6194d97 | 2016-03-08 07:38:04 +0900 | [diff] [blame] | 21 | #include "mojo/public/cpp/bindings/associated_binding.h" |
rockot | a6edf83 | 2016-07-14 09:34:11 +0900 | [diff] [blame] | 22 | #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h" |
rockot | af32acb | 2015-11-13 10:33:59 +0900 | [diff] [blame] | 23 | #include "mojo/public/cpp/system/core.h" |
rockot | 6e3d492 | 2016-03-23 10:32:18 +0900 | [diff] [blame] | 24 | #include "mojo/public/cpp/system/message_pipe.h" |
Ken Rockot | b3a77c9 | 2017-09-14 13:23:41 +0900 | [diff] [blame] | 25 | #include "mojo/public/interfaces/bindings/native_struct.mojom.h" |
morrita@chromium.org | 15996aa | 2014-08-05 08:44:17 +0900 | [diff] [blame] | 26 | |
| 27 | namespace IPC { |
| 28 | namespace internal { |
| 29 | |
| 30 | // A helper class to handle bytestream directly over mojo::MessagePipe |
| 31 | // in template-method pattern. MessagePipeReader manages the lifetime |
| 32 | // of given MessagePipe and participates the event loop, and |
| 33 | // read the stream and call the client when it is ready. |
| 34 | // |
| 35 | // Each client has to: |
| 36 | // |
| 37 | // * Provide a subclass implemenation of a specific use of a MessagePipe |
| 38 | // and implement callbacks. |
| 39 | // * Create the subclass instance with a MessagePipeHandle. |
| 40 | // The constructor automatically start listening on the pipe. |
| 41 | // |
amistry | 5dfb9c2 | 2015-09-03 03:04:22 +0900 | [diff] [blame] | 42 | // All functions must be called on the IO thread, except for Send(), which can |
| 43 | // be called on any thread. All |Delegate| functions will be called on the IO |
| 44 | // thread. |
morrita@chromium.org | 15996aa | 2014-08-05 08:44:17 +0900 | [diff] [blame] | 45 | // |
Nico Weber | 1615c31 | 2017-08-16 04:19:27 +0900 | [diff] [blame] | 46 | class IPC_EXPORT MessagePipeReader : public mojom::Channel { |
morrita@chromium.org | 15996aa | 2014-08-05 08:44:17 +0900 | [diff] [blame] | 47 | public: |
morrita | 1f42dc6 | 2014-11-26 08:35:57 +0900 | [diff] [blame] | 48 | class Delegate { |
| 49 | public: |
sammc | b83485d | 2016-11-11 07:34:07 +0900 | [diff] [blame] | 50 | virtual void OnPeerPidReceived(int32_t peer_pid) = 0; |
sammc | 6194d97 | 2016-03-08 07:38:04 +0900 | [diff] [blame] | 51 | virtual void OnMessageReceived(const Message& message) = 0; |
rockot | 6e3d492 | 2016-03-23 10:32:18 +0900 | [diff] [blame] | 52 | virtual void OnPipeError() = 0; |
rockot | a6edf83 | 2016-07-14 09:34:11 +0900 | [diff] [blame] | 53 | virtual void OnAssociatedInterfaceRequest( |
| 54 | const std::string& name, |
| 55 | mojo::ScopedInterfaceEndpointHandle handle) = 0; |
morrita | 1f42dc6 | 2014-11-26 08:35:57 +0900 | [diff] [blame] | 56 | }; |
| 57 | |
rockot | 6e3d492 | 2016-03-23 10:32:18 +0900 | [diff] [blame] | 58 | // Builds a reader that reads messages from |receive_handle| and lets |
sammc | 6194d97 | 2016-03-08 07:38:04 +0900 | [diff] [blame] | 59 | // |delegate| know. |
rockot | 6e3d492 | 2016-03-23 10:32:18 +0900 | [diff] [blame] | 60 | // |
| 61 | // |pipe| is the message pipe handle corresponding to the channel's master |
| 62 | // interface. This is the message pipe underlying both |sender| and |
| 63 | // |receiver|. |
| 64 | // |
| 65 | // Both |sender| and |receiver| must be non-null. |
| 66 | // |
sammc | 6194d97 | 2016-03-08 07:38:04 +0900 | [diff] [blame] | 67 | // Note that MessagePipeReader doesn't delete |delegate|. |
rockot | 6e3d492 | 2016-03-23 10:32:18 +0900 | [diff] [blame] | 68 | MessagePipeReader(mojo::MessagePipeHandle pipe, |
| 69 | mojom::ChannelAssociatedPtr sender, |
sammc | 6194d97 | 2016-03-08 07:38:04 +0900 | [diff] [blame] | 70 | mojo::AssociatedInterfaceRequest<mojom::Channel> receiver, |
| 71 | Delegate* delegate); |
| 72 | ~MessagePipeReader() override; |
morrita@chromium.org | 15996aa | 2014-08-05 08:44:17 +0900 | [diff] [blame] | 73 | |
| 74 | // Close and destroy the MessagePipe. |
| 75 | void Close(); |
morrita | 5138bf5 | 2015-04-21 06:20:12 +0900 | [diff] [blame] | 76 | |
morrita@chromium.org | 15996aa | 2014-08-05 08:44:17 +0900 | [diff] [blame] | 77 | // Return true if the MessagePipe is alive. |
Jeremy Roman | 294562e | 2017-06-14 09:53:59 +0900 | [diff] [blame] | 78 | bool IsValid() { return sender_.is_bound(); } |
morrita@chromium.org | 15996aa | 2014-08-05 08:44:17 +0900 | [diff] [blame] | 79 | |
rockot | 6e3d492 | 2016-03-23 10:32:18 +0900 | [diff] [blame] | 80 | // Sends an IPC::Message to the other end of the pipe. Safe to call from any |
| 81 | // thread. |
danakj | c3fb6c5 | 2016-04-23 13:21:09 +0900 | [diff] [blame] | 82 | bool Send(std::unique_ptr<Message> message); |
morrita@chromium.org | 15996aa | 2014-08-05 08:44:17 +0900 | [diff] [blame] | 83 | |
rockot | a6edf83 | 2016-07-14 09:34:11 +0900 | [diff] [blame] | 84 | // Requests an associated interface from the other end of the pipe. |
| 85 | void GetRemoteInterface(const std::string& name, |
| 86 | mojo::ScopedInterfaceEndpointHandle handle); |
| 87 | |
rockot | 7900d34 | 2017-02-09 17:40:15 +0900 | [diff] [blame] | 88 | mojom::ChannelAssociatedPtr& sender() { return sender_; } |
rockot | 685505b | 2016-09-07 03:35:57 +0900 | [diff] [blame] | 89 | |
sammc | 6194d97 | 2016-03-08 07:38:04 +0900 | [diff] [blame] | 90 | protected: |
morrita | 1f42dc6 | 2014-11-26 08:35:57 +0900 | [diff] [blame] | 91 | void OnPipeClosed(); |
| 92 | void OnPipeError(MojoResult error); |
| 93 | |
sammc | 6194d97 | 2016-03-08 07:38:04 +0900 | [diff] [blame] | 94 | private: |
rockot | 6e3d492 | 2016-03-23 10:32:18 +0900 | [diff] [blame] | 95 | // mojom::Channel: |
rockot | a01dbc7 | 2016-07-23 06:18:07 +0900 | [diff] [blame] | 96 | void SetPeerPid(int32_t peer_pid) override; |
Ken Rockot | b3a77c9 | 2017-09-14 13:23:41 +0900 | [diff] [blame] | 97 | void Receive(base::span<const uint8_t> data, |
| 98 | base::Optional<std::vector<mojo::native::SerializedHandlePtr>> |
| 99 | handles) override; |
rockot | a6edf83 | 2016-07-14 09:34:11 +0900 | [diff] [blame] | 100 | void GetAssociatedInterface( |
yzshen | 8af798c | 2016-08-24 10:10:13 +0900 | [diff] [blame] | 101 | const std::string& name, |
rockot | a6edf83 | 2016-07-14 09:34:11 +0900 | [diff] [blame] | 102 | mojom::GenericInterfaceAssociatedRequest request) override; |
morrita@chromium.org | 15996aa | 2014-08-05 08:44:17 +0900 | [diff] [blame] | 103 | |
sammc | 6194d97 | 2016-03-08 07:38:04 +0900 | [diff] [blame] | 104 | // |delegate_| is null once the message pipe is closed. |
morrita | 1f42dc6 | 2014-11-26 08:35:57 +0900 | [diff] [blame] | 105 | Delegate* delegate_; |
sammc | 6194d97 | 2016-03-08 07:38:04 +0900 | [diff] [blame] | 106 | mojom::ChannelAssociatedPtr sender_; |
| 107 | mojo::AssociatedBinding<mojom::Channel> binding_; |
amistry | 5dfb9c2 | 2015-09-03 03:04:22 +0900 | [diff] [blame] | 108 | base::ThreadChecker thread_checker_; |
morrita@chromium.org | 15996aa | 2014-08-05 08:44:17 +0900 | [diff] [blame] | 109 | |
| 110 | DISALLOW_COPY_AND_ASSIGN(MessagePipeReader); |
| 111 | }; |
| 112 | |
| 113 | } // namespace internal |
| 114 | } // namespace IPC |
| 115 | |
| 116 | #endif // IPC_IPC_MESSAGE_PIPE_READER_H_ |