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

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 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 "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"
24
25 namespace ppapi {
26 namespace proxy {
27
28 DeviceEnumerationResourceHelper::DeviceEnumerationResourceHelper(
29 PluginResource* owner)
30 : owner_(owner),
31 pending_enumerate_devices_(false),
32 monitor_callback_id_(0),
33 monitor_callback_(NULL),
34 monitor_user_data_(NULL) {
35 }
36
37 DeviceEnumerationResourceHelper::~DeviceEnumerationResourceHelper() {
38 }
39
40 int32_t DeviceEnumerationResourceHelper::EnumerateDevices0_2(
41 PP_Resource* devices,
42 scoped_refptr<TrackedCallback> callback) {
43 if (pending_enumerate_devices_)
44 return PP_ERROR_INPROGRESS;
45 if (!devices)
46 return PP_ERROR_BADARGUMENT;
47
48 pending_enumerate_devices_ = true;
49 PpapiHostMsg_DeviceEnumeration_EnumerateDevices msg;
50 owner_->Call<PpapiPluginMsg_DeviceEnumeration_EnumerateDevicesReply>(
51 PluginResource::RENDERER, msg,
52 base::Bind(
53 &DeviceEnumerationResourceHelper::OnPluginMsgEnumerateDevicesReply0_2,
54 AsWeakPtr(), devices, callback));
55 return PP_OK_COMPLETIONPENDING;
56 }
57
58 int32_t DeviceEnumerationResourceHelper::EnumerateDevices(
59 const PP_ArrayOutput& output,
60 scoped_refptr<TrackedCallback> callback) {
61 if (pending_enumerate_devices_)
62 return PP_ERROR_INPROGRESS;
63
64 pending_enumerate_devices_ = true;
65 PpapiHostMsg_DeviceEnumeration_EnumerateDevices msg;
66 owner_->Call<PpapiPluginMsg_DeviceEnumeration_EnumerateDevicesReply>(
67 PluginResource::RENDERER, msg,
68 base::Bind(
69 &DeviceEnumerationResourceHelper::OnPluginMsgEnumerateDevicesReply,
70 AsWeakPtr(), output, callback));
71 return PP_OK_COMPLETIONPENDING;
72 }
73
74 int32_t DeviceEnumerationResourceHelper::MonitorDeviceChange(
75 PP_MonitorDeviceChangeCallback callback,
76 void* user_data) {
77 monitor_callback_id_++;
78 monitor_callback_ = callback;
79 monitor_user_data_ = user_data;
80
81 if (callback) {
82 owner_->Post(PluginResource::RENDERER,
83 PpapiHostMsg_DeviceEnumeration_MonitorDeviceChange(
84 monitor_callback_id_));
85 } else {
86 owner_->Post(PluginResource::RENDERER,
87 PpapiHostMsg_DeviceEnumeration_StopMonitoringDeviceChange());
88 }
89 return PP_OK;
90 }
91
92 bool DeviceEnumerationResourceHelper::HandleReply(
93 const ResourceMessageReplyParams& params,
94 const IPC::Message& msg) {
95 IPC_BEGIN_MESSAGE_MAP(DeviceEnumerationResourceHelper, msg)
96 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL(
97 PpapiPluginMsg_DeviceEnumeration_NotifyDeviceChange,
98 OnPluginMsgNotifyDeviceChange)
99 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL_UNHANDLED(return false)
100 IPC_END_MESSAGE_MAP()
101
102 return true;
103 }
104
105 void DeviceEnumerationResourceHelper::LastPluginRefWasDeleted() {
106 // Make sure that no further notifications are sent to the plugin.
107 monitor_callback_id_++;
108 monitor_callback_ = NULL;
109 monitor_user_data_ = NULL;
110
111 // There is no need to do anything with pending callback of
112 // EnumerateDevices(), because OnPluginMsgEnumerateDevicesReply*() will handle
113 // that properly.
114 }
115
116 void DeviceEnumerationResourceHelper::OnPluginMsgEnumerateDevicesReply0_2(
117 PP_Resource* devices_resource,
118 scoped_refptr<TrackedCallback> callback,
119 const ResourceMessageReplyParams& params,
120 const std::vector<DeviceRefData>& devices) {
121 pending_enumerate_devices_ = false;
122
123 // We shouldn't access |devices_resource| if the callback has been called,
124 // which is possible if the last plugin reference to the corresponding
125 // resource has gone away, and the callback has been aborted.
126 if (!TrackedCallback::IsPending(callback))
127 return;
128
129 if (params.result() == PP_OK) {
130 *devices_resource = PPB_DeviceRef_Shared::CreateResourceArray(
131 OBJECT_IS_PROXY, owner_->pp_instance(), devices);
132 }
133
134 callback->Run(params.result());
135 }
136
137 void DeviceEnumerationResourceHelper::OnPluginMsgEnumerateDevicesReply(
138 const PP_ArrayOutput& output,
139 scoped_refptr<TrackedCallback> callback,
140 const ResourceMessageReplyParams& params,
141 const std::vector<DeviceRefData>& devices) {
142 pending_enumerate_devices_ = false;
143
144 // We shouldn't access |output| if the callback has been called, which is
145 // possible if the last plugin reference to the corresponding resource has
146 // gone away, and the callback has been aborted.
147 if (!TrackedCallback::IsPending(callback))
148 return;
149
150 int32_t result = params.result();
151 if (result == PP_OK) {
152 ArrayWriter writer(output);
153 if (writer.is_valid()) {
154 std::vector<scoped_refptr<Resource> > device_resources;
155 for (size_t i = 0; i < devices.size(); ++i) {
156 device_resources.push_back(new PPB_DeviceRef_Shared(
157 OBJECT_IS_PROXY, owner_->pp_instance(), devices[i]));
158 }
159 if (!writer.StoreResourceVector(device_resources))
160 result = PP_ERROR_FAILED;
161 } else {
162 result = PP_ERROR_BADARGUMENT;
163 }
164 }
165
166 callback->Run(params.result());
167 }
168
169 void DeviceEnumerationResourceHelper::OnPluginMsgNotifyDeviceChange(
170 const ResourceMessageReplyParams& /* params */,
171 uint32_t callback_id,
172 const std::vector<DeviceRefData>& devices) {
173 if (monitor_callback_id_ != callback_id) {
174 // A new callback or NULL has been set.
175 return;
176 }
177
178 CHECK(monitor_callback_);
179
180 scoped_array<PP_Resource> elements;
181 uint32_t size = devices.size();
182 if (size > 0) {
183 elements.reset(new PP_Resource[size]);
184 for (size_t index = 0; index < size; ++index) {
185 PPB_DeviceRef_Shared* device_object = new PPB_DeviceRef_Shared(
186 OBJECT_IS_PROXY, owner_->pp_instance(), devices[index]);
187 elements[index] = device_object->GetReference();
188 }
189 }
190
191 // TODO(yzshen): make sure |monitor_callback_| is called on the same thread as
192 // the one on which MonitorDeviceChange() is called.
193 CallWhileUnlocked(base::Bind(monitor_callback_, monitor_user_data_, size,
194 elements.get()));
195 for (size_t index = 0; index < size; ++index)
196 PpapiGlobals::Get()->GetResourceTracker()->ReleaseResource(elements[index]);
197 }
198
199 } // namespace proxy
200 } // namespace ppapi
OLDNEW
« no previous file with comments | « ppapi/proxy/device_enumeration_resource_helper.h ('k') | ppapi/proxy/device_enumeration_resource_helper_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698