Refactor android test results logging.
[chromium-blink-merge.git] / ppapi / proxy / serialized_var.h
blob3b74a3efceeaa396777a0223d1d59a493b3cba47
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 "ppapi/c/pp_var.h"
15 #include "ppapi/proxy/ppapi_proxy_export.h"
16 #include "ppapi/proxy/var_serialization_rules.h"
18 class PickleIterator;
20 namespace IPC {
21 class Message;
24 namespace ppapi {
25 namespace proxy {
27 class Dispatcher;
28 class VarSerializationRules;
30 // This class encapsulates a var so that we can serialize and deserialize it.
31 // The problem is that for strings, serialization and deserialization requires
32 // knowledge from outside about how to get at or create a string. So this
33 // object groups the var with a dispatcher so that string values can be set or
34 // gotten.
36 // Declare IPC messages as using this type, but don't use it directly (it has
37 // no useful public methods). Instead, instantiate one of the helper classes
38 // below which are conveniently named for each use case to prevent screwups.
40 // Design background
41 // -----------------
42 // This is sadly super complicated. The IPC system needs a consistent type to
43 // use for sending and receiving vars (this is a SerializedVar). But there are
44 // different combinations of reference counting for sending and receiving
45 // objects and for dealing with strings
47 // This makes SerializedVar complicated and easy to mess up. To make it
48 // reasonable to use, all functions are protected and there are use-specific
49 // classes that each encapsulate exactly one type of use in a way that typically
50 // won't compile if you do the wrong thing.
52 // The IPC system is designed to pass things around and will make copies in
53 // some cases, so our system must be designed so that this stuff will work.
54 // This is challenging when the SerializedVar must do some cleanup after the
55 // message is sent. To work around this, we create an inner class using a
56 // linked_ptr so all copies of a SerializedVar can share and we can guarantee
57 // that the actual data will get cleaned up on shutdown.
59 // Constness
60 // ---------
61 // SerializedVar basically doesn't support const. Everything is mutable and
62 // most functions are declared const. This unfortunateness is because of the
63 // way the IPC system works. When deserializing, it will have a const
64 // SerializedVar in a Tuple and this will be given to the function. We kind of
65 // want to modify that to convert strings and do refcounting.
67 // The helper classes used for accessing the SerializedVar have more reasonable
68 // behavior and will enforce that you don't do stupid things.
69 class PPAPI_PROXY_EXPORT SerializedVar {
70 public:
71 SerializedVar();
72 ~SerializedVar();
74 // Backend implementation for IPC::ParamTraits<SerializedVar>.
75 void WriteToMessage(IPC::Message* m) const {
76 inner_->WriteToMessage(m);
78 bool ReadFromMessage(const IPC::Message* m, PickleIterator* iter) {
79 return inner_->ReadFromMessage(m, iter);
82 protected:
83 friend class SerializedVarReceiveInput;
84 friend class SerializedVarReturnValue;
85 friend class SerializedVarOutParam;
86 friend class SerializedVarSendInput;
87 friend class SerializedVarTestConstructor;
88 friend class SerializedVarVectorReceiveInput;
90 class PPAPI_PROXY_EXPORT Inner : public base::RefCounted<Inner> {
91 public:
92 Inner();
93 Inner(VarSerializationRules* serialization_rules);
94 ~Inner();
96 VarSerializationRules* serialization_rules() {
97 return serialization_rules_;
99 void set_serialization_rules(VarSerializationRules* serialization_rules) {
100 serialization_rules_ = serialization_rules;
103 // See outer class's declarations above.
104 PP_Var GetVar();
105 void SetVar(PP_Var var);
107 // For the SerializedVarTestConstructor, this writes the Var value as if
108 // it was just received off the wire, without any serialization rules.
109 void ForceSetVarValueForTest(PP_Var value);
111 void WriteToMessage(IPC::Message* m) const;
112 bool ReadFromMessage(const IPC::Message* m, PickleIterator* iter);
114 // Sets the cleanup mode. See the CleanupMode enum below.
115 void SetCleanupModeToEndSendPassRef();
116 void SetCleanupModeToEndReceiveCallerOwned();
118 private:
119 enum CleanupMode {
120 // The serialized var won't do anything special in the destructor
121 // (default).
122 CLEANUP_NONE,
124 // The serialized var will call EndSendPassRef in the destructor.
125 END_SEND_PASS_REF,
127 // The serialized var will call EndReceiveCallerOwned in the destructor.
128 END_RECEIVE_CALLER_OWNED
131 // ReadFromMessage() may be called on the I/O thread, e.g., when reading the
132 // reply to a sync message. We cannot use the var tracker on the I/O thread,
133 // which means we cannot create PP_Var for PP_VARTYPE_STRING and
134 // PP_VARTYPE_ARRAY_BUFFER in ReadFromMessage(). So we save the raw var data
135 // and create PP_Var later when GetVar() is called, which should happen on
136 // the main thread.
137 struct RawVarData {
138 PP_VarType type;
139 std::string data;
142 // Converts |raw_var_data_| to |var_|. It is a no-op if |raw_var_data_| is
143 // NULL.
144 void ConvertRawVarData();
146 // Rules for serializing and deserializing vars for this process type.
147 // This may be NULL, but must be set before trying to serialize to IPC when
148 // sending, or before converting back to a PP_Var when receiving.
149 scoped_refptr<VarSerializationRules> serialization_rules_;
151 // If this is set to VARTYPE_STRING and the 'value.id' is 0, then the
152 // string_from_ipc_ holds the string. This means that the caller hasn't
153 // called Deserialize with a valid Dispatcher yet, which is how we can
154 // convert the serialized string value to a PP_Var string ID.
156 // This var may not be complete until the serialization rules are set when
157 // reading from IPC since we'll need that to convert the string_value to
158 // a string ID. Before this, the as_id will be 0 for VARTYPE_STRING.
159 PP_Var var_;
161 CleanupMode cleanup_mode_;
163 #ifndef NDEBUG
164 // When being sent or received over IPC, we should only be serialized or
165 // deserialized once. These flags help us assert this is true.
166 mutable bool has_been_serialized_;
167 mutable bool has_been_deserialized_;
168 #endif
170 // It will be non-NULL if there is PP_VARTYPE_STRING or
171 // PP_VARTYPE_ARRAY_BUFFER data from ReadFromMessage() that hasn't been
172 // converted to PP_Var.
173 scoped_ptr<RawVarData> raw_var_data_;
175 DISALLOW_COPY_AND_ASSIGN(Inner);
178 SerializedVar(VarSerializationRules* serialization_rules);
180 mutable scoped_refptr<Inner> inner_;
183 // Helpers for message sending side --------------------------------------------
185 // For sending a value to the remote side.
187 // Example for API:
188 // void MyFunction(PP_Var)
189 // IPC message:
190 // IPC_MESSAGE_ROUTED1(MyFunction, SerializedVar);
191 // Sender would be:
192 // void MyFunctionProxy(PP_Var param) {
193 // Send(new MyFunctionMsg(SerializedVarSendInput(dispatcher, param));
194 // }
195 class PPAPI_PROXY_EXPORT SerializedVarSendInput : public SerializedVar {
196 public:
197 SerializedVarSendInput(Dispatcher* dispatcher, const PP_Var& var);
199 // Helper function for serializing a vector of input vars for serialization.
200 static void ConvertVector(Dispatcher* dispatcher,
201 const PP_Var* input,
202 size_t input_count,
203 std::vector<SerializedVar>* output);
205 private:
206 // Disallow the empty constructor, but keep the default copy constructor
207 // which is required to send the object to the IPC system.
208 SerializedVarSendInput();
211 // For the calling side of a function returning a var. The sending side uses
212 // SerializedVarReturnValue.
214 // Example for API:
215 // PP_Var MyFunction()
216 // IPC message:
217 // IPC_SYNC_MESSAGE_ROUTED0_1(MyFunction, SerializedVar);
218 // Message handler would be:
219 // PP_Var MyFunctionProxy() {
220 // ReceiveSerializedVarReturnValue result;
221 // Send(new MyFunctionMsg(&result));
222 // return result.Return(dispatcher());
223 // }
225 // TODO(yzshen): Move the dispatcher parameter to the constructor and store a
226 // VarSerializationRules reference instead, in case the dispatcher is destroyed
227 // while waiting for reply to the sync message.
228 class PPAPI_PROXY_EXPORT ReceiveSerializedVarReturnValue
229 : public SerializedVar {
230 public:
231 // Note that we can't set the dispatcher in the constructor because the
232 // data will be overridden when the return value is set. This constructor is
233 // normally used in the pattern above (operator= will be implicitly invoked
234 // when the sync message writes the output values).
235 ReceiveSerializedVarReturnValue();
237 // This constructor can be used when deserializing manually. This is useful
238 // when you're getting strings "returned" via a struct and need to manually
239 // get the PP_Vars out. In this case just do:
240 // ReceiveSerializedVarReturnValue(serialized).Return(dispatcher);
241 explicit ReceiveSerializedVarReturnValue(const SerializedVar& serialized);
243 PP_Var Return(Dispatcher* dispatcher);
245 private:
246 DISALLOW_COPY_AND_ASSIGN(ReceiveSerializedVarReturnValue);
249 // Example for API:
250 // "void MyFunction(PP_Var* exception);"
251 // IPC message:
252 // IPC_SYNC_MESSAGE_ROUTED0_1(MyFunction, SerializedVar);
253 // Message handler would be:
254 // void OnMsgMyFunction(PP_Var* exception) {
255 // ReceiveSerializedException se(dispatcher(), exception)
256 // Send(new PpapiHostMsg_Foo(&se));
257 // }
258 class PPAPI_PROXY_EXPORT ReceiveSerializedException : public SerializedVar {
259 public:
260 ReceiveSerializedException(Dispatcher* dispatcher, PP_Var* exception);
261 ~ReceiveSerializedException();
263 // Returns true if the exception passed in the constructor is set. Check
264 // this before actually issuing the IPC.
265 bool IsThrown() const;
267 private:
268 // The input/output exception we're wrapping. May be NULL.
269 PP_Var* exception_;
271 DISALLOW_IMPLICIT_CONSTRUCTORS(ReceiveSerializedException);
274 // Helper class for when we're returning a vector of Vars. When it goes out
275 // of scope it will automatically convert the vector filled by the IPC layer
276 // into the array specified by the constructor params.
278 // Example for API:
279 // "void MyFunction(uint32_t* count, PP_Var** vars);"
280 // IPC message:
281 // IPC_SYNC_MESSAGE_ROUTED0_1(MyFunction, std::vector<SerializedVar>);
282 // Proxy function:
283 // void MyFunction(uint32_t* count, PP_Var** vars) {
284 // ReceiveSerializedVarVectorOutParam vect(dispatcher, count, vars);
285 // Send(new MyMsg(vect.OutParam()));
286 // }
287 class PPAPI_PROXY_EXPORT ReceiveSerializedVarVectorOutParam {
288 public:
289 ReceiveSerializedVarVectorOutParam(Dispatcher* dispatcher,
290 uint32_t* output_count,
291 PP_Var** output);
292 ~ReceiveSerializedVarVectorOutParam();
294 std::vector<SerializedVar>* OutParam();
296 private:
297 Dispatcher* dispatcher_;
298 uint32_t* output_count_;
299 PP_Var** output_;
301 std::vector<SerializedVar> vector_;
303 DISALLOW_IMPLICIT_CONSTRUCTORS(ReceiveSerializedVarVectorOutParam);
306 // Helpers for message receiving side ------------------------------------------
308 // For receiving a value from the remote side.
310 // Example for API:
311 // void MyFunction(PP_Var)
312 // IPC message:
313 // IPC_MESSAGE_ROUTED1(MyFunction, SerializedVar);
314 // Message handler would be:
315 // void OnMsgMyFunction(SerializedVarReceiveInput param) {
316 // MyFunction(param.Get());
317 // }
318 class PPAPI_PROXY_EXPORT SerializedVarReceiveInput {
319 public:
320 // We rely on the implicit constructor here since the IPC layer will call
321 // us with a SerializedVar. Pass this object by value, the copy constructor
322 // will pass along the pointer (as cheap as passing a pointer arg).
323 SerializedVarReceiveInput(const SerializedVar& serialized);
324 ~SerializedVarReceiveInput();
326 PP_Var Get(Dispatcher* dispatcher);
328 private:
329 const SerializedVar& serialized_;
332 // For receiving an input vector of vars from the remote side.
334 // Example:
335 // OnMsgMyFunction(SerializedVarVectorReceiveInput vector) {
336 // uint32_t size;
337 // PP_Var* array = vector.Get(dispatcher, &size);
338 // MyFunction(size, array);
339 // }
340 class PPAPI_PROXY_EXPORT SerializedVarVectorReceiveInput {
341 public:
342 SerializedVarVectorReceiveInput(const std::vector<SerializedVar>& serialized);
343 ~SerializedVarVectorReceiveInput();
345 // Only call Get() once. It will return a pointer to the converted array and
346 // place the array size in the out param. Will return NULL when the array is
347 // empty.
348 PP_Var* Get(Dispatcher* dispatcher, uint32_t* array_size);
350 private:
351 const std::vector<SerializedVar>& serialized_;
353 // Filled by Get().
354 std::vector<PP_Var> deserialized_;
357 // For the receiving side of a function returning a var. The calling side uses
358 // ReceiveSerializedVarReturnValue.
360 // Example for API:
361 // PP_Var MyFunction()
362 // IPC message:
363 // IPC_SYNC_MESSAGE_ROUTED0_1(MyFunction, SerializedVar);
364 // Message handler would be:
365 // void OnMsgMyFunction(SerializedVarReturnValue result) {
366 // result.Return(dispatcher(), MyFunction());
367 // }
368 class PPAPI_PROXY_EXPORT SerializedVarReturnValue {
369 public:
370 // We rely on the implicit constructor here since the IPC layer will call
371 // us with a SerializedVar*. Pass this object by value, the copy constructor
372 // will pass along the pointer (as cheap as passing a pointer arg).
373 SerializedVarReturnValue(SerializedVar* serialized);
375 void Return(Dispatcher* dispatcher, const PP_Var& var);
377 // Helper function for code that doesn't use the pattern above, but gets
378 // a return value from the remote side via a struct. You can pass in the
379 // SerializedVar and a PP_Var will be created with return value semantics.
380 static SerializedVar Convert(Dispatcher* dispatcher, const PP_Var& var);
382 private:
383 SerializedVar* serialized_;
386 // For writing an out param to the remote side.
388 // Example for API:
389 // "void MyFunction(PP_Var* out);"
390 // IPC message:
391 // IPC_SYNC_MESSAGE_ROUTED0_1(MyFunction, SerializedVar);
392 // Message handler would be:
393 // void OnMsgMyFunction(SerializedVarOutParam out_param) {
394 // MyFunction(out_param.OutParam(dispatcher()));
395 // }
396 class PPAPI_PROXY_EXPORT SerializedVarOutParam {
397 public:
398 // We rely on the implicit constructor here since the IPC layer will call
399 // us with a SerializedVar*. Pass this object by value, the copy constructor
400 // will pass along the pointer (as cheap as passing a pointer arg).
401 SerializedVarOutParam(SerializedVar* serialized);
402 ~SerializedVarOutParam();
404 // Call this function only once. The caller should write its result to the
405 // returned var pointer before this class goes out of scope. The var's
406 // initial value will be VARTYPE_UNDEFINED.
407 PP_Var* OutParam(Dispatcher* dispatcher);
409 private:
410 SerializedVar* serialized_;
412 // This is the value actually written by the code and returned by OutParam.
413 // We'll write this into serialized_ in our destructor.
414 PP_Var writable_var_;
416 Dispatcher* dispatcher_;
419 // For returning an array of PP_Vars to the other side and transferring
420 // ownership.
422 class PPAPI_PROXY_EXPORT SerializedVarVectorOutParam {
423 public:
424 SerializedVarVectorOutParam(std::vector<SerializedVar>* serialized);
425 ~SerializedVarVectorOutParam();
427 uint32_t* CountOutParam() { return &count_; }
428 PP_Var** ArrayOutParam(Dispatcher* dispatcher);
430 private:
431 Dispatcher* dispatcher_;
432 std::vector<SerializedVar>* serialized_;
434 uint32_t count_;
435 PP_Var* array_;
438 // For tests that just want to construct a SerializedVar for giving it to one
439 // of the other classes. This emulates a SerializedVar just received over the
440 // wire from another process.
441 class PPAPI_PROXY_EXPORT SerializedVarTestConstructor : public SerializedVar {
442 public:
443 // For POD-types and objects.
444 explicit SerializedVarTestConstructor(const PP_Var& pod_var);
446 // For strings.
447 explicit SerializedVarTestConstructor(const std::string& str);
450 // For tests that want to read what's in a SerializedVar.
451 class PPAPI_PROXY_EXPORT SerializedVarTestReader : public SerializedVar {
452 public:
453 explicit SerializedVarTestReader(const SerializedVar& var);
455 // The "incomplete" var is the one sent over the wire. Strings and object
456 // IDs have not yet been converted, so this is the thing that tests will
457 // actually want to check.
458 PP_Var GetVar() const { return inner_->GetVar(); }
461 } // namespace proxy
462 } // namespace ppapi
464 #endif // PPAPI_PROXY_SERIALIZED_VAR_H_