
This fixes a presubmit error: ** Presubmit ERRORS ** Unversioned PPB interface references found in PPAPI C++ wrappers: *************** ppapi/cpp/module.cc *************** Change-Id: Ic9ff58e2ce8ea591a507c75498b0be8bccb3a8aa Reviewed-on: https://chromium-review.googlesource.com/1157170 Reviewed-by: Bill Budge <bbudge@chromium.org> Commit-Queue: Henrique Nakashima <hnakashima@chromium.org> Cr-Commit-Position: refs/heads/master@{#579616}
220 lines
7.2 KiB
C++
220 lines
7.2 KiB
C++
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
// Note that the single accessor, Module::Get(), is not actually implemented
|
|
// in this file. This is an intentional hook that allows users of ppapi's
|
|
// C++ wrapper objects to provide different semantics for how the singleton
|
|
// object is accessed.
|
|
//
|
|
// In general, users of ppapi will also link in ppp_entrypoints.cc, which
|
|
// provides a simple default implementation of Module::Get().
|
|
//
|
|
// A notable exception where the default ppp_entrypoints will not work is
|
|
// when implementing "internal plugins" that are statically linked into the
|
|
// browser. In this case, the process may actually have multiple Modules
|
|
// loaded at once making a traditional "singleton" unworkable. To get around
|
|
// this, the users of ppapi need to get creative about how to properly
|
|
// implement the Module::Get() so that ppapi's C++ wrappers can find the
|
|
// right Module object. One example solution is to use thread local storage
|
|
// to change the Module* returned based on which thread is invoking the
|
|
// function. Leaving Module::Get() unimplemented provides a hook for
|
|
// implementing such behavior.
|
|
|
|
#include "ppapi/cpp/module.h"
|
|
|
|
#include <string.h>
|
|
|
|
#include "ppapi/c/pp_instance.h"
|
|
#include "ppapi/c/pp_var.h"
|
|
#include "ppapi/c/ppp_input_event.h"
|
|
#include "ppapi/c/ppp_instance.h"
|
|
#include "ppapi/c/ppp_messaging.h"
|
|
#include "ppapi/cpp/input_event.h"
|
|
#include "ppapi/cpp/instance.h"
|
|
#include "ppapi/cpp/rect.h"
|
|
#include "ppapi/cpp/resource.h"
|
|
#include "ppapi/cpp/url_loader.h"
|
|
#include "ppapi/cpp/var.h"
|
|
#include "ppapi/cpp/view.h"
|
|
|
|
namespace pp {
|
|
|
|
// PPP_InputEvent implementation -----------------------------------------------
|
|
|
|
PP_Bool InputEvent_HandleEvent(PP_Instance pp_instance, PP_Resource resource) {
|
|
Module* module_singleton = Module::Get();
|
|
if (!module_singleton)
|
|
return PP_FALSE;
|
|
Instance* instance = module_singleton->InstanceForPPInstance(pp_instance);
|
|
if (!instance)
|
|
return PP_FALSE;
|
|
|
|
return PP_FromBool(instance->HandleInputEvent(InputEvent(resource)));
|
|
}
|
|
|
|
const PPP_InputEvent input_event_interface = {
|
|
&InputEvent_HandleEvent
|
|
};
|
|
|
|
// PPP_Instance implementation -------------------------------------------------
|
|
|
|
PP_Bool Instance_DidCreate(PP_Instance pp_instance,
|
|
uint32_t argc,
|
|
const char* argn[],
|
|
const char* argv[]) {
|
|
Module* module_singleton = Module::Get();
|
|
if (!module_singleton)
|
|
return PP_FALSE;
|
|
|
|
Instance* instance = module_singleton->CreateInstance(pp_instance);
|
|
if (!instance)
|
|
return PP_FALSE;
|
|
module_singleton->current_instances_[pp_instance] = instance;
|
|
return PP_FromBool(instance->Init(argc, argn, argv));
|
|
}
|
|
|
|
void Instance_DidDestroy(PP_Instance instance) {
|
|
Module* module_singleton = Module::Get();
|
|
if (!module_singleton)
|
|
return;
|
|
Module::InstanceMap::iterator found =
|
|
module_singleton->current_instances_.find(instance);
|
|
if (found == module_singleton->current_instances_.end())
|
|
return;
|
|
|
|
// Remove it from the map before deleting to try to catch reentrancy.
|
|
Instance* obj = found->second;
|
|
module_singleton->current_instances_.erase(found);
|
|
delete obj;
|
|
}
|
|
|
|
void Instance_DidChangeView(PP_Instance pp_instance,
|
|
PP_Resource view_resource) {
|
|
Module* module_singleton = Module::Get();
|
|
if (!module_singleton)
|
|
return;
|
|
Instance* instance = module_singleton->InstanceForPPInstance(pp_instance);
|
|
if (!instance)
|
|
return;
|
|
instance->DidChangeView(View(view_resource));
|
|
}
|
|
|
|
void Instance_DidChangeFocus(PP_Instance pp_instance, PP_Bool has_focus) {
|
|
Module* module_singleton = Module::Get();
|
|
if (!module_singleton)
|
|
return;
|
|
Instance* instance = module_singleton->InstanceForPPInstance(pp_instance);
|
|
if (!instance)
|
|
return;
|
|
instance->DidChangeFocus(PP_ToBool(has_focus));
|
|
}
|
|
|
|
PP_Bool Instance_HandleDocumentLoad(PP_Instance pp_instance,
|
|
PP_Resource pp_url_loader) {
|
|
Module* module_singleton = Module::Get();
|
|
if (!module_singleton)
|
|
return PP_FALSE;
|
|
Instance* instance = module_singleton->InstanceForPPInstance(pp_instance);
|
|
if (!instance)
|
|
return PP_FALSE;
|
|
return PP_FromBool(instance->HandleDocumentLoad(URLLoader(pp_url_loader)));
|
|
}
|
|
|
|
static PPP_Instance instance_interface = {
|
|
&Instance_DidCreate,
|
|
&Instance_DidDestroy,
|
|
&Instance_DidChangeView,
|
|
&Instance_DidChangeFocus,
|
|
&Instance_HandleDocumentLoad
|
|
};
|
|
|
|
// PPP_Messaging implementation ------------------------------------------------
|
|
|
|
void Messaging_HandleMessage(PP_Instance pp_instance, PP_Var var) {
|
|
Module* module_singleton = Module::Get();
|
|
if (!module_singleton)
|
|
return;
|
|
Instance* instance = module_singleton->InstanceForPPInstance(pp_instance);
|
|
if (!instance)
|
|
return;
|
|
instance->HandleMessage(Var(PASS_REF, var));
|
|
}
|
|
|
|
static PPP_Messaging instance_messaging_interface = {
|
|
&Messaging_HandleMessage
|
|
};
|
|
|
|
// Module ----------------------------------------------------------------------
|
|
|
|
Module::Module() : pp_module_(0), get_browser_interface_(NULL), core_(NULL) {
|
|
}
|
|
|
|
Module::~Module() {
|
|
delete core_;
|
|
core_ = NULL;
|
|
}
|
|
|
|
bool Module::Init() {
|
|
return true;
|
|
}
|
|
|
|
const void* Module::GetPluginInterface(const char* interface_name) {
|
|
if (strcmp(interface_name, PPP_INPUT_EVENT_INTERFACE) == 0)
|
|
return &input_event_interface;
|
|
if (strcmp(interface_name, PPP_INSTANCE_INTERFACE) == 0)
|
|
return &instance_interface;
|
|
if (strcmp(interface_name, PPP_MESSAGING_INTERFACE) == 0)
|
|
return &instance_messaging_interface;
|
|
|
|
// Now see if anything was dynamically registered.
|
|
InterfaceMap::const_iterator found = additional_interfaces_.find(
|
|
std::string(interface_name));
|
|
if (found != additional_interfaces_.end())
|
|
return found->second;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
const void* Module::GetBrowserInterface(const char* interface_name) {
|
|
return get_browser_interface_(interface_name);
|
|
}
|
|
|
|
Instance* Module::InstanceForPPInstance(PP_Instance instance) {
|
|
InstanceMap::iterator found = current_instances_.find(instance);
|
|
if (found == current_instances_.end())
|
|
return NULL;
|
|
return found->second;
|
|
}
|
|
|
|
void Module::AddPluginInterface(const std::string& interface_name,
|
|
const void* vtable) {
|
|
// Verify that we're not trying to register an interface that's already
|
|
// handled, and if it is, that we're re-registering with the same vtable.
|
|
// Calling GetPluginInterface rather than looking it up in the map allows
|
|
// us to also catch "internal" ones in addition to just previously added ones.
|
|
const void* existing_interface = GetPluginInterface(interface_name.c_str());
|
|
if (existing_interface) {
|
|
PP_DCHECK(vtable == existing_interface);
|
|
return;
|
|
}
|
|
additional_interfaces_[interface_name] = vtable;
|
|
}
|
|
|
|
bool Module::InternalInit(PP_Module mod,
|
|
PPB_GetInterface get_browser_interface) {
|
|
pp_module_ = mod;
|
|
get_browser_interface_ = get_browser_interface;
|
|
|
|
// Get the core interface which we require to run.
|
|
const PPB_Core* core = reinterpret_cast<const PPB_Core*>(
|
|
GetBrowserInterface(PPB_CORE_INTERFACE_1_0));
|
|
if (!core)
|
|
return false;
|
|
core_ = new Core(core);
|
|
|
|
return Init();
|
|
}
|
|
|
|
} // namespace pp
|