Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / ppapi / proxy / serialized_var.h
blobd83b7d3175824af7a7a263e978e8f0ad2d9fb9a2
1 // Copyright (c) 2012 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.
5 #ifndef PPAPI_PROXY_SERIALIZED_VAR_H_
6 #define PPAPI_PROXY_SERIALIZED_VAR_H_
8 #include <string>
9 #include <vector>
11 #include "base/basictypes.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/memory/shared_memory.h"
15 #include "ppapi/c/pp_instance.h"
16 #include "ppapi/c/pp_var.h"
17 #include "ppapi/proxy/ppapi_proxy_export.h"
18 #include "ppapi/proxy/raw_var_data.h"
19 #include "ppapi/proxy/serialized_handle.h"
20 #include "ppapi/proxy/serialized_structs.h"
21 #include "ppapi/proxy/var_serialization_rules.h"
23 namespace base {
24 class PickleIterator;
27 namespace IPC {
28 class Message;
31 namespace ppapi {
32 namespace proxy {
34 class Dispatcher;
35 class VarSerializationRules;
37 // This class encapsulates a var so that we can serialize and deserialize it.
38 // The problem is that for strings, serialization and deserialization requires
39 // knowledge from outside about how to get at or create a string. So this
40 // object groups the var with a dispatcher so that string values can be set or
41 // gotten.
43 // Declare IPC messages as using this type, but don't use it directly (it has
44 // no useful public methods). Instead, instantiate one of the helper classes
45 // below which are conveniently named for each use case to prevent screwups.
47 // Design background
48 // -----------------
49 // This is sadly super complicated. The IPC system needs a consistent type to
50 // use for sending and receiving vars (this is a SerializedVar). But there are
51 // different combinations of reference counting for sending and receiving
52 // objects and for dealing with strings
54 // This makes SerializedVar complicated and easy to mess up. To make it
55 // reasonable to use, all functions are protected and there are use-specific
56 // classes that each encapsulate exactly one type of use in a way that typically
57 // won't compile if you do the wrong thing.
59 // The IPC system is designed to pass things around and will make copies in
60 // some cases, so our system must be designed so that this stuff will work.
61 // This is challenging when the SerializedVar must do some cleanup after the
62 // message is sent. To work around this, we create an inner class using a
63 // linked_ptr so all copies of a SerializedVar can share and we can guarantee
64 // that the actual data will get cleaned up on shutdown.
66 // Constness
67 // ---------
68 // SerializedVar basically doesn't support const. Everything is mutable and
69 // most functions are declared const. This unfortunateness is because of the
70 // way the IPC system works. When deserializing, it will have a const
71 // SerializedVar in a Tuple and this will be given to the function. We kind of
72 // want to modify that to convert strings and do refcounting.
74 // The helper classes used for accessing the SerializedVar have more reasonable
75 // behavior and will enforce that you don't do stupid things.
76 class PPAPI_PROXY_EXPORT SerializedVar {
77 public:
78 SerializedVar();
79 ~SerializedVar();
81 // Backend implementation for IPC::ParamTraits<SerializedVar>.
82 void WriteToMessage(IPC::Message* m) const {
83 inner_->WriteToMessage(m);
85 // If ReadFromMessage has been called, WriteDataToMessage will write the var
86 // that has been read from ReadFromMessage back to a message. This is used
87 // when converting handles for use in NaCl.
88 void WriteDataToMessage(IPC::Message* m,
89 const HandleWriter& handle_writer) const {
90 inner_->WriteDataToMessage(m, handle_writer);
92 bool ReadFromMessage(const IPC::Message* m, base::PickleIterator* iter) {
93 return inner_->ReadFromMessage(m, iter);
96 bool is_valid_var() const {
97 return inner_->is_valid_var();
100 // Returns the shared memory handles associated with this SerializedVar.
101 std::vector<SerializedHandle*> GetHandles() const {
102 return inner_->GetHandles();
105 protected:
106 friend class SerializedVarReceiveInput;
107 friend class SerializedVarReturnValue;
108 friend class SerializedVarOutParam;
109 friend class SerializedVarSendInput;
110 friend class SerializedVarSendInputShmem;
111 friend class SerializedVarTestConstructor;
112 friend class SerializedVarVectorReceiveInput;
114 class PPAPI_PROXY_EXPORT Inner : public base::RefCounted<Inner> {
115 public:
116 Inner();
117 Inner(VarSerializationRules* serialization_rules);
118 ~Inner();
120 VarSerializationRules* serialization_rules() {
121 return serialization_rules_.get();
123 void set_serialization_rules(VarSerializationRules* serialization_rules) {
124 serialization_rules_ = serialization_rules;
127 bool is_valid_var() const {
128 return is_valid_var_;
131 std::vector<SerializedHandle*> GetHandles() {
132 return (raw_var_data_ ? raw_var_data_->GetHandles() :
133 std::vector<SerializedHandle*>());
136 // See outer class's declarations above.
137 PP_Var GetVar();
138 void SetVar(PP_Var var);
139 void SetInstance(PP_Instance instance);
141 // For the SerializedVarTestConstructor, this writes the Var value as if
142 // it was just received off the wire, without any serialization rules.
143 void ForceSetVarValueForTest(PP_Var value);
145 void WriteToMessage(IPC::Message* m) const;
146 void WriteDataToMessage(IPC::Message* m,
147 const HandleWriter& handle_writer) const;
148 bool ReadFromMessage(const IPC::Message* m, base::PickleIterator* iter);
150 // Sets the cleanup mode. See the CleanupMode enum below.
151 void SetCleanupModeToEndSendPassRef();
152 void SetCleanupModeToEndReceiveCallerOwned();
154 private:
155 enum CleanupMode {
156 // The serialized var won't do anything special in the destructor
157 // (default).
158 CLEANUP_NONE,
160 // The serialized var will call EndSendPassRef in the destructor.
161 END_SEND_PASS_REF,
163 // The serialized var will call EndReceiveCallerOwned in the destructor.
164 END_RECEIVE_CALLER_OWNED
167 // Rules for serializing and deserializing vars for this process type.
168 // This may be NULL, but must be set before trying to serialize to IPC when
169 // sending, or before converting back to a PP_Var when receiving.
170 scoped_refptr<VarSerializationRules> serialization_rules_;
172 // If this is set to VARTYPE_STRING and the 'value.id' is 0, then the
173 // string_from_ipc_ holds the string. This means that the caller hasn't
174 // called Deserialize with a valid Dispatcher yet, which is how we can
175 // convert the serialized string value to a PP_Var string ID.
177 // This var may not be complete until the serialization rules are set when
178 // reading from IPC since we'll need that to convert the string_value to
179 // a string ID. Before this, the as_id will be 0 for VARTYPE_STRING.
180 PP_Var var_;
182 PP_Instance instance_;
184 CleanupMode cleanup_mode_;
186 // If the var is not properly serialized, this will be false.
187 bool is_valid_var_;
189 #ifndef NDEBUG
190 // When being sent or received over IPC, we should only be serialized or
191 // deserialized once. These flags help us assert this is true.
192 mutable bool has_been_serialized_;
193 mutable bool has_been_deserialized_;
194 #endif
196 // ReadFromMessage() may be called on the I/O thread, e.g., when reading the
197 // reply to a sync message. We cannot use the var tracker on the I/O thread,
198 // which means we cannot create some types of PP_Var
199 // (e.g. PP_VARTYPE_STRING). The data is stored in |raw_var_data_| and the
200 // PP_Var is constructed when |GetVar()| is called.
201 scoped_ptr<RawVarDataGraph> raw_var_data_;
203 DISALLOW_COPY_AND_ASSIGN(Inner);
206 SerializedVar(VarSerializationRules* serialization_rules);
208 mutable scoped_refptr<Inner> inner_;
211 // Helpers for message sending side --------------------------------------------
213 // For sending a value to the remote side.
215 // Example for API:
216 // void MyFunction(PP_Var)
217 // IPC message:
218 // IPC_MESSAGE_ROUTED1(MyFunction, SerializedVar);
219 // Sender would be:
220 // void MyFunctionProxy(PP_Var param) {
221 // Send(new MyFunctionMsg(SerializedVarSendInput(dispatcher, param));
222 // }
223 class PPAPI_PROXY_EXPORT SerializedVarSendInput : public SerializedVar {
224 public:
225 SerializedVarSendInput(Dispatcher* dispatcher, const PP_Var& var);
227 // Helper function for serializing a vector of input vars for serialization.
228 static void ConvertVector(Dispatcher* dispatcher,
229 const PP_Var* input,
230 size_t input_count,
231 std::vector<SerializedVar>* output);
233 private:
234 // Disallow the empty constructor, but keep the default copy constructor
235 // which is required to send the object to the IPC system.
236 SerializedVarSendInput();
239 // Specialization for optionally sending over shared memory.
240 class PPAPI_PROXY_EXPORT SerializedVarSendInputShmem : public SerializedVar {
241 public:
242 SerializedVarSendInputShmem(Dispatcher* dispatcher, const PP_Var& var,
243 const PP_Instance& instance);
245 private:
246 // Disallow the empty constructor, but keep the default copy constructor
247 // which is required to send the object to the IPC system.
248 SerializedVarSendInputShmem();
252 // For the calling side of a function returning a var. The sending side uses
253 // SerializedVarReturnValue.
255 // Example for API:
256 // PP_Var MyFunction()
257 // IPC message:
258 // IPC_SYNC_MESSAGE_ROUTED0_1(MyFunction, SerializedVar);
259 // Message handler would be:
260 // PP_Var MyFunctionProxy() {
261 // ReceiveSerializedVarReturnValue result;
262 // Send(new MyFunctionMsg(&result));
263 // return result.Return(dispatcher());
264 // }
266 // TODO(yzshen): Move the dispatcher parameter to the constructor and store a
267 // VarSerializationRules reference instead, in case the dispatcher is destroyed
268 // while waiting for reply to the sync message.
269 class PPAPI_PROXY_EXPORT ReceiveSerializedVarReturnValue
270 : public SerializedVar {
271 public:
272 // Note that we can't set the dispatcher in the constructor because the
273 // data will be overridden when the return value is set. This constructor is
274 // normally used in the pattern above (operator= will be implicitly invoked
275 // when the sync message writes the output values).
276 ReceiveSerializedVarReturnValue();
278 // This constructor can be used when deserializing manually. This is useful
279 // when you're getting strings "returned" via a struct and need to manually
280 // get the PP_Vars out. In this case just do:
281 // ReceiveSerializedVarReturnValue(serialized).Return(dispatcher);
282 explicit ReceiveSerializedVarReturnValue(const SerializedVar& serialized);
284 PP_Var Return(Dispatcher* dispatcher);
286 private:
287 DISALLOW_COPY_AND_ASSIGN(ReceiveSerializedVarReturnValue);
290 // Example for API:
291 // "void MyFunction(PP_Var* exception);"
292 // IPC message:
293 // IPC_SYNC_MESSAGE_ROUTED0_1(MyFunction, SerializedVar);
294 // Message handler would be:
295 // void OnMsgMyFunction(PP_Var* exception) {
296 // ReceiveSerializedException se(dispatcher(), exception)
297 // Send(new PpapiHostMsg_Foo(&se));
298 // }
299 class PPAPI_PROXY_EXPORT ReceiveSerializedException : public SerializedVar {
300 public:
301 ReceiveSerializedException(Dispatcher* dispatcher, PP_Var* exception);
302 ~ReceiveSerializedException();
304 // Returns true if the exception passed in the constructor is set. Check
305 // this before actually issuing the IPC.
306 bool IsThrown() const;
308 private:
309 // The input/output exception we're wrapping. May be NULL.
310 PP_Var* exception_;
312 DISALLOW_IMPLICIT_CONSTRUCTORS(ReceiveSerializedException);
315 // Helper class for when we're returning a vector of Vars. When it goes out
316 // of scope it will automatically convert the vector filled by the IPC layer
317 // into the array specified by the constructor params.
319 // Example for API:
320 // "void MyFunction(uint32_t* count, PP_Var** vars);"
321 // IPC message:
322 // IPC_SYNC_MESSAGE_ROUTED0_1(MyFunction, std::vector<SerializedVar>);
323 // Proxy function:
324 // void MyFunction(uint32_t* count, PP_Var** vars) {
325 // ReceiveSerializedVarVectorOutParam vect(dispatcher, count, vars);
326 // Send(new MyMsg(vect.OutParam()));
327 // }
328 class PPAPI_PROXY_EXPORT ReceiveSerializedVarVectorOutParam {
329 public:
330 ReceiveSerializedVarVectorOutParam(Dispatcher* dispatcher,
331 uint32_t* output_count,
332 PP_Var** output);
333 ~ReceiveSerializedVarVectorOutParam();
335 std::vector<SerializedVar>* OutParam();
337 private:
338 Dispatcher* dispatcher_;
339 uint32_t* output_count_;
340 PP_Var** output_;
342 std::vector<SerializedVar> vector_;
344 DISALLOW_IMPLICIT_CONSTRUCTORS(ReceiveSerializedVarVectorOutParam);
347 // Helpers for message receiving side ------------------------------------------
349 // For receiving a value from the remote side.
351 // Example for API:
352 // void MyFunction(PP_Var)
353 // IPC message:
354 // IPC_MESSAGE_ROUTED1(MyFunction, SerializedVar);
355 // Message handler would be:
356 // void OnMsgMyFunction(SerializedVarReceiveInput param) {
357 // MyFunction(param.Get());
358 // }
359 class PPAPI_PROXY_EXPORT SerializedVarReceiveInput {
360 public:
361 // We rely on the implicit constructor here since the IPC layer will call
362 // us with a SerializedVar. Pass this object by value, the copy constructor
363 // will pass along the pointer (as cheap as passing a pointer arg).
364 SerializedVarReceiveInput(const SerializedVar& serialized);
365 ~SerializedVarReceiveInput();
367 PP_Var Get(Dispatcher* dispatcher);
368 PP_Var GetForInstance(Dispatcher* dispatcher, PP_Instance instance);
369 bool is_valid_var() { return serialized_.is_valid_var(); }
371 private:
372 const SerializedVar& serialized_;
375 // For receiving an input vector of vars from the remote side.
377 // Example:
378 // OnMsgMyFunction(SerializedVarVectorReceiveInput vector) {
379 // uint32_t size;
380 // PP_Var* array = vector.Get(dispatcher, &size);
381 // MyFunction(size, array);
382 // }
383 class PPAPI_PROXY_EXPORT SerializedVarVectorReceiveInput {
384 public:
385 SerializedVarVectorReceiveInput(const std::vector<SerializedVar>& serialized);
386 ~SerializedVarVectorReceiveInput();
388 // Only call Get() once. It will return a pointer to the converted array and
389 // place the array size in the out param. Will return NULL when the array is
390 // empty.
391 PP_Var* Get(Dispatcher* dispatcher, uint32_t* array_size);
393 private:
394 const std::vector<SerializedVar>& serialized_;
396 // Filled by Get().
397 std::vector<PP_Var> deserialized_;
400 // For the receiving side of a function returning a var. The calling side uses
401 // ReceiveSerializedVarReturnValue.
403 // Example for API:
404 // PP_Var MyFunction()
405 // IPC message:
406 // IPC_SYNC_MESSAGE_ROUTED0_1(MyFunction, SerializedVar);
407 // Message handler would be:
408 // void OnMsgMyFunction(SerializedVarReturnValue result) {
409 // result.Return(dispatcher(), MyFunction());
410 // }
411 class PPAPI_PROXY_EXPORT SerializedVarReturnValue {
412 public:
413 // We rely on the implicit constructor here since the IPC layer will call
414 // us with a SerializedVar*. Pass this object by value, the copy constructor
415 // will pass along the pointer (as cheap as passing a pointer arg).
416 SerializedVarReturnValue(SerializedVar* serialized);
418 void Return(Dispatcher* dispatcher, const PP_Var& var);
420 // Helper function for code that doesn't use the pattern above, but gets
421 // a return value from the remote side via a struct. You can pass in the
422 // SerializedVar and a PP_Var will be created with return value semantics.
423 static SerializedVar Convert(Dispatcher* dispatcher, const PP_Var& var);
425 private:
426 SerializedVar* serialized_;
429 // For writing an out param to the remote side.
431 // Example for API:
432 // "void MyFunction(PP_Var* out);"
433 // IPC message:
434 // IPC_SYNC_MESSAGE_ROUTED0_1(MyFunction, SerializedVar);
435 // Message handler would be:
436 // void OnMsgMyFunction(SerializedVarOutParam out_param) {
437 // MyFunction(out_param.OutParam(dispatcher()));
438 // }
439 class PPAPI_PROXY_EXPORT SerializedVarOutParam {
440 public:
441 // We rely on the implicit constructor here since the IPC layer will call
442 // us with a SerializedVar*. Pass this object by value, the copy constructor
443 // will pass along the pointer (as cheap as passing a pointer arg).
444 SerializedVarOutParam(SerializedVar* serialized);
445 ~SerializedVarOutParam();
447 // Call this function only once. The caller should write its result to the
448 // returned var pointer before this class goes out of scope. The var's
449 // initial value will be VARTYPE_UNDEFINED.
450 PP_Var* OutParam(Dispatcher* dispatcher);
452 private:
453 SerializedVar* serialized_;
455 // This is the value actually written by the code and returned by OutParam.
456 // We'll write this into serialized_ in our destructor.
457 PP_Var writable_var_;
459 Dispatcher* dispatcher_;
462 // For returning an array of PP_Vars to the other side and transferring
463 // ownership.
465 class PPAPI_PROXY_EXPORT SerializedVarVectorOutParam {
466 public:
467 SerializedVarVectorOutParam(std::vector<SerializedVar>* serialized);
468 ~SerializedVarVectorOutParam();
470 uint32_t* CountOutParam() { return &count_; }
471 PP_Var** ArrayOutParam(Dispatcher* dispatcher);
473 private:
474 Dispatcher* dispatcher_;
475 std::vector<SerializedVar>* serialized_;
477 uint32_t count_;
478 PP_Var* array_;
481 // For tests that just want to construct a SerializedVar for giving it to one
482 // of the other classes. This emulates a SerializedVar just received over the
483 // wire from another process.
484 class PPAPI_PROXY_EXPORT SerializedVarTestConstructor : public SerializedVar {
485 public:
486 // For POD-types and objects.
487 explicit SerializedVarTestConstructor(const PP_Var& pod_var);
489 // For strings.
490 explicit SerializedVarTestConstructor(const std::string& str);
493 // For tests that want to read what's in a SerializedVar.
494 class PPAPI_PROXY_EXPORT SerializedVarTestReader : public SerializedVar {
495 public:
496 explicit SerializedVarTestReader(const SerializedVar& var);
498 PP_Var GetVar() const { return inner_->GetVar(); }
501 } // namespace proxy
502 } // namespace ppapi
504 #endif // PPAPI_PROXY_SERIALIZED_VAR_H_