Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / content / renderer / pepper / npapi_glue.h
1 // Copyright (c) 2011 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 CONTENT_RENDERER_PEPPER_NPAPI_GLUE_H_
6 #define CONTENT_RENDERER_PEPPER_NPAPI_GLUE_H_
7
8 #include "base/basictypes.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "content/common/content_export.h"
11 #include "ppapi/c/pp_module.h"
12 #include "ppapi/c/pp_var.h"
13
14 struct NPObject;
15 typedef struct _NPVariant NPVariant;
16 typedef void* NPIdentifier;
17
18 namespace content {
19
20 class PepperPluginInstanceImpl;
21 class PluginObject;
22
23 // Utilities -------------------------------------------------------------------
24
25 // Converts the given PP_Var to an NPVariant, returning true on success.
26 // False means that the given variant is invalid. In this case, the result
27 // NPVariant will be set to a void one.
28 //
29 // The contents of the PP_Var will be copied unless the PP_Var corresponds to
30 // an object.
31 bool PPVarToNPVariant(PP_Var var, NPVariant* result);
32
33 // Returns a PP_Var that corresponds to the given NPVariant. The contents of
34 // the NPVariant will be copied unless the NPVariant corresponds to an
35 // object. This will handle all Variant types including POD, strings, and
36 // objects.
37 //
38 // The returned PP_Var will have a refcount of 1, this passing ownership of
39 // the reference to the caller. This is suitable for returning to a plugin.
40 PP_Var NPVariantToPPVar(PepperPluginInstanceImpl* instance,
41                         const NPVariant* variant);
42
43 // Returns a NPIdentifier that corresponds to the given PP_Var. The contents
44 // of the PP_Var will be copied. Returns 0 if the given PP_Var is not a a
45 // string or integer type.
46 NPIdentifier PPVarToNPIdentifier(PP_Var var);
47
48 // Returns a PP_Var corresponding to the given identifier. In the case of
49 // a string identifier, the returned string will have a reference count of 1.
50 PP_Var NPIdentifierToPPVar(NPIdentifier id);
51
52 // Helper function to create a PP_Var of type object that contains the given
53 // NPObject for use byt he given module. Calling this function multiple times
54 // given the same module + NPObject results in the same PP_Var, assuming that
55 // there is still a PP_Var with a reference open to it from the previous
56 // call.
57 //
58 // The instance is necessary because we can have different instances pointing to
59 // the same NPObject, and we want to keep their refs separate.
60 //
61 // If no ObjectVar currently exists corresponding to the NPObject, one is
62 // created associated with the given module.
63 //
64 // Note: this could easily be changed to take a PP_Instance instead if that
65 // makes certain calls in the future easier. Currently all callers have a
66 // PluginInstance so that's what we use here.
67 CONTENT_EXPORT PP_Var
68     NPObjectToPPVar(PepperPluginInstanceImpl* instance, NPObject* object);
69
70 // This version creates a default v8::Context rather than using the one from
71 // the container of |instance|. It is only for use in unit tests, where we don't
72 // have a real container for |instance|.
73 CONTENT_EXPORT PP_Var NPObjectToPPVarForTest(PepperPluginInstanceImpl* instance,
74                                              NPObject* object);
75
76 // PPResultAndExceptionToNPResult ----------------------------------------------
77
78 // Convenience object for converting a PPAPI call that can throw an exception
79 // and optionally return a value, back to the NPAPI layer which expects a
80 // NPVariant as a result.
81 //
82 // Normal usage is that you will pass the result of exception() to the
83 // PPAPI function as the exception output parameter. Then you will either
84 // call SetResult with the result of the PPAPI call, or
85 // CheckExceptionForNoResult if the PPAPI call doesn't return a PP_Var.
86 //
87 // Both SetResult and CheckExceptionForNoResult will throw an exception to
88 // the JavaScript library if the plugin reported an exception. SetResult
89 // will additionally convert the result to an NPVariant and write it to the
90 // output parameter given in the constructor.
91 class PPResultAndExceptionToNPResult {
92  public:
93   // The object_var parameter is the object to associate any exception with.
94   // It may not be NULL.
95   //
96   // The np_result parameter is the NPAPI result output parameter. This may be
97   // NULL if there is no NPVariant result (like for HasProperty). If this is
98   // specified, you must call SetResult() to set it. If it is not, you must
99   // call CheckExceptionForNoResult to do the exception checking with no result
100   // conversion.
101   PPResultAndExceptionToNPResult(NPObject* object_var, NPVariant* np_result);
102
103   ~PPResultAndExceptionToNPResult();
104
105   // Returns true if an exception has been set.
106   bool has_exception() const { return exception_.type != PP_VARTYPE_UNDEFINED; }
107
108   // Returns a pointer to the exception. You would pass this to the PPAPI
109   // function as the exception parameter. If it is set to non-void, this object
110   // will take ownership of destroying it.
111   PP_Var* exception() { return &exception_; }
112
113   // Returns true if everything succeeded with no exception. This is valid only
114   // after calling SetResult/CheckExceptionForNoResult.
115   bool success() const { return success_; }
116
117   // Call this with the return value of the PPAPI function. It will convert
118   // the result to the NPVariant output parameter and pass any exception on to
119   // the JS engine. It will update the success flag and return it.
120   bool SetResult(PP_Var result);
121
122   // Call this after calling a PPAPI function that could have set the
123   // exception. It will pass the exception on to the JS engine and update
124   // the success flag.
125   //
126   // The success flag will be returned.
127   bool CheckExceptionForNoResult();
128
129   // Call this to ignore any exception. This prevents the DCHECK from failing
130   // in the destructor.
131   void IgnoreException();
132
133  private:
134   // Throws the current exception to JS. The exception must be set.
135   void ThrowException();
136
137   NPObject* object_var_;  // Non-owning ref (see constructor).
138   NPVariant* np_result_;  // Output value, possibly NULL (see constructor).
139   PP_Var exception_;  // Exception set by the PPAPI call. We own a ref to it.
140   bool success_;      // See the success() function above.
141   bool checked_exception_;  // SetResult/CheckExceptionForNoResult was called.
142
143   DISALLOW_COPY_AND_ASSIGN(PPResultAndExceptionToNPResult);
144 };
145
146 // PPVarArrayFromNPVariantArray ------------------------------------------------
147
148 // Converts an array of NPVariants to an array of PP_Var, and scopes the
149 // ownership of the PP_Var. This is used when converting argument lists from
150 // WebKit to the plugin.
151 class PPVarArrayFromNPVariantArray {
152  public:
153   PPVarArrayFromNPVariantArray(PepperPluginInstanceImpl* instance,
154                                size_t size,
155                                const NPVariant* variants);
156   ~PPVarArrayFromNPVariantArray();
157
158   PP_Var* array() { return array_.get(); }
159
160  private:
161   size_t size_;
162   scoped_ptr<PP_Var[]> array_;
163
164   DISALLOW_COPY_AND_ASSIGN(PPVarArrayFromNPVariantArray);
165 };
166
167 // PPVarFromNPObject -----------------------------------------------------------
168
169 // Converts an NPObject tp PP_Var, and scopes the ownership of the PP_Var. This
170 // is used when converting 'this' pointer from WebKit to the plugin.
171 class PPVarFromNPObject {
172  public:
173   PPVarFromNPObject(PepperPluginInstanceImpl* instance, NPObject* object);
174   ~PPVarFromNPObject();
175
176   PP_Var var() const { return var_; }
177
178  private:
179   const PP_Var var_;
180
181   DISALLOW_COPY_AND_ASSIGN(PPVarFromNPObject);
182 };
183
184 // NPObjectAccessorWithIdentifier ----------------------------------------------
185
186 // Helper class for our NPObject wrapper. This converts a call from WebKit
187 // where it gives us an NPObject and an NPIdentifier to an easily-accessible
188 // ObjectVar (corresponding to the NPObject) and PP_Var (corresponding to the
189 // NPIdentifier).
190 //
191 // If the NPObject or identifier is invalid, we'll set is_valid() to false.
192 // The caller should check is_valid() before doing anything with the class.
193 //
194 // JS can't have integer functions, so when dealing with these, we don't want
195 // to allow integer identifiers. The calling code can decode if it wants to
196 // allow integer identifiers (like for property access) or prohibit them
197 // (like for method calling) by setting |allow_integer_identifier|. If this
198 // is false and the identifier is an integer, we'll set is_valid() to false.
199 //
200 // Getting an integer identifier in this case should be impossible. V8
201 // shouldn't be allowing this, and the Pepper Var calls from the plugin are
202 // supposed to error out before calling into V8 (which will then call us back).
203 // Aside from an egregious error, the only time this could happen is an NPAPI
204 // plugin calling us.
205 class NPObjectAccessorWithIdentifier {
206  public:
207   NPObjectAccessorWithIdentifier(NPObject* object,
208                                  NPIdentifier identifier,
209                                  bool allow_integer_identifier);
210   ~NPObjectAccessorWithIdentifier();
211
212   // Returns true if both the object and identifier are valid.
213   bool is_valid() const {
214     return object_ && identifier_.type != PP_VARTYPE_UNDEFINED;
215   }
216
217   PluginObject* object() { return object_; }
218   PP_Var identifier() const { return identifier_; }
219
220  private:
221   PluginObject* object_;
222   PP_Var identifier_;
223
224   DISALLOW_COPY_AND_ASSIGN(NPObjectAccessorWithIdentifier);
225 };
226
227 // TryCatch --------------------------------------------------------------------
228
229 // Instantiate this object on the stack to catch V8 exceptions and pass them
230 // to an optional out parameter supplied by the plugin.
231 class TryCatch {
232  public:
233   // The given exception may be NULL if the consumer isn't interested in
234   // catching exceptions. If non-NULL, the given var will be updated if any
235   // exception is thrown (so it must outlive the TryCatch object).
236   TryCatch(PP_Var* exception);
237   ~TryCatch();
238
239   // Returns true is an exception has been thrown. This can be true immediately
240   // after construction if the var passed to the constructor is non-void.
241   bool has_exception() const { return has_exception_; }
242
243   // Sets the given exception. If an exception has been previously set, this
244   // function will do nothing (normally you want only the first exception).
245   void SetException(const char* message);
246
247  private:
248   static void Catch(void* self, const char* message);
249
250   // True if an exception has been thrown. Since the exception itself may be
251   // NULL if the plugin isn't interested in getting the exception, this will
252   // always indicate if SetException has been called, regardless of whether
253   // the exception itself has been stored.
254   bool has_exception_;
255
256   // May be null if the consumer isn't interesting in catching exceptions.
257   PP_Var* exception_;
258 };
259
260 }  // namespace content
261
262 #endif  // CONTENT_RENDERER_PEPPER_NPAPI_GLUE_H_