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: content/renderer/pepper/pepper_device_enumeration_host_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 "content/renderer/pepper/pepper_device_enumeration_host_helper.h"
6
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/memory/weak_ptr.h"
10 #include "base/message_loop.h"
11 #include "ipc/ipc_message.h"
12 #include "ppapi/c/pp_errors.h"
13 #include "ppapi/host/dispatch_host_message.h"
14 #include "ppapi/host/host_message_context.h"
15 #include "ppapi/host/ppapi_host.h"
16 #include "ppapi/host/resource_host.h"
17 #include "ppapi/proxy/ppapi_messages.h"
18 #include "ppapi/shared_impl/ppb_device_ref_shared.h"
19 #include "webkit/plugins/ppapi/plugin_delegate.h"
20
21 using ppapi::host::HostMessageContext;
22 using webkit::ppapi::PluginDelegate;
23
24 namespace content {
25
26 // Makes sure that StopEnumerateDevices() is called for each EnumerateDevices().
27 class PepperDeviceEnumerationHostHelper::ScopedRequest
28 : public base::SupportsWeakPtr<ScopedRequest> {
29 public:
30 // |owner| must outlive this object.
31 ScopedRequest(PepperDeviceEnumerationHostHelper* owner,
32 const PluginDelegate::EnumerateDevicesCallback& callback)
33 : owner_(owner),
34 callback_(callback),
35 requested_(false),
36 request_id_(0),
37 sync_call_(false) {
38 PluginDelegate* plugin_delegate = owner_->delegate_->GetPluginDelegate();
39 if (!plugin_delegate)
40 return;
41
42 requested_ = true;
43
44 // Note that the callback passed into PluginDelegate::EnumerateDevices() may
45 // be called synchronously. In that case, |request_id_| hasn't been updated
46 // when the callback is called. Moreover, |callback| may destroy this
47 // object. So we don't pass in |callback| directly. Instead, we use
48 // EnumerateDevicesCallbackBody() to ensure that we always call |callback|
49 // asynchronously.
50 sync_call_ = true;
51 request_id_ = plugin_delegate->EnumerateDevices(
52 owner_->device_type_,
53 base::Bind(&ScopedRequest::EnumerateDevicesCallbackBody, AsWeakPtr()));
54 sync_call_ = false;
55 }
56
57 ~ScopedRequest() {
58 if (requested_) {
59 PluginDelegate* plugin_delegate = owner_->delegate_->GetPluginDelegate();
60 if (plugin_delegate)
61 plugin_delegate->StopEnumerateDevices(request_id_);
62 }
63 }
64
65 bool requested() const { return requested_; }
66
67 private:
68 void EnumerateDevicesCallbackBody(
69 int request_id,
70 bool succeeded,
71 const std::vector<ppapi::DeviceRefData>& devices) {
72 if (sync_call_) {
73 MessageLoop::current()->PostTask(
74 FROM_HERE,
75 base::Bind(&ScopedRequest::EnumerateDevicesCallbackBody, AsWeakPtr(),
76 request_id, succeeded, devices));
77 } else {
78 DCHECK_EQ(request_id_, request_id);
79 callback_.Run(request_id, succeeded, devices);
80 // This object may have been destroyed at this point.
81 }
82 }
83
84 PepperDeviceEnumerationHostHelper* owner_;
85 PluginDelegate::EnumerateDevicesCallback callback_;
86 bool requested_;
87 int request_id_;
88 bool sync_call_;
89
90 DISALLOW_COPY_AND_ASSIGN(ScopedRequest);
91 };
92
93 PepperDeviceEnumerationHostHelper::PepperDeviceEnumerationHostHelper(
94 ppapi::host::ResourceHost* resource_host,
95 Delegate* delegate,
96 PP_DeviceType_Dev device_type)
97 : resource_host_(resource_host),
98 delegate_(delegate),
99 device_type_(device_type) {
100 }
101
102 PepperDeviceEnumerationHostHelper::~PepperDeviceEnumerationHostHelper() {
103 }
104
105 bool PepperDeviceEnumerationHostHelper::HandleResourceMessage(
106 const IPC::Message& msg,
107 HostMessageContext* context,
108 int32_t* result) {
109 bool return_value = false;
110 *result = InternalHandleResourceMessage(msg, context, &return_value);
111 return return_value;
112 }
113
114 int32_t PepperDeviceEnumerationHostHelper::InternalHandleResourceMessage(
115 const IPC::Message& msg,
116 HostMessageContext* context,
117 bool* handled) {
118 *handled = true;
119 IPC_BEGIN_MESSAGE_MAP(PepperDeviceEnumerationHostHelper, msg)
120 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(
121 PpapiHostMsg_DeviceEnumeration_EnumerateDevices, OnMsgEnumerateDevices)
122 PPAPI_DISPATCH_HOST_RESOURCE_CALL(
123 PpapiHostMsg_DeviceEnumeration_MonitorDeviceChange,
124 OnMsgMonitorDeviceChange)
125 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(
126 PpapiHostMsg_DeviceEnumeration_StopMonitoringDeviceChange,
127 OnMsgStopMonitoringDeviceChange)
128 IPC_END_MESSAGE_MAP()
129
130 *handled = false;
131 return PP_ERROR_FAILED;
132 }
133
134 int32_t PepperDeviceEnumerationHostHelper::OnMsgEnumerateDevices(
135 HostMessageContext* context) {
136 if (enumerate_devices_context_.get())
137 return PP_ERROR_INPROGRESS;
138
139 enumerate_.reset(new ScopedRequest(
140 this,
141 base::Bind(&PepperDeviceEnumerationHostHelper::OnEnumerateDevicesComplete,
142 base::Unretained(this))));
143 if (!enumerate_->requested())
144 return PP_ERROR_FAILED;
145
146 enumerate_devices_context_.reset(
147 new ppapi::host::ReplyMessageContext(context->MakeReplyMessageContext()));
148 return PP_OK_COMPLETIONPENDING;
149 }
150
151 int32_t PepperDeviceEnumerationHostHelper::OnMsgMonitorDeviceChange(
152 HostMessageContext* /* context */,
153 uint32_t callback_id) {
154 monitor_.reset(new ScopedRequest(
155 this,
156 base::Bind(&PepperDeviceEnumerationHostHelper::OnNotifyDeviceChange,
157 base::Unretained(this), callback_id)));
158
159 return monitor_->requested() ? PP_OK : PP_ERROR_FAILED;
160 }
161
162 int32_t PepperDeviceEnumerationHostHelper::OnMsgStopMonitoringDeviceChange(
163 HostMessageContext* /* context */) {
164 monitor_.reset(NULL);
165 return PP_OK;
166 }
167
168 void PepperDeviceEnumerationHostHelper::OnEnumerateDevicesComplete(
169 int /* request_id */,
170 bool succeeded,
171 const std::vector<ppapi::DeviceRefData>& devices) {
172 DCHECK(enumerate_devices_context_.get());
173
174 enumerate_.reset(NULL);
175
176 enumerate_devices_context_->params.set_result(
177 succeeded ? PP_OK : PP_ERROR_FAILED);
178 resource_host_->host()->SendReply(
179 *enumerate_devices_context_,
180 PpapiPluginMsg_DeviceEnumeration_EnumerateDevicesReply(
181 succeeded ? devices : std::vector<ppapi::DeviceRefData>()));
182 enumerate_devices_context_.reset();
183 }
184
185 void PepperDeviceEnumerationHostHelper::OnNotifyDeviceChange(
186 uint32_t callback_id,
187 int /* request_id */,
188 bool succeeded,
189 const std::vector<ppapi::DeviceRefData>& devices) {
190 resource_host_->host()->SendUnsolicitedReply(
191 resource_host_->pp_resource(),
192 PpapiPluginMsg_DeviceEnumeration_NotifyDeviceChange(
193 callback_id,
194 succeeded ? devices : std::vector<ppapi::DeviceRefData>()));
195 }
196
197 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698