1// Copyright 2013 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/apps/app_browsertest_util.h"
6
7#include "base/command_line.h"
8#include "base/strings/stringprintf.h"
9#include "chrome/browser/apps/scoped_keep_alive.h"
10#include "chrome/browser/extensions/api/tabs/tabs_api.h"
11#include "chrome/browser/extensions/extension_function_test_utils.h"
12#include "chrome/browser/ui/apps/chrome_app_delegate.h"
13#include "chrome/browser/ui/browser.h"
14#include "chrome/browser/ui/extensions/application_launch.h"
15#include "content/public/browser/notification_service.h"
16#include "content/public/test/browser_test_utils.h"
17#include "content/public/test/test_utils.h"
18#include "extensions/browser/app_window/app_window_contents.h"
19#include "extensions/browser/app_window/app_window_registry.h"
20#include "extensions/browser/app_window/native_app_window.h"
21#include "extensions/browser/process_manager.h"
22#include "extensions/common/switches.h"
23#include "extensions/test/extension_test_message_listener.h"
24
25using content::WebContents;
26
27namespace {
28
29const char kAppWindowTestApp[] = "app_window/generic";
30
31}  // namespace
32
33namespace utils = extension_function_test_utils;
34
35namespace extensions {
36
37PlatformAppBrowserTest::PlatformAppBrowserTest() {
38  ChromeAppDelegate::DisableExternalOpenForTesting();
39}
40
41void PlatformAppBrowserTest::SetUpCommandLine(CommandLine* command_line) {
42  // Skips ExtensionApiTest::SetUpCommandLine.
43  ExtensionBrowserTest::SetUpCommandLine(command_line);
44
45  // Make event pages get suspended quicker.
46  ProcessManager::SetEventPageIdleTimeForTesting(1000);
47  ProcessManager::SetEventPageSuspendingTimeForTesting(1000);
48}
49
50// static
51AppWindow* PlatformAppBrowserTest::GetFirstAppWindowForBrowser(
52    Browser* browser) {
53  AppWindowRegistry* app_registry = AppWindowRegistry::Get(browser->profile());
54  const AppWindowRegistry::AppWindowList& app_windows =
55      app_registry->app_windows();
56
57  AppWindowRegistry::const_iterator iter = app_windows.begin();
58  if (iter != app_windows.end())
59    return *iter;
60
61  return NULL;
62}
63
64const Extension* PlatformAppBrowserTest::LoadAndLaunchPlatformApp(
65    const char* name,
66    ExtensionTestMessageListener* listener) {
67  DCHECK(listener);
68  const Extension* extension = LoadExtension(
69      test_data_dir_.AppendASCII("platform_apps").AppendASCII(name));
70  EXPECT_TRUE(extension);
71
72  LaunchPlatformApp(extension);
73
74  EXPECT_TRUE(listener->WaitUntilSatisfied()) << "'" << listener->message()
75                                              << "' message was not receieved";
76
77  return extension;
78}
79
80const Extension* PlatformAppBrowserTest::LoadAndLaunchPlatformApp(
81    const char* name,
82    const std::string& message) {
83  ExtensionTestMessageListener launched_listener(message, false);
84  const Extension* extension =
85      LoadAndLaunchPlatformApp(name, &launched_listener);
86
87  return extension;
88}
89
90const Extension* PlatformAppBrowserTest::InstallPlatformApp(
91    const char* name) {
92  const Extension* extension = InstallExtension(
93      test_data_dir_.AppendASCII("platform_apps").AppendASCII(name), 1);
94  EXPECT_TRUE(extension);
95
96  return extension;
97}
98
99const Extension* PlatformAppBrowserTest::InstallAndLaunchPlatformApp(
100    const char* name) {
101  content::WindowedNotificationObserver app_loaded_observer(
102      content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME,
103      content::NotificationService::AllSources());
104
105  const Extension* extension = InstallPlatformApp(name);
106
107  LaunchPlatformApp(extension);
108
109  app_loaded_observer.Wait();
110
111  return extension;
112}
113
114void PlatformAppBrowserTest::LaunchPlatformApp(const Extension* extension) {
115  OpenApplication(AppLaunchParams(
116      browser()->profile(), extension, LAUNCH_CONTAINER_NONE, NEW_WINDOW));
117}
118
119WebContents* PlatformAppBrowserTest::GetFirstAppWindowWebContents() {
120  AppWindow* window = GetFirstAppWindow();
121  if (window)
122    return window->web_contents();
123
124  return NULL;
125}
126
127AppWindow* PlatformAppBrowserTest::GetFirstAppWindow() {
128  return GetFirstAppWindowForBrowser(browser());
129}
130
131AppWindow* PlatformAppBrowserTest::GetFirstAppWindowForApp(
132    const std::string& app_id) {
133  AppWindowRegistry* app_registry =
134      AppWindowRegistry::Get(browser()->profile());
135  const AppWindowRegistry::AppWindowList& app_windows =
136      app_registry->GetAppWindowsForApp(app_id);
137
138  AppWindowRegistry::const_iterator iter = app_windows.begin();
139  if (iter != app_windows.end())
140    return *iter;
141
142  return NULL;
143}
144
145size_t PlatformAppBrowserTest::RunGetWindowsFunctionForExtension(
146    const Extension* extension) {
147  scoped_refptr<WindowsGetAllFunction> function = new WindowsGetAllFunction();
148  function->set_extension(extension);
149  scoped_ptr<base::ListValue> result(utils::ToList(
150      utils::RunFunctionAndReturnSingleResult(function.get(),
151                                              "[]",
152                                              browser())));
153  return result->GetSize();
154}
155
156bool PlatformAppBrowserTest::RunGetWindowFunctionForExtension(
157    int window_id,
158    const Extension* extension) {
159  scoped_refptr<WindowsGetFunction> function = new WindowsGetFunction();
160  function->set_extension(extension);
161  utils::RunFunction(
162          function.get(),
163          base::StringPrintf("[%u]", window_id),
164          browser(),
165          utils::NONE);
166  return function->GetResultList() != NULL;
167}
168
169size_t PlatformAppBrowserTest::GetAppWindowCount() {
170  return AppWindowRegistry::Get(browser()->profile())->app_windows().size();
171}
172
173size_t PlatformAppBrowserTest::GetAppWindowCountForApp(
174    const std::string& app_id) {
175  return AppWindowRegistry::Get(browser()->profile())
176      ->GetAppWindowsForApp(app_id)
177      .size();
178}
179
180void PlatformAppBrowserTest::ClearCommandLineArgs() {
181  CommandLine* command_line = CommandLine::ForCurrentProcess();
182  CommandLine::StringVector args = command_line->GetArgs();
183  CommandLine::StringVector argv = command_line->argv();
184  for (size_t i = 0; i < args.size(); i++)
185    argv.pop_back();
186  command_line->InitFromArgv(argv);
187}
188
189void PlatformAppBrowserTest::SetCommandLineArg(const std::string& test_file) {
190  ClearCommandLineArgs();
191  CommandLine* command_line = CommandLine::ForCurrentProcess();
192  base::FilePath test_doc(test_data_dir_.AppendASCII(test_file));
193  test_doc = test_doc.NormalizePathSeparators();
194  command_line->AppendArgPath(test_doc);
195}
196
197AppWindow* PlatformAppBrowserTest::CreateAppWindow(const Extension* extension) {
198  return CreateAppWindowFromParams(extension, AppWindow::CreateParams());
199}
200
201AppWindow* PlatformAppBrowserTest::CreateAppWindowFromParams(
202    const Extension* extension,
203    const AppWindow::CreateParams& params) {
204  AppWindow* window =
205      new AppWindow(browser()->profile(),
206                    new ChromeAppDelegate(make_scoped_ptr(new ScopedKeepAlive)),
207                    extension);
208  window->Init(GURL(std::string()), new AppWindowContentsImpl(window), params);
209  return window;
210}
211
212void PlatformAppBrowserTest::CloseAppWindow(AppWindow* window) {
213  content::WebContentsDestroyedWatcher destroyed_watcher(
214      window->web_contents());
215  window->GetBaseWindow()->Close();
216  destroyed_watcher.Wait();
217}
218
219void PlatformAppBrowserTest::CallAdjustBoundsToBeVisibleOnScreenForAppWindow(
220    AppWindow* window,
221    const gfx::Rect& cached_bounds,
222    const gfx::Rect& cached_screen_bounds,
223    const gfx::Rect& current_screen_bounds,
224    const gfx::Size& minimum_size,
225    gfx::Rect* bounds) {
226  window->AdjustBoundsToBeVisibleOnScreen(cached_bounds,
227                                          cached_screen_bounds,
228                                          current_screen_bounds,
229                                          minimum_size,
230                                          bounds);
231}
232
233AppWindow* PlatformAppBrowserTest::CreateTestAppWindow(
234    const std::string& window_create_options) {
235  ExtensionTestMessageListener launched_listener("launched", true);
236  ExtensionTestMessageListener loaded_listener("window_loaded", false);
237
238  // Load and launch the test app.
239  const Extension* extension =
240      LoadAndLaunchPlatformApp(kAppWindowTestApp, &launched_listener);
241  EXPECT_TRUE(extension);
242  EXPECT_TRUE(launched_listener.WaitUntilSatisfied());
243
244  // Send the options for window creation.
245  launched_listener.Reply(window_create_options);
246
247  // Wait for the window to be opened and loaded.
248  EXPECT_TRUE(loaded_listener.WaitUntilSatisfied());
249
250  EXPECT_EQ(1U, GetAppWindowCount());
251  AppWindow* app_window = GetFirstAppWindow();
252  return app_window;
253}
254
255void ExperimentalPlatformAppBrowserTest::SetUpCommandLine(
256    CommandLine* command_line) {
257  PlatformAppBrowserTest::SetUpCommandLine(command_line);
258  command_line->AppendSwitch(switches::kEnableExperimentalExtensionApis);
259}
260
261}  // namespace extensions
262