1 // Copyright 2014 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.
5 #include "chrome/browser/ui/app_list/app_list_service_views.h"
7 #include "base/path_service.h"
8 #include "base/run_loop.h"
9 #include "chrome/browser/extensions/extension_browsertest.h"
10 #include "chrome/browser/lifetime/application_lifetime.h"
11 #include "chrome/browser/ui/app_list/app_list_controller_delegate.h"
12 #include "chrome/browser/ui/app_list/test/chrome_app_list_test_support.h"
13 #include "chrome/browser/ui/browser.h"
14 #include "chrome/browser/ui/browser_commands.h"
15 #include "chrome/common/chrome_paths.h"
16 #include "chrome/test/base/in_process_browser_test.h"
17 #include "content/public/browser/notification_service.h"
18 #include "content/public/test/test_utils.h"
19 #include "ui/app_list/app_list_switches.h"
20 #include "ui/app_list/views/app_list_view.h"
21 #include "ui/events/test/event_generator.h"
22 #include "ui/views/widget/widget.h"
24 #if defined(OS_CHROMEOS)
25 #include "ash/shell.h"
26 #include "ash/test/app_list_controller_test_api.h"
31 app_list::AppListView* GetAppListView(AppListService* service) {
32 #if defined(OS_CHROMEOS)
33 return ash::test::AppListControllerTestApi(ash::Shell::GetInstance()).view();
35 return static_cast<AppListServiceViews*>(service)->shower().app_list();
43 // Allow access to private variables of the AppListView for testing.
44 class AppListViewTestApi {
46 explicit AppListViewTestApi(app_list::AppListView* view) : view_(view) {}
47 virtual ~AppListViewTestApi() {}
49 bool is_overlay_visible() {
50 DCHECK(view_->overlay_view_);
51 return view_->overlay_view_->visible();
55 app_list::AppListView* view_;
57 DISALLOW_COPY_AND_ASSIGN(AppListViewTestApi);
62 // Browser Test for AppListService on Views platforms.
63 typedef InProcessBrowserTest AppListServiceViewsBrowserTest;
65 // Test closing the native app list window as if via a request from the OS.
66 IN_PROC_BROWSER_TEST_F(AppListServiceViewsBrowserTest, NativeClose) {
67 AppListService* service = test::GetAppListService();
68 EXPECT_FALSE(service->GetAppListWindow());
70 // Since the profile is loaded, this will create a view immediately. This is
71 // important, because anything asynchronous would need an interactive_uitest
72 // due to the possibility of the app list being dismissed, and
73 // AppListService::GetAppListWindow returning NULL.
74 service->ShowForProfile(browser()->profile());
75 gfx::NativeWindow window = service->GetAppListWindow();
78 views::Widget* widget = views::Widget::GetWidgetForNativeWindow(window);
82 // Close is asynchronous (dismiss is not) so sink the message queue.
83 base::RunLoop().RunUntilIdle();
84 EXPECT_FALSE(service->GetAppListWindow());
86 // Show again to get some code coverage for possibly stale pointers.
87 service->ShowForProfile(browser()->profile());
88 EXPECT_TRUE(service->GetAppListWindow());
89 service->DismissAppList(); // Note: in Ash, this will invalidate the window.
91 // Note: no need to sink message queue.
92 EXPECT_FALSE(service->GetAppListWindow());
95 // Dismiss the app list via an accelerator when it is the only thing keeping
96 // Chrome alive and expect everything to clean up properly. This is a regression
97 // test for http://crbug.com/395937.
98 IN_PROC_BROWSER_TEST_F(AppListServiceViewsBrowserTest, AcceleratorClose) {
99 AppListService* service = test::GetAppListService();
100 service->ShowForProfile(browser()->profile());
101 EXPECT_TRUE(service->GetAppListWindow());
103 content::WindowedNotificationObserver close_observer(
104 chrome::NOTIFICATION_BROWSER_CLOSED, content::Source<Browser>(browser()));
105 chrome::CloseWindow(browser());
106 close_observer.Wait();
108 ui::test::EventGenerator generator(service->GetAppListWindow());
109 generator.PressKey(ui::VKEY_ESCAPE, 0);
111 #if !defined(OS_CHROMEOS)
112 EXPECT_TRUE(chrome::WillKeepAlive());
115 base::RunLoop().RunUntilIdle();
117 #if !defined(OS_CHROMEOS)
118 EXPECT_FALSE(chrome::WillKeepAlive());
120 EXPECT_FALSE(service->GetAppListWindow());
123 // Browser Test for AppListController that ensures the App Info dialog opens
125 typedef ExtensionBrowserTest AppListControllerAppInfoDialogBrowserTest;
127 // Test the DoShowAppInfoFlow function of the controller delegate.
128 // flaky: http://crbug.com/378251
129 IN_PROC_BROWSER_TEST_F(AppListControllerAppInfoDialogBrowserTest,
130 DISABLED_DoShowAppInfoFlow) {
131 // Install an extension to open the dialog for.
132 base::FilePath test_extension_path;
133 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_extension_path));
134 test_extension_path = test_extension_path.AppendASCII("extensions")
135 .AppendASCII("platform_apps")
136 .AppendASCII("minimal");
137 const extensions::Extension* extension = InstallExtension(
138 test_extension_path, 1 /* expected_change: new install */);
139 ASSERT_TRUE(extension);
141 // Open the app list window.
142 AppListService* service = test::GetAppListService();
143 EXPECT_FALSE(service->GetAppListWindow());
145 service->ShowForProfile(browser()->profile());
146 app_list::AppListView* app_list_view = GetAppListView(service);
147 ASSERT_TRUE(app_list_view);
148 gfx::NativeView native_view = app_list_view->GetWidget()->GetNativeView();
149 ASSERT_TRUE(native_view);
151 test::AppListViewTestApi test_api(app_list_view);
153 // Open the app info dialog.
154 views::Widget::Widgets owned_widgets;
155 views::Widget::GetAllOwnedWidgets(native_view, &owned_widgets);
156 EXPECT_EQ(0U, owned_widgets.size());
157 EXPECT_FALSE(test_api.is_overlay_visible());
159 AppListControllerDelegate* controller = service->GetControllerDelegate();
160 ASSERT_TRUE(controller);
161 EXPECT_TRUE(controller->GetAppListWindow());
162 controller->DoShowAppInfoFlow(browser()->profile(), extension->id());
164 owned_widgets.clear();
165 views::Widget::GetAllOwnedWidgets(native_view, &owned_widgets);
166 EXPECT_EQ(1U, owned_widgets.size());
167 EXPECT_TRUE(test_api.is_overlay_visible());
169 // Close the app info dialog.
170 views::Widget* app_info_dialog = *owned_widgets.begin();
171 app_info_dialog->CloseNow();
173 owned_widgets.clear();
174 views::Widget::GetAllOwnedWidgets(native_view, &owned_widgets);
175 EXPECT_EQ(0U, owned_widgets.size());
176 EXPECT_FALSE(test_api.is_overlay_visible());