summaryrefslogtreecommitdiffstats
path: root/content/browser/plugin_service_impl_browsertest.cc
diff options
context:
space:
mode:
authorjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-21 06:00:56 +0000
committerjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-21 06:00:56 +0000
commite67385f3093d79371b080f3042b754cf4fd0e63e (patch)
treed0309f72fb6da658e325e7e84080a4cbd8eb397c /content/browser/plugin_service_impl_browsertest.cc
parentd487beefe0374fb88cebc02b95063fa7ae6f5beb (diff)
downloadchromium_src-e67385f3093d79371b080f3042b754cf4fd0e63e.zip
chromium_src-e67385f3093d79371b080f3042b754cf4fd0e63e.tar.gz
chromium_src-e67385f3093d79371b080f3042b754cf4fd0e63e.tar.bz2
Rename PluginService to PluginServiceImpl.
BUG=98716 Review URL: http://codereview.chromium.org/9019004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@115279 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser/plugin_service_impl_browsertest.cc')
-rw-r--r--content/browser/plugin_service_impl_browsertest.cc311
1 files changed, 311 insertions, 0 deletions
diff --git a/content/browser/plugin_service_impl_browsertest.cc b/content/browser/plugin_service_impl_browsertest.cc
new file mode 100644
index 0000000..2fc2ca3
--- /dev/null
+++ b/content/browser/plugin_service_impl_browsertest.cc
@@ -0,0 +1,311 @@
+// 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_service_impl.h"
+
+#include "base/bind.h"
+#include "base/command_line.h"
+#include "base/path_service.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/testing_profile.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "content/browser/resource_context.h"
+#include "content/public/common/content_switches.h"
+#include "content/test/test_browser_thread.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "webkit/plugins/npapi/plugin_list.h"
+
+using content::BrowserThread;
+
+namespace {
+
+const char kNPAPITestPluginMimeType[] = "application/vnd.npapi-test";
+
+void OpenChannel(PluginProcessHost::Client* client) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ // Start opening the channel
+ PluginServiceImpl::GetInstance()->OpenChannelToNpapiPlugin(
+ 0, 0, GURL(), GURL(), kNPAPITestPluginMimeType, client);
+}
+
+// Mock up of the Client and the Listener classes that would supply the
+// communication channel with the plugin.
+class MockPluginProcessHostClient : public PluginProcessHost::Client,
+ public IPC::Channel::Listener {
+ public:
+ MockPluginProcessHostClient(const content::ResourceContext& context)
+ : context_(context),
+ channel_(NULL),
+ set_plugin_info_called_(false) {
+ }
+
+ virtual ~MockPluginProcessHostClient() {
+ if (channel_)
+ BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, channel_);
+ }
+
+ // Client implementation.
+ virtual int ID() OVERRIDE { return 42; }
+ virtual bool OffTheRecord() OVERRIDE { return false; }
+ virtual const content::ResourceContext& GetResourceContext() OVERRIDE {
+ return context_;
+ }
+ virtual void OnFoundPluginProcessHost(PluginProcessHost* host) OVERRIDE {}
+ virtual void OnSentPluginChannelRequest() OVERRIDE {}
+
+ virtual void OnChannelOpened(const IPC::ChannelHandle& handle) OVERRIDE {
+ ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ ASSERT_TRUE(set_plugin_info_called_);
+ ASSERT_TRUE(!channel_);
+ channel_ = new IPC::Channel(handle, IPC::Channel::MODE_CLIENT, this);
+ ASSERT_TRUE(channel_->Connect());
+ }
+
+ void SetPluginInfo(const webkit::WebPluginInfo& info) OVERRIDE {
+ ASSERT_TRUE(info.mime_types.size());
+ ASSERT_EQ(kNPAPITestPluginMimeType, info.mime_types[0].mime_type);
+ set_plugin_info_called_ = true;
+ }
+
+ MOCK_METHOD0(OnError, void());
+
+ // Listener implementation.
+ MOCK_METHOD1(OnMessageReceived, bool(const IPC::Message& message));
+ void OnChannelConnected(int32 peer_pid) OVERRIDE {
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ MessageLoop::QuitClosure());
+ }
+ MOCK_METHOD0(OnChannelError, void());
+ MOCK_METHOD0(OnChannelDenied, void());
+ MOCK_METHOD0(OnChannelListenError, void());
+
+ private:
+ const content::ResourceContext& context_;
+ IPC::Channel* channel_;
+ bool set_plugin_info_called_;
+ DISALLOW_COPY_AND_ASSIGN(MockPluginProcessHostClient);
+};
+
+class PluginServiceTest : public InProcessBrowserTest {
+ public:
+ PluginServiceTest() : InProcessBrowserTest() { }
+
+ 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
+ }
+};
+
+// Try to open a channel to the test plugin. Minimal plugin process spawning
+// test for the PluginService interface.
+IN_PROC_BROWSER_TEST_F(PluginServiceTest, OpenChannelToPlugin) {
+ ::testing::StrictMock<MockPluginProcessHostClient> mock_client(
+ browser()->profile()->GetResourceContext());
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&OpenChannel, &mock_client));
+ ui_test_utils::RunMessageLoop();
+}
+
+// A strict mock that fails if any of the methods are called. They shouldn't be
+// called since the request should get canceled before then.
+class MockCanceledPluginServiceClient : public PluginProcessHost::Client {
+ public:
+ MockCanceledPluginServiceClient(const content::ResourceContext& context)
+ : context_(context),
+ get_resource_context_called_(false) {
+ }
+
+ virtual ~MockCanceledPluginServiceClient() {}
+
+ // Client implementation.
+ MOCK_METHOD0(ID, int());
+ virtual const content::ResourceContext& GetResourceContext() OVERRIDE {
+ get_resource_context_called_ = true;
+ return context_;
+ }
+ MOCK_METHOD0(OffTheRecord, bool());
+ MOCK_METHOD1(OnFoundPluginProcessHost, void(PluginProcessHost* host));
+ MOCK_METHOD0(OnSentPluginChannelRequest, void());
+ MOCK_METHOD1(OnChannelOpened, void(const IPC::ChannelHandle& handle));
+ MOCK_METHOD1(SetPluginInfo, void(const webkit::WebPluginInfo& info));
+ MOCK_METHOD0(OnError, void());
+
+ bool get_resource_context_called() const {
+ return get_resource_context_called_;
+ }
+
+ private:
+ const content::ResourceContext& context_;
+ bool get_resource_context_called_;
+
+ DISALLOW_COPY_AND_ASSIGN(MockCanceledPluginServiceClient);
+};
+
+void DoNothing() {}
+
+void QuitUIMessageLoopFromIOThread() {
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ MessageLoop::QuitClosure());
+}
+
+void OpenChannelAndThenCancel(PluginProcessHost::Client* client) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ // Start opening the channel
+ PluginServiceImpl::GetInstance()->OpenChannelToNpapiPlugin(
+ 0, 0, GURL(), GURL(), kNPAPITestPluginMimeType, client);
+ // Immediately cancel it. This is guaranteed to work since PluginService needs
+ // to consult its filter on the FILE thread.
+ PluginServiceImpl::GetInstance()->CancelOpenChannelToNpapiPlugin(client);
+ // Before we terminate the test, add a roundtrip through the FILE thread to
+ // make sure that it's had a chance to post back to the IO thread. Then signal
+ // the UI thread to stop and exit the test.
+ BrowserThread::PostTaskAndReply(
+ BrowserThread::FILE, FROM_HERE,
+ base::Bind(&DoNothing),
+ base::Bind(&QuitUIMessageLoopFromIOThread));
+}
+
+// Should not attempt to open a channel, since it should be canceled early on.
+IN_PROC_BROWSER_TEST_F(PluginServiceTest, CancelOpenChannelToPluginService) {
+ ::testing::StrictMock<MockCanceledPluginServiceClient> mock_client(
+ browser()->profile()->GetResourceContext());
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ base::Bind(OpenChannelAndThenCancel, &mock_client));
+ ui_test_utils::RunMessageLoop();
+ EXPECT_TRUE(mock_client.get_resource_context_called());
+}
+
+class MockCanceledBeforeSentPluginProcessHostClient
+ : public MockCanceledPluginServiceClient {
+ public:
+ MockCanceledBeforeSentPluginProcessHostClient(
+ const content::ResourceContext& context)
+ : MockCanceledPluginServiceClient(context),
+ set_plugin_info_called_(false),
+ on_found_plugin_process_host_called_(false),
+ host_(NULL) {}
+
+ virtual ~MockCanceledBeforeSentPluginProcessHostClient() {}
+
+ // Client implementation.
+ virtual void SetPluginInfo(const webkit::WebPluginInfo& info) OVERRIDE {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ ASSERT_TRUE(info.mime_types.size());
+ ASSERT_EQ(kNPAPITestPluginMimeType, info.mime_types[0].mime_type);
+ set_plugin_info_called_ = true;
+ }
+ virtual void OnFoundPluginProcessHost(PluginProcessHost* host) OVERRIDE {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ set_on_found_plugin_process_host_called();
+ set_host(host);
+ // This gets called right before we request the plugin<=>renderer channel,
+ // so we have to post a task to cancel it.
+ MessageLoop::current()->PostTask(
+ FROM_HERE,
+ base::Bind(&PluginProcessHost::CancelPendingRequest,
+ base::Unretained(host), this));
+ MessageLoop::current()->PostTask(
+ FROM_HERE,
+ base::Bind(&QuitUIMessageLoopFromIOThread));
+ }
+
+ bool set_plugin_info_called() const {
+ return set_plugin_info_called_;
+ }
+
+ bool on_found_plugin_process_host_called() const {
+ return on_found_plugin_process_host_called_;
+ }
+
+ protected:
+ void set_on_found_plugin_process_host_called() {
+ on_found_plugin_process_host_called_ = true;
+ }
+ void set_host(PluginProcessHost* host) {
+ host_ = host;
+ }
+
+ PluginProcessHost* host() const { return host_; }
+
+ private:
+ bool set_plugin_info_called_;
+ bool on_found_plugin_process_host_called_;
+ PluginProcessHost* host_;
+
+ DISALLOW_COPY_AND_ASSIGN(MockCanceledBeforeSentPluginProcessHostClient);
+};
+
+IN_PROC_BROWSER_TEST_F(
+ PluginServiceTest, CancelBeforeSentOpenChannelToPluginProcessHost) {
+ ::testing::StrictMock<MockCanceledBeforeSentPluginProcessHostClient>
+ mock_client(browser()->profile()->GetResourceContext());
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&OpenChannel, &mock_client));
+ ui_test_utils::RunMessageLoop();
+ EXPECT_TRUE(mock_client.get_resource_context_called());
+ EXPECT_TRUE(mock_client.set_plugin_info_called());
+ EXPECT_TRUE(mock_client.on_found_plugin_process_host_called());
+}
+
+class MockCanceledAfterSentPluginProcessHostClient
+ : public MockCanceledBeforeSentPluginProcessHostClient {
+ public:
+ MockCanceledAfterSentPluginProcessHostClient(
+ const content::ResourceContext& context)
+ : MockCanceledBeforeSentPluginProcessHostClient(context),
+ on_sent_plugin_channel_request_called_(false) {}
+ virtual ~MockCanceledAfterSentPluginProcessHostClient() {}
+
+ // Client implementation.
+
+ virtual int ID() OVERRIDE { return 42; }
+ virtual bool OffTheRecord() OVERRIDE { return false; }
+
+ // We override this guy again since we don't want to cancel yet.
+ virtual void OnFoundPluginProcessHost(PluginProcessHost* host) OVERRIDE {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ set_on_found_plugin_process_host_called();
+ set_host(host);
+ }
+
+ virtual void OnSentPluginChannelRequest() OVERRIDE {
+ on_sent_plugin_channel_request_called_ = true;
+ host()->CancelSentRequest(this);
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ MessageLoop::QuitClosure());
+ }
+
+ bool on_sent_plugin_channel_request_called() const {
+ return on_sent_plugin_channel_request_called_;
+ }
+
+ private:
+ bool on_sent_plugin_channel_request_called_;
+
+ DISALLOW_COPY_AND_ASSIGN(MockCanceledAfterSentPluginProcessHostClient);
+};
+
+// Should not attempt to open a channel, since it should be canceled early on.
+IN_PROC_BROWSER_TEST_F(
+ PluginServiceTest, CancelAfterSentOpenChannelToPluginProcessHost) {
+ ::testing::StrictMock<MockCanceledAfterSentPluginProcessHostClient>
+ mock_client(browser()->profile()->GetResourceContext());
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&OpenChannel, &mock_client));
+ ui_test_utils::RunMessageLoop();
+ EXPECT_TRUE(mock_client.get_resource_context_called());
+ EXPECT_TRUE(mock_client.set_plugin_info_called());
+ EXPECT_TRUE(mock_client.on_found_plugin_process_host_called());
+ EXPECT_TRUE(mock_client.on_sent_plugin_channel_request_called());
+}
+
+} // namespace