• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <map>
6 
7 #include "chrome/browser/chrome_notification_types.h"
8 #include "chrome/browser/extensions/extension_apitest.h"
9 #include "chrome/browser/extensions/extension_service.h"
10 #include "chrome/browser/extensions/extension_system.h"
11 #include "chrome/browser/extensions/extension_test_message_listener.h"
12 #include "chrome/browser/extensions/launch_util.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/ui/browser.h"
15 #include "chrome/browser/ui/browser_commands.h"
16 #include "chrome/browser/ui/browser_finder.h"
17 #include "chrome/browser/ui/browser_iterator.h"
18 #include "chrome/browser/ui/tabs/tab_strip_model.h"
19 #include "chrome/common/chrome_switches.h"
20 #include "chrome/common/extensions/extension_constants.h"
21 #include "content/public/test/test_utils.h"
22 #include "extensions/browser/test_management_policy.h"
23 #include "extensions/common/manifest.h"
24 
25 using extensions::Extension;
26 using extensions::Manifest;
27 
28 namespace {
29 
30 // Find a browser other than |browser|.
FindOtherBrowser(Browser * browser)31 Browser* FindOtherBrowser(Browser* browser) {
32   Browser* found = NULL;
33   for (chrome::BrowserIterator it; !it.done(); it.Next()) {
34     if (*it == browser)
35       continue;
36     found = *it;
37   }
38   return found;
39 }
40 
41 }  // namespace
42 
43 class ExtensionManagementApiTest : public ExtensionApiTest {
44  public:
SetUpCommandLine(CommandLine * command_line)45   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
46     ExtensionApiTest::SetUpCommandLine(command_line);
47     command_line->AppendSwitch(switches::kEnablePanels);
48   }
49 
LoadExtensions()50   virtual void LoadExtensions() {
51     base::FilePath basedir = test_data_dir_.AppendASCII("management");
52 
53     // Load 5 enabled items.
54     LoadNamedExtension(basedir, "enabled_extension");
55     LoadNamedExtension(basedir, "enabled_app");
56     LoadNamedExtension(basedir, "description");
57     LoadNamedExtension(basedir, "permissions");
58     LoadNamedExtension(basedir, "short_name");
59 
60     // Load 2 disabled items.
61     LoadNamedExtension(basedir, "disabled_extension");
62     DisableExtension(extension_ids_["disabled_extension"]);
63     LoadNamedExtension(basedir, "disabled_app");
64     DisableExtension(extension_ids_["disabled_app"]);
65   }
66 
67   // Load an app, and wait for a message from app "management/launch_on_install"
68   // indicating that the new app has been launched.
LoadAndWaitForLaunch(const std::string & app_path,std::string * out_app_id)69   void LoadAndWaitForLaunch(const std::string& app_path,
70                             std::string* out_app_id) {
71     ExtensionTestMessageListener launched_app("launched app", false);
72     ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(app_path)));
73 
74     if (out_app_id)
75       *out_app_id = last_loaded_extension_id();
76 
77     ASSERT_TRUE(launched_app.WaitUntilSatisfied());
78   }
79 
80  protected:
LoadNamedExtension(const base::FilePath & path,const std::string & name)81   void LoadNamedExtension(const base::FilePath& path,
82                           const std::string& name) {
83     const Extension* extension = LoadExtension(path.AppendASCII(name));
84     ASSERT_TRUE(extension);
85     extension_ids_[name] = extension->id();
86   }
87 
InstallNamedExtension(const base::FilePath & path,const std::string & name,Manifest::Location install_source)88   void InstallNamedExtension(const base::FilePath& path,
89                              const std::string& name,
90                              Manifest::Location install_source) {
91     const Extension* extension = InstallExtension(path.AppendASCII(name), 1,
92                                                   install_source);
93     ASSERT_TRUE(extension);
94     extension_ids_[name] = extension->id();
95   }
96 
97   // Maps installed extension names to their IDs.
98   std::map<std::string, std::string> extension_ids_;
99 };
100 
IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest,Basics)101 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, Basics) {
102   LoadExtensions();
103 
104   base::FilePath basedir = test_data_dir_.AppendASCII("management");
105   InstallNamedExtension(basedir, "internal_extension", Manifest::INTERNAL);
106   InstallNamedExtension(basedir, "external_extension",
107                         Manifest::EXTERNAL_PREF);
108   InstallNamedExtension(basedir, "admin_extension",
109                         Manifest::EXTERNAL_POLICY_DOWNLOAD);
110 
111   ASSERT_TRUE(RunExtensionSubtest("management/test", "basics.html"));
112 }
113 
IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest,NoPermission)114 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, NoPermission) {
115   LoadExtensions();
116   ASSERT_TRUE(RunExtensionSubtest("management/no_permission", "test.html"));
117 }
118 
119 // Disabled: http://crbug.com/174411
120 #if defined(OS_WIN)
121 #define MAYBE_Uninstall DISABLED_Uninstall
122 #else
123 #define MAYBE_Uninstall Uninstall
124 #endif
125 
IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest,MAYBE_Uninstall)126 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, MAYBE_Uninstall) {
127   LoadExtensions();
128   ASSERT_TRUE(RunExtensionSubtest("management/test", "uninstall.html"));
129 }
130 
131 // Fails often on Windows dbg bots. http://crbug.com/177163
132 #if defined(OS_WIN)
133 #define MAYBE_ManagementPolicyAllowed DISABLED_ManagementPolicyAllowed
134 #else
135 #define MAYBE_ManagementPolicyAllowed ManagementPolicyAllowed
136 #endif  // defined(OS_WIN)
137 // Tests actions on extensions when no management policy is in place.
IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest,MAYBE_ManagementPolicyAllowed)138 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest,
139                        MAYBE_ManagementPolicyAllowed) {
140   LoadExtensions();
141   ExtensionService* service = extensions::ExtensionSystem::Get(
142       browser()->profile())->extension_service();
143   EXPECT_TRUE(service->GetExtensionById(extension_ids_["enabled_extension"],
144                                         false));
145 
146   // Ensure that all actions are allowed.
147   extensions::ExtensionSystem::Get(
148       browser()->profile())->management_policy()->UnregisterAllProviders();
149 
150   ASSERT_TRUE(RunExtensionSubtest("management/management_policy",
151                                   "allowed.html"));
152   // The last thing the test does is uninstall the "enabled_extension".
153   EXPECT_FALSE(service->GetExtensionById(extension_ids_["enabled_extension"],
154                                          true));
155 }
156 
157 // Fails often on Windows dbg bots. http://crbug.com/177163
158 #if defined(OS_WIN)
159 #define MAYBE_ManagementPolicyProhibited DISABLED_ManagementPolicyProhibited
160 #else
161 #define MAYBE_ManagementPolicyProhibited ManagementPolicyProhibited
162 #endif  // defined(OS_WIN)
163 // Tests actions on extensions when management policy prohibits those actions.
IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest,MAYBE_ManagementPolicyProhibited)164 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest,
165                        MAYBE_ManagementPolicyProhibited) {
166   LoadExtensions();
167   ExtensionService* service = extensions::ExtensionSystem::Get(
168       browser()->profile())->extension_service();
169   EXPECT_TRUE(service->GetExtensionById(extension_ids_["enabled_extension"],
170                                         false));
171 
172   // Prohibit status changes.
173   extensions::ManagementPolicy* policy = extensions::ExtensionSystem::Get(
174       browser()->profile())->management_policy();
175   policy->UnregisterAllProviders();
176   extensions::TestManagementPolicyProvider provider(
177     extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
178   policy->RegisterProvider(&provider);
179   ASSERT_TRUE(RunExtensionSubtest("management/management_policy",
180                                   "prohibited.html"));
181 }
182 
183 // Disabled. See http://crbug.com/176023
IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest,DISABLED_LaunchPanelApp)184 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, DISABLED_LaunchPanelApp) {
185   ExtensionService* service = extensions::ExtensionSystem::Get(
186       browser()->profile())->extension_service();
187 
188   // Load an extension that calls launchApp() on any app that gets
189   // installed.
190   ExtensionTestMessageListener launcher_loaded("launcher loaded", false);
191   ASSERT_TRUE(LoadExtension(
192       test_data_dir_.AppendASCII("management/launch_on_install")));
193   ASSERT_TRUE(launcher_loaded.WaitUntilSatisfied());
194 
195   // Load an app with app.launch.container = "panel".
196   std::string app_id;
197   LoadAndWaitForLaunch("management/launch_app_panel", &app_id);
198   ASSERT_FALSE(HasFatalFailure());  // Stop the test if any ASSERT failed.
199 
200   // Find the app's browser.  Check that it is a popup.
201   ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(),
202                                         browser()->host_desktop_type()));
203   Browser* app_browser = FindOtherBrowser(browser());
204   ASSERT_TRUE(app_browser->is_type_popup());
205   ASSERT_TRUE(app_browser->is_app());
206 
207   // Close the app panel.
208   content::WindowedNotificationObserver signal(
209       chrome::NOTIFICATION_BROWSER_CLOSED,
210       content::Source<Browser>(app_browser));
211 
212   chrome::CloseWindow(app_browser);
213   signal.Wait();
214 
215   // Unload the extension.
216   UninstallExtension(app_id);
217   ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
218                                         browser()->host_desktop_type()));
219   ASSERT_FALSE(service->GetExtensionById(app_id, true));
220 
221   // Set a pref indicating that the user wants to launch in a regular tab.
222   // This should be ignored, because panel apps always load in a popup.
223   extensions::SetLaunchType(service->extension_prefs(),
224       app_id, extensions::LAUNCH_TYPE_REGULAR);
225 
226   // Load the extension again.
227   std::string app_id_new;
228   LoadAndWaitForLaunch("management/launch_app_panel", &app_id_new);
229   ASSERT_FALSE(HasFatalFailure());
230 
231   // If the ID changed, then the pref will not apply to the app.
232   ASSERT_EQ(app_id, app_id_new);
233 
234   // Find the app's browser.  Apps that should load in a panel ignore
235   // prefs, so we should still see the launch in a popup.
236   ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(),
237                                         browser()->host_desktop_type()));
238   app_browser = FindOtherBrowser(browser());
239   ASSERT_TRUE(app_browser->is_type_popup());
240   ASSERT_TRUE(app_browser->is_app());
241 }
242 
243 // Disabled: http://crbug.com/230165
244 #if defined(OS_WIN)
245 #define MAYBE_LaunchTabApp DISABLED_LaunchTabApp
246 #else
247 #define MAYBE_LaunchTabApp LaunchTabApp
248 #endif
IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest,MAYBE_LaunchTabApp)249 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, MAYBE_LaunchTabApp) {
250   ExtensionService* service = extensions::ExtensionSystem::Get(
251       browser()->profile())->extension_service();
252 
253   // Load an extension that calls launchApp() on any app that gets
254   // installed.
255   ExtensionTestMessageListener launcher_loaded("launcher loaded", false);
256   ASSERT_TRUE(LoadExtension(
257       test_data_dir_.AppendASCII("management/launch_on_install")));
258   ASSERT_TRUE(launcher_loaded.WaitUntilSatisfied());
259 
260   // Code below assumes that the test starts with a single browser window
261   // hosting one tab.
262   ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
263                                         browser()->host_desktop_type()));
264   ASSERT_EQ(1, browser()->tab_strip_model()->count());
265 
266   // Load an app with app.launch.container = "tab".
267   std::string app_id;
268   LoadAndWaitForLaunch("management/launch_app_tab", &app_id);
269   ASSERT_FALSE(HasFatalFailure());
270 
271   // Check that the app opened in a new tab of the existing browser.
272   ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
273                                         browser()->host_desktop_type()));
274   ASSERT_EQ(2, browser()->tab_strip_model()->count());
275 
276   // Unload the extension.
277   UninstallExtension(app_id);
278   ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
279                                         browser()->host_desktop_type()));
280   ASSERT_FALSE(service->GetExtensionById(app_id, true));
281 
282   // Set a pref indicating that the user wants to launch in a window.
283   extensions::SetLaunchType(service->extension_prefs(),
284       app_id, extensions::LAUNCH_TYPE_WINDOW);
285 
286   std::string app_id_new;
287   LoadAndWaitForLaunch("management/launch_app_tab", &app_id_new);
288   ASSERT_FALSE(HasFatalFailure());
289 
290   // If the ID changed, then the pref will not apply to the app.
291   ASSERT_EQ(app_id, app_id_new);
292 
293 #if defined(OS_MACOSX)
294   // App windows are not yet implemented on mac os.  We should fall back
295   // to a normal tab.
296   ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
297                                         browser()->host_desktop_type()));
298   ASSERT_EQ(2, browser()->tab_strip_model()->count());
299 #else
300   // Find the app's browser.  Opening in a new window will create
301   // a new browser.
302   ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(),
303                                         browser()->host_desktop_type()));
304   Browser* app_browser = FindOtherBrowser(browser());
305   ASSERT_TRUE(app_browser->is_app());
306 #endif
307 }
308