Fix occasional crash in remote commands code
[chromium-blink-merge.git] / ppapi / cpp / instance.cc
blob74b93216729dfe7d1bc5bb6ec09e93f7c72f8bbf
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.
5 #include "ppapi/cpp/instance.h"
7 #include "ppapi/c/pp_errors.h"
8 #include "ppapi/c/ppb_console.h"
9 #include "ppapi/c/ppb_input_event.h"
10 #include "ppapi/c/ppb_instance.h"
11 #include "ppapi/c/ppb_messaging.h"
12 #include "ppapi/c/ppp_message_handler.h"
13 #include "ppapi/cpp/compositor.h"
14 #include "ppapi/cpp/graphics_2d.h"
15 #include "ppapi/cpp/graphics_3d.h"
16 #include "ppapi/cpp/image_data.h"
17 #include "ppapi/cpp/instance_handle.h"
18 #include "ppapi/cpp/logging.h"
19 #include "ppapi/cpp/message_handler.h"
20 #include "ppapi/cpp/message_loop.h"
21 #include "ppapi/cpp/module.h"
22 #include "ppapi/cpp/module_impl.h"
23 #include "ppapi/cpp/point.h"
24 #include "ppapi/cpp/resource.h"
25 #include "ppapi/cpp/var.h"
26 #include "ppapi/cpp/view.h"
28 namespace pp {
30 namespace {
32 template <> const char* interface_name<PPB_Console_1_0>() {
33 return PPB_CONSOLE_INTERFACE_1_0;
36 template <> const char* interface_name<PPB_InputEvent_1_0>() {
37 return PPB_INPUT_EVENT_INTERFACE_1_0;
40 template <> const char* interface_name<PPB_Instance_1_0>() {
41 return PPB_INSTANCE_INTERFACE_1_0;
44 template <> const char* interface_name<PPB_Messaging_1_0>() {
45 return PPB_MESSAGING_INTERFACE_1_0;
48 template <> const char* interface_name<PPB_Messaging_1_2>() {
49 return PPB_MESSAGING_INTERFACE_1_2;
52 // PPP_MessageHandler implementation -------------------------------------------
53 void HandleMessage(PP_Instance pp_instance,
54 void* user_data,
55 const PP_Var* var) {
56 MessageHandler* message_handler = static_cast<MessageHandler*>(user_data);
57 message_handler->HandleMessage(InstanceHandle(pp_instance), Var(*var));
60 void HandleBlockingMessage(PP_Instance pp_instance,
61 void* user_data,
62 const PP_Var* var,
63 PP_Var* result) {
64 MessageHandler* message_handler = static_cast<MessageHandler*>(user_data);
65 pp::Var result_var =
66 message_handler->HandleBlockingMessage(InstanceHandle(pp_instance),
67 Var(*var));
68 *result = result_var.Detach();
71 void Destroy(PP_Instance pp_instance, void* user_data) {
72 MessageHandler* message_handler = static_cast<MessageHandler*>(user_data);
73 message_handler->WasUnregistered(InstanceHandle(pp_instance));
76 static PPP_MessageHandler_0_2 message_handler_if = {
77 &HandleMessage, &HandleBlockingMessage, &Destroy
80 } // namespace
82 Instance::Instance(PP_Instance instance) : pp_instance_(instance) {
85 Instance::~Instance() {
88 bool Instance::Init(uint32_t /*argc*/, const char* /*argn*/[],
89 const char* /*argv*/[]) {
90 return true;
93 void Instance::DidChangeView(const View& view) {
94 // Call the deprecated version for source backwards-compat.
95 DidChangeView(view.GetRect(), view.GetClipRect());
98 void Instance::DidChangeView(const pp::Rect& /*position*/,
99 const pp::Rect& /*clip*/) {
102 void Instance::DidChangeFocus(bool /*has_focus*/) {
106 bool Instance::HandleDocumentLoad(const URLLoader& /*url_loader*/) {
107 return false;
110 bool Instance::HandleInputEvent(const InputEvent& /*event*/) {
111 return false;
114 void Instance::HandleMessage(const Var& /*message*/) {
115 return;
118 bool Instance::BindGraphics(const Graphics2D& graphics) {
119 if (!has_interface<PPB_Instance_1_0>())
120 return false;
121 return PP_ToBool(get_interface<PPB_Instance_1_0>()->BindGraphics(
122 pp_instance(), graphics.pp_resource()));
125 bool Instance::BindGraphics(const Graphics3D& graphics) {
126 if (!has_interface<PPB_Instance_1_0>())
127 return false;
128 return PP_ToBool(get_interface<PPB_Instance_1_0>()->BindGraphics(
129 pp_instance(), graphics.pp_resource()));
132 bool Instance::BindGraphics(const Compositor& compositor) {
133 if (!has_interface<PPB_Instance_1_0>())
134 return false;
135 return PP_ToBool(get_interface<PPB_Instance_1_0>()->BindGraphics(
136 pp_instance(), compositor.pp_resource()));
139 bool Instance::IsFullFrame() {
140 if (!has_interface<PPB_Instance_1_0>())
141 return false;
142 return PP_ToBool(get_interface<PPB_Instance_1_0>()->IsFullFrame(
143 pp_instance()));
146 int32_t Instance::RequestInputEvents(uint32_t event_classes) {
147 if (!has_interface<PPB_InputEvent_1_0>())
148 return PP_ERROR_NOINTERFACE;
149 return get_interface<PPB_InputEvent_1_0>()->RequestInputEvents(pp_instance(),
150 event_classes);
153 int32_t Instance::RequestFilteringInputEvents(uint32_t event_classes) {
154 if (!has_interface<PPB_InputEvent_1_0>())
155 return PP_ERROR_NOINTERFACE;
156 return get_interface<PPB_InputEvent_1_0>()->RequestFilteringInputEvents(
157 pp_instance(), event_classes);
160 void Instance::ClearInputEventRequest(uint32_t event_classes) {
161 if (!has_interface<PPB_InputEvent_1_0>())
162 return;
163 get_interface<PPB_InputEvent_1_0>()->ClearInputEventRequest(pp_instance(),
164 event_classes);
167 void Instance::PostMessage(const Var& message) {
168 if (has_interface<PPB_Messaging_1_2>()) {
169 get_interface<PPB_Messaging_1_2>()->PostMessage(pp_instance(),
170 message.pp_var());
171 } else if (has_interface<PPB_Messaging_1_0>()) {
172 get_interface<PPB_Messaging_1_0>()->PostMessage(pp_instance(),
173 message.pp_var());
177 int32_t Instance::RegisterMessageHandler(MessageHandler* message_handler,
178 const MessageLoop& message_loop) {
179 if (!has_interface<PPB_Messaging_1_2>())
180 return PP_ERROR_NOTSUPPORTED;
181 return get_interface<PPB_Messaging_1_2>()->RegisterMessageHandler(
182 pp_instance(),
183 message_handler,
184 &message_handler_if,
185 message_loop.pp_resource());
188 void Instance::UnregisterMessageHandler() {
189 if (!has_interface<PPB_Messaging_1_2>())
190 return;
191 get_interface<PPB_Messaging_1_2>()->UnregisterMessageHandler(pp_instance());
194 void Instance::LogToConsole(PP_LogLevel level, const Var& value) {
195 if (!has_interface<PPB_Console_1_0>())
196 return;
197 get_interface<PPB_Console_1_0>()->Log(
198 pp_instance(), level, value.pp_var());
201 void Instance::LogToConsoleWithSource(PP_LogLevel level,
202 const Var& source,
203 const Var& value) {
204 if (!has_interface<PPB_Console_1_0>())
205 return;
206 get_interface<PPB_Console_1_0>()->LogWithSource(
207 pp_instance(), level, source.pp_var(), value.pp_var());
210 void Instance::AddPerInstanceObject(const std::string& interface_name,
211 void* object) {
212 // Ensure we're not trying to register more than one object per interface
213 // type. Otherwise, we'll get confused in GetPerInstanceObject.
214 PP_DCHECK(interface_name_to_objects_.find(interface_name) ==
215 interface_name_to_objects_.end());
216 interface_name_to_objects_[interface_name] = object;
219 void Instance::RemovePerInstanceObject(const std::string& interface_name,
220 void* object) {
221 InterfaceNameToObjectMap::iterator found = interface_name_to_objects_.find(
222 interface_name);
223 if (found == interface_name_to_objects_.end()) {
224 // Attempting to unregister an object that doesn't exist or was already
225 // unregistered.
226 PP_DCHECK(false);
227 return;
230 // Validate that we're removing the object we thing we are.
231 PP_DCHECK(found->second == object);
232 (void)object; // Prevent warning in release mode.
234 interface_name_to_objects_.erase(found);
237 // static
238 void Instance::RemovePerInstanceObject(const InstanceHandle& instance,
239 const std::string& interface_name,
240 void* object) {
241 // TODO(brettw) assert we're on the main thread.
242 Instance* that = Module::Get()->InstanceForPPInstance(instance.pp_instance());
243 if (!that)
244 return;
245 that->RemovePerInstanceObject(interface_name, object);
248 // static
249 void* Instance::GetPerInstanceObject(PP_Instance instance,
250 const std::string& interface_name) {
251 Instance* that = Module::Get()->InstanceForPPInstance(instance);
252 if (!that)
253 return NULL;
254 InterfaceNameToObjectMap::iterator found =
255 that->interface_name_to_objects_.find(interface_name);
256 if (found == that->interface_name_to_objects_.end())
257 return NULL;
258 return found->second;
261 } // namespace pp