• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "content/test/plugin/plugin_client.h"
6 
7 #include "base/strings/string_util.h"
8 #include "content/test/plugin/plugin_execute_stream_javascript.h"
9 #include "content/test/plugin/plugin_test.h"
10 #include "content/test/plugin/plugin_test_factory.h"
11 
12 namespace NPAPIClient {
13 
14 NPNetscapeFuncs* PluginClient::host_functions_;
15 
GetEntryPoints(NPPluginFuncs * pFuncs)16 NPError PluginClient::GetEntryPoints(NPPluginFuncs* pFuncs) {
17   if (pFuncs == NULL)
18     return NPERR_INVALID_FUNCTABLE_ERROR;
19 
20   if (pFuncs->size < sizeof(NPPluginFuncs))
21     return NPERR_INVALID_FUNCTABLE_ERROR;
22 
23   pFuncs->version       = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;
24   pFuncs->newp          = NPP_New;
25   pFuncs->destroy       = NPP_Destroy;
26   pFuncs->setwindow     = NPP_SetWindow;
27   pFuncs->newstream     = NPP_NewStream;
28   pFuncs->destroystream = NPP_DestroyStream;
29   pFuncs->asfile        = NPP_StreamAsFile;
30   pFuncs->writeready    = NPP_WriteReady;
31   pFuncs->write         = NPP_Write;
32   pFuncs->print         = NPP_Print;
33   pFuncs->event         = NPP_HandleEvent;
34   pFuncs->urlnotify     = NPP_URLNotify;
35   pFuncs->getvalue      = NPP_GetValue;
36   pFuncs->setvalue      = NPP_SetValue;
37   pFuncs->javaClass     = NULL;
38   pFuncs->urlredirectnotify = NPP_URLRedirectNotify;
39   pFuncs->clearsitedata = NPP_ClearSiteData;
40 
41   return NPERR_NO_ERROR;
42 }
43 
Initialize(NPNetscapeFuncs * pFuncs)44 NPError PluginClient::Initialize(NPNetscapeFuncs* pFuncs) {
45   if (pFuncs == NULL) {
46     return NPERR_INVALID_FUNCTABLE_ERROR;
47   }
48 
49   if (static_cast<unsigned char>((pFuncs->version >> 8) & 0xff) >
50       NP_VERSION_MAJOR) {
51     return NPERR_INCOMPATIBLE_VERSION_ERROR;
52   }
53 
54 #if defined(OS_WIN)
55   // Check if we should crash.
56   HANDLE crash_event = CreateEvent(NULL, TRUE, FALSE, L"TestPluginCrashOnInit");
57   if (WaitForSingleObject(crash_event, 0) == WAIT_OBJECT_0) {
58     int *zero = NULL;
59     *zero = 0;
60   }
61   CloseHandle(crash_event);
62 #endif
63 
64   host_functions_ = pFuncs;
65 
66   return NPERR_NO_ERROR;
67 }
68 
Shutdown()69 NPError PluginClient::Shutdown() {
70   return NPERR_NO_ERROR;
71 }
72 
73 } // namespace NPAPIClient
74 
75 extern "C" {
NPP_New(NPMIMEType pluginType,NPP instance,uint16 mode,int16 argc,char * argn[],char * argv[],NPSavedData * saved)76 NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode,
77                 int16 argc, char* argn[], char* argv[], NPSavedData* saved) {
78   if (instance == NULL)
79     return NPERR_INVALID_INSTANCE_ERROR;
80 
81   NPAPIClient::PluginTest* new_test = NULL;
82   if (mode == NP_FULL) {
83     new_test = new::NPAPIClient::ExecuteStreamJavaScript(
84         instance, NPAPIClient::PluginClient::HostFunctions());
85   } else {
86     // We look at the test name requested via the plugin arguments.  We match
87     // that against a given test and try to instantiate it.
88 
89     // lookup the name parameter
90     std::string test_name;
91     for (int name_index = 0; name_index < argc; name_index++) {
92       if (base::strcasecmp(argn[name_index], "name") == 0) {
93         test_name = argv[name_index];
94         break;
95       }
96     }
97     if (test_name.empty())
98       return NPERR_GENERIC_ERROR;  // no name found
99 
100     new_test = NPAPIClient::CreatePluginTest(test_name,
101         instance, NPAPIClient::PluginClient::HostFunctions());
102     if (new_test == NULL) {
103       // If we don't have a test case for this, create a
104       // generic one which basically never fails.
105       LOG(WARNING) << "Unknown test name '" << test_name
106                    << "'; using default test.";
107       new_test = new NPAPIClient::PluginTest(instance,
108           NPAPIClient::PluginClient::HostFunctions());
109     }
110   }
111 
112 #if defined(OS_MACOSX)
113   // Set modern drawing and event models.
114   NPError drawing_ret = NPAPIClient::PluginClient::HostFunctions()->setvalue(
115       instance, NPPVpluginDrawingModel, (void*)NPDrawingModelCoreGraphics);
116   NPError event_ret = NPAPIClient::PluginClient::HostFunctions()->setvalue(
117       instance, NPPVpluginEventModel, (void*)NPEventModelCocoa);
118   if (drawing_ret != NPERR_NO_ERROR || event_ret != NPERR_NO_ERROR)
119     return NPERR_INCOMPATIBLE_VERSION_ERROR;
120 #endif
121 
122   NPError ret = new_test->New(mode, argc, (const char**)argn,
123       (const char**)argv, saved);
124   if ((ret == NPERR_NO_ERROR) && new_test->IsWindowless()) {
125     NPAPIClient::PluginClient::HostFunctions()->setvalue(
126           instance, NPPVpluginWindowBool, NULL);
127   }
128 
129   return ret;
130 }
131 
NPP_Destroy(NPP instance,NPSavedData ** save)132 NPError NPP_Destroy(NPP instance, NPSavedData** save) {
133   if (instance == NULL)
134     return NPERR_INVALID_INSTANCE_ERROR;
135 
136   NPAPIClient::PluginTest* plugin =
137       reinterpret_cast<NPAPIClient::PluginTest*>(instance->pdata);
138 
139   NPError rv = plugin->Destroy();
140   delete plugin;
141   return rv;
142 }
143 
NPP_SetWindow(NPP instance,NPWindow * pNPWindow)144 NPError NPP_SetWindow(NPP instance, NPWindow* pNPWindow) {
145   if (instance == NULL)
146     return NPERR_INVALID_INSTANCE_ERROR;
147 
148   NPAPIClient::PluginTest* plugin =
149       reinterpret_cast<NPAPIClient::PluginTest*>(instance->pdata);
150 
151   return plugin->SetWindow(pNPWindow);
152 }
153 
NPP_NewStream(NPP instance,NPMIMEType type,NPStream * stream,NPBool seekable,uint16 * stype)154 NPError NPP_NewStream(NPP instance, NPMIMEType type,
155                       NPStream* stream, NPBool seekable, uint16* stype) {
156   if (instance == NULL)
157     return NPERR_INVALID_INSTANCE_ERROR;
158 
159   NPAPIClient::PluginTest* plugin =
160       reinterpret_cast<NPAPIClient::PluginTest*>(instance->pdata);
161 
162   return plugin->NewStream(type, stream, seekable, stype);
163 }
164 
NPP_WriteReady(NPP instance,NPStream * stream)165 int32 NPP_WriteReady(NPP instance, NPStream *stream) {
166   if (instance == NULL)
167     return NPERR_INVALID_INSTANCE_ERROR;
168 
169   NPAPIClient::PluginTest* plugin =
170       reinterpret_cast<NPAPIClient::PluginTest*>(instance->pdata);
171 
172   return plugin->WriteReady(stream);
173 }
174 
NPP_Write(NPP instance,NPStream * stream,int32 offset,int32 len,void * buffer)175 int32 NPP_Write(NPP instance, NPStream *stream, int32 offset,
176                  int32 len, void *buffer) {
177   if (instance == NULL)
178     return NPERR_INVALID_INSTANCE_ERROR;
179 
180   NPAPIClient::PluginTest* plugin =
181       reinterpret_cast<NPAPIClient::PluginTest*>(instance->pdata);
182 
183   return plugin->Write(stream, offset, len, buffer);
184 }
185 
NPP_DestroyStream(NPP instance,NPStream * stream,NPError reason)186 NPError NPP_DestroyStream(NPP instance, NPStream *stream, NPError reason) {
187   if (instance == NULL)
188     return NPERR_INVALID_INSTANCE_ERROR;
189 
190   NPAPIClient::PluginTest* plugin =
191       reinterpret_cast<NPAPIClient::PluginTest*>(instance->pdata);
192 
193   return plugin->DestroyStream(stream, reason);
194 }
195 
NPP_StreamAsFile(NPP instance,NPStream * stream,const char * fname)196 void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname) {
197   if (instance == NULL)
198     return;
199 
200   NPAPIClient::PluginTest* plugin =
201       reinterpret_cast<NPAPIClient::PluginTest*>(instance->pdata);
202 
203   return plugin->StreamAsFile(stream, fname);
204 }
205 
NPP_Print(NPP instance,NPPrint * printInfo)206 void NPP_Print(NPP instance, NPPrint* printInfo) {
207   if (instance == NULL)
208     return;
209 
210   // XXXMB - do work here.
211 }
212 
NPP_URLNotify(NPP instance,const char * url,NPReason reason,void * notifyData)213 void NPP_URLNotify(NPP instance, const char* url, NPReason reason,
214                    void* notifyData) {
215   if (instance == NULL)
216     return;
217 
218   NPAPIClient::PluginTest* plugin =
219       reinterpret_cast<NPAPIClient::PluginTest*>(instance->pdata);
220 
221   return plugin->URLNotify(url, reason, notifyData);
222 }
223 
NPP_GetValue(NPP instance,NPPVariable variable,void * value)224 NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value) {
225   if (instance == NULL)
226     return NPERR_INVALID_INSTANCE_ERROR;
227 
228   if (variable == NPPVpluginNeedsXEmbed) {
229     *static_cast<NPBool*>(value) = 1;
230     return NPERR_NO_ERROR;
231   }
232 
233   // XXXMB - do work here.
234   return NPERR_GENERIC_ERROR;
235 }
236 
NPP_SetValue(NPP instance,NPNVariable variable,void * value)237 NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value) {
238   if (instance == NULL)
239     return NPERR_INVALID_INSTANCE_ERROR;
240 
241   // XXXMB - do work here.
242   return NPERR_GENERIC_ERROR;
243 }
244 
NPP_HandleEvent(NPP instance,void * event)245 int16 NPP_HandleEvent(NPP instance, void* event) {
246   if (instance == NULL)
247     return 0;
248 
249   NPAPIClient::PluginTest* plugin =
250       reinterpret_cast<NPAPIClient::PluginTest*>(instance->pdata);
251 
252   return plugin->HandleEvent(event);
253 }
254 
NPP_URLRedirectNotify(NPP instance,const char * url,int32_t status,void * notify_data)255 void NPP_URLRedirectNotify(NPP instance, const char* url, int32_t status,
256                            void* notify_data) {
257   if (instance) {
258     NPAPIClient::PluginTest* plugin =
259         reinterpret_cast<NPAPIClient::PluginTest*>(instance->pdata);
260     plugin->URLRedirectNotify(url, status, notify_data);
261   }
262 }
263 
NPP_ClearSiteData(const char * site,uint64 flags,uint64 max_age)264 NPError NPP_ClearSiteData(const char* site,
265                           uint64 flags,
266                           uint64 max_age) {
267   VLOG(0) << "NPP_ClearSiteData called";
268   return NPERR_NO_ERROR;
269 }
270 } // extern "C"
271