Home | History | Annotate | Download | only in plugin
      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 
     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 
     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 
     69 NPError PluginClient::Shutdown() {
     70   return NPERR_NO_ERROR;
     71 }
     72 
     73 } // namespace NPAPIClient
     74 
     75 extern "C" {
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    206 void NPP_Print(NPP instance, NPPrint* printInfo) {
    207   if (instance == NULL)
    208     return;
    209 
    210   // XXXMB - do work here.
    211 }
    212 
    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 
    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 
    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 
    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 
    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 
    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