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/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 {
PendingRequestPepperFlashSettingsManager::Core::PendingRequest92 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
Core(base::WeakPtr<PepperFlashSettingsManager> manager,content::BrowserContext * browser_context)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
~Core()223 PepperFlashSettingsManager::Core::~Core() {
224 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
225 }
226
Initialize()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
Detach()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
DeauthorizeContentLicenses(uint32 request_id)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
GetPermissionSettings(uint32 request_id,PP_Flash_BrowserOperations_SettingType setting_type)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
SetDefaultPermission(uint32 request_id,PP_Flash_BrowserOperations_SettingType setting_type,PP_Flash_BrowserOperations_Permission permission,bool clear_site_specific)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
SetSitePermission(uint32 request_id,PP_Flash_BrowserOperations_SettingType setting_type,const ppapi::FlashSiteSettings & sites)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
GetSitesWithData(uint32 request_id)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
ClearSiteData(uint32 request_id,const std::string & site,uint64 flags,uint64 max_age)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
OnMessageReceived(const IPC::Message & message)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
OnChannelError()332 void PepperFlashSettingsManager::Core::OnChannelError() {
333 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
334 if (state_ == STATE_DETACHED)
335 return;
336
337 NotifyErrorFromIOThread();
338 }
339
ConnectToChannel(bool success,const IPC::ChannelHandle & handle)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
InitializeOnIOThread()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
DeauthorizeContentLicensesOnIOThread(uint32 request_id)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.
DeauthorizeContentLicensesOnBlockingPool(uint32 request_id,const base::FilePath & profile_path)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
DeauthorizeContentLicensesInPlugin(uint32 request_id,bool 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;
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
GetPermissionSettingsOnIOThread(uint32 request_id,PP_Flash_BrowserOperations_SettingType setting_type)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
SetDefaultPermissionOnIOThread(uint32 request_id,PP_Flash_BrowserOperations_SettingType setting_type,PP_Flash_BrowserOperations_Permission permission,bool clear_site_specific)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
SetSitePermissionOnIOThread(uint32 request_id,PP_Flash_BrowserOperations_SettingType setting_type,const ppapi::FlashSiteSettings & sites)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
GetSitesWithDataOnIOThread(uint32 request_id)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
ClearSiteDataOnIOThread(uint32 request_id,const std::string & site,uint64 flags,uint64 max_age)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
DetachOnIOThread()654 void PepperFlashSettingsManager::Core::DetachOnIOThread() {
655 state_ = STATE_DETACHED;
656 }
657
NotifyErrorFromIOThread()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
NotifyDeauthorizeContentLicensesCompleted(uint32 request_id,bool success)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
NotifyGetPermissionSettingsCompleted(uint32 request_id,bool success,PP_Flash_BrowserOperations_Permission default_permission,const ppapi::FlashSiteSettings & sites)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
NotifySetDefaultPermissionCompleted(uint32 request_id,bool success)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
NotifySetSitePermissionCompleted(uint32 request_id,bool success)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
NotifyGetSitesWithDataCompleted(uint32 request_id,const std::vector<std::string> & sites)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
NotifyClearSiteDataCompleted(uint32 request_id,bool success)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
NotifyError(const std::vector<std::pair<uint32,RequestType>> & notifications)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
OnDeauthorizeContentLicensesResult(uint32 request_id,bool success)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
OnGetPermissionSettingsResult(uint32 request_id,bool success,PP_Flash_BrowserOperations_Permission default_permission,const ppapi::FlashSiteSettings & sites)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
OnSetDefaultPermissionResult(uint32 request_id,bool success)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
OnSetSitePermissionResult(uint32 request_id,bool 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;
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
OnGetSitesWithDataResult(uint32 request_id,const std::vector<std::string> & sites)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
OnClearSiteDataResult(uint32 request_id,bool success)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
PepperFlashSettingsManager(Client * client,content::BrowserContext * browser_context)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
~PepperFlashSettingsManager()941 PepperFlashSettingsManager::~PepperFlashSettingsManager() {
942 if (core_.get())
943 core_->Detach();
944 }
945
946 // static
IsPepperFlashInUse(PluginPrefs * plugin_prefs,content::WebPluginInfo * plugin_info)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
RegisterProfilePrefs(user_prefs::PrefRegistrySyncable * registry)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
DeauthorizeContentLicenses(PrefService * prefs)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
GetPermissionSettings(PP_Flash_BrowserOperations_SettingType setting_type)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
SetDefaultPermission(PP_Flash_BrowserOperations_SettingType setting_type,PP_Flash_BrowserOperations_Permission permission,bool clear_site_specific)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
SetSitePermission(PP_Flash_BrowserOperations_SettingType setting_type,const ppapi::FlashSiteSettings & sites)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
GetSitesWithData()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
ClearSiteData(const std::string & site,uint64 flags,uint64 max_age)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
GetNextRequestId()1053 uint32 PepperFlashSettingsManager::GetNextRequestId() {
1054 return next_request_id_++;
1055 }
1056
EnsureCoreExists()1057 void PepperFlashSettingsManager::EnsureCoreExists() {
1058 if (!core_.get()) {
1059 core_ = new Core(weak_ptr_factory_.GetWeakPtr(), browser_context_);
1060 core_->Initialize();
1061 }
1062 }
1063
OnError(Core * core)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