Home | History | Annotate | Download | only in pepper
      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 =
     41       RenderProcessHost::FromID(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(BrowserPpapiHost* host,
     53                                                PP_Instance instance,
     54                                                PP_Resource resource)
     55     : ResourceHost(host->GetPpapiHost(), instance, resource),
     56       host_(host),
     57       weak_factory_(this) {
     58   int unused;
     59   host->GetRenderFrameIDsForInstance(instance, &render_process_id_, &unused);
     60 }
     61 
     62 PepperFlashBrowserHost::~PepperFlashBrowserHost() {}
     63 
     64 int32_t PepperFlashBrowserHost::OnResourceMessageReceived(
     65     const IPC::Message& msg,
     66     ppapi::host::HostMessageContext* context) {
     67   PPAPI_BEGIN_MESSAGE_MAP(PepperFlashBrowserHost, msg)
     68     PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_Flash_UpdateActivity,
     69                                         OnUpdateActivity)
     70     PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Flash_GetLocalTimeZoneOffset,
     71                                       OnGetLocalTimeZoneOffset)
     72     PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(
     73         PpapiHostMsg_Flash_GetLocalDataRestrictions, OnGetLocalDataRestrictions)
     74   PPAPI_END_MESSAGE_MAP()
     75   return PP_ERROR_FAILED;
     76 }
     77 
     78 int32_t PepperFlashBrowserHost::OnUpdateActivity(
     79     ppapi::host::HostMessageContext* host_context) {
     80 #if defined(OS_WIN)
     81   // Reading then writing back the same value to the screensaver timeout system
     82   // setting resets the countdown which prevents the screensaver from turning
     83   // on "for a while". As long as the plugin pings us with this message faster
     84   // than the screensaver timeout, it won't go on.
     85   int value = 0;
     86   if (SystemParametersInfo(SPI_GETSCREENSAVETIMEOUT, 0, &value, 0))
     87     SystemParametersInfo(SPI_SETSCREENSAVETIMEOUT, value, NULL, 0);
     88 #elif defined(OS_MACOSX)
     89   UpdateSystemActivity(OverallAct);
     90 #else
     91 // TODO(brettw) implement this for other platforms.
     92 #endif
     93   return PP_OK;
     94 }
     95 
     96 int32_t PepperFlashBrowserHost::OnGetLocalTimeZoneOffset(
     97     ppapi::host::HostMessageContext* host_context,
     98     const base::Time& t) {
     99   // The reason for this processing being in the browser process is that on
    100   // Linux, the localtime calls require filesystem access prohibited by the
    101   // sandbox.
    102   host_context->reply_msg = PpapiPluginMsg_Flash_GetLocalTimeZoneOffsetReply(
    103       ppapi::PPGetLocalTimeZoneOffset(t));
    104   return PP_OK;
    105 }
    106 
    107 int32_t PepperFlashBrowserHost::OnGetLocalDataRestrictions(
    108     ppapi::host::HostMessageContext* context) {
    109   // Getting the Flash LSO settings requires using the CookieSettings which
    110   // belong to the profile which lives on the UI thread. We lazily initialize
    111   // |cookie_settings_| by grabbing the reference from the UI thread and then
    112   // call |GetLocalDataRestrictions| with it.
    113   GURL document_url = host_->GetDocumentURLForInstance(pp_instance());
    114   GURL plugin_url = host_->GetPluginURLForInstance(pp_instance());
    115   if (cookie_settings_.get()) {
    116     GetLocalDataRestrictions(context->MakeReplyMessageContext(),
    117                              document_url,
    118                              plugin_url,
    119                              cookie_settings_);
    120   } else {
    121     BrowserThread::PostTaskAndReplyWithResult(
    122         BrowserThread::UI,
    123         FROM_HERE,
    124         base::Bind(&GetCookieSettings, render_process_id_),
    125         base::Bind(&PepperFlashBrowserHost::GetLocalDataRestrictions,
    126                    weak_factory_.GetWeakPtr(),
    127                    context->MakeReplyMessageContext(),
    128                    document_url,
    129                    plugin_url));
    130   }
    131   return PP_OK_COMPLETIONPENDING;
    132 }
    133 
    134 void PepperFlashBrowserHost::GetLocalDataRestrictions(
    135     ppapi::host::ReplyMessageContext reply_context,
    136     const GURL& document_url,
    137     const GURL& plugin_url,
    138     scoped_refptr<CookieSettings> cookie_settings) {
    139   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
    140 
    141   // Lazily initialize |cookie_settings_|. The cookie settings are thread-safe
    142   // ref-counted so as long as we hold a reference to them we can safely access
    143   // them on the IO thread.
    144   if (!cookie_settings_.get()) {
    145     cookie_settings_ = cookie_settings;
    146   } else {
    147     DCHECK(cookie_settings_.get() == cookie_settings.get());
    148   }
    149 
    150   PP_FlashLSORestrictions restrictions = PP_FLASHLSORESTRICTIONS_NONE;
    151   if (cookie_settings_.get() && document_url.is_valid() &&
    152       plugin_url.is_valid()) {
    153     if (!cookie_settings_->IsReadingCookieAllowed(document_url, plugin_url))
    154       restrictions = PP_FLASHLSORESTRICTIONS_BLOCK;
    155     else if (cookie_settings_->IsCookieSessionOnly(plugin_url))
    156       restrictions = PP_FLASHLSORESTRICTIONS_IN_MEMORY;
    157   }
    158   SendReply(reply_context,
    159             PpapiPluginMsg_Flash_GetLocalDataRestrictionsReply(
    160                 static_cast<int32_t>(restrictions)));
    161 }
    162 
    163 }  // namespace chrome
    164