summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authoryzshen@chromium.org <yzshen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-27 07:18:46 +0000
committeryzshen@chromium.org <yzshen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-27 07:18:46 +0000
commit1a559448088694cd4dc077c7a14436942fda5061 (patch)
treec539c7259f878cf6c43bbbbc2515eaa46b0f4f45 /chrome
parent3f84377fbfae99a755a20f8a9a5390526cec9ce1 (diff)
downloadchromium_src-1a559448088694cd4dc077c7a14436942fda5061.zip
chromium_src-1a559448088694cd4dc077c7a14436942fda5061.tar.gz
chromium_src-1a559448088694cd4dc077c7a14436942fda5061.tar.bz2
Pepper Flash settings integration: implement "deauthorize content licenses".
A few notes about PepperFlashSettingsManager: - It doesn't re-establish a channel for each request. It might seem unnecessary at this point. But that is needed for implementing content settings (camera/mic and peer networking), which requires more interactions with the broker process. - Similarly, the support of multiple in-flight requests isn't very useful for deauthorizing content licenses, but that is useful for content settings, e.g., sending multiple GetPermissionSettings requests for different setting types. BUG=112190 TEST=None Review URL: https://chromiumcodereview.appspot.com/10391173 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@139210 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/browsing_data_remover.cc22
-rw-r--r--chrome/browser/browsing_data_remover.h16
-rw-r--r--chrome/browser/pepper_flash_settings_manager.cc350
-rw-r--r--chrome/browser/pepper_flash_settings_manager.h53
4 files changed, 437 insertions, 4 deletions
diff --git a/chrome/browser/browsing_data_remover.cc b/chrome/browser/browsing_data_remover.cc
index afb7363..592cc80 100644
--- a/chrome/browser/browsing_data_remover.cc
+++ b/chrome/browser/browsing_data_remover.cc
@@ -102,6 +102,7 @@ BrowsingDataRemover::BrowsingDataRemover(Profile* profile,
cache_(NULL),
main_context_getter_(profile->GetRequestContext()),
media_context_getter_(profile->GetRequestContextForMedia()),
+ deauthorize_content_licenses_request_id_(0),
waiting_for_clear_cache_(false),
waiting_for_clear_cookies_count_(0),
waiting_for_clear_history_(false),
@@ -109,6 +110,7 @@ BrowsingDataRemover::BrowsingDataRemover(Profile* profile,
waiting_for_clear_server_bound_certs_(false),
waiting_for_clear_plugin_data_(false),
waiting_for_clear_quota_managed_data_(false),
+ waiting_for_clear_content_licenses_(false),
remove_mask_(0),
remove_origin_(GURL()),
remove_protected_(false) {
@@ -127,6 +129,7 @@ BrowsingDataRemover::BrowsingDataRemover(Profile* profile,
cache_(NULL),
main_context_getter_(profile->GetRequestContext()),
media_context_getter_(profile->GetRequestContextForMedia()),
+ deauthorize_content_licenses_request_id_(0),
waiting_for_clear_cache_(false),
waiting_for_clear_cookies_count_(0),
waiting_for_clear_history_(false),
@@ -134,6 +137,7 @@ BrowsingDataRemover::BrowsingDataRemover(Profile* profile,
waiting_for_clear_server_bound_certs_(false),
waiting_for_clear_plugin_data_(false),
waiting_for_clear_quota_managed_data_(false),
+ waiting_for_clear_content_licenses_(false),
remove_mask_(0),
remove_origin_(GURL()),
remove_protected_(false) {
@@ -388,7 +392,13 @@ void BrowsingDataRemover::RemoveImpl(int remove_mask,
content::RecordAction(
UserMetricsAction("ClearBrowsingData_ContentLicenses"));
- // TODO(yzshen): Implement it.
+ waiting_for_clear_content_licenses_ = true;
+ if (!pepper_flash_settings_manager_.get()) {
+ pepper_flash_settings_manager_.reset(
+ new PepperFlashSettingsManager(this, profile_));
+ }
+ deauthorize_content_licenses_request_id_ =
+ pepper_flash_settings_manager_->DeauthorizeContentLicenses();
}
// Also delete cached network related data (like TransportSecurityState,
@@ -679,6 +689,16 @@ void BrowsingDataRemover::OnWaitableEventSignaled(
NotifyAndDeleteIfDone();
}
+void BrowsingDataRemover::OnDeauthorizeContentLicensesCompleted(
+ uint32 request_id,
+ bool /* success */) {
+ DCHECK(waiting_for_clear_content_licenses_);
+ DCHECK_EQ(request_id, deauthorize_content_licenses_request_id_);
+
+ waiting_for_clear_content_licenses_ = false;
+ NotifyAndDeleteIfDone();
+}
+
void BrowsingDataRemover::OnClearedCookies(int num_deleted) {
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
BrowserThread::PostTask(
diff --git a/chrome/browser/browsing_data_remover.h b/chrome/browser/browsing_data_remover.h
index f819110..446a7dd 100644
--- a/chrome/browser/browsing_data_remover.h
+++ b/chrome/browser/browsing_data_remover.h
@@ -15,6 +15,7 @@
#include "base/synchronization/waitable_event_watcher.h"
#include "base/time.h"
#include "chrome/browser/cancelable_request.h"
+#include "chrome/browser/pepper_flash_settings_manager.h"
#include "chrome/browser/prefs/pref_member.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
@@ -46,7 +47,8 @@ class QuotaManager;
// visits in url database, downloads, cookies ...
class BrowsingDataRemover : public content::NotificationObserver,
- public base::WaitableEventWatcher::Delegate {
+ public base::WaitableEventWatcher::Delegate,
+ public PepperFlashSettingsManager::Client {
public:
// Time period ranges available when doing browsing data removals.
enum TimePeriod {
@@ -179,6 +181,10 @@ class BrowsingDataRemover : public content::NotificationObserver,
virtual void OnWaitableEventSignaled(
base::WaitableEvent* waitable_event) OVERRIDE;
+ // PepperFlashSettingsManager::Client implementation.
+ virtual void OnDeauthorizeContentLicensesCompleted(uint32 request_id,
+ bool success) OVERRIDE;
+
// Removes the specified items related to browsing for a specific host. If the
// provided |origin| is empty, data is removed for all origins. If
// |remove_protected_origins| is true, then data is removed even if the origin
@@ -255,7 +261,8 @@ class BrowsingDataRemover : public content::NotificationObserver,
!waiting_for_clear_networking_history_ &&
!waiting_for_clear_server_bound_certs_ &&
!waiting_for_clear_plugin_data_ &&
- !waiting_for_clear_quota_managed_data_;
+ !waiting_for_clear_quota_managed_data_ &&
+ !waiting_for_clear_content_licenses_;
}
// Setter for removing_; DCHECKs that we can only start removing if we're not
@@ -294,6 +301,10 @@ class BrowsingDataRemover : public content::NotificationObserver,
scoped_ptr<content::PluginDataRemover> plugin_data_remover_;
base::WaitableEventWatcher watcher_;
+ // Used to deauthorize content licenses for Pepper Flash.
+ scoped_ptr<PepperFlashSettingsManager> pepper_flash_settings_manager_;
+ uint32 deauthorize_content_licenses_request_id_;
+
// True if we're waiting for various data to be deleted.
// These may only be accessed from UI thread in order to avoid races!
bool waiting_for_clear_cache_;
@@ -304,6 +315,7 @@ class BrowsingDataRemover : public content::NotificationObserver,
bool waiting_for_clear_server_bound_certs_;
bool waiting_for_clear_plugin_data_;
bool waiting_for_clear_quota_managed_data_;
+ bool waiting_for_clear_content_licenses_;
// Tracking how many origins need to be deleted, and whether we're finished
// gathering origins.
diff --git a/chrome/browser/pepper_flash_settings_manager.cc b/chrome/browser/pepper_flash_settings_manager.cc
index 4a15ca9..ba7192d 100644
--- a/chrome/browser/pepper_flash_settings_manager.cc
+++ b/chrome/browser/pepper_flash_settings_manager.cc
@@ -4,16 +4,338 @@
#include "chrome/browser/pepper_flash_settings_manager.h"
+#include <map>
+#include <utility>
#include <vector>
+#include "base/bind.h"
+#include "base/compiler_specific.h"
+#include "base/sequenced_task_runner_helpers.h"
+#include "base/utf_string_conversions.h"
#include "chrome/browser/plugin_prefs.h"
#include "chrome/browser/prefs/pref_service.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/common/pref_names.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/pepper_flash_settings_helper.h"
#include "content/public/browser/plugin_service.h"
+#include "content/public/common/content_constants.h"
#include "googleurl/src/gurl.h"
+#include "ipc/ipc_channel.h"
+#include "ppapi/proxy/ppapi_messages.h"
#include "webkit/plugins/plugin_constants.h"
#include "webkit/plugins/webplugininfo.h"
+using content::BrowserThread;
+
+class PepperFlashSettingsManager::Core
+ : public IPC::Channel::Listener,
+ public base::RefCountedThreadSafe<Core, BrowserThread::DeleteOnIOThread> {
+ public:
+ Core(PepperFlashSettingsManager* manager,
+ content::BrowserContext* browser_context);
+
+ // Stops sending notifications to |manager_| and sets it to NULL.
+ void Detach();
+
+ void DeauthorizeContentLicenses(uint32 request_id);
+
+ // IPC::Channel::Listener implementation.
+ virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
+ virtual void OnChannelError() OVERRIDE;
+
+ private:
+ friend struct BrowserThread::DeleteOnThread<BrowserThread::IO>;
+ friend class base::DeleteHelper<Core>;
+
+ enum RequestType {
+ INVALID_REQUEST_TYPE = 0,
+ DEAUTHORIZE_CONTENT_LICENSES
+ };
+
+ struct PendingRequest {
+ PendingRequest() : id(0), type(INVALID_REQUEST_TYPE) {}
+
+ uint32 id;
+ RequestType type;
+ };
+
+ virtual ~Core();
+
+ void Initialize();
+ void ConnectToChannel(bool success, const IPC::ChannelHandle& handle);
+
+ void DeauthorizeContentLicensesOnIOThread(uint32 request_id);
+ void NotifyErrorFromIOThread();
+
+ void NotifyDeauthorizeContentLicensesCompleted(uint32 request_id,
+ bool success);
+ void NotifyError(
+ const std::vector<std::pair<uint32, RequestType> >& notifications);
+
+ // Message handlers.
+ void OnDeauthorizeContentLicensesResult(uint32 request_id, bool success);
+
+ // Used only on the UI thread.
+ PepperFlashSettingsManager* manager_;
+
+ // Used only on the I/O thread.
+ FilePath plugin_data_path_;
+
+ // The channel is NULL until we have opened a connection to the broker
+ // process. Used only on the I/O thread.
+ scoped_ptr<IPC::Channel> channel_;
+
+ // Used only on the I/O thread.
+ bool initialized_;
+
+ // Requests that need to be sent once the channel to the broker process is
+ // established. Used only on the I/O thread.
+ std::vector<PendingRequest> pending_requests_;
+ // Requests that have been sent but haven't got replied. Used only on the
+ // I/O thread.
+ std::map<uint32, RequestType> pending_responses_;
+
+ // Used only on the I/O thread.
+ scoped_refptr<content::PepperFlashSettingsHelper> helper_;
+
+ // Path for the current profile. Must be retrieved on the UI thread from the
+ // browser context when we start so we can use it later on the I/O thread.
+ FilePath browser_context_path_;
+
+ scoped_refptr<PluginPrefs> plugin_prefs_;
+};
+
+PepperFlashSettingsManager::Core::Core(PepperFlashSettingsManager* manager,
+ content::BrowserContext* browser_context)
+ : manager_(manager),
+ initialized_(false),
+ browser_context_path_(browser_context->GetPath()),
+ plugin_prefs_(PluginPrefs::GetForProfile(
+ Profile::FromBrowserContext(browser_context))) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ base::Bind(&Core::Initialize, this));
+}
+
+PepperFlashSettingsManager::Core::~Core() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+}
+
+void PepperFlashSettingsManager::Core::Detach() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ manager_ = NULL;
+}
+
+void PepperFlashSettingsManager::Core::DeauthorizeContentLicenses(
+ uint32 request_id) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&Core::DeauthorizeContentLicensesOnIOThread, this,
+ request_id));
+}
+
+bool PepperFlashSettingsManager::Core::OnMessageReceived(
+ const IPC::Message& message) {
+ IPC_BEGIN_MESSAGE_MAP(Core, message)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_DeauthorizeContentLicensesResult,
+ OnDeauthorizeContentLicensesResult)
+ IPC_MESSAGE_UNHANDLED_ERROR()
+ IPC_END_MESSAGE_MAP()
+
+ return true;
+}
+
+void PepperFlashSettingsManager::Core::OnChannelError() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ NotifyErrorFromIOThread();
+}
+
+void PepperFlashSettingsManager::Core::Initialize() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK(!initialized_);
+
+ webkit::WebPluginInfo plugin_info;
+ if (!PepperFlashSettingsManager::IsPepperFlashInUse(plugin_prefs_.get(),
+ &plugin_info)) {
+ NotifyErrorFromIOThread();
+ return;
+ }
+
+ FilePath profile_path =
+ browser_context_path_.Append(content::kPepperDataDirname);
+#if defined(OS_WIN)
+ plugin_data_path_ = profile_path.Append(plugin_info.name);
+#else
+ plugin_data_path_ = profile_path.Append(UTF16ToUTF8(plugin_info.name));
+#endif
+
+ helper_ = content::PepperFlashSettingsHelper::Create();
+ content::PepperFlashSettingsHelper::OpenChannelCallback callback =
+ base::Bind(&Core::ConnectToChannel, this);
+ helper_->OpenChannelToBroker(plugin_info.path, callback);
+}
+
+void PepperFlashSettingsManager::Core::ConnectToChannel(
+ bool success,
+ const IPC::ChannelHandle& handle) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK(!initialized_);
+ DCHECK(!channel_.get());
+
+ if (!success) {
+ LOG(ERROR) << "Couldn't open plugin channel";
+ NotifyErrorFromIOThread();
+ return;
+ }
+
+ channel_.reset(new IPC::Channel(handle, IPC::Channel::MODE_CLIENT, this));
+ if (!channel_->Connect()) {
+ LOG(ERROR) << "Couldn't connect to plugin";
+ NotifyErrorFromIOThread();
+ return;
+ }
+
+ initialized_ = true;
+
+ std::vector<PendingRequest> temp_pending_requests;
+ temp_pending_requests.swap(pending_requests_);
+ for (std::vector<PendingRequest>::iterator iter =
+ temp_pending_requests.begin();
+ iter != temp_pending_requests.end(); ++iter) {
+ switch (iter->type) {
+ case DEAUTHORIZE_CONTENT_LICENSES:
+ DeauthorizeContentLicensesOnIOThread(iter->id);
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+ }
+}
+
+void PepperFlashSettingsManager::Core::DeauthorizeContentLicensesOnIOThread(
+ uint32 request_id) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ if (!initialized_) {
+ PendingRequest request;
+ request.id = request_id;
+ request.type = DEAUTHORIZE_CONTENT_LICENSES;
+ pending_requests_.push_back(request);
+ return;
+ }
+
+ pending_responses_.insert(
+ std::make_pair(request_id, DEAUTHORIZE_CONTENT_LICENSES));
+ IPC::Message* msg =
+ new PpapiMsg_DeauthorizeContentLicenses(request_id, plugin_data_path_);
+ if (!channel_->Send(msg)) {
+ LOG(ERROR) << "Couldn't send DeauthorizeContentLicenses message";
+ // A failure notification for the current request will be sent since
+ // |pending_responses_| has been updated.
+ NotifyErrorFromIOThread();
+ }
+}
+
+void PepperFlashSettingsManager::Core::NotifyErrorFromIOThread() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ std::vector<std::pair<uint32, RequestType> > notifications;
+ for (std::vector<PendingRequest>::iterator iter = pending_requests_.begin();
+ iter != pending_requests_.end(); ++iter) {
+ notifications.push_back(std::make_pair(iter->id, iter->type));
+ }
+ pending_requests_.clear();
+ notifications.insert(notifications.end(), pending_responses_.begin(),
+ pending_responses_.end());
+ pending_responses_.clear();
+
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&Core::NotifyError, this, notifications));
+}
+
+void
+PepperFlashSettingsManager::Core::NotifyDeauthorizeContentLicensesCompleted(
+ uint32 request_id,
+ bool success) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ if (manager_) {
+ manager_->client_->OnDeauthorizeContentLicensesCompleted(
+ request_id, success);
+ }
+}
+
+void PepperFlashSettingsManager::Core::NotifyError(
+ const std::vector<std::pair<uint32, RequestType> >& notifications) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ scoped_refptr<Core> protector(this);
+ for (std::vector<std::pair<uint32, RequestType> >::const_iterator iter =
+ notifications.begin(); iter != notifications.end(); ++iter) {
+ // Check |manager_| for each iteration in case Detach() happens in one of
+ // the callbacks.
+ if (manager_) {
+ switch (iter->second) {
+ case DEAUTHORIZE_CONTENT_LICENSES:
+ manager_->client_->OnDeauthorizeContentLicensesCompleted(iter->first,
+ false);
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+ }
+ }
+
+ if (manager_)
+ manager_->OnError();
+}
+
+void PepperFlashSettingsManager::Core::OnDeauthorizeContentLicensesResult(
+ uint32 request_id,
+ bool success) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ LOG_IF(ERROR, !success) << "DeauthorizeContentLicenses returned error";
+
+ std::map<uint32, RequestType>::iterator iter =
+ pending_responses_.find(request_id);
+ if (iter != pending_responses_.end()) {
+ DCHECK_EQ(iter->second, DEAUTHORIZE_CONTENT_LICENSES);
+
+ pending_responses_.erase(iter);
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&Core::NotifyDeauthorizeContentLicensesCompleted, this,
+ request_id, success));
+ }
+}
+
+PepperFlashSettingsManager::PepperFlashSettingsManager(
+ Client* client,
+ content::BrowserContext* browser_context)
+ : client_(client),
+ browser_context_(browser_context),
+ next_request_id_(1) {
+ DCHECK(client);
+ DCHECK(browser_context);
+}
+
+PepperFlashSettingsManager::~PepperFlashSettingsManager() {
+ if (core_.get()) {
+ core_->Detach();
+ core_ = NULL;
+ }
+}
+
// static
bool PepperFlashSettingsManager::IsPepperFlashInUse(
PluginPrefs* plugin_prefs,
@@ -48,3 +370,31 @@ void PepperFlashSettingsManager::RegisterUserPrefs(PrefService* prefs) {
true,
PrefService::UNSYNCABLE_PREF);
}
+
+uint32 PepperFlashSettingsManager::DeauthorizeContentLicenses() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ EnsureCoreExists();
+ uint32 id = GetNextRequestId();
+ core_->DeauthorizeContentLicenses(id);
+ return id;
+}
+
+uint32 PepperFlashSettingsManager::GetNextRequestId() {
+ return next_request_id_++;
+}
+
+void PepperFlashSettingsManager::EnsureCoreExists() {
+ if (!core_.get())
+ core_ = new Core(this, browser_context_);
+}
+
+void PepperFlashSettingsManager::OnError() {
+ if (core_.get()) {
+ core_->Detach();
+ core_ = NULL;
+ } else {
+ NOTREACHED();
+ }
+}
+
diff --git a/chrome/browser/pepper_flash_settings_manager.h b/chrome/browser/pepper_flash_settings_manager.h
index 88bd1b0..4a20df3 100644
--- a/chrome/browser/pepper_flash_settings_manager.h
+++ b/chrome/browser/pepper_flash_settings_manager.h
@@ -7,10 +7,15 @@
#pragma once
#include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
class PluginPrefs;
class PrefService;
+namespace content {
+class BrowserContext;
+}
+
namespace webkit {
struct WebPluginInfo;
}
@@ -19,6 +24,20 @@ struct WebPluginInfo;
// read/write Pepper Flash settings.
class PepperFlashSettingsManager {
public:
+ class Client {
+ public:
+ virtual ~Client() {}
+
+ virtual void OnDeauthorizeContentLicensesCompleted(uint32 request_id,
+ bool success) = 0;
+ };
+
+ // |client| must outlive this object. It is guaranteed that |client| won't
+ // receive any notifications after this object goes away.
+ PepperFlashSettingsManager(Client* client,
+ content::BrowserContext* browser_context);
+ ~PepperFlashSettingsManager();
+
// |plugin_info| will be updated if it is not NULL and the method returns
// true.
static bool IsPepperFlashInUse(PluginPrefs* plugin_prefs,
@@ -26,8 +45,40 @@ class PepperFlashSettingsManager {
static void RegisterUserPrefs(PrefService* prefs);
+ // Requests to deauthorize content licenses.
+ // Client::OnDeauthorizeContentLicensesCompleted() will be called when the
+ // operation is completed.
+ // The return value is the same as the request ID passed into
+ // Client::OnDeauthorizeContentLicensesCompleted().
+ uint32 DeauthorizeContentLicenses();
+
private:
- DISALLOW_IMPLICIT_CONSTRUCTORS(PepperFlashSettingsManager);
+ // Core does most of the work. It is ref-counted so that its lifespan can be
+ // independent of the containing object's:
+ // - The manager can be deleted on the UI thread while the core still being
+ // used on the I/O thread.
+ // - The manager can delete the core when it encounters errors and create
+ // another one to handle new requests.
+ class Core;
+
+ uint32 GetNextRequestId();
+
+ void EnsureCoreExists();
+
+ // Notified by |core_| when an error occurs.
+ void OnError();
+
+ // |client_| is not owned by this object and must outlive it.
+ Client* client_;
+
+ // The browser context for the profile.
+ content::BrowserContext* browser_context_;
+
+ scoped_refptr<Core> core_;
+
+ uint32 next_request_id_;
+
+ DISALLOW_COPY_AND_ASSIGN(PepperFlashSettingsManager);
};
#endif // CHROME_BROWSER_PEPPER_FLASH_SETTINGS_MANAGER_H_