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 base::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   if (get_plugin_interface) {
     85     flash_browser_operations_1_0_ =
     86         static_cast<const PPP_Flash_BrowserOperations_1_0*>(
     87             get_plugin_interface_(PPP_FLASH_BROWSEROPERATIONS_INTERFACE_1_0));
     88 
     89     flash_browser_operations_1_2_ =
     90         static_cast<const PPP_Flash_BrowserOperations_1_2*>(
     91             get_plugin_interface_(PPP_FLASH_BROWSEROPERATIONS_INTERFACE_1_2));
     92 
     93     flash_browser_operations_1_3_ =
     94         static_cast<const PPP_Flash_BrowserOperations_1_3*>(
     95             get_plugin_interface_(PPP_FLASH_BROWSEROPERATIONS_INTERFACE_1_3));
     96   }
     97 }
     98 
     99 BrokerProcessDispatcher::~BrokerProcessDispatcher() {
    100   DVLOG(1) << "BrokerProcessDispatcher::~BrokerProcessDispatcher()";
    101   // Don't free the process right away. This timer allows the child process
    102   // to be re-used if the user rapidly goes to a new page that requires this
    103   // plugin. This is the case for common plugins where they may be used on a
    104   // source and destination page of a navigation. We don't want to tear down
    105   // and re-start processes each time in these cases.
    106   process_ref_.ReleaseWithDelay(
    107       base::TimeDelta::FromSeconds(kBrokerReleaseTimeSeconds));
    108 }
    109 
    110 bool BrokerProcessDispatcher::OnMessageReceived(const IPC::Message& msg) {
    111   IPC_BEGIN_MESSAGE_MAP(BrokerProcessDispatcher, msg)
    112     IPC_MESSAGE_HANDLER(PpapiMsg_GetSitesWithData, OnGetSitesWithData)
    113     IPC_MESSAGE_HANDLER(PpapiMsg_ClearSiteData, OnClearSiteData)
    114     IPC_MESSAGE_HANDLER(PpapiMsg_DeauthorizeContentLicenses,
    115                         OnDeauthorizeContentLicenses)
    116     IPC_MESSAGE_HANDLER(PpapiMsg_GetPermissionSettings, OnGetPermissionSettings)
    117     IPC_MESSAGE_HANDLER(PpapiMsg_SetDefaultPermission, OnSetDefaultPermission)
    118     IPC_MESSAGE_HANDLER(PpapiMsg_SetSitePermission, OnSetSitePermission)
    119     IPC_MESSAGE_UNHANDLED(return BrokerSideDispatcher::OnMessageReceived(msg))
    120   IPC_END_MESSAGE_MAP()
    121   return true;
    122 }
    123 
    124 void BrokerProcessDispatcher::OnGetPermissionSettingsCompleted(
    125     uint32 request_id,
    126     bool success,
    127     PP_Flash_BrowserOperations_Permission default_permission,
    128     const ppapi::FlashSiteSettings& sites) {
    129   Send(new PpapiHostMsg_GetPermissionSettingsResult(
    130       request_id, success, default_permission, sites));
    131 }
    132 
    133 void BrokerProcessDispatcher::OnGetSitesWithData(
    134     uint32 request_id,
    135     const base::FilePath& plugin_data_path) {
    136   std::vector<std::string> sites;
    137   GetSitesWithData(plugin_data_path, &sites);
    138   Send(new PpapiHostMsg_GetSitesWithDataResult(request_id, sites));
    139 }
    140 
    141 void BrokerProcessDispatcher::OnClearSiteData(
    142     uint32 request_id,
    143     const base::FilePath& plugin_data_path,
    144     const std::string& site,
    145     uint64 flags,
    146     uint64 max_age) {
    147   Send(new PpapiHostMsg_ClearSiteDataResult(
    148       request_id, ClearSiteData(plugin_data_path, site, flags, max_age)));
    149 }
    150 
    151 void BrokerProcessDispatcher::OnDeauthorizeContentLicenses(
    152     uint32 request_id,
    153     const base::FilePath& plugin_data_path) {
    154   Send(new PpapiHostMsg_DeauthorizeContentLicensesResult(
    155       request_id, DeauthorizeContentLicenses(plugin_data_path)));
    156 }
    157 
    158 void BrokerProcessDispatcher::OnGetPermissionSettings(
    159     uint32 request_id,
    160     const base::FilePath& plugin_data_path,
    161     PP_Flash_BrowserOperations_SettingType setting_type) {
    162   if (flash_browser_operations_1_3_) {
    163     std::string data_str = ConvertPluginDataPath(plugin_data_path);
    164     // The GetPermissionSettingsContext object will be deleted in
    165     // GetPermissionSettingsCallback().
    166     flash_browser_operations_1_3_->GetPermissionSettings(
    167         data_str.c_str(), setting_type, &GetPermissionSettingsCallback,
    168         new GetPermissionSettingsContext(AsWeakPtr(), request_id));
    169     return;
    170   }
    171 
    172   if (flash_browser_operations_1_2_) {
    173     std::string data_str = ConvertPluginDataPath(plugin_data_path);
    174     // The GetPermissionSettingsContext object will be deleted in
    175     // GetPermissionSettingsCallback().
    176     flash_browser_operations_1_2_->GetPermissionSettings(
    177         data_str.c_str(), setting_type, &GetPermissionSettingsCallback,
    178         new GetPermissionSettingsContext(AsWeakPtr(), request_id));
    179     return;
    180   }
    181 
    182   OnGetPermissionSettingsCompleted(
    183       request_id, false, PP_FLASH_BROWSEROPERATIONS_PERMISSION_DEFAULT,
    184       ppapi::FlashSiteSettings());
    185   return;
    186 }
    187 
    188 void BrokerProcessDispatcher::OnSetDefaultPermission(
    189     uint32 request_id,
    190     const base::FilePath& plugin_data_path,
    191     PP_Flash_BrowserOperations_SettingType setting_type,
    192     PP_Flash_BrowserOperations_Permission permission,
    193     bool clear_site_specific) {
    194   Send(new PpapiHostMsg_SetDefaultPermissionResult(
    195       request_id,
    196       SetDefaultPermission(plugin_data_path, setting_type, permission,
    197                            clear_site_specific)));
    198 }
    199 
    200 void BrokerProcessDispatcher::OnSetSitePermission(
    201     uint32 request_id,
    202     const base::FilePath& plugin_data_path,
    203     PP_Flash_BrowserOperations_SettingType setting_type,
    204     const ppapi::FlashSiteSettings& sites) {
    205   Send(new PpapiHostMsg_SetSitePermissionResult(
    206       request_id, SetSitePermission(plugin_data_path, setting_type, sites)));
    207 }
    208 
    209 void BrokerProcessDispatcher::GetSitesWithData(
    210     const base::FilePath& plugin_data_path,
    211     std::vector<std::string>* site_vector) {
    212   std::string data_str = ConvertPluginDataPath(plugin_data_path);
    213   if (flash_browser_operations_1_3_) {
    214     char** sites = NULL;
    215     flash_browser_operations_1_3_->GetSitesWithData(data_str.c_str(), &sites);
    216     if (!sites)
    217       return;
    218 
    219     for (size_t i = 0; sites[i]; ++i)
    220       site_vector->push_back(sites[i]);
    221 
    222     flash_browser_operations_1_3_->FreeSiteList(sites);
    223   }
    224 }
    225 
    226 bool BrokerProcessDispatcher::ClearSiteData(
    227     const base::FilePath& plugin_data_path,
    228     const std::string& site,
    229     uint64 flags,
    230     uint64 max_age) {
    231   std::string data_str = ConvertPluginDataPath(plugin_data_path);
    232   if (flash_browser_operations_1_3_) {
    233     flash_browser_operations_1_3_->ClearSiteData(
    234         data_str.c_str(), site.empty() ? NULL : site.c_str(), flags, max_age);
    235     return true;
    236   }
    237 
    238   // TODO(viettrungluu): Remove this (and the 1.0 interface) sometime after M21
    239   // goes to Stable.
    240   if (flash_browser_operations_1_2_) {
    241     flash_browser_operations_1_2_->ClearSiteData(
    242         data_str.c_str(), site.empty() ? NULL : site.c_str(), flags, max_age);
    243     return true;
    244   }
    245 
    246   if (flash_browser_operations_1_0_) {
    247     flash_browser_operations_1_0_->ClearSiteData(
    248         data_str.c_str(), site.empty() ? NULL : site.c_str(), flags, max_age);
    249     return true;
    250   }
    251 
    252   return false;
    253 }
    254 
    255 bool BrokerProcessDispatcher::DeauthorizeContentLicenses(
    256     const base::FilePath& plugin_data_path) {
    257   if (flash_browser_operations_1_3_) {
    258     std::string data_str = ConvertPluginDataPath(plugin_data_path);
    259     return PP_ToBool(flash_browser_operations_1_3_->DeauthorizeContentLicenses(
    260         data_str.c_str()));
    261   }
    262 
    263   if (flash_browser_operations_1_2_) {
    264     std::string data_str = ConvertPluginDataPath(plugin_data_path);
    265     return PP_ToBool(flash_browser_operations_1_2_->DeauthorizeContentLicenses(
    266         data_str.c_str()));
    267   }
    268 
    269   return false;
    270 }
    271 
    272 bool BrokerProcessDispatcher::SetDefaultPermission(
    273     const base::FilePath& plugin_data_path,
    274     PP_Flash_BrowserOperations_SettingType setting_type,
    275     PP_Flash_BrowserOperations_Permission permission,
    276     bool clear_site_specific) {
    277   if (flash_browser_operations_1_3_) {
    278     std::string data_str = ConvertPluginDataPath(plugin_data_path);
    279     return PP_ToBool(flash_browser_operations_1_3_->SetDefaultPermission(
    280         data_str.c_str(), setting_type, permission,
    281         PP_FromBool(clear_site_specific)));
    282   }
    283 
    284   if (flash_browser_operations_1_2_) {
    285     std::string data_str = ConvertPluginDataPath(plugin_data_path);
    286     return PP_ToBool(flash_browser_operations_1_2_->SetDefaultPermission(
    287         data_str.c_str(), setting_type, permission,
    288         PP_FromBool(clear_site_specific)));
    289   }
    290 
    291   return false;
    292 }
    293 
    294 bool BrokerProcessDispatcher::SetSitePermission(
    295     const base::FilePath& plugin_data_path,
    296     PP_Flash_BrowserOperations_SettingType setting_type,
    297     const ppapi::FlashSiteSettings& sites) {
    298   if (sites.empty())
    299     return true;
    300 
    301   std::string data_str = ConvertPluginDataPath(plugin_data_path);
    302   scoped_ptr<PP_Flash_BrowserOperations_SiteSetting[]> site_array(
    303       new PP_Flash_BrowserOperations_SiteSetting[sites.size()]);
    304 
    305   for (size_t i = 0; i < sites.size(); ++i) {
    306     site_array[i].site = sites[i].site.c_str();
    307     site_array[i].permission = sites[i].permission;
    308   }
    309 
    310   if (flash_browser_operations_1_3_) {
    311     PP_Bool result = flash_browser_operations_1_3_->SetSitePermission(
    312         data_str.c_str(), setting_type, sites.size(), site_array.get());
    313 
    314     return PP_ToBool(result);
    315   }
    316 
    317   if (flash_browser_operations_1_2_) {
    318     PP_Bool result = flash_browser_operations_1_2_->SetSitePermission(
    319         data_str.c_str(), setting_type, sites.size(), site_array.get());
    320 
    321     return PP_ToBool(result);
    322   }
    323 
    324   return false;
    325 }
    326 
    327 }  // namespace content
    328