Fix crash on app list start page contents not existing.
[chromium-blink-merge.git] / content / ppapi_plugin / broker_process_dispatcher.cc
blob97d425043c88248b4ff1a29f549117d5a76cbbd1
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.
5 #include "content/ppapi_plugin/broker_process_dispatcher.h"
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"
16 namespace content {
17 namespace {
19 // How long we wait before releasing the broker process.
20 const int kBrokerReleaseTimeSeconds = 30;
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
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) {
39 base::WeakPtr<BrokerProcessDispatcher> dispatcher;
40 uint32 request_id;
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));
52 if (!context->dispatcher.get())
53 return;
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;
63 site_vector.push_back(
64 ppapi::FlashSiteSetting(sites[i].site, sites[i].permission));
67 if (!success)
68 site_vector.clear();
70 context->dispatcher->OnGetPermissionSettingsCompleted(
71 context->request_id, PP_ToBool(success), default_permission, site_vector);
74 } // namespace
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));
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));
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));
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));
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;
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));
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));
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)));
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)));
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;
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;
182 OnGetPermissionSettingsCompleted(
183 request_id, false, PP_FLASH_BROWSEROPERATIONS_PERMISSION_DEFAULT,
184 ppapi::FlashSiteSettings());
185 return;
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)));
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)));
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;
219 for (size_t i = 0; sites[i]; ++i)
220 site_vector->push_back(sites[i]);
222 flash_browser_operations_1_3_->FreeSiteList(sites);
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;
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;
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;
252 return false;
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()));
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()));
269 return false;
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)));
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)));
291 return false;
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;
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()]);
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;
310 if (flash_browser_operations_1_3_) {
311 PP_Bool result = flash_browser_operations_1_3_->SetSitePermission(
312 data_str.c_str(), setting_type,
313 static_cast<uint32_t>(sites.size()), site_array.get());
315 return PP_ToBool(result);
318 if (flash_browser_operations_1_2_) {
319 PP_Bool result = flash_browser_operations_1_2_->SetSitePermission(
320 data_str.c_str(), setting_type,
321 static_cast<uint32_t>(sites.size()), site_array.get());
323 return PP_ToBool(result);
326 return false;
329 } // namespace content