Home | History | Annotate | Download | only in ppapi_plugin
      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 "content/ppapi_plugin/broker_process_dispatcher.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/bind_helpers.h"
      9 #include "base/memory/scoped_ptr.h"
     10 #include "base/strings/utf_string_conversions.h"
     11 #include "content/child/child_process.h"
     12 #include "ppapi/c/pp_bool.h"
     13 #include "ppapi/c/private/ppp_flash_browser_operations.h"
     14 #include "ppapi/proxy/ppapi_messages.h"
     15 
     16 namespace content {
     17 namespace {
     18 
     19 // How long we wait before releasing the broker process.
     20 const int kBrokerReleaseTimeSeconds = 30;
     21 
     22 std::string ConvertPluginDataPath(const base::FilePath& plugin_data_path) {
     23   // The string is always 8-bit, convert on Windows.
     24 #if defined(OS_WIN)
     25   return WideToUTF8(plugin_data_path.value());
     26 #else
     27   return plugin_data_path.value();
     28 #endif
     29 }
     30 
     31 struct GetPermissionSettingsContext {
     32   GetPermissionSettingsContext(
     33       const base::WeakPtr<BrokerProcessDispatcher> in_dispatcher,
     34       uint32 in_request_id)
     35       : dispatcher(in_dispatcher),
     36         request_id(in_request_id) {
     37   }
     38 
     39   base::WeakPtr<BrokerProcessDispatcher> dispatcher;
     40   uint32 request_id;
     41 };
     42 
     43 void GetPermissionSettingsCallback(
     44     void* user_data,
     45     PP_Bool success,
     46     PP_Flash_BrowserOperations_Permission default_permission,
     47     uint32_t site_count,
     48     const PP_Flash_BrowserOperations_SiteSetting sites[]) {
     49   scoped_ptr<GetPermissionSettingsContext> context(
     50       reinterpret_cast<GetPermissionSettingsContext*>(user_data));
     51 
     52   if (!context->dispatcher.get())
     53     return;
     54 
     55   ppapi::FlashSiteSettings site_vector;
     56   if (success) {
     57     site_vector.reserve(site_count);
     58     for (uint32_t i = 0; i < site_count; ++i) {
     59       if (!sites[i].site) {
     60         success = PP_FALSE;
     61         break;
     62       }
     63       site_vector.push_back(
     64           ppapi::FlashSiteSetting(sites[i].site, sites[i].permission));
     65     }
     66 
     67     if (!success)
     68       site_vector.clear();
     69   }
     70   context->dispatcher->OnGetPermissionSettingsCompleted(
     71       context->request_id, PP_ToBool(success), default_permission, site_vector);
     72 }
     73 
     74 }  // namespace
     75 
     76 BrokerProcessDispatcher::BrokerProcessDispatcher(
     77     PP_GetInterface_Func get_plugin_interface,
     78     PP_ConnectInstance_Func connect_instance)
     79     : ppapi::proxy::BrokerSideDispatcher(connect_instance),
     80       get_plugin_interface_(get_plugin_interface),
     81       flash_browser_operations_1_3_(NULL),
     82       flash_browser_operations_1_2_(NULL),
     83       flash_browser_operations_1_0_(NULL) {
     84   ChildProcess::current()->AddRefProcess();
     85 
     86   if (get_plugin_interface) {
     87     flash_browser_operations_1_0_ =
     88         static_cast<const PPP_Flash_BrowserOperations_1_0*>(
     89             get_plugin_interface_(PPP_FLASH_BROWSEROPERATIONS_INTERFACE_1_0));
     90 
     91     flash_browser_operations_1_2_ =
     92         static_cast<const PPP_Flash_BrowserOperations_1_2*>(
     93             get_plugin_interface_(PPP_FLASH_BROWSEROPERATIONS_INTERFACE_1_2));
     94 
     95     flash_browser_operations_1_3_ =
     96         static_cast<const PPP_Flash_BrowserOperations_1_3*>(
     97             get_plugin_interface_(PPP_FLASH_BROWSEROPERATIONS_INTERFACE_1_3));
     98   }
     99 }
    100 
    101 BrokerProcessDispatcher::~BrokerProcessDispatcher() {
    102   DVLOG(1) << "BrokerProcessDispatcher::~BrokerProcessDispatcher()";
    103   // Don't free the process right away. This timer allows the child process
    104   // to be re-used if the user rapidly goes to a new page that requires this
    105   // plugin. This is the case for common plugins where they may be used on a
    106   // source and destination page of a navigation. We don't want to tear down
    107   // and re-start processes each time in these cases.
    108   base::MessageLoop::current()->PostDelayedTask(
    109       FROM_HERE,
    110       base::Bind(&ChildProcess::ReleaseProcess,
    111                  base::Unretained(ChildProcess::current())),
    112       base::TimeDelta::FromSeconds(kBrokerReleaseTimeSeconds));
    113 }
    114 
    115 bool BrokerProcessDispatcher::OnMessageReceived(const IPC::Message& msg) {
    116   IPC_BEGIN_MESSAGE_MAP(BrokerProcessDispatcher, msg)
    117     IPC_MESSAGE_HANDLER(PpapiMsg_GetSitesWithData, OnGetSitesWithData)
    118     IPC_MESSAGE_HANDLER(PpapiMsg_ClearSiteData, OnClearSiteData)
    119     IPC_MESSAGE_HANDLER(PpapiMsg_DeauthorizeContentLicenses,
    120                         OnDeauthorizeContentLicenses)
    121     IPC_MESSAGE_HANDLER(PpapiMsg_GetPermissionSettings, OnGetPermissionSettings)
    122     IPC_MESSAGE_HANDLER(PpapiMsg_SetDefaultPermission, OnSetDefaultPermission)
    123     IPC_MESSAGE_HANDLER(PpapiMsg_SetSitePermission, OnSetSitePermission)
    124     IPC_MESSAGE_UNHANDLED(return BrokerSideDispatcher::OnMessageReceived(msg))
    125   IPC_END_MESSAGE_MAP()
    126   return true;
    127 }
    128 
    129 void BrokerProcessDispatcher::OnGetPermissionSettingsCompleted(
    130     uint32 request_id,
    131     bool success,
    132     PP_Flash_BrowserOperations_Permission default_permission,
    133     const ppapi::FlashSiteSettings& sites) {
    134   Send(new PpapiHostMsg_GetPermissionSettingsResult(
    135       request_id, success, default_permission, sites));
    136 }
    137 
    138 void BrokerProcessDispatcher::OnGetSitesWithData(
    139     uint32 request_id,
    140     const base::FilePath& plugin_data_path) {
    141   std::vector<std::string> sites;
    142   GetSitesWithData(plugin_data_path, &sites);
    143   Send(new PpapiHostMsg_GetSitesWithDataResult(request_id, sites));
    144 }
    145 
    146 void BrokerProcessDispatcher::OnClearSiteData(
    147     uint32 request_id,
    148     const base::FilePath& plugin_data_path,
    149     const std::string& site,
    150     uint64 flags,
    151     uint64 max_age) {
    152   Send(new PpapiHostMsg_ClearSiteDataResult(
    153       request_id, ClearSiteData(plugin_data_path, site, flags, max_age)));
    154 }
    155 
    156 void BrokerProcessDispatcher::OnDeauthorizeContentLicenses(
    157     uint32 request_id,
    158     const base::FilePath& plugin_data_path) {
    159   Send(new PpapiHostMsg_DeauthorizeContentLicensesResult(
    160       request_id, DeauthorizeContentLicenses(plugin_data_path)));
    161 }
    162 
    163 void BrokerProcessDispatcher::OnGetPermissionSettings(
    164     uint32 request_id,
    165     const base::FilePath& plugin_data_path,
    166     PP_Flash_BrowserOperations_SettingType setting_type) {
    167   if (flash_browser_operations_1_3_) {
    168     std::string data_str = ConvertPluginDataPath(plugin_data_path);
    169     // The GetPermissionSettingsContext object will be deleted in
    170     // GetPermissionSettingsCallback().
    171     flash_browser_operations_1_3_->GetPermissionSettings(
    172         data_str.c_str(), setting_type, &GetPermissionSettingsCallback,
    173         new GetPermissionSettingsContext(AsWeakPtr(), request_id));
    174     return;
    175   }
    176 
    177   if (flash_browser_operations_1_2_) {
    178     std::string data_str = ConvertPluginDataPath(plugin_data_path);
    179     // The GetPermissionSettingsContext object will be deleted in
    180     // GetPermissionSettingsCallback().
    181     flash_browser_operations_1_2_->GetPermissionSettings(
    182         data_str.c_str(), setting_type, &GetPermissionSettingsCallback,
    183         new GetPermissionSettingsContext(AsWeakPtr(), request_id));
    184     return;
    185   }
    186 
    187   OnGetPermissionSettingsCompleted(
    188       request_id, false, PP_FLASH_BROWSEROPERATIONS_PERMISSION_DEFAULT,
    189       ppapi::FlashSiteSettings());
    190   return;
    191 }
    192 
    193 void BrokerProcessDispatcher::OnSetDefaultPermission(
    194     uint32 request_id,
    195     const base::FilePath& plugin_data_path,
    196     PP_Flash_BrowserOperations_SettingType setting_type,
    197     PP_Flash_BrowserOperations_Permission permission,
    198     bool clear_site_specific) {
    199   Send(new PpapiHostMsg_SetDefaultPermissionResult(
    200       request_id,
    201       SetDefaultPermission(plugin_data_path, setting_type, permission,
    202                            clear_site_specific)));
    203 }
    204 
    205 void BrokerProcessDispatcher::OnSetSitePermission(
    206     uint32 request_id,
    207     const base::FilePath& plugin_data_path,
    208     PP_Flash_BrowserOperations_SettingType setting_type,
    209     const ppapi::FlashSiteSettings& sites) {
    210   Send(new PpapiHostMsg_SetSitePermissionResult(
    211       request_id, SetSitePermission(plugin_data_path, setting_type, sites)));
    212 }
    213 
    214 void BrokerProcessDispatcher::GetSitesWithData(
    215     const base::FilePath& plugin_data_path,
    216     std::vector<std::string>* site_vector) {
    217   std::string data_str = ConvertPluginDataPath(plugin_data_path);
    218   if (flash_browser_operations_1_3_) {
    219     char** sites = NULL;
    220     flash_browser_operations_1_3_->GetSitesWithData(data_str.c_str(), &sites);
    221     if (!sites)
    222       return;
    223 
    224     for (size_t i = 0; sites[i]; ++i)
    225       site_vector->push_back(sites[i]);
    226 
    227     flash_browser_operations_1_3_->FreeSiteList(sites);
    228   }
    229 }
    230 
    231 bool BrokerProcessDispatcher::ClearSiteData(
    232     const base::FilePath& plugin_data_path,
    233     const std::string& site,
    234     uint64 flags,
    235     uint64 max_age) {
    236   std::string data_str = ConvertPluginDataPath(plugin_data_path);
    237   if (flash_browser_operations_1_3_) {
    238     flash_browser_operations_1_3_->ClearSiteData(
    239         data_str.c_str(), site.empty() ? NULL : site.c_str(), flags, max_age);
    240     return true;
    241   }
    242 
    243   // TODO(viettrungluu): Remove this (and the 1.0 interface) sometime after M21
    244   // goes to Stable.
    245   if (flash_browser_operations_1_2_) {
    246     flash_browser_operations_1_2_->ClearSiteData(
    247         data_str.c_str(), site.empty() ? NULL : site.c_str(), flags, max_age);
    248     return true;
    249   }
    250 
    251   if (flash_browser_operations_1_0_) {
    252     flash_browser_operations_1_0_->ClearSiteData(
    253         data_str.c_str(), site.empty() ? NULL : site.c_str(), flags, max_age);
    254     return true;
    255   }
    256 
    257   return false;
    258 }
    259 
    260 bool BrokerProcessDispatcher::DeauthorizeContentLicenses(
    261     const base::FilePath& plugin_data_path) {
    262   if (flash_browser_operations_1_3_) {
    263     std::string data_str = ConvertPluginDataPath(plugin_data_path);
    264     return PP_ToBool(flash_browser_operations_1_3_->DeauthorizeContentLicenses(
    265         data_str.c_str()));
    266   }
    267 
    268   if (flash_browser_operations_1_2_) {
    269     std::string data_str = ConvertPluginDataPath(plugin_data_path);
    270     return PP_ToBool(flash_browser_operations_1_2_->DeauthorizeContentLicenses(
    271         data_str.c_str()));
    272   }
    273 
    274   return false;
    275 }
    276 
    277 bool BrokerProcessDispatcher::SetDefaultPermission(
    278     const base::FilePath& plugin_data_path,
    279     PP_Flash_BrowserOperations_SettingType setting_type,
    280     PP_Flash_BrowserOperations_Permission permission,
    281     bool clear_site_specific) {
    282   if (flash_browser_operations_1_3_) {
    283     std::string data_str = ConvertPluginDataPath(plugin_data_path);
    284     return PP_ToBool(flash_browser_operations_1_3_->SetDefaultPermission(
    285         data_str.c_str(), setting_type, permission,
    286         PP_FromBool(clear_site_specific)));
    287   }
    288 
    289   if (flash_browser_operations_1_2_) {
    290     std::string data_str = ConvertPluginDataPath(plugin_data_path);
    291     return PP_ToBool(flash_browser_operations_1_2_->SetDefaultPermission(
    292         data_str.c_str(), setting_type, permission,
    293         PP_FromBool(clear_site_specific)));
    294   }
    295 
    296   return false;
    297 }
    298 
    299 bool BrokerProcessDispatcher::SetSitePermission(
    300     const base::FilePath& plugin_data_path,
    301     PP_Flash_BrowserOperations_SettingType setting_type,
    302     const ppapi::FlashSiteSettings& sites) {
    303   if (sites.empty())
    304     return true;
    305 
    306   std::string data_str = ConvertPluginDataPath(plugin_data_path);
    307   scoped_ptr<PP_Flash_BrowserOperations_SiteSetting[]> site_array(
    308       new PP_Flash_BrowserOperations_SiteSetting[sites.size()]);
    309 
    310   for (size_t i = 0; i < sites.size(); ++i) {
    311     site_array[i].site = sites[i].site.c_str();
    312     site_array[i].permission = sites[i].permission;
    313   }
    314 
    315   if (flash_browser_operations_1_3_) {
    316     PP_Bool result = flash_browser_operations_1_3_->SetSitePermission(
    317         data_str.c_str(), setting_type, sites.size(), site_array.get());
    318 
    319     return PP_ToBool(result);
    320   }
    321 
    322   if (flash_browser_operations_1_2_) {
    323     PP_Bool result = flash_browser_operations_1_2_->SetSitePermission(
    324         data_str.c_str(), setting_type, sites.size(), site_array.get());
    325 
    326     return PP_ToBool(result);
    327   }
    328 
    329   return false;
    330 }
    331 
    332 }  // namespace content
    333