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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: content/renderer/pepper/pepper_device_enumeration_host_helper.cc
diff --git a/content/renderer/pepper/pepper_device_enumeration_host_helper.cc b/content/renderer/pepper/pepper_device_enumeration_host_helper.cc
new file mode 100644
index 0000000000000000000000000000000000000000..155073774fc30e162074917a1c4d0f65d16a5d3f
--- /dev/null
+++ b/content/renderer/pepper/pepper_device_enumeration_host_helper.cc
@@ -0,0 +1,197 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/pepper/pepper_device_enumeration_host_helper.h"
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/memory/weak_ptr.h"
+#include "base/message_loop.h"
+#include "ipc/ipc_message.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/host/dispatch_host_message.h"
+#include "ppapi/host/host_message_context.h"
+#include "ppapi/host/ppapi_host.h"
+#include "ppapi/host/resource_host.h"
+#include "ppapi/proxy/ppapi_messages.h"
+#include "ppapi/shared_impl/ppb_device_ref_shared.h"
+#include "webkit/plugins/ppapi/plugin_delegate.h"
+
+using ppapi::host::HostMessageContext;
+using webkit::ppapi::PluginDelegate;
+
+namespace content {
+
+// Makes sure that StopEnumerateDevices() is called for each EnumerateDevices().
+class PepperDeviceEnumerationHostHelper::ScopedRequest
+ : public base::SupportsWeakPtr<ScopedRequest> {
+ public:
+ // |owner| must outlive this object.
+ ScopedRequest(PepperDeviceEnumerationHostHelper* owner,
+ const PluginDelegate::EnumerateDevicesCallback& callback)
+ : owner_(owner),
+ callback_(callback),
+ requested_(false),
+ request_id_(0),
+ sync_call_(false) {
+ PluginDelegate* plugin_delegate = owner_->delegate_->GetPluginDelegate();
+ if (!plugin_delegate)
+ return;
+
+ requested_ = true;
+
+ // Note that the callback passed into PluginDelegate::EnumerateDevices() may
+ // be called synchronously. In that case, |request_id_| hasn't been updated
+ // when the callback is called. Moreover, |callback| may destroy this
+ // object. So we don't pass in |callback| directly. Instead, we use
+ // EnumerateDevicesCallbackBody() to ensure that we always call |callback|
+ // asynchronously.
+ sync_call_ = true;
+ request_id_ = plugin_delegate->EnumerateDevices(
+ owner_->device_type_,
+ base::Bind(&ScopedRequest::EnumerateDevicesCallbackBody, AsWeakPtr()));
+ sync_call_ = false;
+ }
+
+ ~ScopedRequest() {
+ if (requested_) {
+ PluginDelegate* plugin_delegate = owner_->delegate_->GetPluginDelegate();
+ if (plugin_delegate)
+ plugin_delegate->StopEnumerateDevices(request_id_);
+ }
+ }
+
+ bool requested() const { return requested_; }
+
+ private:
+ void EnumerateDevicesCallbackBody(
+ int request_id,
+ bool succeeded,
+ const std::vector<ppapi::DeviceRefData>& devices) {
+ if (sync_call_) {
+ MessageLoop::current()->PostTask(
+ FROM_HERE,
+ base::Bind(&ScopedRequest::EnumerateDevicesCallbackBody, AsWeakPtr(),
+ request_id, succeeded, devices));
+ } else {
+ DCHECK_EQ(request_id_, request_id);
+ callback_.Run(request_id, succeeded, devices);
+ // This object may have been destroyed at this point.
+ }
+ }
+
+ PepperDeviceEnumerationHostHelper* owner_;
+ PluginDelegate::EnumerateDevicesCallback callback_;
+ bool requested_;
+ int request_id_;
+ bool sync_call_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedRequest);
+};
+
+PepperDeviceEnumerationHostHelper::PepperDeviceEnumerationHostHelper(
+ ppapi::host::ResourceHost* resource_host,
+ Delegate* delegate,
+ PP_DeviceType_Dev device_type)
+ : resource_host_(resource_host),
+ delegate_(delegate),
+ device_type_(device_type) {
+}
+
+PepperDeviceEnumerationHostHelper::~PepperDeviceEnumerationHostHelper() {
+}
+
+bool PepperDeviceEnumerationHostHelper::HandleResourceMessage(
+ const IPC::Message& msg,
+ HostMessageContext* context,
+ int32_t* result) {
+ bool return_value = false;
+ *result = InternalHandleResourceMessage(msg, context, &return_value);
+ return return_value;
+}
+
+int32_t PepperDeviceEnumerationHostHelper::InternalHandleResourceMessage(
+ const IPC::Message& msg,
+ HostMessageContext* context,
+ bool* handled) {
+ *handled = true;
+ IPC_BEGIN_MESSAGE_MAP(PepperDeviceEnumerationHostHelper, msg)
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(
+ PpapiHostMsg_DeviceEnumeration_EnumerateDevices, OnMsgEnumerateDevices)
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL(
+ PpapiHostMsg_DeviceEnumeration_MonitorDeviceChange,
+ OnMsgMonitorDeviceChange)
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(
+ PpapiHostMsg_DeviceEnumeration_StopMonitoringDeviceChange,
+ OnMsgStopMonitoringDeviceChange)
+ IPC_END_MESSAGE_MAP()
+
+ *handled = false;
+ return PP_ERROR_FAILED;
+}
+
+int32_t PepperDeviceEnumerationHostHelper::OnMsgEnumerateDevices(
+ HostMessageContext* context) {
+ if (enumerate_devices_context_.get())
+ return PP_ERROR_INPROGRESS;
+
+ enumerate_.reset(new ScopedRequest(
+ this,
+ base::Bind(&PepperDeviceEnumerationHostHelper::OnEnumerateDevicesComplete,
+ base::Unretained(this))));
+ if (!enumerate_->requested())
+ return PP_ERROR_FAILED;
+
+ enumerate_devices_context_.reset(
+ new ppapi::host::ReplyMessageContext(context->MakeReplyMessageContext()));
+ return PP_OK_COMPLETIONPENDING;
+}
+
+int32_t PepperDeviceEnumerationHostHelper::OnMsgMonitorDeviceChange(
+ HostMessageContext* /* context */,
+ uint32_t callback_id) {
+ monitor_.reset(new ScopedRequest(
+ this,
+ base::Bind(&PepperDeviceEnumerationHostHelper::OnNotifyDeviceChange,
+ base::Unretained(this), callback_id)));
+
+ return monitor_->requested() ? PP_OK : PP_ERROR_FAILED;
+}
+
+int32_t PepperDeviceEnumerationHostHelper::OnMsgStopMonitoringDeviceChange(
+ HostMessageContext* /* context */) {
+ monitor_.reset(NULL);
+ return PP_OK;
+}
+
+void PepperDeviceEnumerationHostHelper::OnEnumerateDevicesComplete(
+ int /* request_id */,
+ bool succeeded,
+ const std::vector<ppapi::DeviceRefData>& devices) {
+ DCHECK(enumerate_devices_context_.get());
+
+ enumerate_.reset(NULL);
+
+ enumerate_devices_context_->params.set_result(
+ succeeded ? PP_OK : PP_ERROR_FAILED);
+ resource_host_->host()->SendReply(
+ *enumerate_devices_context_,
+ PpapiPluginMsg_DeviceEnumeration_EnumerateDevicesReply(
+ succeeded ? devices : std::vector<ppapi::DeviceRefData>()));
+ enumerate_devices_context_.reset();
+}
+
+void PepperDeviceEnumerationHostHelper::OnNotifyDeviceChange(
+ uint32_t callback_id,
+ int /* request_id */,
+ bool succeeded,
+ const std::vector<ppapi::DeviceRefData>& devices) {
+ resource_host_->host()->SendUnsolicitedReply(
+ resource_host_->pp_resource(),
+ PpapiPluginMsg_DeviceEnumeration_NotifyDeviceChange(
+ callback_id,
+ succeeded ? devices : std::vector<ppapi::DeviceRefData>()));
+}
+
+} // namespace content

Powered by Google App Engine
This is Rietveld 408576698