[M85 Dev][EFL] Fix errors to generate ninja files
[platform/framework/web/chromium-efl.git] / chrome / browser / pepper_flash_settings_manager.cc
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/sequenced_task_runner_helpers.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "base/task/thread_pool.h"
17 #include "build/build_config.h"
18 #include "chrome/browser/plugins/plugin_prefs.h"
19 #include "chrome/browser/profiles/profile.h"
20 #include "chrome/browser/renderer_host/pepper/device_id_fetcher.h"
21 #include "chrome/common/pref_names.h"
22 #include "components/pref_registry/pref_registry_syncable.h"
23 #include "components/prefs/pref_service.h"
24 #include "content/public/browser/browser_context.h"
25 #include "content/public/browser/browser_task_traits.h"
26 #include "content/public/browser/browser_thread.h"
27 #include "content/public/browser/pepper_flash_settings_helper.h"
28 #include "content/public/browser/plugin_service.h"
29 #include "content/public/common/content_constants.h"
30 #include "content/public/common/webplugininfo.h"
31 #include "ipc/ipc_channel.h"
32 #include "ipc/ipc_listener.h"
33 #include "ppapi/proxy/ppapi_messages.h"
34 #include "url/gurl.h"
35
36 using content::BrowserThread;
37
38 class PepperFlashSettingsManager::Core
39     : public IPC::Listener,
40       public base::RefCountedThreadSafe<Core, BrowserThread::DeleteOnIOThread> {
41  public:
42   Core(base::WeakPtr<PepperFlashSettingsManager> manager,
43        content::BrowserContext* browser_context);
44
45   void Initialize();
46
47   // Notifies the core that it has been detached. Afterwards, no method should
48   // be called any more.
49   void Detach();
50
51   void DeauthorizeContentLicenses(uint32_t request_id);
52   void GetPermissionSettings(
53       uint32_t request_id,
54       PP_Flash_BrowserOperations_SettingType setting_type);
55   void SetDefaultPermission(uint32_t request_id,
56                             PP_Flash_BrowserOperations_SettingType setting_type,
57                             PP_Flash_BrowserOperations_Permission permission,
58                             bool clear_site_specific);
59   void SetSitePermission(uint32_t request_id,
60                          PP_Flash_BrowserOperations_SettingType setting_type,
61                          const ppapi::FlashSiteSettings& sites);
62   void GetSitesWithData(uint32_t request_id);
63   void ClearSiteData(uint32_t request_id,
64                      const std::string& site,
65                      uint64_t flags,
66                      uint64_t max_age);
67
68   // IPC::Listener implementation.
69   bool OnMessageReceived(const IPC::Message& message) override;
70   void OnChannelError() override;
71
72  private:
73   friend struct BrowserThread::DeleteOnThread<BrowserThread::IO>;
74   friend class base::DeleteHelper<Core>;
75
76   enum RequestType {
77     INVALID_REQUEST_TYPE = 0,
78     DEAUTHORIZE_CONTENT_LICENSES,
79     GET_PERMISSION_SETTINGS,
80     SET_DEFAULT_PERMISSION,
81     SET_SITE_PERMISSION,
82     GET_SITES_WITH_DATA,
83     CLEAR_SITE_DATA,
84   };
85
86   enum State {
87     STATE_UNINITIALIZED = 0,
88     STATE_INITIALIZED,
89     STATE_ERROR,
90     STATE_DETACHED,
91   };
92
93   struct PendingRequest {
94     PendingRequest()
95         : id(0),
96           type(INVALID_REQUEST_TYPE),
97           setting_type(PP_FLASH_BROWSEROPERATIONS_SETTINGTYPE_CAMERAMIC),
98           permission(PP_FLASH_BROWSEROPERATIONS_PERMISSION_DEFAULT),
99           clear_site_specific(false),
100           flags(0),
101           max_age(0) {
102     }
103
104     uint32_t id;
105     RequestType type;
106
107     // Used by GET_PERMISSION_SETTINGS, SET_DEFAULT_PERMISSION and
108     // SET_SITE_PERMISSION.
109     PP_Flash_BrowserOperations_SettingType setting_type;
110
111     // Used by SET_DEFAULT_PERMISSION.
112     PP_Flash_BrowserOperations_Permission permission;
113     bool clear_site_specific;
114
115     // Used by SET_SITE_PERMISSION.
116     ppapi::FlashSiteSettings sites;
117
118     // Used by CLEAR_SITE_DATA
119     std::string site;
120     uint64_t flags;
121     uint64_t max_age;
122   };
123
124   ~Core() override;
125
126   void ConnectToChannel(bool success, const IPC::ChannelHandle& handle);
127
128   void InitializeOnIOThread();
129   void DeauthorizeContentLicensesOnIOThread(uint32_t request_id);
130   void DeauthorizeContentLicensesAsync(uint32_t request_id,
131                                        const base::FilePath& profile_path);
132   void DeauthorizeContentLicensesInPlugin(uint32_t request_id, bool success);
133   void GetPermissionSettingsOnIOThread(
134       uint32_t request_id,
135       PP_Flash_BrowserOperations_SettingType setting_type);
136   void SetDefaultPermissionOnIOThread(
137       uint32_t request_id,
138       PP_Flash_BrowserOperations_SettingType setting_type,
139       PP_Flash_BrowserOperations_Permission permission,
140       bool clear_site_specific);
141   void SetSitePermissionOnIOThread(
142       uint32_t request_id,
143       PP_Flash_BrowserOperations_SettingType setting_type,
144       const ppapi::FlashSiteSettings& sites);
145   void GetSitesWithDataOnIOThread(uint32_t request_id);
146   void ClearSiteDataOnIOThread(uint32_t request_id,
147                                const std::string& site,
148                                uint64_t flags,
149                                uint64_t max_age);
150   void DetachOnIOThread();
151
152   void NotifyErrorFromIOThread();
153
154   void NotifyDeauthorizeContentLicensesCompleted(uint32_t request_id,
155                                                  bool success);
156   void NotifyGetPermissionSettingsCompleted(
157       uint32_t request_id,
158       bool success,
159       PP_Flash_BrowserOperations_Permission default_permission,
160       const ppapi::FlashSiteSettings& sites);
161   void NotifySetDefaultPermissionCompleted(uint32_t request_id, bool success);
162   void NotifySetSitePermissionCompleted(uint32_t request_id, bool success);
163   void NotifyGetSitesWithDataCompleted(uint32_t request_id,
164                                        const std::vector<std::string>& sites);
165   void NotifyClearSiteDataCompleted(uint32_t request_id, bool success);
166
167   void NotifyError(
168       const std::vector<std::pair<uint32_t, RequestType>>& notifications);
169
170   // Message handlers.
171   void OnDeauthorizeContentLicensesResult(uint32_t request_id, bool success);
172   void OnGetPermissionSettingsResult(
173       uint32_t request_id,
174       bool success,
175       PP_Flash_BrowserOperations_Permission default_permission,
176       const ppapi::FlashSiteSettings& sites);
177   void OnSetDefaultPermissionResult(uint32_t request_id, bool success);
178   void OnSetSitePermissionResult(uint32_t request_id, bool success);
179   void OnGetSitesWithDataResult(uint32_t request_id,
180                                 const std::vector<std::string>& sites);
181   void OnClearSiteDataResult(uint32_t request_id, bool success);
182
183   // Used only on the UI thread.
184   base::WeakPtr<PepperFlashSettingsManager> manager_;
185
186   // Used only on the I/O thread.
187   base::FilePath plugin_data_path_;
188
189   // The channel is NULL until we have opened a connection to the broker
190   // process. Used only on the I/O thread.
191   std::unique_ptr<IPC::Channel> channel_;
192
193   // Used only on the I/O thread.
194   State state_;
195
196   // Requests that need to be sent once the channel to the broker process is
197   // established. Used only on the I/O thread.
198   std::vector<PendingRequest> pending_requests_;
199   // Requests that have been sent but haven't got replied. Used only on the
200   // I/O thread.
201   std::map<uint32_t, RequestType> pending_responses_;
202
203   // Used only on the I/O thread.
204   scoped_refptr<content::PepperFlashSettingsHelper> helper_;
205
206   // Path for the current profile. Must be retrieved on the UI thread from the
207   // browser context when we start so we can use it later on the I/O thread.
208   base::FilePath browser_context_path_;
209
210   scoped_refptr<PluginPrefs> plugin_prefs_;
211 };
212
213 PepperFlashSettingsManager::Core::Core(
214     base::WeakPtr<PepperFlashSettingsManager> manager,
215     content::BrowserContext* browser_context)
216     : manager_(manager),
217       state_(STATE_UNINITIALIZED),
218       browser_context_path_(browser_context->GetPath()),
219       plugin_prefs_(PluginPrefs::GetForProfile(
220           Profile::FromBrowserContext(browser_context))) {
221   DCHECK_CURRENTLY_ON(BrowserThread::UI);
222 }
223
224 PepperFlashSettingsManager::Core::~Core() {
225   DCHECK_CURRENTLY_ON(BrowserThread::IO);
226 }
227
228 void PepperFlashSettingsManager::Core::Initialize() {
229   DCHECK_CURRENTLY_ON(BrowserThread::UI);
230   content::GetIOThreadTaskRunner({})->PostTask(
231       FROM_HERE, base::BindOnce(&Core::InitializeOnIOThread, this));
232 }
233
234 void PepperFlashSettingsManager::Core::Detach() {
235   DCHECK_CURRENTLY_ON(BrowserThread::UI);
236
237   // This call guarantees that one ref is retained until we get to the DETACHED
238   // state. This is important. Otherwise, if the ref count drops to zero on the
239   // UI thread (which posts a task to delete this object on the I/O thread)
240   // while the I/O thread doesn't know about it, methods on the I/O thread might
241   // increase the ref count again and cause double deletion.
242   content::GetIOThreadTaskRunner({})->PostTask(
243       FROM_HERE, base::BindOnce(&Core::DetachOnIOThread, this));
244 }
245
246 void PepperFlashSettingsManager::Core::DeauthorizeContentLicenses(
247     uint32_t request_id) {
248   DCHECK_CURRENTLY_ON(BrowserThread::UI);
249
250   content::GetIOThreadTaskRunner({})->PostTask(
251       FROM_HERE, base::BindOnce(&Core::DeauthorizeContentLicensesOnIOThread,
252                                 this, request_id));
253 }
254
255 void PepperFlashSettingsManager::Core::GetPermissionSettings(
256     uint32_t request_id,
257     PP_Flash_BrowserOperations_SettingType setting_type) {
258   DCHECK_CURRENTLY_ON(BrowserThread::UI);
259
260   content::GetIOThreadTaskRunner({})->PostTask(
261       FROM_HERE, base::BindOnce(&Core::GetPermissionSettingsOnIOThread, this,
262                                 request_id, setting_type));
263 }
264
265 void PepperFlashSettingsManager::Core::SetDefaultPermission(
266     uint32_t request_id,
267     PP_Flash_BrowserOperations_SettingType setting_type,
268     PP_Flash_BrowserOperations_Permission permission,
269     bool clear_site_specific) {
270   DCHECK_CURRENTLY_ON(BrowserThread::UI);
271
272   content::GetIOThreadTaskRunner({})->PostTask(
273       FROM_HERE,
274       base::BindOnce(&Core::SetDefaultPermissionOnIOThread, this, request_id,
275                      setting_type, permission, clear_site_specific));
276 }
277
278 void PepperFlashSettingsManager::Core::SetSitePermission(
279     uint32_t request_id,
280     PP_Flash_BrowserOperations_SettingType setting_type,
281     const ppapi::FlashSiteSettings& sites) {
282   DCHECK_CURRENTLY_ON(BrowserThread::UI);
283
284   content::GetIOThreadTaskRunner({})->PostTask(
285       FROM_HERE, base::BindOnce(&Core::SetSitePermissionOnIOThread, this,
286                                 request_id, setting_type, sites));
287 }
288
289 void PepperFlashSettingsManager::Core::GetSitesWithData(uint32_t request_id) {
290   DCHECK_CURRENTLY_ON(BrowserThread::UI);
291
292   content::GetIOThreadTaskRunner({})->PostTask(
293       FROM_HERE,
294       base::BindOnce(&Core::GetSitesWithDataOnIOThread, this, request_id));
295 }
296
297 void PepperFlashSettingsManager::Core::ClearSiteData(uint32_t request_id,
298                                                      const std::string& site,
299                                                      uint64_t flags,
300                                                      uint64_t max_age) {
301   DCHECK_CURRENTLY_ON(BrowserThread::UI);
302
303   content::GetIOThreadTaskRunner({})->PostTask(
304       FROM_HERE, base::BindOnce(&Core::ClearSiteDataOnIOThread, this,
305                                 request_id, site, flags, max_age));
306 }
307
308 bool PepperFlashSettingsManager::Core::OnMessageReceived(
309     const IPC::Message& message) {
310   IPC_BEGIN_MESSAGE_MAP(Core, message)
311     IPC_MESSAGE_HANDLER(PpapiHostMsg_DeauthorizeContentLicensesResult,
312                         OnDeauthorizeContentLicensesResult)
313     IPC_MESSAGE_HANDLER(PpapiHostMsg_GetPermissionSettingsResult,
314                         OnGetPermissionSettingsResult)
315     IPC_MESSAGE_HANDLER(PpapiHostMsg_SetDefaultPermissionResult,
316                         OnSetDefaultPermissionResult)
317     IPC_MESSAGE_HANDLER(PpapiHostMsg_SetSitePermissionResult,
318                         OnSetSitePermissionResult)
319     IPC_MESSAGE_HANDLER(PpapiHostMsg_GetSitesWithDataResult,
320                         OnGetSitesWithDataResult)
321     IPC_MESSAGE_HANDLER(PpapiHostMsg_ClearSiteDataResult,
322                         OnClearSiteDataResult)
323     IPC_MESSAGE_UNHANDLED_ERROR()
324   IPC_END_MESSAGE_MAP()
325
326   return true;
327 }
328
329 void PepperFlashSettingsManager::Core::OnChannelError() {
330   DCHECK_CURRENTLY_ON(BrowserThread::IO);
331   if (state_ == STATE_DETACHED)
332     return;
333
334   NotifyErrorFromIOThread();
335 }
336
337 void PepperFlashSettingsManager::Core::ConnectToChannel(
338     bool success,
339     const IPC::ChannelHandle& handle) {
340   DCHECK_CURRENTLY_ON(BrowserThread::IO);
341   if (state_ == STATE_DETACHED)
342     return;
343
344   DCHECK(state_ == STATE_UNINITIALIZED);
345   DCHECK(!channel_.get());
346
347   if (!success) {
348     DLOG(ERROR) << "Couldn't open plugin channel";
349     NotifyErrorFromIOThread();
350     return;
351   }
352
353   channel_ = IPC::Channel::CreateClient(handle, this,
354                                         base::ThreadTaskRunnerHandle::Get());
355   if (!channel_->Connect()) {
356     DLOG(ERROR) << "Couldn't connect to plugin";
357     NotifyErrorFromIOThread();
358     return;
359   }
360
361   state_ = STATE_INITIALIZED;
362
363   std::vector<PendingRequest> temp_pending_requests;
364   temp_pending_requests.swap(pending_requests_);
365   for (auto iter = temp_pending_requests.begin();
366        iter != temp_pending_requests.end(); ++iter) {
367     switch (iter->type) {
368       case INVALID_REQUEST_TYPE:
369         NOTREACHED();
370         break;
371       case DEAUTHORIZE_CONTENT_LICENSES:
372         DeauthorizeContentLicensesOnIOThread(iter->id);
373         break;
374       case GET_PERMISSION_SETTINGS:
375         GetPermissionSettingsOnIOThread(iter->id, iter->setting_type);
376         break;
377       case SET_DEFAULT_PERMISSION:
378         SetDefaultPermissionOnIOThread(
379             iter->id, iter->setting_type, iter->permission,
380             iter->clear_site_specific);
381         break;
382       case SET_SITE_PERMISSION:
383         SetSitePermissionOnIOThread(iter->id, iter->setting_type, iter->sites);
384         break;
385       case GET_SITES_WITH_DATA:
386         GetSitesWithDataOnIOThread(iter->id);
387         break;
388       case CLEAR_SITE_DATA:
389         ClearSiteDataOnIOThread(iter->id, iter->site, iter->flags,
390                                 iter->max_age);
391         break;
392     }
393   }
394 }
395
396 void PepperFlashSettingsManager::Core::InitializeOnIOThread() {
397   DCHECK_CURRENTLY_ON(BrowserThread::IO);
398   DCHECK_EQ(STATE_UNINITIALIZED, state_);
399
400   content::WebPluginInfo plugin_info;
401   if (!PepperFlashSettingsManager::IsPepperFlashInUse(plugin_prefs_.get(),
402                                                       &plugin_info)) {
403     NotifyErrorFromIOThread();
404     return;
405   }
406
407   base::FilePath profile_path =
408       browser_context_path_.Append(content::kPepperDataDirname);
409 #if defined(OS_WIN)
410   plugin_data_path_ = profile_path.Append(plugin_info.name);
411 #else
412   plugin_data_path_ = profile_path.Append(base::UTF16ToUTF8(plugin_info.name));
413 #endif
414
415   helper_ = content::PepperFlashSettingsHelper::Create();
416   helper_->OpenChannelToBroker(plugin_info.path,
417                                base::BindOnce(&Core::ConnectToChannel, this));
418 }
419
420 void PepperFlashSettingsManager::Core::DeauthorizeContentLicensesOnIOThread(
421     uint32_t request_id) {
422   DCHECK_CURRENTLY_ON(BrowserThread::IO);
423   DCHECK_NE(STATE_DETACHED, state_);
424
425   if (state_ == STATE_UNINITIALIZED) {
426     PendingRequest request;
427     request.id = request_id;
428     request.type = DEAUTHORIZE_CONTENT_LICENSES;
429     pending_requests_.push_back(request);
430     return;
431   }
432
433   pending_responses_.insert(
434       std::make_pair(request_id, DEAUTHORIZE_CONTENT_LICENSES));
435   if (state_ == STATE_ERROR) {
436     NotifyErrorFromIOThread();
437     return;
438   }
439
440 #if defined(OS_CHROMEOS)
441   base::ThreadPool::PostTask(
442       FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
443       base::BindOnce(&Core::DeauthorizeContentLicensesAsync, this, request_id,
444                      browser_context_path_));
445 #else
446   DeauthorizeContentLicensesInPlugin(request_id, true);
447 #endif
448 }
449
450 // TODO(raymes): This is temporary code to migrate ChromeOS devices to the new
451 // scheme for generating device IDs. Delete this once we are sure most ChromeOS
452 // devices have been migrated.
453 void PepperFlashSettingsManager::Core::DeauthorizeContentLicensesAsync(
454     uint32_t request_id,
455     const base::FilePath& profile_path) {
456   // ChromeOS used to store the device ID in a file but this is no longer used.
457   // Wipe that file.
458   const base::FilePath& device_id_path =
459       DeviceIDFetcher::GetLegacyDeviceIDPath(profile_path);
460   bool success = base::DeleteFile(device_id_path, false);
461
462   content::GetIOThreadTaskRunner({})->PostTask(
463       FROM_HERE, base::BindOnce(&Core::DeauthorizeContentLicensesInPlugin, this,
464                                 request_id, success));
465 }
466
467 void PepperFlashSettingsManager::Core::DeauthorizeContentLicensesInPlugin(
468     uint32_t request_id,
469     bool success) {
470   DCHECK_CURRENTLY_ON(BrowserThread::IO);
471   if (!success) {
472     NotifyErrorFromIOThread();
473     return;
474   }
475   IPC::Message* msg =
476       new PpapiMsg_DeauthorizeContentLicenses(request_id, plugin_data_path_);
477   if (!channel_->Send(msg)) {
478     DLOG(ERROR) << "Couldn't send DeauthorizeContentLicenses message";
479     // A failure notification for the current request will be sent since
480     // |pending_responses_| has been updated.
481     NotifyErrorFromIOThread();
482   }
483 }
484
485 void PepperFlashSettingsManager::Core::GetPermissionSettingsOnIOThread(
486     uint32_t request_id,
487     PP_Flash_BrowserOperations_SettingType setting_type) {
488   DCHECK_CURRENTLY_ON(BrowserThread::IO);
489   DCHECK_NE(STATE_DETACHED, state_);
490
491   if (state_ == STATE_UNINITIALIZED) {
492     PendingRequest request;
493     request.id = request_id;
494     request.type = GET_PERMISSION_SETTINGS;
495     request.setting_type = setting_type;
496     pending_requests_.push_back(request);
497     return;
498   }
499
500   pending_responses_.insert(
501       std::make_pair(request_id, GET_PERMISSION_SETTINGS));
502   if (state_ == STATE_ERROR) {
503     NotifyErrorFromIOThread();
504     return;
505   }
506
507   IPC::Message* msg = new PpapiMsg_GetPermissionSettings(
508       request_id, plugin_data_path_, setting_type);
509   if (!channel_->Send(msg)) {
510     DLOG(ERROR) << "Couldn't send GetPermissionSettings message";
511     // A failure notification for the current request will be sent since
512     // |pending_responses_| has been updated.
513     NotifyErrorFromIOThread();
514   }
515 }
516
517 void PepperFlashSettingsManager::Core::SetDefaultPermissionOnIOThread(
518     uint32_t request_id,
519     PP_Flash_BrowserOperations_SettingType setting_type,
520     PP_Flash_BrowserOperations_Permission permission,
521     bool clear_site_specific) {
522   DCHECK_CURRENTLY_ON(BrowserThread::IO);
523   DCHECK_NE(STATE_DETACHED, state_);
524
525   if (state_ == STATE_UNINITIALIZED) {
526     PendingRequest request;
527     request.id = request_id;
528     request.type = SET_DEFAULT_PERMISSION;
529     request.setting_type = setting_type;
530     request.permission = permission;
531     request.clear_site_specific = clear_site_specific;
532     pending_requests_.push_back(request);
533     return;
534   }
535
536   pending_responses_.insert(std::make_pair(request_id, SET_DEFAULT_PERMISSION));
537   if (state_ == STATE_ERROR) {
538     NotifyErrorFromIOThread();
539     return;
540   }
541
542   IPC::Message* msg = new PpapiMsg_SetDefaultPermission(
543       request_id, plugin_data_path_, setting_type, permission,
544       clear_site_specific);
545   if (!channel_->Send(msg)) {
546     DLOG(ERROR) << "Couldn't send SetDefaultPermission message";
547     // A failure notification for the current request will be sent since
548     // |pending_responses_| has been updated.
549     NotifyErrorFromIOThread();
550   }
551 }
552
553 void PepperFlashSettingsManager::Core::SetSitePermissionOnIOThread(
554     uint32_t request_id,
555     PP_Flash_BrowserOperations_SettingType setting_type,
556     const ppapi::FlashSiteSettings& sites) {
557   DCHECK_CURRENTLY_ON(BrowserThread::IO);
558   DCHECK_NE(STATE_DETACHED, state_);
559
560   if (state_ == STATE_UNINITIALIZED) {
561     pending_requests_.push_back(PendingRequest());
562     PendingRequest& request = pending_requests_.back();
563     request.id = request_id;
564     request.type = SET_SITE_PERMISSION;
565     request.setting_type = setting_type;
566     request.sites = sites;
567     return;
568   }
569
570   pending_responses_.insert(std::make_pair(request_id, SET_SITE_PERMISSION));
571   if (state_ == STATE_ERROR) {
572     NotifyErrorFromIOThread();
573     return;
574   }
575
576   IPC::Message* msg = new PpapiMsg_SetSitePermission(
577       request_id, plugin_data_path_, setting_type, sites);
578   if (!channel_->Send(msg)) {
579     DLOG(ERROR) << "Couldn't send SetSitePermission message";
580     // A failure notification for the current request will be sent since
581     // |pending_responses_| has been updated.
582     NotifyErrorFromIOThread();
583   }
584 }
585
586 void PepperFlashSettingsManager::Core::GetSitesWithDataOnIOThread(
587     uint32_t request_id) {
588   DCHECK_CURRENTLY_ON(BrowserThread::IO);
589   DCHECK_NE(STATE_DETACHED, state_);
590
591   if (state_ == STATE_UNINITIALIZED) {
592     pending_requests_.push_back(PendingRequest());
593     PendingRequest& request = pending_requests_.back();
594     request.id = request_id;
595     request.type = GET_SITES_WITH_DATA;
596     return;
597   }
598
599   pending_responses_.insert(std::make_pair(request_id, GET_SITES_WITH_DATA));
600   if (state_ == STATE_ERROR) {
601     NotifyErrorFromIOThread();
602     return;
603   }
604
605   IPC::Message* msg = new PpapiMsg_GetSitesWithData(
606       request_id, plugin_data_path_);
607   if (!channel_->Send(msg)) {
608     DLOG(ERROR) << "Couldn't send GetSitesWithData message";
609     // A failure notification for the current request will be sent since
610     // |pending_responses_| has been updated.
611     NotifyErrorFromIOThread();
612   }
613 }
614
615 void PepperFlashSettingsManager::Core::ClearSiteDataOnIOThread(
616     uint32_t request_id,
617     const std::string& site,
618     uint64_t flags,
619     uint64_t max_age) {
620   DCHECK_CURRENTLY_ON(BrowserThread::IO);
621   DCHECK_NE(STATE_DETACHED, state_);
622
623   if (state_ == STATE_UNINITIALIZED) {
624     pending_requests_.push_back(PendingRequest());
625     PendingRequest& request = pending_requests_.back();
626     request.id = request_id;
627     request.type = CLEAR_SITE_DATA;
628     request.site = site;
629     request.flags = flags;
630     request.max_age = max_age;
631     return;
632   }
633
634   pending_responses_.insert(std::make_pair(request_id, CLEAR_SITE_DATA));
635   if (state_ == STATE_ERROR) {
636     NotifyErrorFromIOThread();
637     return;
638   }
639
640   IPC::Message* msg = new PpapiMsg_ClearSiteData(
641       request_id, plugin_data_path_, site, flags, max_age);
642   if (!channel_->Send(msg)) {
643     DLOG(ERROR) << "Couldn't send ClearSiteData message";
644     // A failure notification for the current request will be sent since
645     // |pending_responses_| has been updated.
646     NotifyErrorFromIOThread();
647   }
648 }
649
650 void PepperFlashSettingsManager::Core::DetachOnIOThread() {
651   state_ = STATE_DETACHED;
652 }
653
654 void PepperFlashSettingsManager::Core::NotifyErrorFromIOThread() {
655   DCHECK_CURRENTLY_ON(BrowserThread::IO);
656   if (state_ == STATE_DETACHED)
657     return;
658
659   state_ = STATE_ERROR;
660   std::vector<std::pair<uint32_t, RequestType>> notifications;
661   for (auto iter = pending_requests_.begin(); iter != pending_requests_.end();
662        ++iter) {
663     notifications.push_back(std::make_pair(iter->id, iter->type));
664   }
665   pending_requests_.clear();
666   notifications.insert(notifications.end(), pending_responses_.begin(),
667                        pending_responses_.end());
668   pending_responses_.clear();
669
670   content::GetUIThreadTaskRunner({})->PostTask(
671       FROM_HERE, base::BindOnce(&Core::NotifyError, this, notifications));
672 }
673
674 void PepperFlashSettingsManager::Core::
675     NotifyDeauthorizeContentLicensesCompleted(uint32_t request_id,
676                                               bool success) {
677   DCHECK_CURRENTLY_ON(BrowserThread::UI);
678
679   if (manager_.get()) {
680     manager_->client_->OnDeauthorizeFlashContentLicensesCompleted(request_id,
681                                                                   success);
682   }
683 }
684
685 void PepperFlashSettingsManager::Core::NotifyGetPermissionSettingsCompleted(
686     uint32_t request_id,
687     bool success,
688     PP_Flash_BrowserOperations_Permission default_permission,
689     const ppapi::FlashSiteSettings& sites) {
690   DCHECK_CURRENTLY_ON(BrowserThread::UI);
691
692   if (manager_.get()) {
693     manager_->client_->OnGetPermissionSettingsCompleted(
694         request_id, success, default_permission, sites);
695   }
696 }
697
698 void PepperFlashSettingsManager::Core::NotifySetDefaultPermissionCompleted(
699     uint32_t request_id,
700     bool success) {
701   DCHECK_CURRENTLY_ON(BrowserThread::UI);
702
703   if (manager_.get()) {
704     manager_->client_->OnSetDefaultPermissionCompleted(
705         request_id, success);
706   }
707 }
708
709 void PepperFlashSettingsManager::Core::NotifySetSitePermissionCompleted(
710     uint32_t request_id,
711     bool success) {
712   DCHECK_CURRENTLY_ON(BrowserThread::UI);
713
714   if (manager_.get()) {
715     manager_->client_->OnSetSitePermissionCompleted(
716         request_id, success);
717   }
718 }
719
720 void PepperFlashSettingsManager::Core::NotifyGetSitesWithDataCompleted(
721     uint32_t request_id,
722     const std::vector<std::string>& sites) {
723   DCHECK_CURRENTLY_ON(BrowserThread::UI);
724
725   if (manager_.get()) {
726     manager_->client_->OnGetSitesWithDataCompleted(
727         request_id, sites);
728   }
729 }
730
731 void PepperFlashSettingsManager::Core::NotifyClearSiteDataCompleted(
732     uint32_t request_id,
733     bool success) {
734   DCHECK_CURRENTLY_ON(BrowserThread::UI);
735
736   if (manager_.get())
737     manager_->client_->OnClearSiteDataCompleted(request_id, success);
738 }
739
740 void PepperFlashSettingsManager::Core::NotifyError(
741     const std::vector<std::pair<uint32_t, RequestType>>& notifications) {
742   DCHECK_CURRENTLY_ON(BrowserThread::UI);
743
744   scoped_refptr<Core> protector(this);
745   for (auto iter = notifications.begin(); iter != notifications.end(); ++iter) {
746     // Check |manager_| for each iteration in case it is destroyed in one of
747     // the callbacks.
748     if (!manager_.get())
749       return;
750
751     switch (iter->second) {
752       case INVALID_REQUEST_TYPE:
753         NOTREACHED();
754         break;
755       case DEAUTHORIZE_CONTENT_LICENSES:
756         manager_->client_->OnDeauthorizeFlashContentLicensesCompleted(
757             iter->first, false);
758         break;
759       case GET_PERMISSION_SETTINGS:
760         manager_->client_->OnGetPermissionSettingsCompleted(
761             iter->first, false, PP_FLASH_BROWSEROPERATIONS_PERMISSION_DEFAULT,
762             ppapi::FlashSiteSettings());
763         break;
764       case SET_DEFAULT_PERMISSION:
765         manager_->client_->OnSetDefaultPermissionCompleted(
766             iter->first, false);
767         break;
768       case SET_SITE_PERMISSION:
769         manager_->client_->OnSetSitePermissionCompleted(iter->first, false);
770         break;
771       case GET_SITES_WITH_DATA:
772         manager_->client_->OnGetSitesWithDataCompleted(
773             iter->first, std::vector<std::string>());
774         break;
775       case CLEAR_SITE_DATA:
776         manager_->client_->OnClearSiteDataCompleted(iter->first, false);
777         break;
778     }
779   }
780
781   if (manager_.get())
782     manager_->OnError(this);
783 }
784
785 void PepperFlashSettingsManager::Core::OnDeauthorizeContentLicensesResult(
786     uint32_t request_id,
787     bool success) {
788   DCHECK_CURRENTLY_ON(BrowserThread::IO);
789   if (state_ == STATE_DETACHED)
790     return;
791
792   DLOG_IF(ERROR, !success) << "DeauthorizeContentLicenses returned error";
793
794   auto iter = pending_responses_.find(request_id);
795   if (iter == pending_responses_.end())
796     return;
797
798   DCHECK_EQ(iter->second, DEAUTHORIZE_CONTENT_LICENSES);
799
800   pending_responses_.erase(iter);
801   content::GetUIThreadTaskRunner({})->PostTask(
802       FROM_HERE,
803       base::BindOnce(&Core::NotifyDeauthorizeContentLicensesCompleted, this,
804                      request_id, success));
805 }
806
807 void PepperFlashSettingsManager::Core::OnGetPermissionSettingsResult(
808     uint32_t request_id,
809     bool success,
810     PP_Flash_BrowserOperations_Permission default_permission,
811     const ppapi::FlashSiteSettings& sites) {
812   DCHECK_CURRENTLY_ON(BrowserThread::IO);
813   if (state_ == STATE_DETACHED)
814     return;
815
816   DLOG_IF(ERROR, !success) << "GetPermissionSettings returned error";
817
818   auto iter = pending_responses_.find(request_id);
819   if (iter == pending_responses_.end())
820     return;
821
822   DCHECK_EQ(iter->second, GET_PERMISSION_SETTINGS);
823
824   pending_responses_.erase(iter);
825   content::GetUIThreadTaskRunner({})->PostTask(
826       FROM_HERE,
827       base::BindOnce(&Core::NotifyGetPermissionSettingsCompleted, this,
828                      request_id, success, default_permission, sites));
829 }
830
831 void PepperFlashSettingsManager::Core::OnSetDefaultPermissionResult(
832     uint32_t request_id,
833     bool success) {
834   DCHECK_CURRENTLY_ON(BrowserThread::IO);
835   if (state_ == STATE_DETACHED)
836     return;
837
838   DLOG_IF(ERROR, !success) << "SetDefaultPermission returned error";
839
840   auto iter = pending_responses_.find(request_id);
841   if (iter == pending_responses_.end())
842     return;
843
844   DCHECK_EQ(iter->second, SET_DEFAULT_PERMISSION);
845
846   pending_responses_.erase(iter);
847   content::GetUIThreadTaskRunner({})->PostTask(
848       FROM_HERE, base::BindOnce(&Core::NotifySetDefaultPermissionCompleted,
849                                 this, request_id, success));
850 }
851
852 void PepperFlashSettingsManager::Core::OnSetSitePermissionResult(
853     uint32_t request_id,
854     bool success) {
855   DCHECK_CURRENTLY_ON(BrowserThread::IO);
856   if (state_ == STATE_DETACHED)
857     return;
858
859   DLOG_IF(ERROR, !success) << "SetSitePermission returned error";
860
861   auto iter = pending_responses_.find(request_id);
862   if (iter == pending_responses_.end())
863     return;
864
865   DCHECK_EQ(iter->second, SET_SITE_PERMISSION);
866
867   pending_responses_.erase(iter);
868   content::GetUIThreadTaskRunner({})->PostTask(
869       FROM_HERE, base::BindOnce(&Core::NotifySetSitePermissionCompleted, this,
870                                 request_id, success));
871 }
872
873 void PepperFlashSettingsManager::Core::OnGetSitesWithDataResult(
874     uint32_t request_id,
875     const std::vector<std::string>& sites) {
876   DCHECK_CURRENTLY_ON(BrowserThread::IO);
877   if (state_ == STATE_DETACHED)
878     return;
879
880   auto iter = pending_responses_.find(request_id);
881   if (iter == pending_responses_.end())
882     return;
883
884   DCHECK_EQ(iter->second, GET_SITES_WITH_DATA);
885
886   pending_responses_.erase(iter);
887   content::GetUIThreadTaskRunner({})->PostTask(
888       FROM_HERE, base::BindOnce(&Core::NotifyGetSitesWithDataCompleted, this,
889                                 request_id, sites));
890 }
891
892 void PepperFlashSettingsManager::Core::OnClearSiteDataResult(
893     uint32_t request_id,
894     bool success) {
895   DCHECK_CURRENTLY_ON(BrowserThread::IO);
896   if (state_ == STATE_DETACHED)
897     return;
898
899   DLOG_IF(ERROR, !success) << "ClearSiteData returned error";
900
901   auto iter = pending_responses_.find(request_id);
902   if (iter == pending_responses_.end())
903     return;
904
905   DCHECK_EQ(iter->second, CLEAR_SITE_DATA);
906
907   pending_responses_.erase(iter);
908   content::GetUIThreadTaskRunner({})->PostTask(
909       FROM_HERE, base::BindOnce(&Core::NotifyClearSiteDataCompleted, this,
910                                 request_id, success));
911 }
912
913 PepperFlashSettingsManager::PepperFlashSettingsManager(
914     Client* client,
915     content::BrowserContext* browser_context)
916     : client_(client), browser_context_(browser_context), next_request_id_(1) {
917   DCHECK(client);
918   DCHECK(browser_context);
919 }
920
921 PepperFlashSettingsManager::~PepperFlashSettingsManager() {
922   if (core_.get())
923     core_->Detach();
924 }
925
926 // static
927 bool PepperFlashSettingsManager::IsPepperFlashInUse(
928     PluginPrefs* plugin_prefs,
929     content::WebPluginInfo* plugin_info) {
930   if (!plugin_prefs)
931     return false;
932
933   content::PluginService* plugin_service =
934       content::PluginService::GetInstance();
935   std::vector<content::WebPluginInfo> plugins;
936   plugin_service->GetPluginInfoArray(
937       GURL(), content::kFlashPluginSwfMimeType, false, &plugins, NULL);
938
939   for (auto iter = plugins.begin(); iter != plugins.end(); ++iter) {
940     if (iter->is_pepper_plugin() && plugin_prefs->IsPluginEnabled(*iter)) {
941       if (plugin_info)
942         *plugin_info = *iter;
943       return true;
944     }
945   }
946   return false;
947 }
948
949 // static
950 void PepperFlashSettingsManager::RegisterProfilePrefs(
951     user_prefs::PrefRegistrySyncable* registry) {
952   registry->RegisterBooleanPref(prefs::kPepperFlashSettingsEnabled, true);
953 }
954
955 uint32_t PepperFlashSettingsManager::DeauthorizeContentLicenses(
956     PrefService* prefs) {
957   DCHECK_CURRENTLY_ON(BrowserThread::UI);
958
959   // Clear the device ID salt which has the effect of regenerating a device
960   // ID. Since this happens synchronously (and on the UI thread), we don't have
961   // to add it to a pending request.
962   prefs->ClearPref(prefs::kDRMSalt);
963
964   EnsureCoreExists();
965   uint32_t id = GetNextRequestId();
966   core_->DeauthorizeContentLicenses(id);
967   return id;
968 }
969
970 uint32_t PepperFlashSettingsManager::GetPermissionSettings(
971     PP_Flash_BrowserOperations_SettingType setting_type) {
972   DCHECK_CURRENTLY_ON(BrowserThread::UI);
973
974   EnsureCoreExists();
975   uint32_t id = GetNextRequestId();
976   core_->GetPermissionSettings(id, setting_type);
977   return id;
978 }
979
980 uint32_t PepperFlashSettingsManager::SetDefaultPermission(
981     PP_Flash_BrowserOperations_SettingType setting_type,
982     PP_Flash_BrowserOperations_Permission permission,
983     bool clear_site_specific) {
984   DCHECK_CURRENTLY_ON(BrowserThread::UI);
985
986   EnsureCoreExists();
987   uint32_t id = GetNextRequestId();
988   core_->SetDefaultPermission(id, setting_type, permission,
989                               clear_site_specific);
990   return id;
991 }
992
993 uint32_t PepperFlashSettingsManager::SetSitePermission(
994     PP_Flash_BrowserOperations_SettingType setting_type,
995     const ppapi::FlashSiteSettings& sites) {
996   DCHECK_CURRENTLY_ON(BrowserThread::UI);
997
998   EnsureCoreExists();
999   uint32_t id = GetNextRequestId();
1000   core_->SetSitePermission(id, setting_type, sites);
1001   return id;
1002 }
1003
1004 uint32_t PepperFlashSettingsManager::GetSitesWithData() {
1005   DCHECK_CURRENTLY_ON(BrowserThread::UI);
1006
1007   EnsureCoreExists();
1008   uint32_t id = GetNextRequestId();
1009   core_->GetSitesWithData(id);
1010   return id;
1011 }
1012
1013 uint32_t PepperFlashSettingsManager::ClearSiteData(const std::string& site,
1014                                                    uint64_t flags,
1015                                                    uint64_t max_age) {
1016   DCHECK_CURRENTLY_ON(BrowserThread::UI);
1017
1018   EnsureCoreExists();
1019   uint32_t id = GetNextRequestId();
1020   core_->ClearSiteData(id, site, flags, max_age);
1021   return id;
1022 }
1023
1024 uint32_t PepperFlashSettingsManager::GetNextRequestId() {
1025   return next_request_id_++;
1026 }
1027
1028 void PepperFlashSettingsManager::EnsureCoreExists() {
1029   if (!core_.get()) {
1030     core_ = new Core(weak_ptr_factory_.GetWeakPtr(), browser_context_);
1031     core_->Initialize();
1032   }
1033 }
1034
1035 void PepperFlashSettingsManager::OnError(Core* core) {
1036   DCHECK(core);
1037   if (core != core_.get())
1038     return;
1039
1040   core_->Detach();
1041   core_.reset();
1042 }