summaryrefslogtreecommitdiffstats
path: root/ppapi/proxy/raw_var_data.h
blob: 4387eb2d56172844965d4a34abe86c4ae5a3687a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef PPAPI_PROXY_RAW_VAR_DATA_H_
#define PPAPI_PROXY_RAW_VAR_DATA_H_

#include <vector>

#include "base/callback.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "ppapi/c/pp_instance.h"
#include "ppapi/c/pp_var.h"
#include "ppapi/proxy/ppapi_param_traits.h"
#include "ppapi/proxy/ppapi_proxy_export.h"
#include "ppapi/proxy/serialized_handle.h"

class PickleIterator;

namespace IPC {
class Message;
}

namespace ppapi {
namespace proxy {

class RawVarData;

typedef base::Callback<void(IPC::Message*, const SerializedHandle&)>
    HandleWriter;

// Contains the data associated with a graph of connected PP_Vars. Useful for
// serializing/deserializing a graph of PP_Vars. First we compute the transitive
// closure of the given PP_Var to find all PP_Vars which are referenced by that
// var. A RawVarData object is created for each of these vars. We then write
// data contained in each RawVarData to the message. The format looks like this:
//    idx | size     | (number of vars in the graph)
//     0  | var type |
//        | var data |
//     1  | var type |
//        | var data |
//     2  | var type |
//        | var data |
//        |   ....   |
//
// Vars that reference other vars (such as Arrays or Dictionaries) use indices
// into the message to denote which PP_Var is pointed to.
class PPAPI_PROXY_EXPORT RawVarDataGraph {
 public:
  // Construct a RawVarDataGraph from a given root PP_Var. A null pointer
  // is returned upon failure.
  static scoped_ptr<RawVarDataGraph> Create(const PP_Var& var,
                                            PP_Instance instance);

  // Constructs an empty RawVarDataGraph.
  RawVarDataGraph();
  ~RawVarDataGraph();

  // Construct a new PP_Var from the graph. All of the PP_Vars referenced by
  // the returned PP_Var are also constructed. Each PP_Var created has a
  // ref-count equal to the number of references it has in the graph of vars.
  // The returned var (the "root") has one additional reference.
  PP_Var CreatePPVar(PP_Instance instance);

  // Write the graph to a message using the given HandleWriter.
  void Write(IPC::Message* m, const HandleWriter& handle_writer);

  // Create a RawVarDataGraph from the given message.
  static scoped_ptr<RawVarDataGraph> Read(const IPC::Message* m,
                                          PickleIterator* iter);

  // Returns a vector of SerializedHandles associated with this RawVarDataGraph.
  // Ownership of the pointers remains with the elements of the RawVarDataGraph.
  std::vector<SerializedHandle*> GetHandles();

  // Sets the threshold size at which point we switch from transmitting
  // array buffers in IPC messages to using shared memory. This is only used
  // for testing purposes where we need to transmit small buffers using shmem
  // (in order to have fast tests).
  static void SetMinimumArrayBufferSizeForShmemForTest(uint32 threshold);

  // A list of the nodes in the graph.
  ScopedVector<RawVarData> data_;
};

// Abstract base class for the data contained in a PP_Var.
class RawVarData {
 public:
  // Create a new, empty RawVarData for the given type.
  static RawVarData* Create(PP_VarType type);
  RawVarData();
  virtual ~RawVarData();

  // Returns the type of the PP_Var represented by the RawVarData.
  virtual PP_VarType Type() = 0;

  // Initializes a RawVarData from a PP_Var. Returns true on success.
  virtual bool Init(const PP_Var& var, PP_Instance instance) = 0;

  // Create a PP_Var from the raw data contained in this object.
  virtual PP_Var CreatePPVar(PP_Instance instance) = 0;
  // Some PP_Vars may require 2-step initialization. For example, they may
  // reference other PP_Vars which had not yet been created when |CreatePPVar|
  // was called. The original var created with |CreatePPVar| is passed back in,
  // along with the graph it is a part of to be initialized.
  virtual void PopulatePPVar(const PP_Var& var,
                             const std::vector<PP_Var>& graph) = 0;

  // Writes the RawVarData to a message.
  virtual void Write(IPC::Message* m,
                     const HandleWriter& handle_writer) = 0;
  // Reads the RawVarData from a message. Returns true on success.
  virtual bool Read(PP_VarType type,
                    const IPC::Message* m,
                    PickleIterator* iter) = 0;

  // Returns a SerializedHandle associated with this RawVarData or NULL if none
  // exists. Ownership of the pointer remains with the RawVarData.
  virtual SerializedHandle* GetHandle();

  bool initialized() { return initialized_; }

 protected:
  bool initialized_;
};

// A RawVarData class for PP_Vars which are value types.
class BasicRawVarData : public RawVarData {
 public:
  BasicRawVarData();
  virtual ~BasicRawVarData();

  // RawVarData implementation.
  virtual PP_VarType Type() override;
  virtual bool Init(const PP_Var& var, PP_Instance instance) override;
  virtual PP_Var CreatePPVar(PP_Instance instance) override;
  virtual void PopulatePPVar(const PP_Var& var,
                             const std::vector<PP_Var>& graph) override;
  virtual void Write(IPC::Message* m,
                     const HandleWriter& handle_writer) override;
  virtual bool Read(PP_VarType type,
                    const IPC::Message* m,
                    PickleIterator* iter) override;

 private:
  PP_Var var_;
};

// A RawVarData class for string PP_Vars.
class StringRawVarData : public RawVarData {
 public:
  StringRawVarData();
  virtual ~StringRawVarData();

