1 // Copyright (c) 2010 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 "chrome/browser/extensions/extension_apitest.h" 6 #include "chrome/browser/extensions/extension_service.h" 7 #include "chrome/browser/extensions/extension_test_message_listener.h" 8 #include "chrome/browser/profiles/profile.h" 9 #include "chrome/browser/ui/browser.h" 10 #include "chrome/browser/ui/browser_list.h" 11 #include "chrome/test/ui_test_utils.h" 12 13 namespace { 14 15 // Find a browser other than |browser|. 16 Browser* FindOtherBrowser(Browser* browser) { 17 Browser* found = NULL; 18 for (BrowserList::const_iterator it = BrowserList::begin(); 19 it != BrowserList::end(); ++it) { 20 if (*it == browser) 21 continue; 22 found = *it; 23 } 24 25 return found; 26 } 27 28 } // namespace 29 30 class ExtensionManagementApiTest : public ExtensionApiTest { 31 public: 32 virtual void InstallExtensions() { 33 FilePath basedir = test_data_dir_.AppendASCII("management"); 34 35 // Load 4 enabled items. 36 ASSERT_TRUE(LoadExtension(basedir.AppendASCII("enabled_extension"))); 37 ASSERT_TRUE(LoadExtension(basedir.AppendASCII("enabled_app"))); 38 ASSERT_TRUE(LoadExtension(basedir.AppendASCII("description"))); 39 ASSERT_TRUE(LoadExtension(basedir.AppendASCII("permissions"))); 40 41 // Load 2 disabled items. 42 ExtensionService* service = browser()->profile()->GetExtensionService(); 43 ASSERT_TRUE(LoadExtension(basedir.AppendASCII("disabled_extension"))); 44 service->DisableExtension(last_loaded_extension_id_); 45 ASSERT_TRUE(LoadExtension(basedir.AppendASCII("disabled_app"))); 46 service->DisableExtension(last_loaded_extension_id_); 47 } 48 49 // Load an app, and wait for a message from app "management/launch_on_install" 50 // indicating that the new app has been launched. 51 void LoadAndWaitForLaunch(const std::string& app_path, 52 std::string* out_app_id) { 53 ExtensionTestMessageListener launched_app("launched app", false); 54 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(app_path))); 55 56 if (out_app_id) 57 *out_app_id = last_loaded_extension_id_; 58 59 ASSERT_TRUE(launched_app.WaitUntilSatisfied()); 60 } 61 }; 62 63 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, Basics) { 64 InstallExtensions(); 65 ASSERT_TRUE(RunExtensionSubtest("management/test", "basics.html")); 66 } 67 68 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, Uninstall) { 69 InstallExtensions(); 70 ASSERT_TRUE(RunExtensionSubtest("management/test", "uninstall.html")); 71 } 72 73 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, LaunchPanelApp) { 74 ExtensionService* service = browser()->profile()->GetExtensionService(); 75 76 // Load an extension that calls launchApp() on any app that gets 77 // installed. 78 ExtensionTestMessageListener launcher_loaded("launcher loaded", false); 79 ASSERT_TRUE(LoadExtension( 80 test_data_dir_.AppendASCII("management/launch_on_install"))); 81 ASSERT_TRUE(launcher_loaded.WaitUntilSatisfied()); 82 83 // Load an app with app.launch.container = "panel". 84 std::string app_id; 85 LoadAndWaitForLaunch("management/launch_app_panel", &app_id); 86 ASSERT_FALSE(HasFatalFailure()); // Stop the test if any ASSERT failed. 87 88 // Find the app's browser. Check that it is a panel. 89 ASSERT_EQ(2u, BrowserList::GetBrowserCount(browser()->profile())); 90 Browser* app_browser = FindOtherBrowser(browser()); 91 ASSERT_EQ(Browser::TYPE_APP_POPUP, app_browser->type()); 92 93 // Close the app panel. 94 app_browser->CloseWindow(); 95 ui_test_utils::WaitForNotificationFrom(NotificationType::BROWSER_CLOSED, 96 Source<Browser>(app_browser)); 97 98 // Unload the extension. 99 UninstallExtension(app_id); 100 ASSERT_EQ(1u, BrowserList::GetBrowserCount(browser()->profile())); 101 ASSERT_FALSE(service->GetExtensionById(app_id, true)); 102 103 // Set a pref indicating that the user wants to launch in a regular tab. 104 // This should be ignored, because panel apps always load in a panel. 105 service->extension_prefs()->SetLaunchType( 106 app_id, ExtensionPrefs::LAUNCH_REGULAR); 107 108 // Load the extension again. 109 std::string app_id_new; 110 LoadAndWaitForLaunch("management/launch_app_panel", &app_id_new); 111 ASSERT_FALSE(HasFatalFailure()); 112 113 // If the ID changed, then the pref will not apply to the app. 114 ASSERT_EQ(app_id, app_id_new); 115 116 // Find the app's browser. Apps that should load in a panel ignore 117 // prefs, so we should still see the launch in a panel. 118 ASSERT_EQ(2u, BrowserList::GetBrowserCount(browser()->profile())); 119 app_browser = FindOtherBrowser(browser()); 120 ASSERT_EQ(Browser::TYPE_APP_POPUP, app_browser->type()); 121 } 122 123 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, LaunchTabApp) { 124 ExtensionService* service = browser()->profile()->GetExtensionService(); 125 126 // Load an extension that calls launchApp() on any app that gets 127 // installed. 128 ExtensionTestMessageListener launcher_loaded("launcher loaded", false); 129 ASSERT_TRUE(LoadExtension( 130 test_data_dir_.AppendASCII("management/launch_on_install"))); 131 ASSERT_TRUE(launcher_loaded.WaitUntilSatisfied()); 132 133 // Code below assumes that the test starts with a single browser window 134 // hosting one tab. 135 ASSERT_EQ(1u, BrowserList::GetBrowserCount(browser()->profile())); 136 ASSERT_EQ(1, browser()->tab_count()); 137 138 // Load an app with app.launch.container = "tab". 139 std::string app_id; 140 LoadAndWaitForLaunch("management/launch_app_tab", &app_id); 141 ASSERT_FALSE(HasFatalFailure()); 142 143 // Check that the app opened in a new tab of the existing browser. 144 ASSERT_EQ(1u, BrowserList::GetBrowserCount(browser()->profile())); 145 ASSERT_EQ(2, browser()->tab_count()); 146 147 // Unload the extension. 148 UninstallExtension(app_id); 149 ASSERT_EQ(1u, BrowserList::GetBrowserCount(browser()->profile())); 150 ASSERT_FALSE(service->GetExtensionById(app_id, true)); 151 152 // Set a pref indicating that the user wants to launch in a window. 153 service->extension_prefs()->SetLaunchType( 154 app_id, ExtensionPrefs::LAUNCH_WINDOW); 155 156 std::string app_id_new; 157 LoadAndWaitForLaunch("management/launch_app_tab", &app_id_new); 158 ASSERT_FALSE(HasFatalFailure()); 159 160 // If the ID changed, then the pref will not apply to the app. 161 ASSERT_EQ(app_id, app_id_new); 162 163 #if defined(OS_MACOSX) 164 // App windows are not yet implemented on mac os. We should fall back 165 // to a normal tab. 166 ASSERT_EQ(1u, BrowserList::GetBrowserCount(browser()->profile())); 167 ASSERT_EQ(2, browser()->tab_count()); 168 #else 169 // Find the app's browser. Opening in a new window will create 170 // a new browser. 171 ASSERT_EQ(2u, BrowserList::GetBrowserCount(browser()->profile())); 172 Browser* app_browser = FindOtherBrowser(browser()); 173 ASSERT_EQ(Browser::TYPE_APP, app_browser->type()); 174 #endif 175 } 176