Refactor management of overview window copy lifetime into a separate class.
[chromium-blink-merge.git] / content / renderer / pepper / pepper_device_enumeration_host_helper.cc
blob9ec6373a096b88704ac2b648b52716becb6a8893
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 "content/renderer/pepper/pepper_device_enumeration_host_helper.h"
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/memory/weak_ptr.h"
10 #include "base/message_loop/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"
20 using ppapi::host::HostMessageContext;
22 namespace content {
24 // Makes sure that StopEnumerateDevices() is called for each EnumerateDevices().
25 class PepperDeviceEnumerationHostHelper::ScopedRequest
26 : public base::SupportsWeakPtr<ScopedRequest> {
27 public:
28 // |owner| must outlive this object.
29 ScopedRequest(
30 PepperDeviceEnumerationHostHelper* owner,
31 const Delegate::EnumerateDevicesCallback& callback)
32 : owner_(owner),
33 callback_(callback),
34 requested_(false),
35 request_id_(0),
36 sync_call_(false) {
37 requested_ = true;
39 // Note that the callback passed into
40 // PepperDeviceEnumerationHostHelper::Delegate::EnumerateDevices() may be
41 // called synchronously. In that case, |request_id_| hasn't been updated
42 // when the callback is called. Moreover, |callback| may destroy this
43 // object. So we don't pass in |callback| directly. Instead, we use
44 // EnumerateDevicesCallbackBody() to ensure that we always call |callback|
45 // asynchronously.
46 sync_call_ = true;
47 request_id_ = owner_->delegate_->EnumerateDevices(
48 owner_->device_type_,
49 base::Bind(&ScopedRequest::EnumerateDevicesCallbackBody, AsWeakPtr()));
50 sync_call_ = false;
53 ~ScopedRequest() {
54 if (requested_) {
55 owner_->delegate_->StopEnumerateDevices(request_id_);
59 bool requested() const { return requested_; }
61 private:
62 void EnumerateDevicesCallbackBody(
63 int request_id,
64 bool succeeded,
65 const std::vector<ppapi::DeviceRefData>& devices) {
66 if (sync_call_) {
67 base::MessageLoop::current()->PostTask(
68 FROM_HERE,
69 base::Bind(&ScopedRequest::EnumerateDevicesCallbackBody,
70 AsWeakPtr(),
71 request_id,
72 succeeded,
73 devices));
74 } else {
75 DCHECK_EQ(request_id_, request_id);
76 callback_.Run(request_id, succeeded, devices);
77 // This object may have been destroyed at this point.
81 PepperDeviceEnumerationHostHelper* owner_;
82 PepperDeviceEnumerationHostHelper::Delegate::EnumerateDevicesCallback
83 callback_;
84 bool requested_;
85 int request_id_;
86 bool sync_call_;
88 DISALLOW_COPY_AND_ASSIGN(ScopedRequest);
91 PepperDeviceEnumerationHostHelper::PepperDeviceEnumerationHostHelper(
92 ppapi::host::ResourceHost* resource_host,
93 Delegate* delegate,
94 PP_DeviceType_Dev device_type)
95 : resource_host_(resource_host),
96 delegate_(delegate),
97 device_type_(device_type) {
100 PepperDeviceEnumerationHostHelper::~PepperDeviceEnumerationHostHelper() {
103 bool PepperDeviceEnumerationHostHelper::HandleResourceMessage(
104 const IPC::Message& msg,
105 HostMessageContext* context,
106 int32_t* result) {
107 bool return_value = false;
108 *result = InternalHandleResourceMessage(msg, context, &return_value);
109 return return_value;
112 int32_t PepperDeviceEnumerationHostHelper::InternalHandleResourceMessage(
113 const IPC::Message& msg,
114 HostMessageContext* context,
115 bool* handled) {
116 *handled = true;
117 IPC_BEGIN_MESSAGE_MAP(PepperDeviceEnumerationHostHelper, msg)
118 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(
119 PpapiHostMsg_DeviceEnumeration_EnumerateDevices, OnEnumerateDevices)
120 PPAPI_DISPATCH_HOST_RESOURCE_CALL(
121 PpapiHostMsg_DeviceEnumeration_MonitorDeviceChange,
122 OnMonitorDeviceChange)
123 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(
124 PpapiHostMsg_DeviceEnumeration_StopMonitoringDeviceChange,
125 OnStopMonitoringDeviceChange)
126 IPC_END_MESSAGE_MAP()
128 *handled = false;
129 return PP_ERROR_FAILED;
132 int32_t PepperDeviceEnumerationHostHelper::OnEnumerateDevices(
133 HostMessageContext* context) {
134 if (enumerate_devices_context_)
135 return PP_ERROR_INPROGRESS;
137 enumerate_.reset(new ScopedRequest(
138 this,
139 base::Bind(&PepperDeviceEnumerationHostHelper::OnEnumerateDevicesComplete,
140 base::Unretained(this))));
141 if (!enumerate_->requested())
142 return PP_ERROR_FAILED;
144 enumerate_devices_context_.reset(
145 new ppapi::host::ReplyMessageContext(context->MakeReplyMessageContext()));
146 return PP_OK_COMPLETIONPENDING;
149 int32_t PepperDeviceEnumerationHostHelper::OnMonitorDeviceChange(
150 HostMessageContext* /* context */,
151 uint32_t callback_id) {
152 monitor_.reset(new ScopedRequest(
153 this,
154 base::Bind(&PepperDeviceEnumerationHostHelper::OnNotifyDeviceChange,
155 base::Unretained(this), callback_id)));
157 return monitor_->requested() ? PP_OK : PP_ERROR_FAILED;
160 int32_t PepperDeviceEnumerationHostHelper::OnStopMonitoringDeviceChange(
161 HostMessageContext* /* context */) {
162 monitor_.reset(NULL);
163 return PP_OK;
166 void PepperDeviceEnumerationHostHelper::OnEnumerateDevicesComplete(
167 int /* request_id */,
168 bool succeeded,
169 const std::vector<ppapi::DeviceRefData>& devices) {
170 DCHECK(enumerate_devices_context_.get());
172 enumerate_.reset(NULL);
174 enumerate_devices_context_->params.set_result(
175 succeeded ? PP_OK : PP_ERROR_FAILED);
176 resource_host_->host()->SendReply(
177 *enumerate_devices_context_,
178 PpapiPluginMsg_DeviceEnumeration_EnumerateDevicesReply(
179 succeeded ? devices : std::vector<ppapi::DeviceRefData>()));
180 enumerate_devices_context_.reset();
183 void PepperDeviceEnumerationHostHelper::OnNotifyDeviceChange(
184 uint32_t callback_id,
185 int /* request_id */,
186 bool succeeded,
187 const std::vector<ppapi::DeviceRefData>& devices) {
188 resource_host_->host()->SendUnsolicitedReply(
189 resource_host_->pp_resource(),
190 PpapiPluginMsg_DeviceEnumeration_NotifyDeviceChange(
191 callback_id,
192 succeeded ? devices : std::vector<ppapi::DeviceRefData>()));
195 } // namespace content