pepper_output_protection_message_filter.cc revision 4e180b6a0b4720a9b8e9e959a882386f690f08ff
1// Copyright 2013 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 "chrome/browser/renderer_host/pepper/pepper_output_protection_message_filter.h" 6 7#include "build/build_config.h" 8#include "content/public/browser/browser_ppapi_host.h" 9#include "content/public/browser/browser_thread.h" 10#include "content/public/browser/render_view_host.h" 11#include "content/public/browser/web_contents.h" 12#include "ppapi/c/pp_errors.h" 13#include "ppapi/c/private/ppb_output_protection_private.h" 14#include "ppapi/host/dispatch_host_message.h" 15#include "ppapi/host/host_message_context.h" 16#include "ppapi/host/ppapi_host.h" 17#include "ppapi/proxy/ppapi_messages.h" 18 19#if defined(USE_ASH) && defined(OS_CHROMEOS) 20#include "ash/shell.h" 21#include "ash/shell_delegate.h" 22#include "chromeos/display/output_configurator.h" 23#endif 24 25namespace chrome { 26 27namespace { 28 29#if defined(OS_CHROMEOS) 30COMPILE_ASSERT( 31 static_cast<int>(PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_NONE) == 32 static_cast<int>(chromeos::OUTPUT_TYPE_NONE), 33 PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_NONE); 34COMPILE_ASSERT( 35 static_cast<int>(PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_UNKNOWN) == 36 static_cast<int>(chromeos::OUTPUT_TYPE_UNKNOWN), 37 PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_UNKNOWN); 38COMPILE_ASSERT( 39 static_cast<int>(PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_INTERNAL) == 40 static_cast<int>(chromeos::OUTPUT_TYPE_INTERNAL), 41 PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_INTERNAL); 42COMPILE_ASSERT( 43 static_cast<int>(PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_VGA) == 44 static_cast<int>(chromeos::OUTPUT_TYPE_VGA), 45 PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_VGA); 46COMPILE_ASSERT( 47 static_cast<int>(PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_HDMI) == 48 static_cast<int>(chromeos::OUTPUT_TYPE_HDMI), 49 PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_HDMI); 50COMPILE_ASSERT( 51 static_cast<int>(PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_DVI) == 52 static_cast<int>(chromeos::OUTPUT_TYPE_DVI), 53 PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_DVI); 54COMPILE_ASSERT( 55 static_cast<int>(PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_DISPLAYPORT) == 56 static_cast<int>(chromeos::OUTPUT_TYPE_DISPLAYPORT), 57 PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_DISPLAYPORT); 58COMPILE_ASSERT( 59 static_cast<int>(PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_NETWORK) == 60 static_cast<int>(chromeos::OUTPUT_TYPE_NETWORK), 61 PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_NETWORK); 62COMPILE_ASSERT( 63 static_cast<int>(PP_OUTPUT_PROTECTION_METHOD_PRIVATE_NONE) == 64 static_cast<int>(chromeos::OUTPUT_PROTECTION_METHOD_NONE), 65 PP_OUTPUT_PROTECTION_METHOD_PRIVATE_NONE); 66COMPILE_ASSERT( 67 static_cast<int>(PP_OUTPUT_PROTECTION_METHOD_PRIVATE_HDCP) == 68 static_cast<int>(chromeos::OUTPUT_PROTECTION_METHOD_HDCP), 69 PP_OUTPUT_PROTECTION_METHOD_PRIVATE_HDCP); 70#endif 71 72#if defined(OS_CHROMEOS) && defined(USE_ASH) 73void UnregisterClientOnUIThread( 74 chromeos::OutputConfigurator::OutputProtectionClientId client_id) { 75 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 76 chromeos::OutputConfigurator* configurator = 77 ash::Shell::GetInstance()->output_configurator(); 78 configurator->UnregisterOutputProtectionClient(client_id); 79} 80#endif 81 82} // namespace 83 84PepperOutputProtectionMessageFilter::PepperOutputProtectionMessageFilter( 85 content::BrowserPpapiHost* host, 86 PP_Instance instance) { 87#if defined(OS_CHROMEOS) && defined(USE_ASH) && defined(USE_X11) 88 client_id_ = 0; 89 host->GetRenderViewIDsForInstance( 90 instance, &render_process_id_, &render_view_id_); 91#else 92 NOTIMPLEMENTED(); 93#endif 94} 95 96PepperOutputProtectionMessageFilter::~PepperOutputProtectionMessageFilter() { 97#if defined(OS_CHROMEOS) && defined(USE_ASH) 98 if (client_id_ != 0) { 99 content::BrowserThread::PostTask( 100 content::BrowserThread::UI, 101 FROM_HERE, 102 base::Bind(&UnregisterClientOnUIThread, client_id_)); 103 } 104#endif 105} 106 107scoped_refptr<base::TaskRunner> 108PepperOutputProtectionMessageFilter::OverrideTaskRunnerForMessage( 109 const IPC::Message& message) { 110 return content::BrowserThread::GetMessageLoopProxyForThread( 111 content::BrowserThread::UI); 112} 113 114int32_t PepperOutputProtectionMessageFilter::OnResourceMessageReceived( 115 const IPC::Message& msg, 116 ppapi::host::HostMessageContext* context) { 117 IPC_BEGIN_MESSAGE_MAP(PepperOutputProtectionMessageFilter, msg) 118 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0( 119 PpapiHostMsg_OutputProtection_QueryStatus, 120 OnQueryStatus); 121 PPAPI_DISPATCH_HOST_RESOURCE_CALL( 122 PpapiHostMsg_OutputProtection_EnableProtection, 123 OnEnableProtection); 124 IPC_END_MESSAGE_MAP() 125 return PP_ERROR_FAILED; 126} 127 128#if defined(OS_CHROMEOS) 129chromeos::OutputConfigurator::OutputProtectionClientId 130PepperOutputProtectionMessageFilter::GetClientId() { 131 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 132 if (client_id_ == 0) { 133#if defined(USE_ASH) && defined(USE_X11) 134 chromeos::OutputConfigurator* configurator = 135 ash::Shell::GetInstance()->output_configurator(); 136 client_id_ = configurator->RegisterOutputProtectionClient(); 137#endif 138 } 139 return client_id_; 140} 141#endif 142 143int32_t PepperOutputProtectionMessageFilter::OnQueryStatus( 144 ppapi::host::HostMessageContext* context) { 145 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 146 147#if defined(OS_CHROMEOS) && defined(USE_ASH) && defined(USE_X11) 148 ppapi::host::ReplyMessageContext reply_context = 149 context->MakeReplyMessageContext(); 150 uint32_t link_mask = 0, protection_mask = 0; 151 chromeos::OutputConfigurator* configurator = 152 ash::Shell::GetInstance()->output_configurator(); 153 bool result = configurator->QueryOutputProtectionStatus( 154 GetClientId(), &link_mask, &protection_mask); 155 156 // If we successfully retrieved the device level status, check for capturers. 157 if (result) { 158 // Ensure the RenderViewHost is still alive. 159 content::RenderViewHost* rvh = 160 content::RenderViewHost::FromID(render_process_id_, render_view_id_); 161 if (rvh) { 162 if (content::WebContents::FromRenderViewHost(rvh)->GetCapturerCount() > 0) 163 link_mask |= chromeos::OUTPUT_TYPE_NETWORK; 164 } 165 } 166 167 reply_context.params.set_result(result ? PP_OK : PP_ERROR_FAILED); 168 SendReply( 169 reply_context, 170 PpapiPluginMsg_OutputProtection_QueryStatusReply( 171 link_mask, protection_mask)); 172 return PP_OK_COMPLETIONPENDING; 173#else 174 NOTIMPLEMENTED(); 175 return PP_ERROR_NOTSUPPORTED; 176#endif 177} 178 179int32_t PepperOutputProtectionMessageFilter::OnEnableProtection( 180 ppapi::host::HostMessageContext* context, 181 uint32_t desired_method_mask) { 182 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 183 184#if defined(OS_CHROMEOS) && defined(USE_ASH) && defined(USE_X11) 185 ppapi::host::ReplyMessageContext reply_context = 186 context->MakeReplyMessageContext(); 187 chromeos::OutputConfigurator* configurator = 188 ash::Shell::GetInstance()->output_configurator(); 189 bool result = configurator->EnableOutputProtection( 190 GetClientId(), desired_method_mask); 191 reply_context.params.set_result(result ? PP_OK : PP_ERROR_FAILED); 192 SendReply( 193 reply_context, 194 PpapiPluginMsg_OutputProtection_EnableProtectionReply()); 195 return PP_OK_COMPLETIONPENDING; 196#else 197 NOTIMPLEMENTED(); 198 return PP_ERROR_NOTSUPPORTED; 199#endif 200} 201 202} // namespace chrome 203 204