blob: ed6c6b6021338fd1e2fd62a713cb9441708f20fc [file] [log] [blame]
[email protected]677d0942012-08-28 17:42:111// 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 "base/command_line.h"
6#include "base/file_util.h"
7#include "base/path_service.h"
8#include "base/process_util.h"
9#include "base/utf_string_conversions.h"
10#include "chrome/browser/plugin_prefs.h"
11#include "chrome/browser/ui/browser.h"
12#include "chrome/browser/ui/browser_tabstrip.h"
13#include "chrome/test/base/in_process_browser_test.h"
14#include "chrome/test/base/ui_test_utils.h"
15#include "content/public/browser/browser_thread.h"
16#include "content/public/browser/browser_child_process_host_iterator.h"
17#include "content/public/browser/child_process_data.h"
18#include "content/public/browser/plugin_service.h"
19#include "content/public/common/content_paths.h"
20#include "content/public/test/browser_test_utils.h"
21#include "content/public/test/test_utils.h"
22#include "net/base/net_util.h"
23#include "webkit/plugins/webplugininfo.h"
24
25using content::BrowserThread;
26
27class ChromePluginTest : public InProcessBrowserTest {
28 protected:
29 ChromePluginTest() {}
30
[email protected]3bbe942e2012-08-28 23:15:3531 static GURL GetURL(const char* filename) {
32 FilePath path;
33 PathService::Get(content::DIR_TEST_DATA, &path);
34 path = path.AppendASCII("plugin").AppendASCII(filename);
35 CHECK(file_util::PathExists(path));
36 return net::FilePathToFileURL(path);
37 }
38
[email protected]677d0942012-08-28 17:42:1139 static void LoadAndWait(Browser* window, const GURL& url, bool pass) {
40 content::WebContents* web_contents = chrome::GetActiveWebContents(window);
41 string16 expected_title(ASCIIToUTF16(pass ? "OK" : "plugin_not_found"));
42 content::TitleWatcher title_watcher(web_contents, expected_title);
43 title_watcher.AlsoWaitForTitle(ASCIIToUTF16("FAIL"));
44 title_watcher.AlsoWaitForTitle(ASCIIToUTF16(
45 pass ? "plugin_not_found" : "OK"));
46 ui_test_utils::NavigateToURL(window, url);
47 ASSERT_EQ(expected_title, title_watcher.WaitAndGetTitle());
48 }
49
50 static void CrashFlash() {
51 scoped_refptr<content::MessageLoopRunner> runner =
52 new content::MessageLoopRunner;
53 BrowserThread::PostTask(
54 BrowserThread::IO,
55 FROM_HERE,
56 base::Bind(&CrashFlashInternal, runner->QuitClosure()));
57 runner->Run();
58 }
59
60 static FilePath GetFlashPath() {
[email protected]43075012012-08-29 05:42:4961 std::vector<webkit::WebPluginInfo> plugins = GetPlugins();
62 for (std::vector<webkit::WebPluginInfo>::const_iterator it =
63 plugins.begin(); it != plugins.end(); ++it) {
64 if (it->name == ASCIIToUTF16("Shockwave Flash"))
65 return it->path;
66 }
67 return FilePath();
68 }
69
70 static std::vector<webkit::WebPluginInfo> GetPlugins() {
71 std::vector<webkit::WebPluginInfo> plugins;
[email protected]677d0942012-08-28 17:42:1172 scoped_refptr<content::MessageLoopRunner> runner =
73 new content::MessageLoopRunner;
74 content::PluginService::GetInstance()->GetPlugins(
[email protected]43075012012-08-29 05:42:4975 base::Bind(&GetPluginsInfoCallback, &plugins, runner->QuitClosure()));
[email protected]677d0942012-08-28 17:42:1176 runner->Run();
[email protected]43075012012-08-29 05:42:4977 return plugins;
[email protected]677d0942012-08-28 17:42:1178 }
79
[email protected]3bbe942e2012-08-28 23:15:3580 static void EnableFlash(bool enable, Profile* profile) {
[email protected]677d0942012-08-28 17:42:1181 FilePath flash_path = GetFlashPath();
82 ASSERT_FALSE(flash_path.empty());
83
84 PluginPrefs* plugin_prefs = PluginPrefs::GetForProfile(profile);
85 scoped_refptr<content::MessageLoopRunner> runner =
86 new content::MessageLoopRunner;
[email protected]54f3ef52012-09-05 18:53:3987 plugin_prefs->EnablePlugin(enable, flash_path,
88 base::Bind(&AssertPluginEnabled, runner));
[email protected]677d0942012-08-28 17:42:1189 runner->Run();
90 }
91
92 static void EnsureFlashProcessCount(int expected) {
93 int actual = 0;
94 scoped_refptr<content::MessageLoopRunner> runner =
95 new content::MessageLoopRunner;
96 BrowserThread::PostTask(
97 BrowserThread::IO,
98 FROM_HERE,
99 base::Bind(&CountPluginProcesses, &actual, runner->QuitClosure()));
100 runner->Run();
101 ASSERT_EQ(expected, actual);
102 }
103
104 private:
105 static void CrashFlashInternal(const base::Closure& quit_task) {
106 bool found = false;
107 for (content::BrowserChildProcessHostIterator iter; !iter.Done(); ++iter) {
108 if (iter.GetData().type != content::PROCESS_TYPE_PLUGIN &&
109 iter.GetData().type != content::PROCESS_TYPE_PPAPI_PLUGIN) {
110 continue;
111 }
112 base::KillProcess(iter.GetData().handle, 0, true);
113 found = true;
114 }
115 ASSERT_TRUE(found) << "Didn't find Flash process!";
116 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, quit_task);
117 }
118
119 static void GetPluginsInfoCallback(
[email protected]43075012012-08-29 05:42:49120 std::vector<webkit::WebPluginInfo>* rv,
[email protected]677d0942012-08-28 17:42:11121 const base::Closure& quit_task,
122 const std::vector<webkit::WebPluginInfo>& plugins) {
[email protected]43075012012-08-29 05:42:49123 *rv = plugins;
[email protected]677d0942012-08-28 17:42:11124 quit_task.Run();
125 }
126
127 static void CountPluginProcesses(int* count, const base::Closure& quit_task) {
128 for (content::BrowserChildProcessHostIterator iter; !iter.Done(); ++iter) {
129 if (iter.GetData().type == content::PROCESS_TYPE_PLUGIN ||
130 iter.GetData().type == content::PROCESS_TYPE_PPAPI_PLUGIN) {
131 (*count)++;
132 }
133 }
134 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, quit_task);
135 }
[email protected]54f3ef52012-09-05 18:53:39136
137 static void AssertPluginEnabled(
138 scoped_refptr<content::MessageLoopRunner> runner,
139 bool did_enable) {
140 ASSERT_TRUE(did_enable);
141 runner->Quit();
142 }
[email protected]677d0942012-08-28 17:42:11143};
144
145// Tests a bunch of basic scenarios with Flash.
[email protected]407cc4812012-09-20 14:39:30146// This test fails under ASan on Mac, see http://crbug.com/147004.
147#if defined(ADDRESS_SANITIZER) && defined(OS_MACOSX)
148#define MAYBE_Flash DISABLED_Flash
149#else
150#define MAYBE_Flash Flash
151#endif
152IN_PROC_BROWSER_TEST_F(ChromePluginTest, MAYBE_Flash) {
[email protected]677d0942012-08-28 17:42:11153 // Official builds always have bundled Flash.
154#if !defined(OFFICIAL_BUILD)
155 if (GetFlashPath().empty()) {
156 LOG(INFO) << "Test not running because couldn't find Flash.";
157 return;
158 }
159#endif
160
[email protected]3bbe942e2012-08-28 23:15:35161 GURL url = GetURL("flash.html");
[email protected]677d0942012-08-28 17:42:11162 EnsureFlashProcessCount(0);
163
164 // Try a single tab.
165 ASSERT_NO_FATAL_FAILURE(LoadAndWait(browser(), url, true));
166 EnsureFlashProcessCount(1);
167 Profile* profile = browser()->profile();
168 // Try another tab.
169 ASSERT_NO_FATAL_FAILURE(LoadAndWait(CreateBrowser(profile), url, true));
170 // Try an incognito window.
171 ASSERT_NO_FATAL_FAILURE(LoadAndWait(CreateIncognitoBrowser(), url, true));
172 EnsureFlashProcessCount(1);
173
174 // Now kill Flash process and verify it reloads.
175 CrashFlash();
176 EnsureFlashProcessCount(0);
177
178 ASSERT_NO_FATAL_FAILURE(LoadAndWait(browser(), url, true));
179 EnsureFlashProcessCount(1);
180
181 // Now try disabling it.
[email protected]3bbe942e2012-08-28 23:15:35182 EnableFlash(false, profile);
[email protected]677d0942012-08-28 17:42:11183 CrashFlash();
184
185 ASSERT_NO_FATAL_FAILURE(LoadAndWait(browser(), url, false));
186 EnsureFlashProcessCount(0);
[email protected]3bbe942e2012-08-28 23:15:35187
188 // Now enable it again.
189 EnableFlash(true, profile);
190 ASSERT_NO_FATAL_FAILURE(LoadAndWait(browser(), url, true));
191 EnsureFlashProcessCount(1);
[email protected]677d0942012-08-28 17:42:11192}
[email protected]43075012012-08-29 05:42:49193
194// Verify that the official builds have the known set of plugins.
195IN_PROC_BROWSER_TEST_F(ChromePluginTest, InstalledPlugins) {
196#if !defined(OFFICIAL_BUILD)
197 return;
198#endif
199 const char* expected[] = {
200 "Chrome PDF Viewer",
201 "Shockwave Flash",
202 "Native Client",
203#if defined(OS_CHROMEOS)
204 "Chrome Remote Desktop Viewer",
205 "Google Talk Plugin",
206 "Google Talk Plugin Video Accelerator",
207 "Netflix",
208#endif
209 };
210
211 std::vector<webkit::WebPluginInfo> plugins = GetPlugins();
212 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(expected); ++i) {
213 size_t j = 0;
214 for (; j < plugins.size(); ++j) {
215 if (plugins[j].name == ASCIIToUTF16(expected[i]))
216 break;
217 }
218 ASSERT_TRUE(j != plugins.size()) << "Didn't find " << expected[i];
219 }
220}