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 "base/command_line.h"
6#include "base/prefs/pref_service.h"
7#include "chrome/browser/content_settings/host_content_settings_map.h"
8#include "chrome/browser/extensions/extension_browsertest.h"
9#include "chrome/browser/extensions/extension_service.h"
10#include "chrome/browser/profiles/profile.h"
11#include "chrome/browser/ui/browser.h"
12#include "chrome/browser/ui/browser_commands.h"
13#include "chrome/browser/ui/tabs/tab_strip_model.h"
14#include "chrome/common/pref_names.h"
15#include "chrome/test/base/test_switches.h"
16#include "chrome/test/base/ui_test_utils.h"
17#include "content/public/browser/navigation_controller.h"
18#include "content/public/browser/plugin_service.h"
19#include "content/public/browser/web_contents.h"
20#include "content/public/test/browser_test_utils.h"
21#include "extensions/browser/extension_system.h"
22#include "extensions/common/extension.h"
23#include "net/base/filename_util.h"
24
25using content::NavigationController;
26using content::WebContents;
27using extensions::Extension;
28
29#if defined(OS_WIN)
30// http://crbug.com/123851 : test flakily fails on win.
31#define MAYBE_PluginLoadUnload DISABLED_PluginLoadUnload
32#elif defined(OS_MACOSX) && defined(ADDRESS_SANITIZER)
33// ExtensionBrowserTest.PluginLoadUnload started failing after the switch to
34// dynamic ASan runtime library on Mac. See http://crbug.com/234591.
35#define MAYBE_PluginLoadUnload DISABLED_PluginLoadUnload
36#elif defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
37// Timing out on ARM linux http://crbug.com/238460
38#define MAYBE_PluginLoadUnload DISABLED_PluginLoadUnload
39#else
40#define MAYBE_PluginLoadUnload PluginLoadUnload
41#endif
42
43// Tests that a renderer's plugin list is properly updated when we load and
44// unload an extension that contains a plugin.
45IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, MAYBE_PluginLoadUnload) {
46  if (!content::PluginService::GetInstance()->NPAPIPluginsSupported())
47    return;
48  browser()->profile()->GetPrefs()->SetBoolean(prefs::kPluginsAlwaysAuthorize,
49                                               true);
50
51  base::FilePath extension_dir =
52      test_data_dir_.AppendASCII("uitest").AppendASCII("plugins");
53
54  ui_test_utils::NavigateToURL(browser(),
55      net::FilePathToFileURL(extension_dir.AppendASCII("test.html")));
56  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
57
58  // With no extensions, the plugin should not be loaded.
59  bool result = false;
60  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
61      tab, "testPluginWorks()", &result));
62  EXPECT_FALSE(result);
63
64  ExtensionService* service = extensions::ExtensionSystem::Get(
65      browser()->profile())->extension_service();
66  service->set_show_extensions_prompts(false);
67  const size_t size_before = service->extensions()->size();
68  const Extension* extension = LoadExtension(extension_dir);
69  ASSERT_TRUE(extension);
70  EXPECT_EQ(size_before + 1, service->extensions()->size());
71  // Now the plugin should be in the cache.
72  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
73      tab, "testPluginWorks()", &result));
74  // We don't allow extension plugins to run on ChromeOS.
75#if defined(OS_CHROMEOS)
76  EXPECT_FALSE(result);
77#else
78  EXPECT_TRUE(result);
79#endif
80
81  EXPECT_EQ(size_before + 1, service->extensions()->size());
82  UnloadExtension(extension->id());
83  EXPECT_EQ(size_before, service->extensions()->size());
84
85  // Now the plugin should be unloaded, and the page should be broken.
86
87  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
88      tab, "testPluginWorks()", &result));
89  EXPECT_FALSE(result);
90
91  // If we reload the extension and page, it should work again.
92
93  ASSERT_TRUE(LoadExtension(extension_dir));
94  EXPECT_EQ(size_before + 1, service->extensions()->size());
95  {
96    content::WindowedNotificationObserver observer(
97        content::NOTIFICATION_LOAD_STOP,
98        content::Source<NavigationController>(
99            &browser()->tab_strip_model()->GetActiveWebContents()->
100                GetController()));
101    chrome::Reload(browser(), CURRENT_TAB);
102    observer.Wait();
103  }
104  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
105      tab, "testPluginWorks()", &result));
106  // We don't allow extension plugins to run on ChromeOS.
107#if defined(OS_CHROMEOS)
108  EXPECT_FALSE(result);
109#else
110  EXPECT_TRUE(result);
111#endif
112}
113
114#if defined(OS_MACOSX) && defined(ADDRESS_SANITIZER)
115// ExtensionBrowserTest.PluginPrivate started failing after the switch to
116// dynamic ASan runtime library on Mac. See http://crbug.com/234591.
117#define MAYBE_PluginPrivate DISABLED_PluginPrivate
118#elif defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
119// Timing out on ARM linux http://crbug.com/238467
120#define MAYBE_PluginPrivate DISABLED_PluginPrivate
121#elif defined(OS_WIN) && defined(ARCH_CPU_X86_64)
122// TODO(jschuh): Failing plugin tests. crbug.com/244653
123#define MAYBE_PluginPrivate DISABLED_PluginPrivate
124#else
125#define MAYBE_PluginPrivate PluginPrivate
126#endif
127// Tests that private extension plugins are only visible to the extension.
128IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, MAYBE_PluginPrivate) {
129#if defined(OS_WIN) && defined(USE_ASH)
130  // Disable this test in Metro+Ash for now (http://crbug.com/262796).
131  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
132    return;
133#endif
134
135  if (!content::PluginService::GetInstance()->NPAPIPluginsSupported())
136    return;
137
138  browser()->profile()->GetPrefs()->SetBoolean(prefs::kPluginsAlwaysAuthorize,
139                                               true);
140
141  base::FilePath extension_dir =
142      test_data_dir_.AppendASCII("uitest").AppendASCII("plugins_private");
143
144  ExtensionService* service = extensions::ExtensionSystem::Get(
145      browser()->profile())->extension_service();
146  service->set_show_extensions_prompts(false);
147  const size_t size_before = service->extensions()->size();
148  const Extension* extension = LoadExtension(extension_dir);
149  ASSERT_TRUE(extension);
150  EXPECT_EQ(size_before + 1, service->extensions()->size());
151
152  // Load the test page through the extension URL, and the plugin should work.
153  ui_test_utils::NavigateToURL(browser(),
154      extension->GetResourceURL("test.html"));
155  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
156  bool result = false;
157  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
158      tab, "testPluginWorks()", &result));
159  // We don't allow extension plugins to run on ChromeOS.
160#if defined(OS_CHROMEOS)
161  EXPECT_FALSE(result);
162#else
163  // TODO(bauerb): This might wrongly fail if the plug-in takes too long
164  // to load. Extension-private plug-ins don't appear in navigator.plugins, so
165  // we can't check for the plug-in in Javascript.
166  EXPECT_TRUE(result);
167#endif
168
169  // Regression test for http://crbug.com/131811: The plug-in should be
170  // whitelisted for the extension (and only for the extension), so it should be
171  // loaded even if content settings are set to block plug-ins.
172  browser()->profile()->GetHostContentSettingsMap()->SetDefaultContentSetting(
173      CONTENT_SETTINGS_TYPE_PLUGINS, CONTENT_SETTING_BLOCK);
174  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
175      tab, "testPluginWorks()", &result));
176  // We don't allow extension plugins to run on ChromeOS.
177#if defined(OS_CHROMEOS)
178  EXPECT_FALSE(result);
179#else
180  EXPECT_TRUE(result);
181#endif
182
183  // Now load it through a file URL. The plugin should not load.
184  ui_test_utils::NavigateToURL(browser(),
185      net::FilePathToFileURL(extension_dir.AppendASCII("test.html")));
186  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
187      tab, "testPluginWorks()", &result));
188  EXPECT_FALSE(result);
189}
190