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 "chrome/browser/pepper_flash_settings_manager.h" 6 7 #include <map> 8 #include <utility> 9 #include <vector> 10 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" 32 33 using content::BrowserThread; 34 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); 41 42 void Initialize(); 43 44 // Notifies the core that it has been detached. Afterwards, no method should 45 // be called any more. 46 void Detach(); 47 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); 65 66 // IPC::Listener implementation. 67 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; 68 virtual void OnChannelError() OVERRIDE; 69 70 private: 71 friend struct BrowserThread::DeleteOnThread<BrowserThread::IO>; 72 friend class base::DeleteHelper<Core>; 73 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, 82 }; 83 84 enum State { 85 STATE_UNINITIALIZED = 0, 86 STATE_INITIALIZED, 87 STATE_ERROR, 88 STATE_DETACHED, 89 }; 90 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) { 100 } 101 102 uint32 id; 103 RequestType type; 104 105 // Used by GET_PERMISSION_SETTINGS, SET_DEFAULT_PERMISSION and 106 // SET_SITE_PERMISSION. 107 PP_Flash_BrowserOperations_SettingType setting_type; 108 109 // Used by SET_DEFAULT_PERMISSION. 110 PP_Flash_BrowserOperations_Permission permission; 111 bool clear_site_specific; 112 113 // Used by SET_SITE_PERMISSION. 114 ppapi::FlashSiteSettings sites; 115 116 // Used by CLEAR_SITE_DATA 117 std::string site; 118 uint64 flags; 119 uint64 max_age; 120 }; 121 122 virtual ~Core(); 123 124 void ConnectToChannel(bool success, const IPC::ChannelHandle& handle); 125 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(); 150 151 void NotifyErrorFromIOThread(); 152 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); 165 166 void NotifyError( 167 const std::vector<std::pair<uint32, RequestType> >& notifications); 168 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); 181 182 // Used only on the UI thread. 183 base::WeakPtr<PepperFlashSettingsManager> manager_; 184 185 // Used only on the I/O thread. 186 base::FilePath plugin_data_path_; 187 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_; 191 192 // Used only on the I/O thread. 193 State state_; 194 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_; 201 202 // Used only on the I/O thread. 203 scoped_refptr<content::PepperFlashSettingsHelper> helper_; 204 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_; 208 209 scoped_refptr<PluginPrefs> plugin_prefs_; 210 }; 211 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)); 221 } 222 223 PepperFlashSettingsManager::Core::~Core() { 224 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 225 } 226 227 void PepperFlashSettingsManager::Core::Initialize() { 228 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 229 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 230 base::Bind(&Core::InitializeOnIOThread, this)); 231 } 232 233 void PepperFlashSettingsManager::Core::Detach() { 234 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 235 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)); 243 } 244 245 void PepperFlashSettingsManager::Core::DeauthorizeContentLicenses( 246 uint32 request_id) { 247 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 248 249 BrowserThread::PostTask( 250 BrowserThread::IO, FROM_HERE, 251 base::Bind(&Core::DeauthorizeContentLicensesOnIOThread, this, 252 request_id)); 253 } 254 255 void PepperFlashSettingsManager::Core::GetPermissionSettings( 256 uint32 request_id, 257 PP_Flash_BrowserOperations_SettingType setting_type) { 258 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 259 260 BrowserThread::PostTask( 261 BrowserThread::IO, FROM_HERE, 262 base::Bind(&Core::GetPermissionSettingsOnIOThread, this, request_id, 263 setting_type)); 264 } 265 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)); 272 273 BrowserThread::PostTask( 274 BrowserThread::IO, FROM_HERE, 275 base::Bind(&Core::SetDefaultPermissionOnIOThread, this, request_id, 276 setting_type, permission, clear_site_specific)); 277 } 278 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)); 284 285 BrowserThread::PostTask( 286 BrowserThread::IO, FROM_HERE, 287 base::Bind(&Core::SetSitePermissionOnIOThread, this, request_id, 288 setting_type, sites)); 289 } 290 291 void PepperFlashSettingsManager::Core::GetSitesWithData(uint32 request_id) { 292 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 293 294 BrowserThread::PostTask( 295 BrowserThread::IO, FROM_HERE, 296 base::Bind(&Core::GetSitesWithDataOnIOThread, this, request_id)); 297 } 298 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)); 304 305 BrowserThread::PostTask( 306 BrowserThread::IO, FROM_HERE, 307 base::Bind(&Core::ClearSiteDataOnIOThread, this, request_id, 308 site, flags, max_age)); 309 } 310 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() 328 329 return true; 330 } 331 332 void PepperFlashSettingsManager::Core::OnChannelError() { 333 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 334 if (state_ == STATE_DETACHED) 335 return; 336 337 NotifyErrorFromIOThread(); 338 } 339 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; 346 347 DCHECK(state_ == STATE_UNINITIALIZED); 348 DCHECK(!channel_.get()); 349 350 if (!success) { 351 DLOG(ERROR) << "Couldn't open plugin channel"; 352 NotifyErrorFromIOThread(); 353 return; 354 } 355 356 channel_ = IPC::Channel::CreateClient(handle, this); 357 if (!channel_->Connect()) { 358 DLOG(ERROR) << "Couldn't connect to plugin"; 359 NotifyErrorFromIOThread(); 360 return; 361 } 362 363 state_ = STATE_INITIALIZED; 364 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; 395 } 396 } 397 } 398 399 void PepperFlashSettingsManager::Core::InitializeOnIOThread() { 400 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 401 DCHECK_EQ(STATE_UNINITIALIZED, state_); 402 403 content::WebPluginInfo plugin_info; 404 if (!PepperFlashSettingsManager::IsPepperFlashInUse(plugin_prefs_.get(), 405 &plugin_info)) { 406 NotifyErrorFromIOThread(); 407 return; 408 } 409 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 417 418 helper_ = content::PepperFlashSettingsHelper::Create(); 419 content::PepperFlashSettingsHelper::OpenChannelCallback callback = 420 base::Bind(&Core::ConnectToChannel, this); 421 helper_->OpenChannelToBroker(plugin_info.path, callback); 422 } 423 424 void PepperFlashSettingsManager::Core::DeauthorizeContentLicensesOnIOThread( 425 uint32 request_id) { 426 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 427 DCHECK_NE(STATE_DETACHED, state_); 428 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; 435 } 436 437 pending_responses_.insert( 438 std::make_pair(request_id, DEAUTHORIZE_CONTENT_LICENSES)); 439 if (state_ == STATE_ERROR) { 440 NotifyErrorFromIOThread(); 441 return; 442 } 443 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 451 } 452 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); 464 465 BrowserThread::PostTask( 466 BrowserThread::IO, FROM_HERE, 467 base::Bind(&Core::DeauthorizeContentLicensesInPlugin, this, request_id, 468 success)); 469 } 470 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; 478 } 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(); 486 } 487 } 488 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_); 494 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; 502 } 503 504 pending_responses_.insert( 505 std::make_pair(request_id, GET_PERMISSION_SETTINGS)); 506 if (state_ == STATE_ERROR) { 507 NotifyErrorFromIOThread(); 508 return; 509 } 510 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(); 518 } 519 } 520 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_); 528 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; 538 } 539 540 pending_responses_.insert(std::make_pair(request_id, SET_DEFAULT_PERMISSION)); 541 if (state_ == STATE_ERROR) { 542 NotifyErrorFromIOThread(); 543 return; 544 } 545 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(); 554 } 555 } 556 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_); 563 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; 572 } 573 574 pending_responses_.insert(std::make_pair(request_id, SET_SITE_PERMISSION)); 575 if (state_ == STATE_ERROR) { 576 NotifyErrorFromIOThread(); 577 return; 578 } 579 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(); 587 } 588 } 589 590 void PepperFlashSettingsManager::Core::GetSitesWithDataOnIOThread( 591 uint32 request_id) { 592 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 593 DCHECK_NE(STATE_DETACHED, state_); 594 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; 601 } 602 603 pending_responses_.insert(std::make_pair(request_id, GET_SITES_WITH_DATA)); 604 if (state_ == STATE_ERROR) { 605 NotifyErrorFromIOThread(); 606 return; 607 } 608 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(); 616 } 617 } 618 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_); 626 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; 636 } 637 638 pending_responses_.insert(std::make_pair(request_id, CLEAR_SITE_DATA)); 639 if (state_ == STATE_ERROR) { 640 NotifyErrorFromIOThread(); 641 return; 642 } 643 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(); 651 } 652 } 653 654 void PepperFlashSettingsManager::Core::DetachOnIOThread() { 655 state_ = STATE_DETACHED; 656 } 657 658 void PepperFlashSettingsManager::Core::NotifyErrorFromIOThread() { 659 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 660 if (state_ == STATE_DETACHED) 661 return; 662 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)); 668 } 669 pending_requests_.clear(); 670 notifications.insert(notifications.end(), pending_responses_.begin(), 671 pending_responses_.end()); 672 pending_responses_.clear(); 673 674 BrowserThread::PostTask( 675 BrowserThread::UI, FROM_HERE, 676 base::Bind(&Core::NotifyError, this, notifications)); 677 } 678 679 void 680 PepperFlashSettingsManager::Core::NotifyDeauthorizeContentLicensesCompleted( 681 uint32 request_id, 682 bool success) { 683 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 684 685 if (manager_.get()) { 686 manager_->client_->OnDeauthorizeContentLicensesCompleted( 687 request_id, success); 688 } 689 } 690 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)); 697 698 if (manager_.get()) { 699 manager_->client_->OnGetPermissionSettingsCompleted( 700 request_id, success, default_permission, sites); 701 } 702 } 703 704 void PepperFlashSettingsManager::Core::NotifySetDefaultPermissionCompleted( 705 uint32 request_id, 706 bool success) { 707 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 708 709 if (manager_.get()) { 710 manager_->client_->OnSetDefaultPermissionCompleted( 711 request_id, success); 712 } 713 } 714 715 void PepperFlashSettingsManager::Core::NotifySetSitePermissionCompleted( 716 uint32 request_id, 717 bool success) { 718 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 719 720 if (manager_.get()) { 721 manager_->client_->OnSetSitePermissionCompleted( 722 request_id, success); 723 } 724 } 725 726 void PepperFlashSettingsManager::Core::NotifyGetSitesWithDataCompleted( 727 uint32 request_id, 728 const std::vector<std::string>& sites) { 729 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 730 731 if (manager_.get()) { 732 manager_->client_->OnGetSitesWithDataCompleted( 733 request_id, sites); 734 } 735 } 736 737 void PepperFlashSettingsManager::Core::NotifyClearSiteDataCompleted( 738 uint32 request_id, 739 bool success) { 740 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 741 742 if (manager_.get()) 743 manager_->client_->OnClearSiteDataCompleted(request_id, success); 744 } 745 746 void PepperFlashSettingsManager::Core::NotifyError( 747 const std::vector<std::pair<uint32, RequestType> >& notifications) { 748 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 749 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; 757 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; 785 } 786 } 787 788 if (manager_.get()) 789 manager_->OnError(this); 790 } 791 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; 798 799 DLOG_IF(ERROR, !success) << "DeauthorizeContentLicenses returned error"; 800 801 std::map<uint32, RequestType>::iterator iter = 802 pending_responses_.find(request_id); 803 if (iter == pending_responses_.end()) 804 return; 805 806 DCHECK_EQ(iter->second, DEAUTHORIZE_CONTENT_LICENSES); 807 808 pending_responses_.erase(iter); 809 BrowserThread::PostTask( 810 BrowserThread::UI, FROM_HERE, 811 base::Bind(&Core::NotifyDeauthorizeContentLicensesCompleted, this, 812 request_id, success)); 813 } 814 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; 823 824 DLOG_IF(ERROR, !success) << "GetPermissionSettings returned error"; 825 826 std::map<uint32, RequestType>::iterator iter = 827 pending_responses_.find(request_id); 828 if (iter == pending_responses_.end()) 829 return; 830 831 DCHECK_EQ(iter->second, GET_PERMISSION_SETTINGS); 832 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)); 838 } 839 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; 846 847 DLOG_IF(ERROR, !success) << "SetDefaultPermission returned error"; 848 849 std::map<uint32, RequestType>::iterator iter = 850 pending_responses_.find(request_id); 851 if (iter == pending_responses_.end()) 852 return; 853 854 DCHECK_EQ(iter->second, SET_DEFAULT_PERMISSION); 855 856 pending_responses_.erase(iter); 857 BrowserThread::PostTask( 858 BrowserThread::UI, FROM_HERE, 859 base::Bind(&Core::NotifySetDefaultPermissionCompleted, this, 860 request_id, success)); 861 } 862 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; 869 870 DLOG_IF(ERROR, !success) << "SetSitePermission returned error"; 871 872 std::map<uint32, RequestType>::iterator iter = 873 pending_responses_.find(request_id); 874 if (iter == pending_responses_.end()) 875 return; 876 877 DCHECK_EQ(iter->second, SET_SITE_PERMISSION); 878 879 pending_responses_.erase(iter); 880 BrowserThread::PostTask( 881 BrowserThread::UI, FROM_HERE, 882 base::Bind(&Core::NotifySetSitePermissionCompleted, this, request_id, 883 success)); 884 } 885 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; 892 893 std::map<uint32, RequestType>::iterator iter = 894 pending_responses_.find(request_id); 895 if (iter == pending_responses_.end()) 896 return; 897 898 DCHECK_EQ(iter->second, GET_SITES_WITH_DATA); 899 900 pending_responses_.erase(iter); 901 BrowserThread::PostTask( 902 BrowserThread::UI, FROM_HERE, 903 base::Bind(&Core::NotifyGetSitesWithDataCompleted, this, request_id, 904 sites)); 905 } 906 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; 913 914 DLOG_IF(ERROR, !success) << "ClearSiteData returned error"; 915 916 std::map<uint32, RequestType>::iterator iter = 917 pending_responses_.find(request_id); 918 if (iter == pending_responses_.end()) 919 return; 920 921 DCHECK_EQ(iter->second, CLEAR_SITE_DATA); 922 923 pending_responses_.erase(iter); 924 BrowserThread::PostTask( 925 BrowserThread::UI, FROM_HERE, 926 base::Bind(&Core::NotifyClearSiteDataCompleted, this, request_id, 927 success)); 928 } 929 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); 939 } 940 941 PepperFlashSettingsManager::~PepperFlashSettingsManager() { 942 if (core_.get()) 943 core_->Detach(); 944 } 945 946 // static 947 bool PepperFlashSettingsManager::IsPepperFlashInUse( 948 PluginPrefs* plugin_prefs, 949 content::WebPluginInfo* plugin_info) { 950 if (!plugin_prefs) 951 return false; 952 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); 958 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; 965 } 966 } 967 return false; 968 } 969 970 // static 971 void PepperFlashSettingsManager::RegisterProfilePrefs( 972 user_prefs::PrefRegistrySyncable* registry) { 973 registry->RegisterBooleanPref( 974 prefs::kDeauthorizeContentLicenses, 975 false, 976 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 977 978 registry->RegisterBooleanPref( 979 prefs::kPepperFlashSettingsEnabled, 980 true, 981 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 982 } 983 984 uint32 PepperFlashSettingsManager::DeauthorizeContentLicenses( 985 PrefService* prefs) { 986 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 987 988 // Clear the device ID salt which has the effect of regenerating a device 989 // ID. Since this happens synchronously (and on the UI thread), we don't have 990 // to add it to a pending request. 991 prefs->ClearPref(prefs::kDRMSalt); 992 993 EnsureCoreExists(); 994 uint32 id = GetNextRequestId(); 995 core_->DeauthorizeContentLicenses(id); 996 return id; 997 } 998 999 uint32 PepperFlashSettingsManager::GetPermissionSettings( 1000 PP_Flash_BrowserOperations_SettingType setting_type) { 1001 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1002 1003 EnsureCoreExists(); 1004 uint32 id = GetNextRequestId(); 1005 core_->GetPermissionSettings(id, setting_type); 1006 return id; 1007 } 1008 1009 uint32 PepperFlashSettingsManager::SetDefaultPermission( 1010 PP_Flash_BrowserOperations_SettingType setting_type, 1011 PP_Flash_BrowserOperations_Permission permission, 1012 bool clear_site_specific) { 1013 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1014 1015 EnsureCoreExists(); 1016 uint32 id = GetNextRequestId(); 1017 core_->SetDefaultPermission(id, setting_type, permission, 1018 clear_site_specific); 1019 return id; 1020 } 1021 1022 uint32 PepperFlashSettingsManager::SetSitePermission( 1023 PP_Flash_BrowserOperations_SettingType setting_type, 1024 const ppapi::FlashSiteSettings& sites) { 1025 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1026 1027 EnsureCoreExists(); 1028 uint32 id = GetNextRequestId(); 1029 core_->SetSitePermission(id, setting_type, sites); 1030 return id; 1031 } 1032 1033 uint32 PepperFlashSettingsManager::GetSitesWithData() { 1034 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1035 1036 EnsureCoreExists(); 1037 uint32 id = GetNextRequestId(); 1038 core_->GetSitesWithData(id); 1039 return id; 1040 } 1041 1042 uint32 PepperFlashSettingsManager::ClearSiteData(const std::string& site, 1043 uint64 flags, 1044 uint64 max_age) { 1045 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1046 1047 EnsureCoreExists(); 1048 uint32 id = GetNextRequestId(); 1049 core_->ClearSiteData(id, site, flags, max_age); 1050 return id; 1051 } 1052 1053 uint32 PepperFlashSettingsManager::GetNextRequestId() { 1054 return next_request_id_++; 1055 } 1056 1057 void PepperFlashSettingsManager::EnsureCoreExists() { 1058 if (!core_.get()) { 1059 core_ = new Core(weak_ptr_factory_.GetWeakPtr(), browser_context_); 1060 core_->Initialize(); 1061 } 1062 } 1063 1064 void PepperFlashSettingsManager::OnError(Core* core) { 1065 DCHECK(core); 1066 if (core != core_.get()) 1067 return; 1068 1069 core_->Detach(); 1070 core_ = NULL; 1071 } 1072