Port Android relocation packer to chromium build
[chromium-blink-merge.git] / ppapi / proxy / device_enumeration_resource_helper.cc
blob32a4e1db9840ea3156151769a255dec452e0ed59
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/proxy/device_enumeration_resource_helper.h"
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "ipc/ipc_message.h"
11 #include "ipc/ipc_message_macros.h"
12 #include "ppapi/c/pp_array_output.h"
13 #include "ppapi/c/pp_errors.h"
14 #include "ppapi/proxy/dispatch_reply_message.h"
15 #include "ppapi/proxy/plugin_resource.h"
16 #include "ppapi/proxy/ppapi_messages.h"
17 #include "ppapi/proxy/resource_message_params.h"
18 #include "ppapi/shared_impl/array_writer.h"
19 #include "ppapi/shared_impl/ppapi_globals.h"
20 #include "ppapi/shared_impl/ppb_device_ref_shared.h"
21 #include "ppapi/shared_impl/proxy_lock.h"
22 #include "ppapi/shared_impl/resource_tracker.h"
23 #include "ppapi/shared_impl/tracked_callback.h"
25 namespace ppapi {
26 namespace proxy {
28 DeviceEnumerationResourceHelper::DeviceEnumerationResourceHelper(
29 PluginResource* owner)
30 : owner_(owner),
31 pending_enumerate_devices_(false),
32 monitor_callback_id_(0),
33 monitor_user_data_(NULL) {
36 DeviceEnumerationResourceHelper::~DeviceEnumerationResourceHelper() {
39 int32_t DeviceEnumerationResourceHelper::EnumerateDevices(
40 const PP_ArrayOutput& output,
41 scoped_refptr<TrackedCallback> callback) {
42 if (pending_enumerate_devices_)
43 return PP_ERROR_INPROGRESS;
45 pending_enumerate_devices_ = true;
46 PpapiHostMsg_DeviceEnumeration_EnumerateDevices msg;
47 owner_->Call<PpapiPluginMsg_DeviceEnumeration_EnumerateDevicesReply>(
48 PluginResource::RENDERER, msg,
49 base::Bind(
50 &DeviceEnumerationResourceHelper::OnPluginMsgEnumerateDevicesReply,
51 AsWeakPtr(), output, callback));
52 return PP_OK_COMPLETIONPENDING;
55 int32_t DeviceEnumerationResourceHelper::EnumerateDevicesSync(
56 const PP_ArrayOutput& output) {
57 std::vector<DeviceRefData> devices;
58 int32_t result =
59 owner_->SyncCall<PpapiPluginMsg_DeviceEnumeration_EnumerateDevicesReply>(
60 PluginResource::RENDERER,
61 PpapiHostMsg_DeviceEnumeration_EnumerateDevices(),
62 &devices);
64 if (result == PP_OK)
65 result = WriteToArrayOutput(devices, output);
67 return result;
70 int32_t DeviceEnumerationResourceHelper::MonitorDeviceChange(
71 PP_MonitorDeviceChangeCallback callback,
72 void* user_data) {
73 monitor_callback_id_++;
74 monitor_user_data_ = user_data;
75 if (callback) {
76 monitor_callback_.reset(
77 ThreadAwareCallback<PP_MonitorDeviceChangeCallback>::Create(callback));
78 if (!monitor_callback_.get())
79 return PP_ERROR_NO_MESSAGE_LOOP;
81 owner_->Post(PluginResource::RENDERER,
82 PpapiHostMsg_DeviceEnumeration_MonitorDeviceChange(
83 monitor_callback_id_));
84 } else {
85 monitor_callback_.reset(NULL);
87 owner_->Post(PluginResource::RENDERER,
88 PpapiHostMsg_DeviceEnumeration_StopMonitoringDeviceChange());
90 return PP_OK;
93 bool DeviceEnumerationResourceHelper::HandleReply(
94 const ResourceMessageReplyParams& params,
95 const IPC::Message& msg) {
96 PPAPI_BEGIN_MESSAGE_MAP(DeviceEnumerationResourceHelper, msg)
97 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL(
98 PpapiPluginMsg_DeviceEnumeration_NotifyDeviceChange,
99 OnPluginMsgNotifyDeviceChange)
100 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL_UNHANDLED(return false)
101 PPAPI_END_MESSAGE_MAP()
103 return true;
106 void DeviceEnumerationResourceHelper::LastPluginRefWasDeleted() {
107 // Make sure that no further notifications are sent to the plugin.
108 monitor_callback_id_++;
109 monitor_callback_.reset(NULL);
110 monitor_user_data_ = NULL;
112 // There is no need to do anything with pending callback of
113 // EnumerateDevices(), because OnPluginMsgEnumerateDevicesReply*() will handle
114 // that properly.
117 void DeviceEnumerationResourceHelper::OnPluginMsgEnumerateDevicesReply(
118 const PP_ArrayOutput& output,
119 scoped_refptr<TrackedCallback> callback,
120 const ResourceMessageReplyParams& params,
121 const std::vector<DeviceRefData>& devices) {
122 pending_enumerate_devices_ = false;
124 // We shouldn't access |output| if the callback has been called, which is
125 // possible if the last plugin reference to the corresponding resource has
126 // gone away, and the callback has been aborted.
127 if (!TrackedCallback::IsPending(callback))
128 return;
130 int32_t result = params.result();
131 if (result == PP_OK)
132 result = WriteToArrayOutput(devices, output);
134 callback->Run(result);
137 void DeviceEnumerationResourceHelper::OnPluginMsgNotifyDeviceChange(
138 const ResourceMessageReplyParams& /* params */,
139 uint32_t callback_id,
140 const std::vector<DeviceRefData>& devices) {
141 if (monitor_callback_id_ != callback_id) {
142 // A new callback or NULL has been set.
143 return;
146 CHECK(monitor_callback_.get());
148 scoped_ptr<PP_Resource[]> elements;
149 uint32_t size = static_cast<uint32_t>(devices.size());
150 if (size > 0) {
151 elements.reset(new PP_Resource[size]);
152 for (size_t index = 0; index < size; ++index) {
153 PPB_DeviceRef_Shared* device_object = new PPB_DeviceRef_Shared(
154 OBJECT_IS_PROXY, owner_->pp_instance(), devices[index]);
155 elements[index] = device_object->GetReference();
159 monitor_callback_->RunOnTargetThread(monitor_user_data_, size,
160 elements.get());
161 for (size_t index = 0; index < size; ++index)
162 PpapiGlobals::Get()->GetResourceTracker()->ReleaseResource(elements[index]);
165 int32_t DeviceEnumerationResourceHelper::WriteToArrayOutput(
166 const std::vector<DeviceRefData>& devices,
167 const PP_ArrayOutput& output) {
168 ArrayWriter writer(output);
169 if (!writer.is_valid())
170 return PP_ERROR_BADARGUMENT;
172 std::vector<scoped_refptr<Resource> > device_resources;
173 for (size_t i = 0; i < devices.size(); ++i) {
174 device_resources.push_back(new PPB_DeviceRef_Shared(
175 OBJECT_IS_PROXY, owner_->pp_instance(), devices[i]));
177 if (!writer.StoreResourceVector(device_resources))
178 return PP_ERROR_FAILED;
180 return PP_OK;
183 } // namespace proxy
184 } // namespace ppapi