[email protected] | 6486088 | 2014-08-04 23:44:17 | [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 | 246998d8 | 2015-12-22 02:39:04 | [diff] [blame] | 8 | #include <stdint.h> |
| 9 | |
dcheng | 0917ec4 | 2015-11-19 07:00:20 | [diff] [blame] | 10 | #include <memory> |
[email protected] | 6486088 | 2014-08-04 23:44:17 | [diff] [blame] | 11 | #include <vector> |
| 12 | |
amistry | 0b0e748 | 2015-09-02 18:04:22 | [diff] [blame] | 13 | #include "base/atomicops.h" |
morrita | d68bedf4 | 2014-11-25 23:35:57 | [diff] [blame] | 14 | #include "base/compiler_specific.h" |
Ken Rockot | 3044d21 | 2018-01-23 02:44:39 | [diff] [blame] | 15 | #include "base/component_export.h" |
avi | 246998d8 | 2015-12-22 02:39:04 | [diff] [blame] | 16 | #include "base/macros.h" |
rockot | 0e4de5f | 2016-07-22 21:18:07 | [diff] [blame] | 17 | #include "base/process/process_handle.h" |
amistry | 0b0e748 | 2015-09-02 18:04:22 | [diff] [blame] | 18 | #include "base/threading/thread_checker.h" |
amistry | d4aa70d | 2016-06-23 07:52:37 | [diff] [blame] | 19 | #include "ipc/ipc.mojom.h" |
morrita | d68bedf4 | 2014-11-25 23:35:57 | [diff] [blame] | 20 | #include "ipc/ipc_message.h" |
sammc | e4d0abd | 2016-03-07 22:38:04 | [diff] [blame] | 21 | #include "mojo/public/cpp/bindings/associated_binding.h" |
rockot | 7c6bf95 | 2016-07-14 00:34:11 | [diff] [blame] | 22 | #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h" |
rockot | 85dce086 | 2015-11-13 01:33:59 | [diff] [blame] | 23 | #include "mojo/public/cpp/system/core.h" |
rockot | 506f92fa2 | 2016-03-23 01:32:18 | [diff] [blame] | 24 | #include "mojo/public/cpp/system/message_pipe.h" |
Ken Rockot | fd90763 | 2017-09-14 04:23:41 | [diff] [blame] | 25 | #include "mojo/public/interfaces/bindings/native_struct.mojom.h" |
[email protected] | 6486088 | 2014-08-04 23:44:17 | [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 | 0b0e748 | 2015-09-02 18:04:22 | [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. |
[email protected] | 6486088 | 2014-08-04 23:44:17 | [diff] [blame] | 45 | // |
Ken Rockot | 3044d21 | 2018-01-23 02:44:39 | [diff] [blame] | 46 | class COMPONENT_EXPORT(IPC) MessagePipeReader : public mojom::Channel { |
[email protected] | 6486088 | 2014-08-04 23:44:17 | [diff] [blame] | 47 | public: |
morrita | d68bedf4 | 2014-11-25 23:35:57 | [diff] [blame] | 48 | class Delegate { |
| 49 | public: |
sammc | f810f07f | 2016-11-10 22:34:07 | [diff] [blame] | 50 | virtual void OnPeerPidReceived(int32_t peer_pid) = 0; |
sammc | e4d0abd | 2016-03-07 22:38:04 | [diff] [blame] | 51 | virtual void OnMessageReceived(const Message& message) = 0; |
Roman Karasev | a43d5b4e | 2017-12-21 03:06:02 | [diff] [blame] | 52 | virtual void OnBrokenDataReceived() = 0; |
rockot | 506f92fa2 | 2016-03-23 01:32:18 | [diff] [blame] | 53 | virtual void OnPipeError() = 0; |
rockot | 7c6bf95 | 2016-07-14 00:34:11 | [diff] [blame] | 54 | virtual void OnAssociatedInterfaceRequest( |
| 55 | const std::string& name, |
| 56 | mojo::ScopedInterfaceEndpointHandle handle) = 0; |
morrita | d68bedf4 | 2014-11-25 23:35:57 | [diff] [blame] | 57 | }; |
| 58 | |
rockot | 506f92fa2 | 2016-03-23 01:32:18 | [diff] [blame] | 59 | // Builds a reader that reads messages from |receive_handle| and lets |
sammc | e4d0abd | 2016-03-07 22:38:04 | [diff] [blame] | 60 | // |delegate| know. |
rockot | 506f92fa2 | 2016-03-23 01:32:18 | [diff] [blame] | 61 | // |
| 62 | // |pipe| is the message pipe handle corresponding to the channel's master |
| 63 | // interface. This is the message pipe underlying both |sender| and |
| 64 | // |receiver|. |
| 65 | // |
| 66 | // Both |sender| and |receiver| must be non-null. |
| 67 | // |
sammc | e4d0abd | 2016-03-07 22:38:04 | [diff] [blame] | 68 | // Note that MessagePipeReader doesn't delete |delegate|. |
rockot | 506f92fa2 | 2016-03-23 01:32:18 | [diff] [blame] | 69 | MessagePipeReader(mojo::MessagePipeHandle pipe, |
| 70 | mojom::ChannelAssociatedPtr sender, |
sammc | e4d0abd | 2016-03-07 22:38:04 | [diff] [blame] | 71 | mojo::AssociatedInterfaceRequest<mojom::Channel> receiver, |
| 72 | Delegate* delegate); |
| 73 | ~MessagePipeReader() override; |
[email protected] | 6486088 | 2014-08-04 23:44:17 | [diff] [blame] | 74 | |
| 75 | // Close and destroy the MessagePipe. |
| 76 | void Close(); |
morrita | b447214 | 2015-04-20 21:20:12 | [diff] [blame] | 77 | |
[email protected] | 6486088 | 2014-08-04 23:44:17 | [diff] [blame] | 78 | // Return true if the MessagePipe is alive. |
Jeremy Roman | c1348298 | 2017-06-14 00:53:59 | [diff] [blame] | 79 | bool IsValid() { return sender_.is_bound(); } |
[email protected] | 6486088 | 2014-08-04 23:44:17 | [diff] [blame] | 80 | |
rockot | 506f92fa2 | 2016-03-23 01:32:18 | [diff] [blame] | 81 | // Sends an IPC::Message to the other end of the pipe. Safe to call from any |
| 82 | // thread. |
danakj | 03de39b2 | 2016-04-23 04:21:09 | [diff] [blame] | 83 | bool Send(std::unique_ptr<Message> message); |
[email protected] | 6486088 | 2014-08-04 23:44:17 | [diff] [blame] | 84 | |
rockot | 7c6bf95 | 2016-07-14 00:34:11 | [diff] [blame] | 85 | // Requests an associated interface from the other end of the pipe. |
| 86 | void GetRemoteInterface(const std::string& name, |
| 87 | mojo::ScopedInterfaceEndpointHandle handle); |
| 88 | |
rockot | a628d0b | 2017-02-09 08:40:15 | [diff] [blame] | 89 | mojom::ChannelAssociatedPtr& sender() { return sender_; } |
rockot | 401fb2c | 2016-09-06 18:35:57 | [diff] [blame] | 90 | |
sammc | e4d0abd | 2016-03-07 22:38:04 | [diff] [blame] | 91 | protected: |
morrita | d68bedf4 | 2014-11-25 23:35:57 | [diff] [blame] | 92 | void OnPipeClosed(); |
| 93 | void OnPipeError(MojoResult error); |
| 94 | |
sammc | e4d0abd | 2016-03-07 22:38:04 | [diff] [blame] | 95 | private: |
rockot | 506f92fa2 | 2016-03-23 01:32:18 | [diff] [blame] | 96 | // mojom::Channel: |
rockot | 0e4de5f | 2016-07-22 21:18:07 | [diff] [blame] | 97 | void SetPeerPid(int32_t peer_pid) override; |
Eve Martin-Jones | 475e7e6 | 2018-02-13 22:57:25 | [diff] [blame] | 98 | void Receive(base::span<const uint8_t> data, |
| 99 | base::Optional<std::vector<mojo::native::SerializedHandlePtr>> |
| 100 | handles) override; |
rockot | 7c6bf95 | 2016-07-14 00:34:11 | [diff] [blame] | 101 | void GetAssociatedInterface( |
yzshen | 24b40a3 | 2016-08-24 01:10:13 | [diff] [blame] | 102 | const std::string& name, |
rockot | 7c6bf95 | 2016-07-14 00:34:11 | [diff] [blame] | 103 | mojom::GenericInterfaceAssociatedRequest request) override; |
[email protected] | 6486088 | 2014-08-04 23:44:17 | [diff] [blame] | 104 | |
sammc | e4d0abd | 2016-03-07 22:38:04 | [diff] [blame] | 105 | // |delegate_| is null once the message pipe is closed. |
morrita | d68bedf4 | 2014-11-25 23:35:57 | [diff] [blame] | 106 | Delegate* delegate_; |
sammc | e4d0abd | 2016-03-07 22:38:04 | [diff] [blame] | 107 | mojom::ChannelAssociatedPtr sender_; |
| 108 | mojo::AssociatedBinding<mojom::Channel> binding_; |
amistry | 0b0e748 | 2015-09-02 18:04:22 | [diff] [blame] | 109 | base::ThreadChecker thread_checker_; |
[email protected] | 6486088 | 2014-08-04 23:44:17 | [diff] [blame] | 110 | |
| 111 | DISALLOW_COPY_AND_ASSIGN(MessagePipeReader); |
| 112 | }; |
| 113 | |
| 114 | } // namespace internal |
| 115 | } // namespace IPC |
| 116 | |
| 117 | #endif // IPC_IPC_MESSAGE_PIPE_READER_H_ |