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