Run canExecute before executing delete command.
[chromium-blink-merge.git] / chrome / browser / pepper_flash_settings_manager.cc
blobeb64b49fe8cbbf2fe4218494d804b2bf70187422
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 "chrome/browser/pepper_flash_settings_manager.h"
7 #include <map>
8 #include <utility>
9 #include <vector>
11 #include "base/bind.h"
12 #include "base/compiler_specific.h"
13 #include "base/files/file_util.h"
14 #include "base/prefs/pref_service.h"
15 #include "base/sequenced_task_runner_helpers.h"
16 #include "base/strings/utf_string_conversions.h"
17 #include "chrome/browser/plugins/plugin_prefs.h"
18 #include "chrome/browser/profiles/profile.h"
19 #include "chrome/browser/renderer_host/pepper/device_id_fetcher.h"
20 #include "chrome/common/pref_names.h"
21 #include "components/pref_registry/pref_registry_syncable.h"
22 #include "content/public/browser/browser_context.h"
23 #include "content/public/browser/browser_thread.h"
24 #include "content/public/browser/pepper_flash_settings_helper.h"
25 #include "content/public/browser/plugin_service.h"
26 #include "content/public/common/content_constants.h"
27 #include "content/public/common/webplugininfo.h"
28 #include "ipc/ipc_channel.h"
29 #include "ipc/ipc_listener.h"
30 #include "ppapi/proxy/ppapi_messages.h"
31 #include "url/gurl.h"
33 using content::BrowserThread;
35 class PepperFlashSettingsManager::Core
36 : public IPC::Listener,
37 public base::RefCountedThreadSafe<Core, BrowserThread::DeleteOnIOThread> {
38 public:
39 Core(base::WeakPtr<PepperFlashSettingsManager> manager,
40 content::BrowserContext* browser_context);
42 void Initialize();
44 // Notifies the core that it has been detached. Afterwards, no method should
45 // be called any more.
46 void Detach();
48 void DeauthorizeContentLicenses(uint32 request_id);
49 void GetPermissionSettings(
50 uint32 request_id,
51 PP_Flash_BrowserOperations_SettingType setting_type);
52 void SetDefaultPermission(
53 uint32 request_id,
54 PP_Flash_BrowserOperations_SettingType setting_type,
55 PP_Flash_BrowserOperations_Permission permission,
56 bool clear_site_specific);
57 void SetSitePermission(uint32 request_id,
58 PP_Flash_BrowserOperations_SettingType setting_type,
59 const ppapi::FlashSiteSettings& sites);
60 void GetSitesWithData(uint32 request_id);
61 void ClearSiteData(uint32 request_id,
62 const std::string& site,
63 uint64 flags,
64 uint64 max_age);
66 // IPC::Listener implementation.
67 bool OnMessageReceived(const IPC::Message& message) override;
68 void OnChannelError() override;
70 private:
71 friend struct BrowserThread::DeleteOnThread<BrowserThread::IO>;
72 friend class base::DeleteHelper<Core>;
74 enum RequestType {
75 INVALID_REQUEST_TYPE = 0,
76 DEAUTHORIZE_CONTENT_LICENSES,
77 GET_PERMISSION_SETTINGS,
78 SET_DEFAULT_PERMISSION,
79 SET_SITE_PERMISSION,
80 GET_SITES_WITH_DATA,
81 CLEAR_SITE_DATA,
84 enum State {
85 STATE_UNINITIALIZED = 0,
86 STATE_INITIALIZED,
87 STATE_ERROR,
88 STATE_DETACHED,
91 struct PendingRequest {
92 PendingRequest()
93 : id(0),
94 type(INVALID_REQUEST_TYPE),
95 setting_type(PP_FLASH_BROWSEROPERATIONS_SETTINGTYPE_CAMERAMIC),
96 permission(PP_FLASH_BROWSEROPERATIONS_PERMISSION_DEFAULT),
97 clear_site_specific(false),
98 flags(0),
99 max_age(0) {
102 uint32 id;
103 RequestType type;
105 // Used by GET_PERMISSION_SETTINGS, SET_DEFAULT_PERMISSION and
106 // SET_SITE_PERMISSION.
107 PP_Flash_BrowserOperations_SettingType setting_type;
109 // Used by SET_DEFAULT_PERMISSION.
110 PP_Flash_BrowserOperations_Permission permission;
111 bool clear_site_specific;
113 // Used by SET_SITE_PERMISSION.
114 ppapi::FlashSiteSettings sites;
116 // Used by CLEAR_SITE_DATA
117 std::string site;
118 uint64 flags;
119 uint64 max_age;
122 ~Core() override;
124 void ConnectToChannel(bool success, const IPC::ChannelHandle& handle);
126 void InitializeOnIOThread();
127 void DeauthorizeContentLicensesOnIOThread(uint32 request_id);
128 void DeauthorizeContentLicensesOnBlockingPool(
129 uint32 request_id,
130 const base::FilePath& profile_path);
131 void DeauthorizeContentLicensesInPlugin(uint32 request_id, bool success);
132 void GetPermissionSettingsOnIOThread(
133 uint32 request_id,
134 PP_Flash_BrowserOperations_SettingType setting_type);
135 void SetDefaultPermissionOnIOThread(
136 uint32 request_id,
137 PP_Flash_BrowserOperations_SettingType setting_type,
138 PP_Flash_BrowserOperations_Permission permission,
139 bool clear_site_specific);
140 void SetSitePermissionOnIOThread(
141 uint32 request_id,
142 PP_Flash_BrowserOperations_SettingType setting_type,
143 const ppapi::FlashSiteSettings& sites);
144 void GetSitesWithDataOnIOThread(uint32 request_id);
145 void ClearSiteDataOnIOThread(uint32 request_id,
146 const std::string& site,
147 uint64 flags,
148 uint64 max_age);
149 void DetachOnIOThread();
151 void NotifyErrorFromIOThread();
153 void NotifyDeauthorizeContentLicensesCompleted(uint32 request_id,
154 bool success);
155 void NotifyGetPermissionSettingsCompleted(
156 uint32 request_id,
157 bool success,
158 PP_Flash_BrowserOperations_Permission default_permission,
159 const ppapi::FlashSiteSettings& sites);
160 void NotifySetDefaultPermissionCompleted(uint32 request_id, bool success);
161 void NotifySetSitePermissionCompleted(uint32 request_id, bool success);
162 void NotifyGetSitesWithDataCompleted(uint32 request_id,
163 const std::vector<std::string>& sites);
164 void NotifyClearSiteDataCompleted(uint32 request_id, bool success);
166 void NotifyError(
167 const std::vector<std::pair<uint32, RequestType> >& notifications);
169 // Message handlers.
170 void OnDeauthorizeContentLicensesResult(uint32 request_id, bool success);
171 void OnGetPermissionSettingsResult(
172 uint32 request_id,
173 bool success,
174 PP_Flash_BrowserOperations_Permission default_permission,
175 const ppapi::FlashSiteSettings& sites);
176 void OnSetDefaultPermissionResult(uint32 request_id, bool success);
177 void OnSetSitePermissionResult(uint32 request_id, bool success);
178 void OnGetSitesWithDataResult(uint32 request_id,
179 const std::vector<std::string>& sites);
180 void OnClearSiteDataResult(uint32 request_id, bool success);
182 // Used only on the UI thread.
183 base::WeakPtr<PepperFlashSettingsManager> manager_;
185 // Used only on the I/O thread.
186 base::FilePath plugin_data_path_;
188 // The channel is NULL until we have opened a connection to the broker
189 // process. Used only on the I/O thread.
190 scoped_ptr<IPC::Channel> channel_;
192 // Used only on the I/O thread.
193 State state_;
195 // Requests that need to be sent once the channel to the broker process is
196 // established. Used only on the I/O thread.
197 std::vector<PendingRequest> pending_requests_;
198 // Requests that have been sent but haven't got replied. Used only on the
199 // I/O thread.
200 std::map<uint32, RequestType> pending_responses_;
202 // Used only on the I/O thread.
203 scoped_refptr<content::PepperFlashSettingsHelper> helper_;
205 // Path for the current profile. Must be retrieved on the UI thread from the
206 // browser context when we start so we can use it later on the I/O thread.
207 base::FilePath browser_context_path_;
209 scoped_refptr<PluginPrefs> plugin_prefs_;
212 PepperFlashSettingsManager::Core::Core(
213 base::WeakPtr<PepperFlashSettingsManager> manager,
214 content::BrowserContext* browser_context)
215 : manager_(manager),
216 state_(STATE_UNINITIALIZED),
217 browser_context_path_(browser_context->GetPath()),
218 plugin_prefs_(PluginPrefs::GetForProfile(
219 Profile::FromBrowserContext(browser_context))) {
220 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
223 PepperFlashSettingsManager::Core::~Core() {
224 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
227 void PepperFlashSettingsManager::Core::Initialize() {
228 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
229 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
230 base::Bind(&Core::InitializeOnIOThread, this));
233 void PepperFlashSettingsManager::Core::Detach() {
234 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
236 // This call guarantees that one ref is retained until we get to the DETACHED
237 // state. This is important. Otherwise, if the ref count drops to zero on the
238 // UI thread (which posts a task to delete this object on the I/O thread)
239 // while the I/O thread doesn't know about it, methods on the I/O thread might
240 // increase the ref count again and cause double deletion.
241 BrowserThread::PostTask(
242 BrowserThread::IO, FROM_HERE, base::Bind(&Core::DetachOnIOThread, this));
245 void PepperFlashSettingsManager::Core::DeauthorizeContentLicenses(
246 uint32 request_id) {
247 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
249 BrowserThread::PostTask(
250 BrowserThread::IO, FROM_HERE,
251 base::Bind(&Core::DeauthorizeContentLicensesOnIOThread, this,
252 request_id));
255 void PepperFlashSettingsManager::Core::GetPermissionSettings(
256 uint32 request_id,
257 PP_Flash_BrowserOperations_SettingType setting_type) {
258 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
260 BrowserThread::PostTask(
261 BrowserThread::IO, FROM_HERE,
262 base::Bind(&Core::GetPermissionSettingsOnIOThread, this, request_id,
263 setting_type));
266 void PepperFlashSettingsManager::Core::SetDefaultPermission(
267 uint32 request_id,
268 PP_Flash_BrowserOperations_SettingType setting_type,
269 PP_Flash_BrowserOperations_Permission permission,
270 bool clear_site_specific) {
271 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
273 BrowserThread::PostTask(
274 BrowserThread::IO, FROM_HERE,
275 base::Bind(&Core::SetDefaultPermissionOnIOThread, this, request_id,
276 setting_type, permission, clear_site_specific));
279 void PepperFlashSettingsManager::Core::SetSitePermission(
280 uint32 request_id,
281 PP_Flash_BrowserOperations_SettingType setting_type,
282 const ppapi::FlashSiteSettings& sites) {
283 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
285 BrowserThread::PostTask(
286 BrowserThread::IO, FROM_HERE,
287 base::Bind(&Core::SetSitePermissionOnIOThread, this, request_id,
288 setting_type, sites));
291 void PepperFlashSettingsManager::Core::GetSitesWithData(uint32 request_id) {
292 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
294 BrowserThread::PostTask(
295 BrowserThread::IO, FROM_HERE,
296 base::Bind(&Core::GetSitesWithDataOnIOThread, this, request_id));
299 void PepperFlashSettingsManager::Core::ClearSiteData(uint32 request_id,
300 const std::string& site,
301 uint64 flags,
302 uint64 max_age) {
303 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
305 BrowserThread::PostTask(
306 BrowserThread::IO, FROM_HERE,
307 base::Bind(&Core::ClearSiteDataOnIOThread, this, request_id,
308 site, flags, max_age));
311 bool PepperFlashSettingsManager::Core::OnMessageReceived(
312 const IPC::Message& message) {
313 IPC_BEGIN_MESSAGE_MAP(Core, message)
314 IPC_MESSAGE_HANDLER(PpapiHostMsg_DeauthorizeContentLicensesResult,
315 OnDeauthorizeContentLicensesResult)
316 IPC_MESSAGE_HANDLER(PpapiHostMsg_GetPermissionSettingsResult,
317 OnGetPermissionSettingsResult)
318 IPC_MESSAGE_HANDLER(PpapiHostMsg_SetDefaultPermissionResult,
319 OnSetDefaultPermissionResult)
320 IPC_MESSAGE_HANDLER(PpapiHostMsg_SetSitePermissionResult,
321 OnSetSitePermissionResult)
322 IPC_MESSAGE_HANDLER(PpapiHostMsg_GetSitesWithDataResult,
323 OnGetSitesWithDataResult)
324 IPC_MESSAGE_HANDLER(PpapiHostMsg_ClearSiteDataResult,
325 OnClearSiteDataResult)
326 IPC_MESSAGE_UNHANDLED_ERROR()
327 IPC_END_MESSAGE_MAP()
329 return true;
332 void PepperFlashSettingsManager::Core::OnChannelError() {
333 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
334 if (state_ == STATE_DETACHED)
335 return;
337 NotifyErrorFromIOThread();
340 void PepperFlashSettingsManager::Core::ConnectToChannel(
341 bool success,
342 const IPC::ChannelHandle& handle) {
343 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
344 if (state_ == STATE_DETACHED)
345 return;
347 DCHECK(state_ == STATE_UNINITIALIZED);
348 DCHECK(!channel_.get());
350 if (!success) {
351 DLOG(ERROR) << "Couldn't open plugin channel";
352 NotifyErrorFromIOThread();
353 return;
356 channel_ = IPC::Channel::CreateClient(handle, this);
357 if (!channel_->Connect()) {
358 DLOG(ERROR) << "Couldn't connect to plugin";
359 NotifyErrorFromIOThread();
360 return;
363 state_ = STATE_INITIALIZED;
365 std::vector<PendingRequest> temp_pending_requests;
366 temp_pending_requests.swap(pending_requests_);
367 for (std::vector<PendingRequest>::iterator iter =
368 temp_pending_requests.begin();
369 iter != temp_pending_requests.end(); ++iter) {
370 switch (iter->type) {
371 case INVALID_REQUEST_TYPE:
372 NOTREACHED();
373 break;
374 case DEAUTHORIZE_CONTENT_LICENSES:
375 DeauthorizeContentLicensesOnIOThread(iter->id);
376 break;
377 case GET_PERMISSION_SETTINGS:
378 GetPermissionSettingsOnIOThread(iter->id, iter->setting_type);
379 break;
380 case SET_DEFAULT_PERMISSION:
381 SetDefaultPermissionOnIOThread(
382 iter->id, iter->setting_type, iter->permission,
383 iter->clear_site_specific);
384 break;
385 case SET_SITE_PERMISSION:
386 SetSitePermissionOnIOThread(iter->id, iter->setting_type, iter->sites);
387 break;
388 case GET_SITES_WITH_DATA:
389 GetSitesWithDataOnIOThread(iter->id);
390 break;
391 case CLEAR_SITE_DATA:
392 ClearSiteDataOnIOThread(iter->id, iter->site, iter->flags,
393 iter->max_age);
394 break;
399 void PepperFlashSettingsManager::Core::InitializeOnIOThread() {
400 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
401 DCHECK_EQ(STATE_UNINITIALIZED, state_);
403 content::WebPluginInfo plugin_info;
404 if (!PepperFlashSettingsManager::IsPepperFlashInUse(plugin_prefs_.get(),
405 &plugin_info)) {
406 NotifyErrorFromIOThread();
407 return;
410 base::FilePath profile_path =
411 browser_context_path_.Append(content::kPepperDataDirname);
412 #if defined(OS_WIN)
413 plugin_data_path_ = profile_path.Append(plugin_info.name);
414 #else
415 plugin_data_path_ = profile_path.Append(base::UTF16ToUTF8(plugin_info.name));
416 #endif
418 helper_ = content::PepperFlashSettingsHelper::Create();
419 content::PepperFlashSettingsHelper::OpenChannelCallback callback =
420 base::Bind(&Core::ConnectToChannel, this);
421 helper_->OpenChannelToBroker(plugin_info.path, callback);
424 void PepperFlashSettingsManager::Core::DeauthorizeContentLicensesOnIOThread(
425 uint32 request_id) {
426 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
427 DCHECK_NE(STATE_DETACHED, state_);
429 if (state_ == STATE_UNINITIALIZED) {
430 PendingRequest request;
431 request.id = request_id;
432 request.type = DEAUTHORIZE_CONTENT_LICENSES;
433 pending_requests_.push_back(request);
434 return;
437 pending_responses_.insert(
438 std::make_pair(request_id, DEAUTHORIZE_CONTENT_LICENSES));
439 if (state_ == STATE_ERROR) {
440 NotifyErrorFromIOThread();
441 return;
444 #if defined(OS_CHROMEOS)
445 BrowserThread::PostBlockingPoolTask(FROM_HERE,
446 base::Bind(&Core::DeauthorizeContentLicensesOnBlockingPool, this,
447 request_id, browser_context_path_));
448 #else
449 DeauthorizeContentLicensesInPlugin(request_id, true);
450 #endif
453 // TODO(raymes): This is temporary code to migrate ChromeOS devices to the new
454 // scheme for generating device IDs. Delete this once we are sure most ChromeOS
455 // devices have been migrated.
456 void PepperFlashSettingsManager::Core::DeauthorizeContentLicensesOnBlockingPool(
457 uint32 request_id,
458 const base::FilePath& profile_path) {
459 // ChromeOS used to store the device ID in a file but this is no longer used.
460 // Wipe that file.
461 const base::FilePath& device_id_path =
462 chrome::DeviceIDFetcher::GetLegacyDeviceIDPath(profile_path);
463 bool success = base::DeleteFile(device_id_path, false);
465 BrowserThread::PostTask(
466 BrowserThread::IO, FROM_HERE,
467 base::Bind(&Core::DeauthorizeContentLicensesInPlugin, this, request_id,
468 success));
471 void PepperFlashSettingsManager::Core::DeauthorizeContentLicensesInPlugin(
472 uint32 request_id,
473 bool success) {
474 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
475 if (!success) {
476 NotifyErrorFromIOThread();
477 return;
479 IPC::Message* msg =
480 new PpapiMsg_DeauthorizeContentLicenses(request_id, plugin_data_path_);
481 if (!channel_->Send(msg)) {
482 DLOG(ERROR) << "Couldn't send DeauthorizeContentLicenses message";
483 // A failure notification for the current request will be sent since
484 // |pending_responses_| has been updated.
485 NotifyErrorFromIOThread();
489 void PepperFlashSettingsManager::Core::GetPermissionSettingsOnIOThread(
490 uint32 request_id,
491 PP_Flash_BrowserOperations_SettingType setting_type) {
492 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
493 DCHECK_NE(STATE_DETACHED, state_);
495 if (state_ == STATE_UNINITIALIZED) {
496 PendingRequest request;
497 request.id = request_id;
498 request.type = GET_PERMISSION_SETTINGS;
499 request.setting_type = setting_type;
500 pending_requests_.push_back(request);
501 return;
504 pending_responses_.insert(
505 std::make_pair(request_id, GET_PERMISSION_SETTINGS));
506 if (state_ == STATE_ERROR) {
507 NotifyErrorFromIOThread();
508 return;
511 IPC::Message* msg = new PpapiMsg_GetPermissionSettings(
512 request_id, plugin_data_path_, setting_type);
513 if (!channel_->Send(msg)) {
514 DLOG(ERROR) << "Couldn't send GetPermissionSettings message";
515 // A failure notification for the current request will be sent since
516 // |pending_responses_| has been updated.
517 NotifyErrorFromIOThread();
521 void PepperFlashSettingsManager::Core::SetDefaultPermissionOnIOThread(
522 uint32 request_id,
523 PP_Flash_BrowserOperations_SettingType setting_type,
524 PP_Flash_BrowserOperations_Permission permission,
525 bool clear_site_specific) {
526 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
527 DCHECK_NE(STATE_DETACHED, state_);
529 if (state_ == STATE_UNINITIALIZED) {
530 PendingRequest request;
531 request.id = request_id;
532 request.type = SET_DEFAULT_PERMISSION;
533 request.setting_type = setting_type;
534 request.permission = permission;
535 request.clear_site_specific = clear_site_specific;
536 pending_requests_.push_back(request);
537 return;
540 pending_responses_.insert(std::make_pair(request_id, SET_DEFAULT_PERMISSION));
541 if (state_ == STATE_ERROR) {
542 NotifyErrorFromIOThread();
543 return;
546 IPC::Message* msg = new PpapiMsg_SetDefaultPermission(
547 request_id, plugin_data_path_, setting_type, permission,
548 clear_site_specific);
549 if (!channel_->Send(msg)) {
550 DLOG(ERROR) << "Couldn't send SetDefaultPermission message";
551 // A failure notification for the current request will be sent since
552 // |pending_responses_| has been updated.
553 NotifyErrorFromIOThread();
557 void PepperFlashSettingsManager::Core::SetSitePermissionOnIOThread(
558 uint32 request_id,
559 PP_Flash_BrowserOperations_SettingType setting_type,
560 const ppapi::FlashSiteSettings& sites) {
561 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
562 DCHECK_NE(STATE_DETACHED, state_);
564 if (state_ == STATE_UNINITIALIZED) {
565 pending_requests_.push_back(PendingRequest());
566 PendingRequest& request = pending_requests_.back();
567 request.id = request_id;
568 request.type = SET_SITE_PERMISSION;
569 request.setting_type = setting_type;
570 request.sites = sites;
571 return;
574 pending_responses_.insert(std::make_pair(request_id, SET_SITE_PERMISSION));
575 if (state_ == STATE_ERROR) {
576 NotifyErrorFromIOThread();
577 return;
580 IPC::Message* msg = new PpapiMsg_SetSitePermission(
581 request_id, plugin_data_path_, setting_type, sites);
582 if (!channel_->Send(msg)) {
583 DLOG(ERROR) << "Couldn't send SetSitePermission message";
584 // A failure notification for the current request will be sent since
585 // |pending_responses_| has been updated.
586 NotifyErrorFromIOThread();
590 void PepperFlashSettingsManager::Core::GetSitesWithDataOnIOThread(
591 uint32 request_id) {
592 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
593 DCHECK_NE(STATE_DETACHED, state_);
595 if (state_ == STATE_UNINITIALIZED) {
596 pending_requests_.push_back(PendingRequest());
597 PendingRequest& request = pending_requests_.back();
598 request.id = request_id;
599 request.type = GET_SITES_WITH_DATA;
600 return;
603 pending_responses_.insert(std::make_pair(request_id, GET_SITES_WITH_DATA));
604 if (state_ == STATE_ERROR) {
605 NotifyErrorFromIOThread();
606 return;
609 IPC::Message* msg = new PpapiMsg_GetSitesWithData(
610 request_id, plugin_data_path_);
611 if (!channel_->Send(msg)) {
612 DLOG(ERROR) << "Couldn't send GetSitesWithData message";
613 // A failure notification for the current request will be sent since
614 // |pending_responses_| has been updated.
615 NotifyErrorFromIOThread();
619 void PepperFlashSettingsManager::Core::ClearSiteDataOnIOThread(
620 uint32 request_id,
621 const std::string& site,
622 uint64 flags,
623 uint64 max_age) {
624 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
625 DCHECK_NE(STATE_DETACHED, state_);
627 if (state_ == STATE_UNINITIALIZED) {
628 pending_requests_.push_back(PendingRequest());
629 PendingRequest& request = pending_requests_.back();
630 request.id = request_id;
631 request.type = CLEAR_SITE_DATA;
632 request.site = site;
633 request.flags = flags;
634 request.max_age = max_age;
635 return;
638 pending_responses_.insert(std::make_pair(request_id, CLEAR_SITE_DATA));
639 if (state_ == STATE_ERROR) {
640 NotifyErrorFromIOThread();
641 return;
644 IPC::Message* msg = new PpapiMsg_ClearSiteData(
645 request_id, plugin_data_path_, site, flags, max_age);
646 if (!channel_->Send(msg)) {
647 DLOG(ERROR) << "Couldn't send ClearSiteData message";
648 // A failure notification for the current request will be sent since
649 // |pending_responses_| has been updated.
650 NotifyErrorFromIOThread();
654 void PepperFlashSettingsManager::Core::DetachOnIOThread() {
655 state_ = STATE_DETACHED;
658 void PepperFlashSettingsManager::Core::NotifyErrorFromIOThread() {
659 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
660 if (state_ == STATE_DETACHED)
661 return;
663 state_ = STATE_ERROR;
664 std::vector<std::pair<uint32, RequestType> > notifications;
665 for (std::vector<PendingRequest>::iterator iter = pending_requests_.begin();
666 iter != pending_requests_.end(); ++iter) {
667 notifications.push_back(std::make_pair(iter->id, iter->type));
669 pending_requests_.clear();
670 notifications.insert(notifications.end(), pending_responses_.begin(),
671 pending_responses_.end());
672 pending_responses_.clear();
674 BrowserThread::PostTask(
675 BrowserThread::UI, FROM_HERE,
676 base::Bind(&Core::NotifyError, this, notifications));
679 void
680 PepperFlashSettingsManager::Core::NotifyDeauthorizeContentLicensesCompleted(
681 uint32 request_id,
682 bool success) {
683 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
685 if (manager_.get()) {
686 manager_->client_->OnDeauthorizeContentLicensesCompleted(
687 request_id, success);
691 void PepperFlashSettingsManager::Core::NotifyGetPermissionSettingsCompleted(
692 uint32 request_id,
693 bool success,
694 PP_Flash_BrowserOperations_Permission default_permission,
695 const ppapi::FlashSiteSettings& sites) {
696 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
698 if (manager_.get()) {
699 manager_->client_->OnGetPermissionSettingsCompleted(
700 request_id, success, default_permission, sites);
704 void PepperFlashSettingsManager::Core::NotifySetDefaultPermissionCompleted(
705 uint32 request_id,
706 bool success) {
707 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
709 if (manager_.get()) {
710 manager_->client_->OnSetDefaultPermissionCompleted(
711 request_id, success);
715 void PepperFlashSettingsManager::Core::NotifySetSitePermissionCompleted(
716 uint32 request_id,
717 bool success) {
718 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
720 if (manager_.get()) {
721 manager_->client_->OnSetSitePermissionCompleted(
722 request_id, success);
726 void PepperFlashSettingsManager::Core::NotifyGetSitesWithDataCompleted(
727 uint32 request_id,
728 const std::vector<std::string>& sites) {
729 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
731 if (manager_.get()) {
732 manager_->client_->OnGetSitesWithDataCompleted(
733 request_id, sites);
737 void PepperFlashSettingsManager::Core::NotifyClearSiteDataCompleted(
738 uint32 request_id,
739 bool success) {
740 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
742 if (manager_.get())
743 manager_->client_->OnClearSiteDataCompleted(request_id, success);
746 void PepperFlashSettingsManager::Core::NotifyError(
747 const std::vector<std::pair<uint32, RequestType> >& notifications) {
748 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
750 scoped_refptr<Core> protector(this);
751 for (std::vector<std::pair<uint32, RequestType> >::const_iterator iter =
752 notifications.begin(); iter != notifications.end(); ++iter) {
753 // Check |manager_| for each iteration in case it is destroyed in one of
754 // the callbacks.
755 if (!manager_.get())
756 return;
758 switch (iter->second) {
759 case INVALID_REQUEST_TYPE:
760 NOTREACHED();
761 break;
762 case DEAUTHORIZE_CONTENT_LICENSES:
763 manager_->client_->OnDeauthorizeContentLicensesCompleted(
764 iter->first, false);
765 break;
766 case GET_PERMISSION_SETTINGS:
767 manager_->client_->OnGetPermissionSettingsCompleted(
768 iter->first, false, PP_FLASH_BROWSEROPERATIONS_PERMISSION_DEFAULT,
769 ppapi::FlashSiteSettings());
770 break;
771 case SET_DEFAULT_PERMISSION:
772 manager_->client_->OnSetDefaultPermissionCompleted(
773 iter->first, false);
774 break;
775 case SET_SITE_PERMISSION:
776 manager_->client_->OnSetSitePermissionCompleted(iter->first, false);
777 break;
778 case GET_SITES_WITH_DATA:
779 manager_->client_->OnGetSitesWithDataCompleted(
780 iter->first, std::vector<std::string>());
781 break;
782 case CLEAR_SITE_DATA:
783 manager_->client_->OnClearSiteDataCompleted(iter->first, false);
784 break;
788 if (manager_.get())
789 manager_->OnError(this);
792 void PepperFlashSettingsManager::Core::OnDeauthorizeContentLicensesResult(
793 uint32 request_id,
794 bool success) {
795 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
796 if (state_ == STATE_DETACHED)
797 return;
799 DLOG_IF(ERROR, !success) << "DeauthorizeContentLicenses returned error";
801 std::map<uint32, RequestType>::iterator iter =
802 pending_responses_.find(request_id);
803 if (iter == pending_responses_.end())
804 return;
806 DCHECK_EQ(iter->second, DEAUTHORIZE_CONTENT_LICENSES);
808 pending_responses_.erase(iter);
809 BrowserThread::PostTask(
810 BrowserThread::UI, FROM_HERE,
811 base::Bind(&Core::NotifyDeauthorizeContentLicensesCompleted, this,
812 request_id, success));
815 void PepperFlashSettingsManager::Core::OnGetPermissionSettingsResult(
816 uint32 request_id,
817 bool success,
818 PP_Flash_BrowserOperations_Permission default_permission,
819 const ppapi::FlashSiteSettings& sites) {
820 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
821 if (state_ == STATE_DETACHED)
822 return;
824 DLOG_IF(ERROR, !success) << "GetPermissionSettings returned error";
826 std::map<uint32, RequestType>::iterator iter =
827 pending_responses_.find(request_id);
828 if (iter == pending_responses_.end())
829 return;
831 DCHECK_EQ(iter->second, GET_PERMISSION_SETTINGS);
833 pending_responses_.erase(iter);
834 BrowserThread::PostTask(
835 BrowserThread::UI, FROM_HERE,
836 base::Bind(&Core::NotifyGetPermissionSettingsCompleted, this,
837 request_id, success, default_permission, sites));
840 void PepperFlashSettingsManager::Core::OnSetDefaultPermissionResult(
841 uint32 request_id,
842 bool success) {
843 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
844 if (state_ == STATE_DETACHED)
845 return;
847 DLOG_IF(ERROR, !success) << "SetDefaultPermission returned error";
849 std::map<uint32, RequestType>::iterator iter =
850 pending_responses_.find(request_id);
851 if (iter == pending_responses_.end())
852 return;
854 DCHECK_EQ(iter->second, SET_DEFAULT_PERMISSION);
856 pending_responses_.erase(iter);
857 BrowserThread::PostTask(
858 BrowserThread::UI, FROM_HERE,
859 base::Bind(&Core::NotifySetDefaultPermissionCompleted, this,
860 request_id, success));
863 void PepperFlashSettingsManager::Core::OnSetSitePermissionResult(
864 uint32 request_id,
865 bool success) {
866 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
867 if (state_ == STATE_DETACHED)
868 return;
870 DLOG_IF(ERROR, !success) << "SetSitePermission returned error";
872 std::map<uint32, RequestType>::iterator iter =
873 pending_responses_.find(request_id);
874 if (iter == pending_responses_.end())
875 return;
877 DCHECK_EQ(iter->second, SET_SITE_PERMISSION);
879 pending_responses_.erase(iter);
880 BrowserThread::PostTask(
881 BrowserThread::UI, FROM_HERE,
882 base::Bind(&Core::NotifySetSitePermissionCompleted, this, request_id,
883 success));
886 void PepperFlashSettingsManager::Core::OnGetSitesWithDataResult(
887 uint32 request_id,
888 const std::vector<std::string>& sites) {
889 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
890 if (state_ == STATE_DETACHED)
891 return;
893 std::map<uint32, RequestType>::iterator iter =
894 pending_responses_.find(request_id);
895 if (iter == pending_responses_.end())
896 return;
898 DCHECK_EQ(iter->second, GET_SITES_WITH_DATA);
900 pending_responses_.erase(iter);
901 BrowserThread::PostTask(
902 BrowserThread::UI, FROM_HERE,
903 base::Bind(&Core::NotifyGetSitesWithDataCompleted, this, request_id,
904 sites));
907 void PepperFlashSettingsManager::Core::OnClearSiteDataResult(
908 uint32 request_id,
909 bool success) {
910 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
911 if (state_ == STATE_DETACHED)
912 return;
914 DLOG_IF(ERROR, !success) << "ClearSiteData returned error";
916 std::map<uint32, RequestType>::iterator iter =
917 pending_responses_.find(request_id);
918 if (iter == pending_responses_.end())
919 return;
921 DCHECK_EQ(iter->second, CLEAR_SITE_DATA);
923 pending_responses_.erase(iter);
924 BrowserThread::PostTask(
925 BrowserThread::UI, FROM_HERE,
926 base::Bind(&Core::NotifyClearSiteDataCompleted, this, request_id,
927 success));
930 PepperFlashSettingsManager::PepperFlashSettingsManager(
931 Client* client,
932 content::BrowserContext* browser_context)
933 : client_(client),
934 browser_context_(browser_context),
935 next_request_id_(1),
936 weak_ptr_factory_(this) {
937 DCHECK(client);
938 DCHECK(browser_context);
941 PepperFlashSettingsManager::~PepperFlashSettingsManager() {
942 if (core_.get())
943 core_->Detach();
946 // static
947 bool PepperFlashSettingsManager::IsPepperFlashInUse(
948 PluginPrefs* plugin_prefs,
949 content::WebPluginInfo* plugin_info) {
950 if (!plugin_prefs)
951 return false;
953 content::PluginService* plugin_service =
954 content::PluginService::GetInstance();
955 std::vector<content::WebPluginInfo> plugins;
956 plugin_service->GetPluginInfoArray(
957 GURL(), content::kFlashPluginSwfMimeType, false, &plugins, NULL);
959 for (std::vector<content::WebPluginInfo>::iterator iter = plugins.begin();
960 iter != plugins.end(); ++iter) {
961 if (iter->is_pepper_plugin() && plugin_prefs->IsPluginEnabled(*iter)) {
962 if (plugin_info)
963 *plugin_info = *iter;
964 return true;
967 return false;
970 // static
971 void PepperFlashSettingsManager::RegisterProfilePrefs(
972 user_prefs::PrefRegistrySyncable* registry) {
973 registry->RegisterBooleanPref(prefs::kDeauthorizeContentLicenses, false);
975 registry->RegisterBooleanPref(prefs::kPepperFlashSettingsEnabled, true);
978 uint32 PepperFlashSettingsManager::DeauthorizeContentLicenses(
979 PrefService* prefs) {
980 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
982 // Clear the device ID salt which has the effect of regenerating a device
983 // ID. Since this happens synchronously (and on the UI thread), we don't have
984 // to add it to a pending request.
985 prefs->ClearPref(prefs::kDRMSalt);
987 EnsureCoreExists();
988 uint32 id = GetNextRequestId();
989 core_->DeauthorizeContentLicenses(id);
990 return id;
993 uint32 PepperFlashSettingsManager::GetPermissionSettings(
994 PP_Flash_BrowserOperations_SettingType setting_type) {
995 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
997 EnsureCoreExists();
998 uint32 id = GetNextRequestId();
999 core_->GetPermissionSettings(id, setting_type);
1000 return id;
1003 uint32 PepperFlashSettingsManager::SetDefaultPermission(
1004 PP_Flash_BrowserOperations_SettingType setting_type,
1005 PP_Flash_BrowserOperations_Permission permission,
1006 bool clear_site_specific) {
1007 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1009 EnsureCoreExists();
1010 uint32 id = GetNextRequestId();
1011 core_->SetDefaultPermission(id, setting_type, permission,
1012 clear_site_specific);
1013 return id;
1016 uint32 PepperFlashSettingsManager::SetSitePermission(
1017 PP_Flash_BrowserOperations_SettingType setting_type,
1018 const ppapi::FlashSiteSettings& sites) {
1019 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1021 EnsureCoreExists();
1022 uint32 id = GetNextRequestId();
1023 core_->SetSitePermission(id, setting_type, sites);
1024 return id;
1027 uint32 PepperFlashSettingsManager::GetSitesWithData() {
1028 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1030 EnsureCoreExists();
1031 uint32 id = GetNextRequestId();
1032 core_->GetSitesWithData(id);
1033 return id;
1036 uint32 PepperFlashSettingsManager::ClearSiteData(const std::string& site,
1037 uint64 flags,
1038 uint64 max_age) {
1039 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1041 EnsureCoreExists();
1042 uint32 id = GetNextRequestId();
1043 core_->ClearSiteData(id, site, flags, max_age);
1044 return id;
1047 uint32 PepperFlashSettingsManager::GetNextRequestId() {
1048 return next_request_id_++;
1051 void PepperFlashSettingsManager::EnsureCoreExists() {
1052 if (!core_.get()) {
1053 core_ = new Core(weak_ptr_factory_.GetWeakPtr(), browser_context_);
1054 core_->Initialize();
1058 void PepperFlashSettingsManager::OnError(Core* core) {
1059 DCHECK(core);
1060 if (core != core_.get())
1061 return;
1063 core_->Detach();
1064 core_ = NULL;