1010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// found in the LICENSE file. 4010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 5010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "chrome/browser/ui/app_list/app_list_service_views.h" 6010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/path_service.h" 8010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/run_loop.h" 9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/extensions/extension_browsertest.h" 1003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/browser/lifetime/application_lifetime.h" 11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/ui/app_list/app_list_controller_delegate.h" 12010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "chrome/browser/ui/app_list/test/chrome_app_list_test_support.h" 13010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "chrome/browser/ui/browser.h" 1403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/browser/ui/browser_commands.h" 15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/common/chrome_paths.h" 16010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "chrome/test/base/in_process_browser_test.h" 1703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "content/public/browser/notification_service.h" 1803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "content/public/test/test_utils.h" 19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/app_list/app_list_switches.h" 20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/app_list/views/app_list_view.h" 2103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "ui/events/test/event_generator.h" 22010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "ui/views/widget/widget.h" 23010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if defined(OS_CHROMEOS) 25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ash/shell.h" 26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ash/test/app_list_controller_test_api.h" 27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif 28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 29116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace { 30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 31116680a4aac90f2aa7413d9095a592090648e557Ben Murdochapp_list::AppListView* GetAppListView(AppListService* service) { 32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(OS_CHROMEOS) 33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return ash::test::AppListControllerTestApi(ash::Shell::GetInstance()).view(); 34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#else 35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return static_cast<AppListServiceViews*>(service)->shower().app_list(); 36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif 37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} // namespace 40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 41116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace test { 42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Allow access to private variables of the AppListView for testing. 44116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass AppListViewTestApi { 45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public: 46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch explicit AppListViewTestApi(app_list::AppListView* view) : view_(view) {} 47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch virtual ~AppListViewTestApi() {} 48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool is_overlay_visible() { 50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(view_->overlay_view_); 51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return view_->overlay_view_->visible(); 52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private: 55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch app_list::AppListView* view_; 56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DISALLOW_COPY_AND_ASSIGN(AppListViewTestApi); 58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}; 59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} // namespace test 61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 62010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Browser Test for AppListService on Views platforms. 63010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)typedef InProcessBrowserTest AppListServiceViewsBrowserTest; 64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 65010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Test closing the native app list window as if via a request from the OS. 66010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(AppListServiceViewsBrowserTest, NativeClose) { 67010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) AppListService* service = test::GetAppListService(); 68010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) EXPECT_FALSE(service->GetAppListWindow()); 69010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 70010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Since the profile is loaded, this will create a view immediately. This is 71010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // important, because anything asynchronous would need an interactive_uitest 72010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // due to the possibility of the app list being dismissed, and 73010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // AppListService::GetAppListWindow returning NULL. 74010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) service->ShowForProfile(browser()->profile()); 75010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) gfx::NativeWindow window = service->GetAppListWindow(); 76010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) EXPECT_TRUE(window); 77010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 78010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) views::Widget* widget = views::Widget::GetWidgetForNativeWindow(window); 79010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) EXPECT_TRUE(widget); 80010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) widget->Close(); 81010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 82010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Close is asynchronous (dismiss is not) so sink the message queue. 83010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::RunLoop().RunUntilIdle(); 84010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) EXPECT_FALSE(service->GetAppListWindow()); 85010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 86010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Show again to get some code coverage for possibly stale pointers. 87010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) service->ShowForProfile(browser()->profile()); 88010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) EXPECT_TRUE(service->GetAppListWindow()); 89010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) service->DismissAppList(); // Note: in Ash, this will invalidate the window. 90010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 91010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Note: no need to sink message queue. 92010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) EXPECT_FALSE(service->GetAppListWindow()); 93010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 9503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Dismiss the app list via an accelerator when it is the only thing keeping 9603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Chrome alive and expect everything to clean up properly. This is a regression 9703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// test for http://crbug.com/395937. 9803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(AppListServiceViewsBrowserTest, AcceleratorClose) { 9903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) AppListService* service = test::GetAppListService(); 10003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) service->ShowForProfile(browser()->profile()); 10103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_TRUE(service->GetAppListWindow()); 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 10303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) content::WindowedNotificationObserver close_observer( 10403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) chrome::NOTIFICATION_BROWSER_CLOSED, content::Source<Browser>(browser())); 10503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) chrome::CloseWindow(browser()); 10603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) close_observer.Wait(); 107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 10803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ui::test::EventGenerator generator(service->GetAppListWindow()); 10903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) generator.PressKey(ui::VKEY_ESCAPE, 0); 11003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 11103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#if !defined(OS_CHROMEOS) 11203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_TRUE(chrome::WillKeepAlive()); 11303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#endif 11403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 11503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 11603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 11703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#if !defined(OS_CHROMEOS) 11803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_FALSE(chrome::WillKeepAlive()); 11903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#endif 12003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_FALSE(service->GetAppListWindow()); 12103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 12203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 12303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Browser Test for AppListController that ensures the App Info dialog opens 12403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// correctly. 12503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)typedef ExtensionBrowserTest AppListControllerAppInfoDialogBrowserTest; 126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Test the DoShowAppInfoFlow function of the controller delegate. 1286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// flaky: http://crbug.com/378251 129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(AppListControllerAppInfoDialogBrowserTest, 1306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DISABLED_DoShowAppInfoFlow) { 131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Install an extension to open the dialog for. 132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::FilePath test_extension_path; 133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_extension_path)); 134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) test_extension_path = test_extension_path.AppendASCII("extensions") 135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) .AppendASCII("platform_apps") 136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) .AppendASCII("minimal"); 137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const extensions::Extension* extension = InstallExtension( 138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) test_extension_path, 1 /* expected_change: new install */); 139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ASSERT_TRUE(extension); 140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Open the app list window. 142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) AppListService* service = test::GetAppListService(); 143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_FALSE(service->GetAppListWindow()); 144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) service->ShowForProfile(browser()->profile()); 14603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) app_list::AppListView* app_list_view = GetAppListView(service); 14703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ASSERT_TRUE(app_list_view); 14803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) gfx::NativeView native_view = app_list_view->GetWidget()->GetNativeView(); 14903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ASSERT_TRUE(native_view); 150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 15103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) test::AppListViewTestApi test_api(app_list_view); 152116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Open the app info dialog. 154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) views::Widget::Widgets owned_widgets; 15503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) views::Widget::GetAllOwnedWidgets(native_view, &owned_widgets); 156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(0U, owned_widgets.size()); 157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_FALSE(test_api.is_overlay_visible()); 158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) AppListControllerDelegate* controller = service->GetControllerDelegate(); 160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ASSERT_TRUE(controller); 16103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_TRUE(controller->GetAppListWindow()); 162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) controller->DoShowAppInfoFlow(browser()->profile(), extension->id()); 163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) owned_widgets.clear(); 16503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) views::Widget::GetAllOwnedWidgets(native_view, &owned_widgets); 166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(1U, owned_widgets.size()); 167116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_TRUE(test_api.is_overlay_visible()); 168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Close the app info dialog. 170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) views::Widget* app_info_dialog = *owned_widgets.begin(); 171116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch app_info_dialog->CloseNow(); 172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) owned_widgets.clear(); 17403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) views::Widget::GetAllOwnedWidgets(native_view, &owned_widgets); 175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(0U, owned_widgets.size()); 176116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_FALSE(test_api.is_overlay_visible()); 177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 178