Home | History | Annotate | Download | only in app_list
      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.
      4 
      5 #include "chrome/browser/ui/app_list/app_list_service_views.h"
      6 
      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"
     23 
     24 #if defined(OS_CHROMEOS)
     25 #include "ash/shell.h"
     26 #include "ash/test/app_list_controller_test_api.h"
     27 #endif
     28 
     29 namespace {
     30 
     31 app_list::AppListView* GetAppListView(AppListService* service) {
     32 #if defined(OS_CHROMEOS)
     33   return ash::test::AppListControllerTestApi(ash::Shell::GetInstance()).view();
     34 #else
     35   return static_cast<AppListServiceViews*>(service)->shower().app_list();
     36 #endif
     37 }
     38 
     39 }  // namespace
     40 
     41 namespace test {
     42 
     43 // Allow access to private variables of the AppListView for testing.
     44 class AppListViewTestApi {
     45  public:
     46   explicit AppListViewTestApi(app_list::AppListView* view) : view_(view) {}
     47   virtual ~AppListViewTestApi() {}
     48 
     49   bool is_overlay_visible() {
     50     DCHECK(view_->overlay_view_);
     51     return view_->overlay_view_->visible();
     52   }
     53 
     54  private:
     55   app_list::AppListView* view_;
     56 
     57   DISALLOW_COPY_AND_ASSIGN(AppListViewTestApi);
     58 };
     59 
     60 }  // namespace test
     61 
     62 // Browser Test for AppListService on Views platforms.
     63 typedef InProcessBrowserTest AppListServiceViewsBrowserTest;
     64 
     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());
     69 
     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();
     76   EXPECT_TRUE(window);
     77 
     78   views::Widget* widget = views::Widget::GetWidgetForNativeWindow(window);
     79   EXPECT_TRUE(widget);
     80   widget->Close();
     81 
     82   // Close is asynchronous (dismiss is not) so sink the message queue.
     83   base::RunLoop().RunUntilIdle();
     84   EXPECT_FALSE(service->GetAppListWindow());
     85 
     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.
     90 
     91   // Note: no need to sink message queue.
     92   EXPECT_FALSE(service->GetAppListWindow());
     93 }
     94 
     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());
    102 
    103   content::WindowedNotificationObserver close_observer(
    104       chrome::NOTIFICATION_BROWSER_CLOSED, content::Source<Browser>(browser()));
    105   chrome::CloseWindow(browser());
    106   close_observer.Wait();
    107 
    108   ui::test::EventGenerator generator(service->GetAppListWindow());
    109   generator.PressKey(ui::VKEY_ESCAPE, 0);
    110 
    111 #if !defined(OS_CHROMEOS)
    112   EXPECT_TRUE(chrome::WillKeepAlive());
    113 #endif
    114 
    115   base::RunLoop().RunUntilIdle();
    116 
    117 #if !defined(OS_CHROMEOS)
    118   EXPECT_FALSE(chrome::WillKeepAlive());
    119 #endif
    120   EXPECT_FALSE(service->GetAppListWindow());
    121 }
    122 
    123 // Browser Test for AppListController that ensures the App Info dialog opens
    124 // correctly.
    125 typedef ExtensionBrowserTest AppListControllerAppInfoDialogBrowserTest;
    126 
    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);
    140 
    141   // Open the app list window.
    142   AppListService* service = test::GetAppListService();
    143   EXPECT_FALSE(service->GetAppListWindow());
    144 
    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);
    150 
    151   test::AppListViewTestApi test_api(app_list_view);
    152 
    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());
    158 
    159   AppListControllerDelegate* controller = service->GetControllerDelegate();
    160   ASSERT_TRUE(controller);
    161   EXPECT_TRUE(controller->GetAppListWindow());
    162   controller->DoShowAppInfoFlow(browser()->profile(), extension->id());
    163 
    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());
    168 
    169   // Close the app info dialog.
    170   views::Widget* app_info_dialog = *owned_widgets.begin();
    171   app_info_dialog->CloseNow();
    172 
    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());
    177 }
    178