Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(156)

Side by Side Diff: remoting/host/host_plugin.cc

Issue 7216018: Move the Remoting Host plugin into its own sub-directory. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix missed path in remoting.gyp. Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « remoting/host/disconnect_window_win.cc ('k') | remoting/host/host_plugin.def » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 #include <stdio.h>
6 #include <string.h>
7
8 #include <string>
9 #include <vector>
10
11 #include "base/at_exit.h"
12 #include "base/basictypes.h"
13 #include "base/logging.h"
14 #include "base/stringize_macros.h"
15 #include "remoting/host/host_plugin_utils.h"
16 #include "remoting/host/host_script_object.h"
17 #include "third_party/npapi/bindings/npapi.h"
18 #include "third_party/npapi/bindings/npfunctions.h"
19 #include "third_party/npapi/bindings/npruntime.h"
20
21 // Symbol export is handled with a separate def file on Windows.
22 #if defined (__GNUC__) && __GNUC__ >= 4
23 #define EXPORT __attribute__((visibility("default")))
24 #else
25 #define EXPORT
26 #endif
27
28 #if defined(OS_WIN)
29 // TODO(wez): libvpx expects these 64-bit division functions to be provided
30 // by libgcc.a, which we aren't linked against. These implementations can
31 // be removed once we have native MSVC libvpx builds for Windows.
32 extern "C" {
33
34 int64_t __cdecl __divdi3(int64_t a, int64_t b) {
35 return a / b;
36 }
37 uint64_t __cdecl __udivdi3(uint64_t a, uint64_t b) {
38 return a / b;
39 }
40
41 }
42 #endif
43
44 using remoting::g_npnetscape_funcs;
45 using remoting::HostNPScriptObject;
46 using remoting::StringFromNPIdentifier;
47
48 namespace {
49
50 base::AtExitManager* g_at_exit_manager = NULL;
51
52 // The name and description are returned by GetValue, but are also
53 // combined with the MIME type to satisfy GetMIMEDescription, so we
54 // use macros here to allow that to happen at compile-time.
55 #define HOST_PLUGIN_NAME "Remoting Host Plugin"
56 #define HOST_PLUGIN_DESCRIPTION "Remoting Host Plugin"
57
58 // NPAPI plugin implementation for remoting host.
59 // Documentation for most of the calls in this class can be found here:
60 // https://developer.mozilla.org/en/Gecko_Plugin_API_Reference/Scripting_plugins
61 class HostNPPlugin {
62 public:
63 // |mode| is the display mode of plug-in. Values:
64 // NP_EMBED: (1) Instance was created by an EMBED tag and shares the browser
65 // window with other content.
66 // NP_FULL: (2) Instance was created by a separate file and is the primary
67 // content in the window.
68 HostNPPlugin(NPP instance, uint16 mode)
69 : instance_(instance), scriptable_object_(NULL) {}
70
71 ~HostNPPlugin() {
72 if (scriptable_object_) {
73 g_npnetscape_funcs->releaseobject(scriptable_object_);
74 scriptable_object_ = NULL;
75 }
76 }
77
78 bool Init(int16 argc, char** argn, char** argv, NPSavedData* saved) {
79 #if defined(OS_MACOSX)
80 // Use the modern CoreGraphics and Cocoa models when available, since
81 // QuickDraw and Carbon are deprecated.
82 // The drawing and event models don't change anything for this plugin, since
83 // none of the functions affected by the models actually do anything.
84 // This does however keep the plugin from breaking when Chromium eventually
85 // drops support for QuickDraw and Carbon, and it also keeps the browser
86 // from sending Null Events once a second to support old Carbon based
87 // timers.
88 // Chromium should always be supporting the newer models.
89
90 // Sanity check to see if Chromium supports the CoreGraphics drawing model.
91 NPBool supports_core_graphics = false;
92 NPError err = g_npnetscape_funcs->getvalue(instance_,
93 NPNVsupportsCoreGraphicsBool,
94 &supports_core_graphics);
95 if (err == NPERR_NO_ERROR && supports_core_graphics) {
96 // Switch to CoreGraphics drawing model.
97 g_npnetscape_funcs->setvalue(instance_, NPPVpluginDrawingModel,
98 reinterpret_cast<void*>(NPDrawingModelCoreGraphics));
99 } else {
100 LOG(ERROR) << "No Core Graphics support";
101 return false;
102 }
103
104 // Sanity check to see if Chromium supports the Cocoa event model.
105 NPBool supports_cocoa = false;
106 err = g_npnetscape_funcs->getvalue(instance_, NPNVsupportsCocoaBool,
107 &supports_cocoa);
108 if (err == NPERR_NO_ERROR && supports_cocoa) {
109 // Switch to Cocoa event model.
110 g_npnetscape_funcs->setvalue(instance_, NPPVpluginEventModel,
111 reinterpret_cast<void*>(NPEventModelCocoa));
112 } else {
113 LOG(ERROR) << "No Cocoa Event Model support";
114 return false;
115 }
116 #endif // OS_MACOSX
117 return true;
118 }
119
120 bool Save(NPSavedData** saved) {
121 return true;
122 }
123
124 NPObject* GetScriptableObject() {
125 if (!scriptable_object_) {
126 // Must be static. If it is a temporary, objects created by this
127 // method will fail in weird and wonderful ways later.
128 static NPClass npc_ref_object = {
129 NP_CLASS_STRUCT_VERSION,
130 &Allocate,
131 &Deallocate,
132 &Invalidate,
133 &HasMethod,
134 &Invoke,
135 &InvokeDefault,
136 &HasProperty,
137 &GetProperty,
138 &SetProperty,
139 &RemoveProperty,
140 &Enumerate,
141 NULL
142 };
143 scriptable_object_ = g_npnetscape_funcs->createobject(instance_,
144 &npc_ref_object);
145 }
146 return scriptable_object_;
147 }
148
149 private:
150 struct ScriptableNPObject : public NPObject {
151 HostNPScriptObject* scriptable_object;
152 };
153
154 static HostNPScriptObject* ScriptableFromObject(NPObject* obj) {
155 return reinterpret_cast<ScriptableNPObject*>(obj)->scriptable_object;
156 }
157
158 static NPObject* Allocate(NPP npp, NPClass* aClass) {
159 VLOG(2) << "static Allocate";
160 ScriptableNPObject* object =
161 reinterpret_cast<ScriptableNPObject*>(
162 g_npnetscape_funcs->memalloc(sizeof(ScriptableNPObject)));
163
164 object->_class = aClass;
165 object->referenceCount = 1;
166 object->scriptable_object = new HostNPScriptObject(npp, object);
167 if (!object->scriptable_object->Init()) {
168 Deallocate(object);
169 object = NULL;
170 }
171 return object;
172 }
173
174 static void Deallocate(NPObject* npobj) {
175 VLOG(2) << "static Deallocate";
176 if (npobj) {
177 Invalidate(npobj);
178 g_npnetscape_funcs->memfree(npobj);
179 }
180 }
181
182 static void Invalidate(NPObject* npobj) {
183 if (npobj) {
184 ScriptableNPObject* object = reinterpret_cast<ScriptableNPObject*>(npobj);
185 if (object->scriptable_object) {
186 delete object->scriptable_object;
187 object->scriptable_object = NULL;
188 }
189 }
190 }
191
192 static bool HasMethod(NPObject* obj, NPIdentifier method_name) {
193 VLOG(2) << "static HasMethod";
194 HostNPScriptObject* scriptable = ScriptableFromObject(obj);
195 if (!scriptable) return false;
196 std::string method_name_string = StringFromNPIdentifier(method_name);
197 if (method_name_string.empty())
198 return false;
199 return scriptable->HasMethod(method_name_string);
200 }
201
202 static bool InvokeDefault(NPObject* obj,
203 const NPVariant* args,
204 uint32_t argCount,
205 NPVariant* result) {
206 VLOG(2) << "static InvokeDefault";
207 HostNPScriptObject* scriptable = ScriptableFromObject(obj);
208 if (!scriptable) return false;
209 return scriptable->InvokeDefault(args, argCount, result);
210 }
211
212 static bool Invoke(NPObject* obj,
213 NPIdentifier method_name,
214 const NPVariant* args,
215 uint32_t argCount,
216 NPVariant* result) {
217 VLOG(2) << "static Invoke";
218 HostNPScriptObject* scriptable = ScriptableFromObject(obj);
219 if (!scriptable)
220 return false;
221 std::string method_name_string = StringFromNPIdentifier(method_name);
222 if (method_name_string.empty())
223 return false;
224 return scriptable->Invoke(method_name_string, args, argCount, result);
225 }
226
227 static bool HasProperty(NPObject* obj, NPIdentifier property_name) {
228 VLOG(2) << "static HasProperty";
229 HostNPScriptObject* scriptable = ScriptableFromObject(obj);
230 if (!scriptable) return false;
231 std::string property_name_string = StringFromNPIdentifier(property_name);
232 if (property_name_string.empty())
233 return false;
234 return scriptable->HasProperty(property_name_string);
235 }
236
237 static bool GetProperty(NPObject* obj,
238 NPIdentifier property_name,
239 NPVariant* result) {
240 VLOG(2) << "static GetProperty";
241 HostNPScriptObject* scriptable = ScriptableFromObject(obj);
242 if (!scriptable) return false;
243 std::string property_name_string = StringFromNPIdentifier(property_name);
244 if (property_name_string.empty())
245 return false;
246 return scriptable->GetProperty(property_name_string, result);
247 }
248
249 static bool SetProperty(NPObject* obj,
250 NPIdentifier property_name,
251 const NPVariant* value) {
252 VLOG(2) << "static SetProperty";
253 HostNPScriptObject* scriptable = ScriptableFromObject(obj);
254 if (!scriptable) return false;
255 std::string property_name_string = StringFromNPIdentifier(property_name);
256 if (property_name_string.empty())
257 return false;
258 return scriptable->SetProperty(property_name_string, value);
259 }
260
261 static bool RemoveProperty(NPObject* obj, NPIdentifier property_name) {
262 VLOG(2) << "static RemoveProperty";
263 HostNPScriptObject* scriptable = ScriptableFromObject(obj);
264 if (!scriptable) return false;
265 std::string property_name_string = StringFromNPIdentifier(property_name);
266 if (property_name_string.empty())
267 return false;
268 return scriptable->RemoveProperty(property_name_string);
269 }
270
271 static bool Enumerate(NPObject* obj,
272 NPIdentifier** value,
273 uint32_t* count) {
274 VLOG(2) << "static Enumerate";
275 HostNPScriptObject* scriptable = ScriptableFromObject(obj);
276 if (!scriptable) return false;
277 std::vector<std::string> values;
278 bool is_good = scriptable->Enumerate(&values);
279 if (is_good) {
280 *count = values.size();
281 *value = reinterpret_cast<NPIdentifier*>(
282 g_npnetscape_funcs->memalloc(sizeof(NPIdentifier) * (*count)));
283 for (uint32_t i = 0; i < *count; ++i) {
284 (*value)[i] =
285 g_npnetscape_funcs->getstringidentifier(values[i].c_str());
286 }
287 }
288 return is_good;
289 }
290
291 NPP instance_;
292 NPObject* scriptable_object_;
293 };
294
295 // Utility functions to map NPAPI Entry Points to C++ Objects.
296 HostNPPlugin* PluginFromInstance(NPP instance) {
297 return reinterpret_cast<HostNPPlugin*>(instance->pdata);
298 }
299
300 NPError CreatePlugin(NPMIMEType pluginType,
301 NPP instance,
302 uint16 mode,
303 int16 argc,
304 char** argn,
305 char** argv,
306 NPSavedData* saved) {
307 VLOG(2) << "CreatePlugin";
308 HostNPPlugin* plugin = new HostNPPlugin(instance, mode);
309 instance->pdata = plugin;
310 if (!plugin->Init(argc, argn, argv, saved)) {
311 delete plugin;
312 instance->pdata = NULL;
313 return NPERR_INVALID_PLUGIN_ERROR;
314 } else {
315 return NPERR_NO_ERROR;
316 }
317 }
318
319 NPError DestroyPlugin(NPP instance,
320 NPSavedData** save) {
321 VLOG(2) << "DestroyPlugin";
322 HostNPPlugin* plugin = PluginFromInstance(instance);
323 if (plugin) {
324 plugin->Save(save);
325 delete plugin;
326 instance->pdata = NULL;
327 return NPERR_NO_ERROR;
328 } else {
329 return NPERR_INVALID_PLUGIN_ERROR;
330 }
331 }
332
333 NPError GetValue(NPP instance, NPPVariable variable, void* value) {
334 switch(variable) {
335 default:
336 VLOG(2) << "GetValue - default " << variable;
337 return NPERR_GENERIC_ERROR;
338 case NPPVpluginNameString:
339 VLOG(2) << "GetValue - name string";
340 *reinterpret_cast<const char**>(value) = HOST_PLUGIN_NAME;
341 break;
342 case NPPVpluginDescriptionString:
343 VLOG(2) << "GetValue - description string";
344 *reinterpret_cast<const char**>(value) = HOST_PLUGIN_DESCRIPTION;
345 break;
346 case NPPVpluginNeedsXEmbed:
347 VLOG(2) << "GetValue - NeedsXEmbed";
348 *(static_cast<NPBool*>(value)) = true;
349 break;
350 case NPPVpluginScriptableNPObject:
351 VLOG(2) << "GetValue - scriptable object";
352 HostNPPlugin* plugin = PluginFromInstance(instance);
353 if (!plugin)
354 return NPERR_INVALID_PLUGIN_ERROR;
355 NPObject* scriptable_object = plugin->GetScriptableObject();
356 g_npnetscape_funcs->retainobject(scriptable_object);
357 *reinterpret_cast<NPObject**>(value) = scriptable_object;
358 break;
359 }
360 return NPERR_NO_ERROR;
361 }
362
363 NPError HandleEvent(NPP instance, void* ev) {
364 VLOG(2) << "HandleEvent";
365 return NPERR_NO_ERROR;
366 }
367
368 NPError SetWindow(NPP instance, NPWindow* pNPWindow) {
369 VLOG(2) << "SetWindow";
370 return NPERR_NO_ERROR;
371 }
372
373 } // namespace
374
375 #if defined(OS_WIN)
376 HMODULE g_hModule = NULL;
377
378 BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved) {
379 switch (dwReason) {
380 case DLL_PROCESS_ATTACH:
381 g_hModule = hModule;
382 DisableThreadLibraryCalls(hModule);
383 break;
384 case DLL_PROCESS_DETACH:
385 case DLL_THREAD_ATTACH:
386 case DLL_THREAD_DETACH:
387 break;
388 }
389 return TRUE;
390 }
391 #endif
392
393 // The actual required NPAPI Entry points
394
395 extern "C" {
396
397 EXPORT NPError API_CALL NP_GetEntryPoints(NPPluginFuncs* nppfuncs) {
398 VLOG(2) << "NP_GetEntryPoints";
399 nppfuncs->version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;
400 nppfuncs->newp = &CreatePlugin;
401 nppfuncs->destroy = &DestroyPlugin;
402 nppfuncs->getvalue = &GetValue;
403 nppfuncs->event = &HandleEvent;
404 nppfuncs->setwindow = &SetWindow;
405
406 return NPERR_NO_ERROR;
407 }
408
409 EXPORT NPError API_CALL NP_Initialize(NPNetscapeFuncs* npnetscape_funcs
410 #if defined(OS_POSIX) && !defined(OS_MACOSX)
411 , NPPluginFuncs* nppfuncs
412 #endif
413 ) {
414 VLOG(2) << "NP_Initialize";
415 if (g_at_exit_manager)
416 return NPERR_MODULE_LOAD_FAILED_ERROR;
417
418 if(npnetscape_funcs == NULL)
419 return NPERR_INVALID_FUNCTABLE_ERROR;
420
421 if(((npnetscape_funcs->version & 0xff00) >> 8) > NP_VERSION_MAJOR)
422 return NPERR_INCOMPATIBLE_VERSION_ERROR;
423
424 g_at_exit_manager = new base::AtExitManager;
425 g_npnetscape_funcs = npnetscape_funcs;
426 #if defined(OS_POSIX) && !defined(OS_MACOSX)
427 NP_GetEntryPoints(nppfuncs);
428 #endif
429 return NPERR_NO_ERROR;
430 }
431
432 EXPORT NPError API_CALL NP_Shutdown() {
433 VLOG(2) << "NP_Shutdown";
434 delete g_at_exit_manager;
435 g_at_exit_manager = NULL;
436 return NPERR_NO_ERROR;
437 }
438
439 #if defined(OS_POSIX) && !defined(OS_MACOSX)
440 EXPORT const char* API_CALL NP_GetMIMEDescription(void) {
441 VLOG(2) << "NP_GetMIMEDescription";
442 return STRINGIZE(HOST_PLUGIN_MIME_TYPE) ":"
443 HOST_PLUGIN_NAME ":"
444 HOST_PLUGIN_DESCRIPTION;
445 }
446
447 EXPORT NPError API_CALL NP_GetValue(void* npp,
448 NPPVariable variable,
449 void* value) {
450 return GetValue((NPP)npp, variable, value);
451 }
452 #endif
453
454 } // extern "C"
OLDNEW
« no previous file with comments | « remoting/host/disconnect_window_win.cc ('k') | remoting/host/host_plugin.def » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698