OLD | NEW |
| (Empty) |
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_ | |
OLD | NEW |