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