• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
ConvertPluginDataPath(const base::FilePath & plugin_data_path)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 {
GetPermissionSettingsContextcontent::__anon414662a00111::GetPermissionSettingsContext32   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 
GetPermissionSettingsCallback(void * user_data,PP_Bool success,PP_Flash_BrowserOperations_Permission default_permission,uint32_t site_count,const PP_Flash_BrowserOperations_SiteSetting sites[])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 
BrokerProcessDispatcher(PP_GetInterface_Func get_plugin_interface,PP_ConnectInstance_Func connect_instance)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 
~BrokerProcessDispatcher()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 
OnMessageReceived(const IPC::Message & msg)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 
OnGetPermissionSettingsCompleted(uint32 request_id,bool success,PP_Flash_BrowserOperations_Permission default_permission,const ppapi::FlashSiteSettings & sites)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 
OnGetSitesWithData(uint32 request_id,const base::FilePath & plugin_data_path)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 
OnClearSiteData(uint32 request_id,const base::FilePath & plugin_data_path,const std::string & site,uint64 flags,uint64 max_age)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 
OnDeauthorizeContentLicenses(uint32 request_id,const base::FilePath & plugin_data_path)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 
OnGetPermissionSettings(uint32 request_id,const base::FilePath & plugin_data_path,PP_Flash_BrowserOperations_SettingType setting_type)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 
OnSetDefaultPermission(uint32 request_id,const base::FilePath & plugin_data_path,PP_Flash_BrowserOperations_SettingType setting_type,PP_Flash_BrowserOperations_Permission permission,bool clear_site_specific)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 
OnSetSitePermission(uint32 request_id,const base::FilePath & plugin_data_path,PP_Flash_BrowserOperations_SettingType setting_type,const ppapi::FlashSiteSettings & sites)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 
GetSitesWithData(const base::FilePath & plugin_data_path,std::vector<std::string> * site_vector)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 
ClearSiteData(const base::FilePath & plugin_data_path,const std::string & site,uint64 flags,uint64 max_age)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 
DeauthorizeContentLicenses(const base::FilePath & plugin_data_path)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 
SetDefaultPermission(const base::FilePath & plugin_data_path,PP_Flash_BrowserOperations_SettingType setting_type,PP_Flash_BrowserOperations_Permission permission,bool clear_site_specific)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 
SetSitePermission(const base::FilePath & plugin_data_path,PP_Flash_BrowserOperations_SettingType setting_type,const ppapi::FlashSiteSettings & sites)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