Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(139)

Side by Side Diff: ppapi/proxy/device_enumeration_resource_helper.cc

Issue 11411047: Introduce PPB_AudioInput_Dev v0.3 and refactor the device enumeration code: (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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 "ppapi/proxy/device_enumeration_resource_helper.h"
6
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "ipc/ipc_message.h"
10 #include "ipc/ipc_message_macros.h"
11 #include "ppapi/c/pp_array_output.h"
12 #include "ppapi/c/pp_errors.h"
13 #include "ppapi/proxy/dispatch_reply_message.h"
14 #include "ppapi/proxy/plugin_resource.h"
15 #include "ppapi/proxy/ppapi_messages.h"
16 #include "ppapi/proxy/resource_message_params.h"
17 #include "ppapi/shared_impl/array_writer.h"
18 #include "ppapi/shared_impl/ppapi_globals.h"
19 #include "ppapi/shared_impl/ppb_device_ref_shared.h"
20 #include "ppapi/shared_impl/proxy_lock.h"
21 #include "ppapi/shared_impl/resource_tracker.h"
22 #include "ppapi/shared_impl/tracked_callback.h"
23
24 namespace ppapi {
25 namespace proxy {
26
27 DeviceEnumerationResourceHelper::DeviceEnumerationResourceHelper(
28 PluginResource* owner)
29 : owner_(owner),
30 pending_enumerate_devices_(false),
31 monitor_callback_id_(0),
32 monitor_callback_(NULL),
33 monitor_user_data_(NULL) {
34 }
35
36 DeviceEnumerationResourceHelper::~DeviceEnumerationResourceHelper() {
37 }
38
39 int32_t DeviceEnumerationResourceHelper::EnumerateDevices0_2(
40 PP_Resource* devices,
41 scoped_refptr<TrackedCallback> callback) {
42 if (pending_enumerate_devices_)
43 return PP_ERROR_INPROGRESS;
44 if (!devices)
45 return PP_ERROR_BADARGUMENT;
46
47 pending_enumerate_devices_ = true;
48 PpapiHostMsg_DeviceEnumeration_EnumerateDevices msg;
49 owner_->Call<PpapiPluginMsg_DeviceEnumeration_EnumerateDevicesReply>(
50 PluginResource::RENDERER, msg,
51 base::Bind(
52 &DeviceEnumerationResourceHelper::OnPluginMsgEnumerateDevicesReply0_2,
53 AsWeakPtr(), devices, callback));
54 return PP_OK_COMPLETIONPENDING;
55 }
56
57 int32_t DeviceEnumerationResourceHelper::EnumerateDevices(
58 const PP_ArrayOutput& output,
59 scoped_refptr<TrackedCallback> callback) {
60 if (pending_enumerate_devices_)
61 return PP_ERROR_INPROGRESS;
62
63 pending_enumerate_devices_ = true;
64 PpapiHostMsg_DeviceEnumeration_EnumerateDevices msg;
65 owner_->Call<PpapiPluginMsg_DeviceEnumeration_EnumerateDevicesReply>(
66 PluginResource::RENDERER, msg,
67 base::Bind(
68 &DeviceEnumerationResourceHelper::OnPluginMsgEnumerateDevicesReply,
69 AsWeakPtr(), output, callback));
70 return PP_OK_COMPLETIONPENDING;
71 }
72
73 int32_t DeviceEnumerationResourceHelper::MonitorDeviceChange(
74 PP_MonitorDeviceChangeCallback callback,
75 void* user_data) {
76 monitor_callback_id_++;
77 monitor_callback_ = callback;
78 monitor_user_data_ = user_data;
79
80 if (callback) {
81 owner_->Post(PluginResource::RENDERER,
82 PpapiHostMsg_DeviceEnumeration_MonitorDeviceChange(
83 monitor_callback_id_));
84 } else {
85 owner_->Post(PluginResource::RENDERER,
86 PpapiHostMsg_DeviceEnumeration_StopMonitoringDeviceChange());
87 }
88 return PP_OK;
89 }
90
91 bool DeviceEnumerationResourceHelper::HandleReply(
92 const ResourceMessageReplyParams& params,
93 const IPC::Message& msg) {
94 IPC_BEGIN_MESSAGE_MAP(DeviceEnumerationResourceHelper, msg)
95 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL(
96 PpapiPluginMsg_DeviceEnumeration_NotifyDeviceChange,
97 OnPluginMsgNotifyDeviceChange)
98 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL_UNHANDLED(return false)
99 IPC_END_MESSAGE_MAP()
100
101 return true;
102 }
103
104 void DeviceEnumerationResourceHelper::LastPluginRefWasDeleted() {
105 // Make sure that no further notifications are sent to the plugin.
106 monitor_callback_id_++;
107 monitor_callback_ = NULL;
108 monitor_user_data_ = NULL;
109
110 // There is no need to do anything with pending callback of
111 // EnumerateDevices(), because OnPluginMsgEnumerateDevicesReply*() will handle
112 // that properly.
113 }
114
115 void DeviceEnumerationResourceHelper::OnPluginMsgEnumerateDevicesReply0_2(
116 PP_Resource* devices_resource,
117 scoped_refptr<TrackedCallback> callback,
118 const ResourceMessageReplyParams& params,
119 const std::vector<DeviceRefData>& devices) {
120 pending_enumerate_devices_ = false;
121
122 // We shouldn't access |devices_resource| if the callback has been called,
123 // which is possible if the last plugin reference to the corresponding
124 // resource has gone away, and the callback has been aborted.
125 if (!TrackedCallback::IsPending(callback))
126 return;
127
128 if (params.result() == PP_OK) {
129 *devices_resource = PPB_DeviceRef_Shared::CreateResourceArray(
130 OBJECT_IS_PROXY, owner_->pp_instance(), devices);
131 }
132
133 callback->Run(params.result());
134 }
135
136 void DeviceEnumerationResourceHelper::OnPluginMsgEnumerateDevicesReply(
137 const PP_ArrayOutput& output,
138 scoped_refptr<TrackedCallback> callback,
139 const ResourceMessageReplyParams& params,
140 const std::vector<DeviceRefData>& devices) {
141 pending_enumerate_devices_ = false;
142
143 // We shouldn't access |output| if the callback has been called, which is
144 // possible if the last plugin reference to the corresponding resource has
145 // gone away, and the callback has been aborted.
146 if (!TrackedCallback::IsPending(callback))
147 return;
148
149 int32_t result = params.result();
150 if (result == PP_OK) {
151 ArrayWriter writer(output);
152 if (writer.is_valid()) {
153 std::vector<scoped_refptr<Resource> > device_resources;
154 for (size_t i = 0; i < devices.size(); ++i) {
155 device_resources.push_back(new PPB_DeviceRef_Shared(
156 OBJECT_IS_PROXY, owner_->pp_instance(), devices[i]));
157 }
158 if (!writer.StoreResourceVector(device_resources))
159 result = PP_ERROR_FAILED;
160 } else {
161 result = PP_ERROR_BADARGUMENT;
162 }
163 }
164
165 callback->Run(params.result());
166 }
167
168 void DeviceEnumerationResourceHelper::OnPluginMsgNotifyDeviceChange(
169 const ResourceMessageReplyParams& /* params */,
170 uint32_t callback_id,
171 const std::vector<DeviceRefData>& devices) {
172 if (monitor_callback_id_ != callback_id) {
173 // A new callback or NULL has been set.
174 return;
175 }
176
177 CHECK(monitor_callback_);
178
179 scoped_array<PP_Resource> elements;
180 uint32_t size = devices.size();
181 if (size > 0) {
182 elements.reset(new PP_Resource[size]);
183 for (size_t index = 0; index < size; ++index) {
184 PPB_DeviceRef_Shared* device_object = new PPB_DeviceRef_Shared(
185 OBJECT_IS_PROXY, owner_->pp_instance(), devices[index]);
186 elements[index] = device_object->GetReference();
187 }
188 }
189 CallWhileUnlocked(base::Bind(monitor_callback_, monitor_user_data_, size,
190 elements.get()));
191 for (size_t index = 0; index < size; ++index)
192 PpapiGlobals::Get()->GetResourceTracker()->ReleaseResource(elements[index]);
193 }
194
195 } // namespace proxy
196 } // namespace ppapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698