Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / renderer_host / pepper / pepper_flash_drm_host.cc
blobdb47ce3bacd430530af3b9b37c29aaee9489b496
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 "chrome/browser/renderer_host/pepper/pepper_flash_drm_host.h"
7 #if defined(OS_WIN)
8 #include <Windows.h>
9 #endif
11 #include "base/bind.h"
12 #include "base/compiler_specific.h"
13 #include "base/logging.h"
14 #include "base/memory/ref_counted.h"
15 #include "content/public/browser/browser_ppapi_host.h"
16 #include "content/public/browser/browser_thread.h"
17 #include "content/public/browser/child_process_security_policy.h"
18 #include "content/public/browser/render_frame_host.h"
19 #include "content/public/common/pepper_plugin_info.h"
20 #include "ppapi/c/pp_errors.h"
21 #include "ppapi/host/dispatch_host_message.h"
22 #include "ppapi/host/host_message_context.h"
23 #include "ppapi/host/ppapi_host.h"
24 #include "ppapi/proxy/ppapi_messages.h"
26 #if defined(USE_AURA)
27 #include "ui/aura/root_window.h"
28 #include "ui/aura/window.h"
29 #endif
31 using content::BrowserPpapiHost;
33 namespace chrome {
35 namespace {
36 const base::FilePath::CharType kVoucherFilename[] =
37 FILE_PATH_LITERAL("plugin.vch");
40 #if defined (OS_WIN)
41 // Helper class to get the UI thread which monitor is showing the
42 // window associated with the instance's render view. Since we get
43 // called by the IO thread and we cannot block, the first answer is
44 // of GetMonitor() may be NULL, but eventually it will contain the
45 // right monitor.
46 class MonitorFinder : public base::RefCountedThreadSafe<MonitorFinder> {
47 public:
48 MonitorFinder(int process_id, int render_frame_id)
49 : process_id_(process_id),
50 render_frame_id_(render_frame_id),
51 monitor_(NULL),
52 request_sent_(0) {
55 int64_t GetMonitor() {
56 // We use |request_sent_| as an atomic boolean so that we
57 // never have more than one task posted at a given time. We
58 // do this because we don't know how often our client is going
59 // to call and we can't cache the |monitor_| value.
60 if (InterlockedCompareExchange(&request_sent_, 1, 0) == 0) {
61 content::BrowserThread::PostTask(
62 content::BrowserThread::UI, FROM_HERE,
63 base::Bind(&MonitorFinder::FetchMonitorFromWidget, this));
65 return reinterpret_cast<int64_t>(monitor_);
68 private:
69 friend class base::RefCountedThreadSafe<MonitorFinder>;
70 ~MonitorFinder() { }
72 void FetchMonitorFromWidget() {
73 InterlockedExchange(&request_sent_, 0);
74 content::RenderFrameHost* rfh =
75 content::RenderFrameHost::FromID(process_id_, render_frame_id_);
76 if (!rfh)
77 return;
78 gfx::NativeView native_view = rfh->GetNativeView();
79 #if defined(USE_AURA)
80 aura::WindowEventDispatcher* dispatcher = native_view->GetDispatcher();
81 if (!dispatcher)
82 return;
83 HWND window = dispatcher->host()->GetAcceleratedWidget();
84 #else
85 HWND window = native_view;
86 #endif
87 HMONITOR monitor = ::MonitorFromWindow(window, MONITOR_DEFAULTTONULL);
88 InterlockedExchangePointer(reinterpret_cast<void* volatile *>(&monitor_),
89 monitor);
92 const int process_id_;
93 const int render_frame_id_;
94 volatile HMONITOR monitor_;
95 volatile long request_sent_;
97 #else
98 // TODO(cpu): Support Mac and Linux someday.
99 class MonitorFinder : public base::RefCountedThreadSafe<MonitorFinder> {
100 public:
101 MonitorFinder(int, int) { }
102 int64_t GetMonitor() { return 0; }
104 private:
105 friend class base::RefCountedThreadSafe<MonitorFinder>;
106 ~MonitorFinder() { }
108 #endif
110 PepperFlashDRMHost::PepperFlashDRMHost(BrowserPpapiHost* host,
111 PP_Instance instance,
112 PP_Resource resource)
113 : ppapi::host::ResourceHost(host->GetPpapiHost(), instance, resource),
114 weak_factory_(this){
115 // Grant permissions to read the flash voucher file.
116 int render_process_id;
117 int render_frame_id;
118 bool success =
119 host->GetRenderFrameIDsForInstance(
120 instance, &render_process_id, &render_frame_id);
121 base::FilePath plugin_dir = host->GetPluginPath().DirName();
122 DCHECK(!plugin_dir.empty() && success);
123 base::FilePath voucher_file = plugin_dir.Append(
124 base::FilePath(kVoucherFilename));
125 content::ChildProcessSecurityPolicy::GetInstance()->GrantReadFile(
126 render_process_id, voucher_file);
128 fetcher_ = new DeviceIDFetcher(render_process_id);
129 monitor_finder_ = new MonitorFinder(render_process_id, render_frame_id);
130 monitor_finder_->GetMonitor();
133 PepperFlashDRMHost::~PepperFlashDRMHost() {
136 int32_t PepperFlashDRMHost::OnResourceMessageReceived(
137 const IPC::Message& msg,
138 ppapi::host::HostMessageContext* context) {
139 IPC_BEGIN_MESSAGE_MAP(PepperFlashDRMHost, msg)
140 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FlashDRM_GetDeviceID,
141 OnHostMsgGetDeviceID)
142 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FlashDRM_GetHmonitor,
143 OnHostMsgGetHmonitor)
144 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FlashDRM_MonitorIsExternal,
145 OnHostMsgMonitorIsExternal)
146 IPC_END_MESSAGE_MAP()
147 return PP_ERROR_FAILED;
150 int32_t PepperFlashDRMHost::OnHostMsgGetDeviceID(
151 ppapi::host::HostMessageContext* context) {
152 if (!fetcher_->Start(base::Bind(&PepperFlashDRMHost::GotDeviceID,
153 weak_factory_.GetWeakPtr(),
154 context->MakeReplyMessageContext()))) {
155 return PP_ERROR_INPROGRESS;
157 return PP_OK_COMPLETIONPENDING;
160 int32_t PepperFlashDRMHost::OnHostMsgGetHmonitor(
161 ppapi::host::HostMessageContext* context) {
162 int64_t monitor_id = monitor_finder_->GetMonitor();
163 if (monitor_id) {
164 context->reply_msg = PpapiPluginMsg_FlashDRM_GetHmonitorReply(monitor_id);
165 return PP_OK;
166 } else {
167 return PP_ERROR_FAILED;
171 int32_t PepperFlashDRMHost::OnHostMsgMonitorIsExternal(
172 ppapi::host::HostMessageContext* context) {
173 int64_t monitor_id = monitor_finder_->GetMonitor();
174 if (monitor_id) {
175 // TODO(bbudge) get information about whether monitor is external.
176 context->reply_msg =
177 PpapiPluginMsg_FlashDRM_MonitorIsExternalReply(PP_FALSE);
178 return PP_OK;
179 } else {
180 return PP_ERROR_FAILED;
184 void PepperFlashDRMHost::GotDeviceID(
185 ppapi::host::ReplyMessageContext reply_context,
186 const std::string& id,
187 int32_t result) {
188 if (id.empty() && result == PP_OK) {
189 NOTREACHED();
190 result = PP_ERROR_FAILED;
192 reply_context.params.set_result(result);
193 host()->SendReply(reply_context,
194 PpapiPluginMsg_FlashDRM_GetDeviceIDReply(id));
197 } // namespace chrome