blob: 8c4ab87e5842fbacbb45c85e5df939989c0674e1 [file] [log] [blame]
Avi Drissmanea1be232022-09-14 23:29:061// Copyright 2012 The Chromium Authors
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
darin@chromium.org7c854372011-08-15 20:41:465#ifndef IPC_IPC_MESSAGE_H_
6#define IPC_IPC_MESSAGE_H_
initial.commit09911bf2008-07-26 23:55:297
avi246998d82015-12-22 02:39:048#include <stddef.h>
tfarina10a5c062015-09-04 18:47:579#include <stdint.h>
10
initial.commit09911bf2008-07-26 23:55:2911#include <string>
12
dskiba6f3790a2015-09-30 17:24:3013#include "base/gtest_prod_util.h"
morrita1aa788c2015-01-31 05:45:4214#include "base/memory/ref_counted.h"
initial.commit09911bf2008-07-26 23:55:2915#include "base/pickle.h"
avi246998d82015-12-22 02:39:0416#include "build/build_config.h"
Scott Violeta35f9a42018-03-22 22:00:4417#include "ipc/ipc_buildflags.h"
Ken Rockotfd907632017-09-14 04:23:4118#include "ipc/ipc_message_support_export.h"
19
20namespace mojo {
21namespace internal {
22struct UnmappedNativeStructSerializerImpl;
23}
24} // namespace mojo
agl@chromium.orge707d5e62009-02-12 04:00:0825
initial.commit09911bf2008-07-26 23:55:2926namespace IPC {
27
erikchende9412b82015-07-27 18:26:1428namespace internal {
29class ChannelReader;
30} // namespace internal
31
initial.commit09911bf2008-07-26 23:55:2932//------------------------------------------------------------------------------
33
initial.commit09911bf2008-07-26 23:55:2934struct LogData;
morrita4b5c28e22015-01-14 21:17:0635class MessageAttachmentSet;
initial.commit09911bf2008-07-26 23:55:2936
Ken Rockotfd907632017-09-14 04:23:4137class IPC_MESSAGE_SUPPORT_EXPORT Message : public base::Pickle {
initial.commit09911bf2008-07-26 23:55:2938 public:
bbudge@chromium.org753bb252013-11-04 22:28:1239 enum PriorityValue {
40 PRIORITY_LOW = 1,
41 PRIORITY_NORMAL,
42 PRIORITY_HIGH
43 };
44
brettw@chromium.org73d96dc2012-03-30 22:35:2745 // Bit values used in the flags field.
jbates@chromium.org2a2e3d62012-09-04 23:08:0946 // Upper 24 bits of flags store a reference number, so this enum is limited to
47 // 8 bits.
brettw@chromium.org73d96dc2012-03-30 22:35:2748 enum {
bbudge@chromium.org753bb252013-11-04 22:28:1249 PRIORITY_MASK = 0x03, // Low 2 bits of store the priority value.
jbates@chromium.org2a2e3d62012-09-04 23:08:0950 SYNC_BIT = 0x04,
51 REPLY_BIT = 0x08,
52 REPLY_ERROR_BIT = 0x10,
53 UNBLOCK_BIT = 0x20,
Julie Jeongeun Kim84f3cfa12021-02-17 10:00:5154 PUMPING_MSGS_BIT = 0x40, // Deprecated.
jbates@chromium.org2a2e3d62012-09-04 23:08:0955 HAS_SENT_TIME_BIT = 0x80,
brettw@chromium.org73d96dc2012-03-30 22:35:2756 };
57
dchengfe61fca2014-10-22 02:29:5258 ~Message() override;
initial.commit09911bf2008-07-26 23:55:2959
60 Message();
61
bbudge@chromium.org753bb252013-11-04 22:28:1262 // Initialize a message with a user-defined type, priority value, and
63 // destination WebView ID.
tfarina10a5c062015-09-04 18:47:5764 Message(int32_t routing_id, uint32_t type, PriorityValue priority);
initial.commit09911bf2008-07-26 23:55:2965
66 // Initializes a message from a const block of data. The data is not copied;
67 // instead the data is merely referenced by this message. Only const methods
68 // should be used on the message when initialized this way.
Peter Kasting7064abb2022-08-11 18:11:3869 Message(const char* data, size_t data_len);
initial.commit09911bf2008-07-26 23:55:2970
71 Message(const Message& other);
72 Message& operator=(const Message& other);
73
Roman Karaseva43d5b4e2017-12-21 03:06:0274 bool IsValid() const { return header_size() == sizeof(Header) && header(); }
75
bbudge@chromium.org753bb252013-11-04 22:28:1276 PriorityValue priority() const {
77 return static_cast<PriorityValue>(header()->flags & PRIORITY_MASK);
78 }
79
initial.commit09911bf2008-07-26 23:55:2980 // True if this is a synchronous message.
brettw@chromium.org73d96dc2012-03-30 22:35:2781 void set_sync() {
82 header()->flags |= SYNC_BIT;
83 }
initial.commit09911bf2008-07-26 23:55:2984 bool is_sync() const {
85 return (header()->flags & SYNC_BIT) != 0;
86 }
87
88 // Set this on a reply to a synchronous message.
89 void set_reply() {
90 header()->flags |= REPLY_BIT;
91 }
92
93 bool is_reply() const {
94 return (header()->flags & REPLY_BIT) != 0;
95 }
96
97 // Set this on a reply to a synchronous message to indicate that no receiver
98 // was found.
99 void set_reply_error() {
100 header()->flags |= REPLY_ERROR_BIT;
101 }
102
103 bool is_reply_error() const {
104 return (header()->flags & REPLY_ERROR_BIT) != 0;
105 }
106
107 // Normally when a receiver gets a message and they're blocked on a
108 // synchronous message Send, they buffer a message. Setting this flag causes
109 // the receiver to be unblocked and the message to be dispatched immediately.
110 void set_unblock(bool unblock) {
111 if (unblock) {
112 header()->flags |= UNBLOCK_BIT;
113 } else {
Peter Kasting7064abb2022-08-11 18:11:38114 header()->flags &= static_cast<uint32_t>(~UNBLOCK_BIT);
initial.commit09911bf2008-07-26 23:55:29115 }
116 }
117
118 bool should_unblock() const {
119 return (header()->flags & UNBLOCK_BIT) != 0;
120 }
121
jam@chromium.orgef2f6ba2014-05-15 23:06:07122 void set_dispatch_error() const {
123 dispatch_error_ = true;
124 }
125
126 bool dispatch_error() const {
127 return dispatch_error_;
128 }
129
tfarina10a5c062015-09-04 18:47:57130 uint32_t type() const {
initial.commit09911bf2008-07-26 23:55:29131 return header()->type;
132 }
133
tfarina10a5c062015-09-04 18:47:57134 int32_t routing_id() const {
initial.commit09911bf2008-07-26 23:55:29135 return header()->routing;
136 }
137
tfarina10a5c062015-09-04 18:47:57138 void set_routing_id(int32_t new_id) {
initial.commit09911bf2008-07-26 23:55:29139 header()->routing = new_id;
140 }
141
tfarina10a5c062015-09-04 18:47:57142 uint32_t flags() const {
brettw@chromium.org73d96dc2012-03-30 22:35:27143 return header()->flags;
144 }
145
brettw@chromium.org34d48612012-06-29 00:05:04146 // Sets all the given header values. The message should be empty at this
147 // call.
tfarina10a5c062015-09-04 18:47:57148 void SetHeaderValues(int32_t routing, uint32_t type, uint32_t flags);
brettw@chromium.org34d48612012-06-29 00:05:04149
jam@chromium.org5636d902014-05-13 23:19:10150 template<class T, class S, class P>
151 static bool Dispatch(const Message* msg, T* obj, S* sender, P* parameter,
jam@chromium.org65412272010-12-21 20:03:24152 void (T::*func)()) {
initial.commit09911bf2008-07-26 23:55:29153 (obj->*func)();
154 return true;
155 }
156
jam@chromium.org5636d902014-05-13 23:19:10157 template<class T, class S, class P>
158 static bool Dispatch(const Message* msg, T* obj, S* sender, P* parameter,
159 void (T::*func)(P*)) {
160 (obj->*func)(parameter);
initial.commit09911bf2008-07-26 23:55:29161 return true;
162 }
163
164 // Used for async messages with no parameters.
jam@chromium.org21fa3a12010-12-08 23:34:16165 static void Log(std::string* name, const Message* msg, std::string* l) {
initial.commit09911bf2008-07-26 23:55:29166 }
167
erikchen29e0f2f2015-09-11 19:08:53168 // The static method FindNext() returns several pieces of information, which
169 // are aggregated into an instance of this struct.
Ken Rockotfd907632017-09-14 04:23:41170 struct IPC_MESSAGE_SUPPORT_EXPORT NextMessageInfo {
erikchen29e0f2f2015-09-11 19:08:53171 NextMessageInfo();
172 ~NextMessageInfo();
173
dskiba6f3790a2015-09-30 17:24:30174 // Total message size. Always valid if |message_found| is true.
175 // If |message_found| is false but we could determine message size
176 // from the header, this field is non-zero. Otherwise it's zero.
177 size_t message_size;
erikchen29e0f2f2015-09-11 19:08:53178 // Whether an entire message was found in the given memory range.
179 bool message_found;
180 // Only filled in if |message_found| is true.
181 // The start address is passed into FindNext() by the caller, so isn't
182 // repeated in this struct. The end address of the pickle should be used to
183 // construct a base::Pickle.
184 const char* pickle_end;
185 // Only filled in if |message_found| is true.
186 // The end address of the message should be used to determine the start
187 // address of the next message.
188 const char* message_end;
erikchen29e0f2f2015-09-11 19:08:53189 };
190
191 // |info| is an output parameter and must not be nullptr.
192 static void FindNext(const char* range_start,
193 const char* range_end,
194 NextMessageInfo* info);
initial.commit09911bf2008-07-26 23:55:29195
morrita1aa788c2015-01-31 05:45:42196 // WriteAttachment appends |attachment| to the end of the set. It returns
197 // false iff the set is full.
rockot502c94f2016-02-03 20:20:16198 bool WriteAttachment(
199 scoped_refptr<base::Pickle::Attachment> attachment) override;
morrita1aa788c2015-01-31 05:45:42200 // ReadAttachment parses an attachment given the parsing state |iter| and
201 // writes it to |*attachment|. It returns true on success.
rockot502c94f2016-02-03 20:20:16202 bool ReadAttachment(
203 base::PickleIterator* iter,
204 scoped_refptr<base::Pickle::Attachment>* attachment) const override;
morrita1aa788c2015-01-31 05:45:42205 // Returns true if there are any attachment in this message.
rockot502c94f2016-02-03 20:20:16206 bool HasAttachments() const override;
agl@chromium.org526776c2009-02-07 00:39:26207
davidsz041528a2017-05-12 09:19:23208#if BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
initial.commit09911bf2008-07-26 23:55:29209 // Adds the outgoing time from Time::Now() at the end of the message and sets
210 // a bit to indicate that it's been added.
tfarina10a5c062015-09-04 18:47:57211 void set_sent_time(int64_t time);
212 int64_t sent_time() const;
initial.commit09911bf2008-07-26 23:55:29213
tfarina10a5c062015-09-04 18:47:57214 void set_received_time(int64_t time) const;
215 int64_t received_time() const { return received_time_; }
erg@google.com252cad62010-08-18 18:33:57216 void set_output_params(const std::string& op) const { output_params_ = op; }
217 const std::string& output_params() const { return output_params_; }
initial.commit09911bf2008-07-26 23:55:29218 // The following four functions are needed so we can log sync messages with
219 // delayed replies. We stick the log data from the sent message into the
220 // reply message, so that when it's sent and we have the output parameters
221 // we can log it. As such, we set a flag on the sent message to not log it.
222 void set_sync_log_data(LogData* data) const { log_data_ = data; }
223 LogData* sync_log_data() const { return log_data_; }
224 void set_dont_log() const { dont_log_ = true; }
225 bool dont_log() const { return dont_log_; }
226#endif
227
228 protected:
229 friend class Channel;
morrita@chromium.org64860882014-08-04 23:44:17230 friend class ChannelMojo;
morrita@chromium.org2f60c9b2014-06-06 20:13:51231 friend class ChannelNacl;
232 friend class ChannelPosix;
233 friend class ChannelWin;
erikchende9412b82015-07-27 18:26:14234 friend class internal::ChannelReader;
initial.commit09911bf2008-07-26 23:55:29235 friend class MessageReplyDeserializer;
236 friend class SyncMessage;
237
Ken Rockotfd907632017-09-14 04:23:41238 friend struct mojo::internal::UnmappedNativeStructSerializerImpl;
239
apatrick@google.com168ae922009-12-04 18:08:45240#pragma pack(push, 4)
brettw05cfd8ddb2015-06-02 07:02:47241 struct Header : base::Pickle::Header {
tfarina10a5c062015-09-04 18:47:57242 int32_t routing; // ID of the view that this message is destined for
243 uint32_t type; // specifies the user-defined message type
244 uint32_t flags; // specifies control flags for the message
Xiaohan Wangab909b32022-01-12 17:57:39245#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
tfarina10a5c062015-09-04 18:47:57246 uint16_t num_fds; // the number of descriptors included with this message
247 uint16_t pad; // explicitly initialize this to appease valgrind
agl@chromium.org526776c2009-02-07 00:39:26248#endif
initial.commit09911bf2008-07-26 23:55:29249 };
250#pragma pack(pop)
251
252 Header* header() {
253 return headerT<Header>();
254 }
255 const Header* header() const {
256 return headerT<Header>();
257 }
258
jam@chromium.orgef2f6ba2014-05-15 23:06:07259 void Init();
260
261 // Used internally to support IPC::Listener::OnBadMessageReceived.
262 mutable bool dispatch_error_;
initial.commit09911bf2008-07-26 23:55:29263
agl@chromium.org526776c2009-02-07 00:39:26264 // The set of file descriptors associated with this message.
morrita4b5c28e22015-01-14 21:17:06265 scoped_refptr<MessageAttachmentSet> attachment_set_;
agl@chromium.org7135bb042009-02-12 04:05:28266
morrita4b5c28e22015-01-14 21:17:06267 // Ensure that a MessageAttachmentSet is allocated
268 void EnsureMessageAttachmentSet();
agl@chromium.org7135bb042009-02-12 04:05:28269
morrita4b5c28e22015-01-14 21:17:06270 MessageAttachmentSet* attachment_set() {
271 EnsureMessageAttachmentSet();
272 return attachment_set_.get();
agl@chromium.org7135bb042009-02-12 04:05:28273 }
morrita4b5c28e22015-01-14 21:17:06274 const MessageAttachmentSet* attachment_set() const {
275 return attachment_set_.get();
agl@chromium.org7135bb042009-02-12 04:05:28276 }
agl@chromium.org526776c2009-02-07 00:39:26277
davidsz041528a2017-05-12 09:19:23278#if BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
initial.commit09911bf2008-07-26 23:55:29279 // Used for logging.
tfarina10a5c062015-09-04 18:47:57280 mutable int64_t received_time_;
erg@google.com252cad62010-08-18 18:33:57281 mutable std::string output_params_;
initial.commit09911bf2008-07-26 23:55:29282 mutable LogData* log_data_;
283 mutable bool dont_log_;
284#endif
dskiba6f3790a2015-09-30 17:24:30285
286 FRIEND_TEST_ALL_PREFIXES(IPCMessageTest, FindNext);
287 FRIEND_TEST_ALL_PREFIXES(IPCMessageTest, FindNextOverflow);
initial.commit09911bf2008-07-26 23:55:29288};
289
290//------------------------------------------------------------------------------
291
292} // namespace IPC
293
294enum SpecialRoutingIDs {
295 // indicates that we don't have a routing ID yet.
296 MSG_ROUTING_NONE = -2,
297
298 // indicates a general message not sent to a particular tab.
tfarina7023f522015-09-11 19:58:48299 MSG_ROUTING_CONTROL = INT32_MAX,
initial.commit09911bf2008-07-26 23:55:29300};
301
apatrick@google.com168ae922009-12-04 18:08:45302#define IPC_REPLY_ID 0xFFFFFFF0 // Special message id for replies
303#define IPC_LOGGING_ID 0xFFFFFFF1 // Special message id for logging
initial.commit09911bf2008-07-26 23:55:29304
darin@chromium.org7c854372011-08-15 20:41:46305#endif // IPC_IPC_MESSAGE_H_