  // RawVarData implementation.
  virtual PP_VarType Type() override;
  virtual bool Init(const PP_Var& var, PP_Instance instance) override;
  virtual PP_Var CreatePPVar(PP_Instance instance) override;
  virtual void PopulatePPVar(const PP_Var& var,
                             const std::vector<PP_Var>& graph) override;
  virtual void Write(IPC::Message* m,
                     const HandleWriter& handle_writer) override;
  virtual bool Read(PP_VarType type,
                    const IPC::Message* m,
                    PickleIterator* iter) override;

 private:
  // The data in the string.
  std::string data_;
};

// A RawVarData class for array buffer PP_Vars.
class ArrayBufferRawVarData : public RawVarData {
 public:
  // Enum for array buffer message types.
  enum ShmemType {
    ARRAY_BUFFER_NO_SHMEM,
    ARRAY_BUFFER_SHMEM_HOST,
    ARRAY_BUFFER_SHMEM_PLUGIN,
  };

  ArrayBufferRawVarData();
  virtual ~ArrayBufferRawVarData();

  // RawVarData implementation.
  virtual PP_VarType Type() override;
  virtual bool Init(const PP_Var& var, PP_Instance instance) override;
  virtual PP_Var CreatePPVar(PP_Instance instance) override;
  virtual void PopulatePPVar(const PP_Var& var,
                             const std::vector<PP_Var>& graph) override;
  virtual void Write(IPC::Message* m,
                     const HandleWriter& handle_writer) override;
  virtual bool Read(PP_VarType type,
                    const IPC::Message* m,
                    PickleIterator* iter) override;
  virtual SerializedHandle* GetHandle() override;

 private:
  // The type of the storage underlying the array buffer.
  ShmemType type_;
  // The data in the buffer. Valid for |type_| == ARRAY_BUFFER_NO_SHMEM.
  std::string data_;
  // Host shmem handle. Valid for |type_| == ARRAY_BUFFER_SHMEM_HOST.
  int host_shm_handle_id_;
  // Plugin shmem handle. Valid for |type_| == ARRAY_BUFFER_SHMEM_PLUGIN.
  SerializedHandle plugin_shm_handle_;
};

// A RawVarData class for array PP_Vars.
class ArrayRawVarData : public RawVarData {
 public:
  ArrayRawVarData();
  virtual ~ArrayRawVarData();

  void AddChild(size_t element);

  // RawVarData implementation.
  virtual PP_VarType Type() override;
  virtual bool Init(const PP_Var& var, PP_Instance instance) override;
  virtual PP_Var CreatePPVar(PP_Instance instance) override;
  virtual void PopulatePPVar(const PP_Var& var,
                             const std::vector<PP_Var>& graph) override;
  virtual void Write(IPC::Message* m,
                     const HandleWriter& handle_writer) override;
  virtual bool Read(PP_VarType type,
                    const IPC::Message* m,
                    PickleIterator* iter) override;

 private:
  std::vector<size_t> children_;
};

// A RawVarData class for dictionary PP_Vars.
class DictionaryRawVarData : public RawVarData {
 public:
  DictionaryRawVarData();
  virtual ~DictionaryRawVarData();

  void AddChild(const std::string& key, size_t value);

  // RawVarData implementation.
  virtual PP_VarType Type() override;
  virtual bool Init(const PP_Var& var, PP_Instance instance) override;
  virtual PP_Var CreatePPVar(PP_Instance instance) override;
  virtual void PopulatePPVar(const PP_Var& var,
                             const std::vector<PP_Var>& graph) override;
  virtual void Write(IPC::Message* m,
                     const HandleWriter& handle_writer) override;
  virtual bool Read(PP_VarType type,
                    const IPC::Message* m,
                    PickleIterator* iter) override;

 private:
  std::vector<std::pair<std::string, size_t> > children_;
};

// A RawVarData class for resource PP_Vars.
// This class does not hold a reference on the PP_Resource that is being
// serialized. If sending a resource from the plugin to the host, the plugin
// should not release the ResourceVar before sending the serialized message to
// the host, and the host should immediately consume the ResourceVar before
// processing further messages.
class ResourceRawVarData : public RawVarData {
 public:
  ResourceRawVarData();
  virtual ~ResourceRawVarData();

  // RawVarData implementation.
  virtual PP_VarType Type() override;
  virtual bool Init(const PP_Var& var, PP_Instance instance) override;
  virtual PP_Var CreatePPVar(PP_Instance instance) override;
  virtual void PopulatePPVar(const PP_Var& var,
                             const std::vector<PP_Var>& graph) override;
  virtual void Write(IPC::Message* m,
                     const HandleWriter& handle_writer) override;
  virtual bool Read(PP_VarType type,
                    const IPC::Message* m,
                    PickleIterator* iter) override;

 private:
  // Resource ID in the plugin. If one has not yet been created, this is 0.
  // This is a borrowed reference; the resource's refcount is not incremented.
  PP_Resource pp_resource_;

  // Pending resource host ID in the renderer.
  int pending_renderer_host_id_;

  // Pending resource host ID in the browser.
  int pending_browser_host_id_;

  // A message containing information about how to create a plugin-side
  // resource. The message type will vary based on the resource type, and will
  // usually contain a pending resource host ID, and other required information.
  // If the resource was created directly, this is NULL.
  scoped_ptr<IPC::Message> creation_message_;
};

}  // namespace proxy
}  // namespace ppapi

#endif  // PPAPI_PROXY_RAW_VAR_DATA_H_