diff options
author | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-17 18:31:54 +0000 |
---|---|---|
committer | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-17 18:31:54 +0000 |
commit | d8e682015deccd427d67145d17ca6eb78c090674 (patch) | |
tree | 692690ce8b6ad4245750dc2807790b79890993a8 /content | |
parent | 4d87a94b75030786e356c3b4a25a06e9634a0012 (diff) | |
download | chromium_src-d8e682015deccd427d67145d17ca6eb78c090674.zip chromium_src-d8e682015deccd427d67145d17ca6eb78c090674.tar.gz chromium_src-d8e682015deccd427d67145d17ca6eb78c090674.tar.bz2 |
Move the PluginDataRemover class to content, and remove the chrome pieces from it. This class really belongs in content because it's part of the web platform. I've also wrapped it with an interface that is used by chrome.
BUG=98716
Review URL: http://codereview.chromium.org/8590016
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@110530 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r-- | content/browser/plugin_data_remover_impl.cc | 190 | ||||
-rw-r--r-- | content/browser/plugin_data_remover_impl.h | 77 | ||||
-rw-r--r-- | content/browser/plugin_data_remover_impl_browsertest.cc | 45 | ||||
-rw-r--r-- | content/content_browser.gypi | 31 | ||||
-rw-r--r-- | content/public/browser/plugin_data_remover.h | 44 |
5 files changed, 373 insertions, 14 deletions
diff --git a/content/browser/plugin_data_remover_impl.cc b/content/browser/plugin_data_remover_impl.cc new file mode 100644 index 0000000..e6cec77 --- /dev/null +++ b/content/browser/plugin_data_remover_impl.cc @@ -0,0 +1,190 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/plugin_data_remover_impl.h" + +#include "base/bind.h" +#include "base/metrics/histogram.h" +#include "base/synchronization/waitable_event.h" +#include "base/version.h" +#include "content/browser/plugin_service.h" +#include "content/common/plugin_messages.h" +#include "content/public/browser/browser_thread.h" +#include "webkit/plugins/npapi/plugin_group.h" + +using content::BrowserThread; + +namespace { + +const char kFlashMimeType[] = "application/x-shockwave-flash"; +// The minimum Flash Player version that implements NPP_ClearSiteData. +const char kMinFlashVersion[] = "10.3"; +const int64 kRemovalTimeoutMs = 10000; +const uint64 kClearAllData = 0; + +} // namespace + +namespace content { + +// static +PluginDataRemover* PluginDataRemover::Create( + const content::ResourceContext& resource_context) { + return new PluginDataRemoverImpl(resource_context); +} + +// static +bool PluginDataRemover::IsSupported(webkit::WebPluginInfo* plugin) { + bool allow_wildcard = false; + std::vector<webkit::WebPluginInfo> plugins; + PluginService::GetInstance()->GetPluginInfoArray( + GURL(), kFlashMimeType, allow_wildcard, &plugins, NULL); + std::vector<webkit::WebPluginInfo>::iterator plugin_it = plugins.begin(); + if (plugin_it == plugins.end()) + return false; + scoped_ptr<Version> version( + webkit::npapi::PluginGroup::CreateVersionFromString(plugin_it->version)); + scoped_ptr<Version> min_version( + Version::GetVersionFromString(kMinFlashVersion)); + bool rv = version.get() && min_version->CompareTo(*version) == -1; + if (rv) + *plugin = *plugin_it; + return rv; +} + +} + +PluginDataRemoverImpl::PluginDataRemoverImpl( + const content::ResourceContext& resource_context) + : mime_type_(kFlashMimeType), + is_starting_process_(false), + is_removing_(false), + context_(resource_context), + event_(new base::WaitableEvent(true, false)), + channel_(NULL), + ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { +} + +PluginDataRemoverImpl::~PluginDataRemoverImpl() { + if (is_starting_process_) + PluginService::GetInstance()->CancelOpenChannelToNpapiPlugin(this); + DCHECK(!is_removing_); + if (channel_) + BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, channel_); +} + +base::WaitableEvent* PluginDataRemoverImpl::StartRemoving( + base::Time begin_time) { + DCHECK(!is_removing_); + remove_start_time_ = base::Time::Now(); + begin_time_ = begin_time; + + is_starting_process_ = true; + is_removing_ = true; + PluginService::GetInstance()->OpenChannelToNpapiPlugin( + 0, 0, GURL(), GURL(), mime_type_, this); + + BrowserThread::PostDelayedTask( + BrowserThread::IO, + FROM_HERE, + base::Bind(&PluginDataRemoverImpl::OnTimeout, weak_factory_.GetWeakPtr()), + kRemovalTimeoutMs); + + return event_.get(); +} + +int PluginDataRemoverImpl::ID() { + // Generate a unique identifier for this PluginProcessHostClient. + return ChildProcessInfo::GenerateChildProcessUniqueId(); +} + +bool PluginDataRemoverImpl::OffTheRecord() { + return false; +} + +const content::ResourceContext& PluginDataRemoverImpl::GetResourceContext() { + return context_; +} + +void PluginDataRemoverImpl::SetPluginInfo( + const webkit::WebPluginInfo& info) { +} + +void PluginDataRemoverImpl::OnFoundPluginProcessHost( + PluginProcessHost* host) { +} + +void PluginDataRemoverImpl::OnSentPluginChannelRequest() { +} + +void PluginDataRemoverImpl::OnChannelOpened(const IPC::ChannelHandle& handle) { + is_starting_process_ = false; + ConnectToChannel(handle); +} + +void PluginDataRemoverImpl::ConnectToChannel(const IPC::ChannelHandle& handle) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + + // If we timed out, don't bother connecting. + if (!is_removing_) + return; + + DCHECK(!channel_); + channel_ = new IPC::Channel(handle, IPC::Channel::MODE_CLIENT, this); + if (!channel_->Connect()) { + NOTREACHED() << "Couldn't connect to plugin"; + SignalDone(); + return; + } + + if (!channel_->Send(new PluginMsg_ClearSiteData(std::string(), + kClearAllData, + begin_time_))) { + NOTREACHED() << "Couldn't send ClearSiteData message"; + SignalDone(); + return; + } +} + +void PluginDataRemoverImpl::OnError() { + LOG(DFATAL) << "Couldn't open plugin channel"; + SignalDone(); +} + +void PluginDataRemoverImpl::OnClearSiteDataResult(bool success) { + LOG_IF(ERROR, !success) << "ClearSiteData returned error"; + UMA_HISTOGRAM_TIMES("ClearPluginData.time", + base::Time::Now() - remove_start_time_); + SignalDone(); +} + +void PluginDataRemoverImpl::OnTimeout() { + LOG_IF(ERROR, is_removing_) << "Timed out"; + SignalDone(); +} + +bool PluginDataRemoverImpl::OnMessageReceived(const IPC::Message& msg) { + IPC_BEGIN_MESSAGE_MAP(PluginDataRemoverImpl, msg) + IPC_MESSAGE_HANDLER(PluginHostMsg_ClearSiteDataResult, + OnClearSiteDataResult) + IPC_MESSAGE_UNHANDLED_ERROR() + IPC_END_MESSAGE_MAP() + + return true; +} + +void PluginDataRemoverImpl::OnChannelError() { + is_starting_process_ = false; + if (is_removing_) { + NOTREACHED() << "Channel error"; + SignalDone(); + } +} + +void PluginDataRemoverImpl::SignalDone() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + if (!is_removing_) + return; + is_removing_ = false; + event_->Signal(); +} diff --git a/content/browser/plugin_data_remover_impl.h b/content/browser/plugin_data_remover_impl.h new file mode 100644 index 0000000..d16c0d8 --- /dev/null +++ b/content/browser/plugin_data_remover_impl.h @@ -0,0 +1,77 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_PLUGIN_DATA_REMOVER_IMPL_H_ +#define CONTENT_BROWSER_PLUGIN_DATA_REMOVER_IMPL_H_ +#pragma once + +#include <string> + +#include "base/memory/weak_ptr.h" +#include "content/browser/plugin_process_host.h" +#include "content/public/browser/plugin_data_remover.h" + +class PluginDataRemoverImpl : public content::PluginDataRemover, + public PluginProcessHost::Client, + public IPC::Channel::Listener { + public: + explicit PluginDataRemoverImpl( + const content::ResourceContext& resource_context); + virtual ~PluginDataRemoverImpl(); + + // content::PluginDataRemover implementation: + virtual base::WaitableEvent* StartRemoving(base::Time begin_time) OVERRIDE; + + // The plug-in whose data should be removed (usually Flash) is specified via + // its MIME type. This method sets a different MIME type in order to call a + // different plug-in (for example in tests). + void set_mime_type(const std::string& mime_type) { mime_type_ = mime_type; } + + // PluginProcessHost::Client methods. + virtual int ID() OVERRIDE; + virtual bool OffTheRecord() OVERRIDE; + virtual const content::ResourceContext& GetResourceContext() OVERRIDE; + virtual void SetPluginInfo(const webkit::WebPluginInfo& info) OVERRIDE; + virtual void OnFoundPluginProcessHost(PluginProcessHost* host) OVERRIDE; + virtual void OnSentPluginChannelRequest() OVERRIDE; + virtual void OnChannelOpened(const IPC::ChannelHandle& handle) OVERRIDE; + virtual void OnError() OVERRIDE; + + // IPC::Channel::Listener methods. + virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; + virtual void OnChannelError() OVERRIDE; + + private: + // Signals that we are finished with removing data (successful or not). This + // method is safe to call multiple times. + void SignalDone(); + // Connects the client side of a newly opened plug-in channel. + void ConnectToChannel(const IPC::ChannelHandle& handle); + // Handles the PluginHostMsg_ClearSiteDataResult message. + void OnClearSiteDataResult(bool success); + // Called when a timeout happens in order not to block the client + // indefinitely. + void OnTimeout(); + + std::string mime_type_; + bool is_starting_process_; + bool is_removing_; + // The point in time when we start removing data. + base::Time remove_start_time_; + // The point in time from which on we remove data. + base::Time begin_time_; + // The resource context for the profile. + const content::ResourceContext& context_; + scoped_ptr<base::WaitableEvent> event_; + // We own the channel, but it's used on the IO thread, so it needs to be + // deleted there. It's NULL until we have opened a connection to the plug-in + // process. + IPC::Channel* channel_; + + base::WeakPtrFactory<PluginDataRemoverImpl> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(PluginDataRemoverImpl); +}; + +#endif // CONTENT_BROWSER_PLUGIN_DATA_REMOVER_IMPL_H_ diff --git a/content/browser/plugin_data_remover_impl_browsertest.cc b/content/browser/plugin_data_remover_impl_browsertest.cc new file mode 100644 index 0000000..c1689e3 --- /dev/null +++ b/content/browser/plugin_data_remover_impl_browsertest.cc @@ -0,0 +1,45 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/base_paths.h" +#include "base/command_line.h" +#include "base/path_service.h" +#include "base/synchronization/waitable_event_watcher.h" +#include "content/browser/plugin_data_remover_impl.h" +#include "content/public/common/content_switches.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" + +namespace { +const char* kNPAPITestPluginMimeType = "application/vnd.npapi-test"; +} + +class PluginDataRemoverTest : public InProcessBrowserTest, + public base::WaitableEventWatcher::Delegate { + public: + PluginDataRemoverTest() : InProcessBrowserTest() { } + + virtual void OnWaitableEventSignaled(base::WaitableEvent* waitable_event) { + MessageLoop::current()->Quit(); + } + + virtual void SetUpCommandLine(CommandLine* command_line) { +#ifdef OS_MACOSX + FilePath browser_directory; + PathService::Get(base::DIR_MODULE, &browser_directory); + command_line->AppendSwitchPath(switches::kExtraPluginDir, + browser_directory.AppendASCII("plugins")); +#endif + } +}; + +IN_PROC_BROWSER_TEST_F(PluginDataRemoverTest, RemoveData) { + PluginDataRemoverImpl plugin_data_remover(GetResourceContext()); + plugin_data_remover.set_mime_type(kNPAPITestPluginMimeType); + base::WaitableEventWatcher watcher; + base::WaitableEvent* event = + plugin_data_remover.StartRemoving(base::Time()); + watcher.StartWatching(event, this); + ui_test_utils::RunMessageLoop(); +} diff --git a/content/content_browser.gypi b/content/content_browser.gypi index c590656..4bb1e0b 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -25,6 +25,21 @@ '<(INTERMEDIATE_DIR)', ], 'sources': [ + 'public/browser/browser_main_parts.h', + 'public/browser/browser_thread.h', + 'public/browser/content_browser_client.h', + 'public/browser/download_manager_delegate.h', + 'public/browser/native_web_keyboard_event.h', + 'public/browser/navigation_types.h', + 'public/browser/notification_details.h', + 'public/browser/notification_observer.h', + 'public/browser/notification_registrar.cc', + 'public/browser/notification_registrar.h', + 'public/browser/notification_service.h', + 'public/browser/notification_source.h', + 'public/browser/notification_types.h', + 'public/browser/plugin_data_remover.h', + 'public/browser/resource_dispatcher_host_delegate.h', 'browser/accessibility/browser_accessibility.cc', 'browser/accessibility/browser_accessibility.h', 'browser/accessibility/browser_accessibility_cocoa.h', @@ -283,6 +298,8 @@ 'browser/net/url_request_slow_http_job.h', 'browser/notification_service_impl.cc', 'browser/notification_service_impl.h', + 'browser/plugin_data_remover_impl.cc', + 'browser/plugin_data_remover_impl.h', 'browser/plugin_loader_posix.cc', 'browser/plugin_loader_posix.h', 'browser/plugin_process_host.cc', @@ -584,20 +601,6 @@ 'browser/zygote_host_linux.cc', 'browser/zygote_host_linux.h', 'browser/zygote_main_linux.cc', - 'public/browser/browser_main_parts.h', - 'public/browser/browser_thread.h', - 'public/browser/content_browser_client.h', - 'public/browser/download_manager_delegate.h', - 'public/browser/native_web_keyboard_event.h', - 'public/browser/navigation_types.h', - 'public/browser/notification_details.h', - 'public/browser/notification_observer.h', - 'public/browser/notification_registrar.cc', - 'public/browser/notification_registrar.h', - 'public/browser/notification_service.h', - 'public/browser/notification_source.h', - 'public/browser/notification_types.h', - 'public/browser/resource_dispatcher_host_delegate.h', ], 'conditions': [ ['p2p_apis==1', { diff --git a/content/public/browser/plugin_data_remover.h b/content/public/browser/plugin_data_remover.h new file mode 100644 index 0000000..03fe582 --- /dev/null +++ b/content/public/browser/plugin_data_remover.h @@ -0,0 +1,44 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_PUBLIC_BROWSER_PLUGIN_DATA_REMOVER_H_ +#define CONTENT_PUBLIC_BROWSER_PLUGIN_DATA_REMOVER_H_ +#pragma once + +#include "base/time.h" +#include "content/common/content_export.h" + +namespace base { +class WaitableEvent; +} + +namespace content { +class ResourceContext; +} + +namespace webkit { +struct WebPluginInfo; +} + +namespace content { + +class CONTENT_EXPORT PluginDataRemover { + public: + static PluginDataRemover* Create( + const content::ResourceContext& resource_context); + virtual ~PluginDataRemover() {} + + // Starts removing plug-in data stored since |begin_time|. + virtual base::WaitableEvent* StartRemoving(base::Time begin_time) = 0; + + // Returns whether there is a plug-in installed that supports removing LSO + // data. If it returns true |plugin| is also set to that plugin. This method + // will use cached plugin data. Call PluginService::GetPlugins() if the latest + // data is needed. + static bool IsSupported(webkit::WebPluginInfo* plugin); +}; + +} // namespace content + +#endif // CONTENT_PUBLIC_BROWSER_PLUGIN_DATA_REMOVER_H_ |