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 "chrome/browser/renderer_host/pepper/pepper_flash_browser_host.h" 6 7 #include "base/time/time.h" 8 #include "chrome/browser/content_settings/cookie_settings.h" 9 #include "chrome/browser/profiles/profile.h" 10 #include "content/public/browser/browser_context.h" 11 #include "content/public/browser/browser_ppapi_host.h" 12 #include "content/public/browser/browser_thread.h" 13 #include "content/public/browser/render_process_host.h" 14 #include "ipc/ipc_message_macros.h" 15 #include "ppapi/c/pp_errors.h" 16 #include "ppapi/c/private/ppb_flash.h" 17 #include "ppapi/host/dispatch_host_message.h" 18 #include "ppapi/proxy/ppapi_messages.h" 19 #include "ppapi/proxy/resource_message_params.h" 20 #include "ppapi/shared_impl/time_conversion.h" 21 #include "url/gurl.h" 22 23 #if defined(OS_WIN) 24 #include <windows.h> 25 #elif defined(OS_MACOSX) 26 #include <CoreServices/CoreServices.h> 27 #endif 28 29 using content::BrowserPpapiHost; 30 using content::BrowserThread; 31 using content::RenderProcessHost; 32 33 namespace chrome { 34 35 namespace { 36 37 // Get the CookieSettings on the UI thread for the given render process ID. 38 scoped_refptr<CookieSettings> GetCookieSettings(int render_process_id) { 39 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 40 RenderProcessHost* render_process_host = RenderProcessHost::FromID( 41 render_process_id); 42 if (render_process_host && render_process_host->GetBrowserContext()) { 43 Profile* profile = 44 Profile::FromBrowserContext(render_process_host->GetBrowserContext()); 45 return CookieSettings::Factory::GetForProfile(profile); 46 } 47 return NULL; 48 } 49 50 } // namespace 51 52 PepperFlashBrowserHost::PepperFlashBrowserHost( 53 BrowserPpapiHost* host, 54 PP_Instance instance, 55 PP_Resource resource) 56 : ResourceHost(host->GetPpapiHost(), instance, resource), 57 host_(host), 58 weak_factory_(this) { 59 int unused; 60 host->GetRenderViewIDsForInstance(instance, &render_process_id_, &unused); 61 } 62 63 PepperFlashBrowserHost::~PepperFlashBrowserHost() { 64 } 65 66 int32_t PepperFlashBrowserHost::OnResourceMessageReceived( 67 const IPC::Message& msg, 68 ppapi::host::HostMessageContext* context) { 69 IPC_BEGIN_MESSAGE_MAP(PepperFlashBrowserHost, msg) 70 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_Flash_UpdateActivity, 71 OnUpdateActivity); 72 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Flash_GetLocalTimeZoneOffset, 73 OnGetLocalTimeZoneOffset); 74 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0( 75 PpapiHostMsg_Flash_GetLocalDataRestrictions, 76 OnGetLocalDataRestrictions); 77 IPC_END_MESSAGE_MAP() 78 return PP_ERROR_FAILED; 79 } 80 81 int32_t PepperFlashBrowserHost::OnUpdateActivity( 82 ppapi::host::HostMessageContext* host_context) { 83 #if defined(OS_WIN) 84 // Reading then writing back the same value to the screensaver timeout system 85 // setting resets the countdown which prevents the screensaver from turning 86 // on "for a while". As long as the plugin pings us with this message faster 87 // than the screensaver timeout, it won't go on. 88 int value = 0; 89 if (SystemParametersInfo(SPI_GETSCREENSAVETIMEOUT, 0, &value, 0)) 90 SystemParametersInfo(SPI_SETSCREENSAVETIMEOUT, value, NULL, 0); 91 #elif defined(OS_MACOSX) 92 UpdateSystemActivity(OverallAct); 93 #else 94 // TODO(brettw) implement this for other platforms. 95 #endif 96 return PP_OK; 97 } 98 99 int32_t PepperFlashBrowserHost::OnGetLocalTimeZoneOffset( 100 ppapi::host::HostMessageContext* host_context, 101 const base::Time& t) { 102 // The reason for this processing being in the browser process is that on 103 // Linux, the localtime calls require filesystem access prohibited by the 104 // sandbox. 105 host_context->reply_msg = PpapiPluginMsg_Flash_GetLocalTimeZoneOffsetReply( 106 ppapi::PPGetLocalTimeZoneOffset(t)); 107 return PP_OK; 108 } 109 110 int32_t PepperFlashBrowserHost::OnGetLocalDataRestrictions( 111 ppapi::host::HostMessageContext* context) { 112 // Getting the Flash LSO settings requires using the CookieSettings which 113 // belong to the profile which lives on the UI thread. We lazily initialize 114 // |cookie_settings_| by grabbing the reference from the UI thread and then 115 // call |GetLocalDataRestrictions| with it. 116 GURL document_url = host_->GetDocumentURLForInstance(pp_instance()); 117 GURL plugin_url = host_->GetPluginURLForInstance(pp_instance()); 118 if (cookie_settings_.get()) { 119 GetLocalDataRestrictions(context->MakeReplyMessageContext(), document_url, 120 plugin_url, cookie_settings_); 121 } else { 122 BrowserThread::PostTaskAndReplyWithResult(BrowserThread::UI, FROM_HERE, 123 base::Bind(&GetCookieSettings, render_process_id_), 124 base::Bind(&PepperFlashBrowserHost::GetLocalDataRestrictions, 125 weak_factory_.GetWeakPtr(), 126 context->MakeReplyMessageContext(), 127 document_url, plugin_url)); 128 } 129 return PP_OK_COMPLETIONPENDING; 130 } 131 132 void PepperFlashBrowserHost::GetLocalDataRestrictions( 133 ppapi::host::ReplyMessageContext reply_context, 134 const GURL& document_url, 135 const GURL& plugin_url, 136 scoped_refptr<CookieSettings> cookie_settings) { 137 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 138 139 // Lazily initialize |cookie_settings_|. The cookie settings are thread-safe 140 // ref-counted so as long as we hold a reference to them we can safely access 141 // them on the IO thread. 142 if (!cookie_settings_.get()) { 143 cookie_settings_ = cookie_settings; 144 } else { 145 DCHECK(cookie_settings_.get() == cookie_settings.get()); 146 } 147 148 PP_FlashLSORestrictions restrictions = PP_FLASHLSORESTRICTIONS_NONE; 149 if (cookie_settings_.get() && document_url.is_valid() && 150 plugin_url.is_valid()) { 151 if (!cookie_settings_->IsReadingCookieAllowed(document_url, plugin_url)) 152 restrictions = PP_FLASHLSORESTRICTIONS_BLOCK; 153 else if (cookie_settings_->IsCookieSessionOnly(plugin_url)) 154 restrictions = PP_FLASHLSORESTRICTIONS_IN_MEMORY; 155 } 156 SendReply(reply_context, PpapiPluginMsg_Flash_GetLocalDataRestrictionsReply( 157 static_cast<int32_t>(restrictions))); 158 } 159 160 } // namespace chrome 161