• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "apps/app_window.h"
6 #include "apps/app_window_registry.h"
7 #include "apps/common/api/app_runtime.h"
8 #include "apps/launcher.h"
9 #include "apps/ui/native_app_window.h"
10 #include "base/bind.h"
11 #include "base/command_line.h"
12 #include "base/file_util.h"
13 #include "base/files/scoped_temp_dir.h"
14 #include "base/prefs/pref_service.h"
15 #include "base/stl_util.h"
16 #include "base/strings/utf_string_conversions.h"
17 #include "chrome/app/chrome_command_ids.h"
18 #include "chrome/browser/apps/app_browsertest_util.h"
19 #include "chrome/browser/chrome_notification_types.h"
20 #include "chrome/browser/devtools/devtools_window.h"
21 #include "chrome/browser/extensions/api/permissions/permissions_api.h"
22 #include "chrome/browser/extensions/component_loader.h"
23 #include "chrome/browser/extensions/extension_browsertest.h"
24 #include "chrome/browser/extensions/extension_service.h"
25 #include "chrome/browser/extensions/extension_test_message_listener.h"
26 #include "chrome/browser/renderer_context_menu/render_view_context_menu.h"
27 #include "chrome/browser/ui/browser.h"
28 #include "chrome/browser/ui/extensions/application_launch.h"
29 #include "chrome/browser/ui/tabs/tab_strip_model.h"
30 #include "chrome/browser/ui/webui/print_preview/print_preview_ui.h"
31 #include "chrome/common/chrome_switches.h"
32 #include "chrome/common/pref_names.h"
33 #include "chrome/common/url_constants.h"
34 #include "chrome/test/base/test_switches.h"
35 #include "chrome/test/base/ui_test_utils.h"
36 #include "components/pref_registry/pref_registry_syncable.h"
37 #include "components/web_modal/web_contents_modal_dialog_manager.h"
38 #include "content/public/browser/devtools_agent_host.h"
39 #include "content/public/browser/render_process_host.h"
40 #include "content/public/browser/render_widget_host_view.h"
41 #include "content/public/test/test_utils.h"
42 #include "extensions/browser/event_router.h"
43 #include "extensions/browser/extension_prefs.h"
44 #include "extensions/browser/extension_system.h"
45 #include "extensions/browser/pref_names.h"
46 #include "net/test/embedded_test_server/embedded_test_server.h"
47 #include "url/gurl.h"
48 
49 #if defined(OS_CHROMEOS)
50 #include "base/memory/scoped_ptr.h"
51 #include "chrome/browser/chromeos/login/users/mock_user_manager.h"
52 #include "chrome/browser/chromeos/login/users/user_manager.h"
53 #include "chromeos/dbus/dbus_thread_manager.h"
54 #include "chromeos/dbus/fake_dbus_thread_manager.h"
55 #include "chromeos/dbus/fake_power_manager_client.h"
56 #endif
57 
58 using apps::AppWindow;
59 using apps::AppWindowRegistry;
60 using content::WebContents;
61 using web_modal::WebContentsModalDialogManager;
62 
63 namespace app_runtime = apps::api::app_runtime;
64 
65 namespace extensions {
66 
67 namespace {
68 
69 // Non-abstract RenderViewContextMenu class.
70 class PlatformAppContextMenu : public RenderViewContextMenu {
71  public:
PlatformAppContextMenu(content::RenderFrameHost * render_frame_host,const content::ContextMenuParams & params)72   PlatformAppContextMenu(content::RenderFrameHost* render_frame_host,
73                          const content::ContextMenuParams& params)
74       : RenderViewContextMenu(render_frame_host, params) {}
75 
HasCommandWithId(int command_id)76   bool HasCommandWithId(int command_id) {
77     return menu_model_.GetIndexOfCommandId(command_id) != -1;
78   }
79 
80  protected:
81   // RenderViewContextMenu implementation.
GetAcceleratorForCommandId(int command_id,ui::Accelerator * accelerator)82   virtual bool GetAcceleratorForCommandId(
83       int command_id,
84       ui::Accelerator* accelerator) OVERRIDE {
85     return false;
86   }
PlatformInit()87   virtual void PlatformInit() OVERRIDE {}
PlatformCancel()88   virtual void PlatformCancel() OVERRIDE {}
89 };
90 
91 // This class keeps track of tabs as they are added to the browser. It will be
92 // "done" (i.e. won't block on Wait()) once |observations| tabs have been added.
93 class TabsAddedNotificationObserver
94     : public content::WindowedNotificationObserver {
95  public:
TabsAddedNotificationObserver(size_t observations)96   explicit TabsAddedNotificationObserver(size_t observations)
97       : content::WindowedNotificationObserver(
98             chrome::NOTIFICATION_TAB_ADDED,
99             content::NotificationService::AllSources()),
100         observations_(observations) {
101   }
102 
Observe(int type,const content::NotificationSource & source,const content::NotificationDetails & details)103   virtual void Observe(int type,
104                        const content::NotificationSource& source,
105                        const content::NotificationDetails& details) OVERRIDE {
106     observed_tabs_.push_back(
107         content::Details<WebContents>(details).ptr());
108     if (observed_tabs_.size() == observations_)
109       content::WindowedNotificationObserver::Observe(type, source, details);
110   }
111 
tabs()112   const std::vector<content::WebContents*>& tabs() { return observed_tabs_; }
113 
114  private:
115   size_t observations_;
116   std::vector<content::WebContents*> observed_tabs_;
117 
118   DISALLOW_COPY_AND_ASSIGN(TabsAddedNotificationObserver);
119 };
120 
121 class ScopedPreviewTestingDelegate : PrintPreviewUI::TestingDelegate {
122  public:
ScopedPreviewTestingDelegate(bool auto_cancel)123   explicit ScopedPreviewTestingDelegate(bool auto_cancel)
124       : auto_cancel_(auto_cancel),
125         total_page_count_(1),
126         rendered_page_count_(0) {
127     PrintPreviewUI::SetDelegateForTesting(this);
128   }
129 
~ScopedPreviewTestingDelegate()130   ~ScopedPreviewTestingDelegate() {
131     PrintPreviewUI::SetDelegateForTesting(NULL);
132   }
133 
134   // PrintPreviewUI::TestingDelegate implementation.
IsAutoCancelEnabled()135   virtual bool IsAutoCancelEnabled() OVERRIDE {
136     return auto_cancel_;
137   }
138 
139   // PrintPreviewUI::TestingDelegate implementation.
DidGetPreviewPageCount(int page_count)140   virtual void DidGetPreviewPageCount(int page_count) OVERRIDE {
141     total_page_count_ = page_count;
142   }
143 
144   // PrintPreviewUI::TestingDelegate implementation.
DidRenderPreviewPage(content::WebContents * preview_dialog)145   virtual void DidRenderPreviewPage(content::WebContents* preview_dialog)
146       OVERRIDE {
147     dialog_size_ = preview_dialog->GetContainerBounds().size();
148     ++rendered_page_count_;
149     CHECK(rendered_page_count_ <= total_page_count_);
150     if (waiting_runner_ && rendered_page_count_ == total_page_count_) {
151       waiting_runner_->Quit();
152     }
153   }
154 
WaitUntilPreviewIsReady()155   void WaitUntilPreviewIsReady() {
156     CHECK(!waiting_runner_);
157     if (rendered_page_count_ < total_page_count_) {
158       waiting_runner_ = new content::MessageLoopRunner;
159       waiting_runner_->Run();
160       waiting_runner_ = NULL;
161     }
162   }
163 
dialog_size()164   gfx::Size dialog_size() {
165     return dialog_size_;
166   }
167 
168  private:
169   bool auto_cancel_;
170   int total_page_count_;
171   int rendered_page_count_;
172   scoped_refptr<content::MessageLoopRunner> waiting_runner_;
173   gfx::Size dialog_size_;
174 };
175 
176 #if !defined(OS_CHROMEOS) && !defined(OS_WIN)
CopyTestDataAndSetCommandLineArg(const base::FilePath & test_data_file,const base::FilePath & temp_dir,const char * filename)177 bool CopyTestDataAndSetCommandLineArg(
178     const base::FilePath& test_data_file,
179     const base::FilePath& temp_dir,
180     const char* filename) {
181   base::FilePath path = temp_dir.AppendASCII(
182       filename).NormalizePathSeparators();
183   if (!(base::CopyFile(test_data_file, path)))
184     return false;
185 
186   CommandLine* command_line = CommandLine::ForCurrentProcess();
187   command_line->AppendArgPath(path);
188   return true;
189 }
190 #endif  // !defined(OS_CHROMEOS) && !defined(OS_WIN)
191 
192 #if !defined(OS_CHROMEOS)
193 const char kTestFilePath[] = "platform_apps/launch_files/test.txt";
194 #endif
195 
196 }  // namespace
197 
198 // Tests that CreateAppWindow doesn't crash if you close it straight away.
199 // LauncherPlatformAppBrowserTest relies on this behaviour, but is only run for
200 // ash, so we test that it works here.
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,CreateAndCloseAppWindow)201 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, CreateAndCloseAppWindow) {
202   const Extension* extension = LoadAndLaunchPlatformApp("minimal", "Launched");
203   AppWindow* window = CreateAppWindow(extension);
204   CloseAppWindow(window);
205 }
206 
207 // Tests that platform apps received the "launch" event when launched.
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,OnLaunchedEvent)208 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, OnLaunchedEvent) {
209   ASSERT_TRUE(RunPlatformAppTest("platform_apps/launch")) << message_;
210 }
211 
212 // Tests that platform apps cannot use certain disabled window properties, but
213 // can override them and then use them.
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,DisabledWindowProperties)214 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, DisabledWindowProperties) {
215   ASSERT_TRUE(RunPlatformAppTest("platform_apps/disabled_window_properties"))
216       << message_;
217 }
218 
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,EmptyContextMenu)219 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, EmptyContextMenu) {
220   LoadAndLaunchPlatformApp("minimal", "Launched");
221 
222   // The empty app doesn't add any context menu items, so its menu should
223   // only include the developer tools.
224   WebContents* web_contents = GetFirstAppWindowWebContents();
225   ASSERT_TRUE(web_contents);
226   content::ContextMenuParams params;
227   scoped_ptr<PlatformAppContextMenu> menu;
228   menu.reset(new PlatformAppContextMenu(web_contents->GetMainFrame(), params));
229   menu->Init();
230   ASSERT_TRUE(menu->HasCommandWithId(IDC_CONTENT_CONTEXT_INSPECTELEMENT));
231   ASSERT_TRUE(
232       menu->HasCommandWithId(IDC_CONTENT_CONTEXT_INSPECTBACKGROUNDPAGE));
233   ASSERT_TRUE(menu->HasCommandWithId(IDC_CONTENT_CONTEXT_RELOAD_PACKAGED_APP));
234   ASSERT_FALSE(menu->HasCommandWithId(IDC_BACK));
235   ASSERT_FALSE(menu->HasCommandWithId(IDC_SAVE_PAGE));
236 }
237 
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,AppWithContextMenu)238 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, AppWithContextMenu) {
239   LoadAndLaunchPlatformApp("context_menu", "Launched");
240 
241   // The context_menu app has two context menu items. These, along with a
242   // separator and the developer tools, is all that should be in the menu.
243   WebContents* web_contents = GetFirstAppWindowWebContents();
244   ASSERT_TRUE(web_contents);
245   content::ContextMenuParams params;
246   scoped_ptr<PlatformAppContextMenu> menu;
247   menu.reset(new PlatformAppContextMenu(web_contents->GetMainFrame(), params));
248   menu->Init();
249   ASSERT_TRUE(menu->HasCommandWithId(IDC_EXTENSIONS_CONTEXT_CUSTOM_FIRST));
250   ASSERT_TRUE(menu->HasCommandWithId(IDC_EXTENSIONS_CONTEXT_CUSTOM_FIRST + 1));
251   ASSERT_TRUE(menu->HasCommandWithId(IDC_CONTENT_CONTEXT_INSPECTELEMENT));
252   ASSERT_TRUE(
253       menu->HasCommandWithId(IDC_CONTENT_CONTEXT_INSPECTBACKGROUNDPAGE));
254   ASSERT_TRUE(menu->HasCommandWithId(IDC_CONTENT_CONTEXT_RELOAD_PACKAGED_APP));
255   ASSERT_FALSE(menu->HasCommandWithId(IDC_BACK));
256   ASSERT_FALSE(menu->HasCommandWithId(IDC_SAVE_PAGE));
257   ASSERT_FALSE(menu->HasCommandWithId(IDC_CONTENT_CONTEXT_UNDO));
258 }
259 
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,InstalledAppWithContextMenu)260 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, InstalledAppWithContextMenu) {
261   ExtensionTestMessageListener launched_listener("Launched", false);
262   InstallAndLaunchPlatformApp("context_menu");
263 
264   // Wait for the extension to tell us it's initialized its context menus and
265   // launched a window.
266   ASSERT_TRUE(launched_listener.WaitUntilSatisfied());
267 
268   // The context_menu app has two context menu items. For an installed app
269   // these are all that should be in the menu.
270   WebContents* web_contents = GetFirstAppWindowWebContents();
271   ASSERT_TRUE(web_contents);
272   content::ContextMenuParams params;
273   scoped_ptr<PlatformAppContextMenu> menu;
274   menu.reset(new PlatformAppContextMenu(web_contents->GetMainFrame(), params));
275   menu->Init();
276   ASSERT_TRUE(menu->HasCommandWithId(IDC_EXTENSIONS_CONTEXT_CUSTOM_FIRST));
277   ASSERT_TRUE(menu->HasCommandWithId(IDC_EXTENSIONS_CONTEXT_CUSTOM_FIRST + 1));
278   ASSERT_FALSE(menu->HasCommandWithId(IDC_CONTENT_CONTEXT_INSPECTELEMENT));
279   ASSERT_FALSE(
280       menu->HasCommandWithId(IDC_CONTENT_CONTEXT_INSPECTBACKGROUNDPAGE));
281   ASSERT_FALSE(menu->HasCommandWithId(IDC_CONTENT_CONTEXT_RELOAD_PACKAGED_APP));
282   ASSERT_FALSE(menu->HasCommandWithId(IDC_BACK));
283   ASSERT_FALSE(menu->HasCommandWithId(IDC_SAVE_PAGE));
284   ASSERT_FALSE(menu->HasCommandWithId(IDC_CONTENT_CONTEXT_UNDO));
285 }
286 
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,AppWithContextMenuTextField)287 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, AppWithContextMenuTextField) {
288   LoadAndLaunchPlatformApp("context_menu", "Launched");
289 
290   // The context_menu app has one context menu item. This, along with a
291   // separator and the developer tools, is all that should be in the menu.
292   WebContents* web_contents = GetFirstAppWindowWebContents();
293   ASSERT_TRUE(web_contents);
294   content::ContextMenuParams params;
295   params.is_editable = true;
296   scoped_ptr<PlatformAppContextMenu> menu;
297   menu.reset(new PlatformAppContextMenu(web_contents->GetMainFrame(), params));
298   menu->Init();
299   ASSERT_TRUE(menu->HasCommandWithId(IDC_EXTENSIONS_CONTEXT_CUSTOM_FIRST));
300   ASSERT_TRUE(menu->HasCommandWithId(IDC_CONTENT_CONTEXT_INSPECTELEMENT));
301   ASSERT_TRUE(
302       menu->HasCommandWithId(IDC_CONTENT_CONTEXT_INSPECTBACKGROUNDPAGE));
303   ASSERT_TRUE(menu->HasCommandWithId(IDC_CONTENT_CONTEXT_RELOAD_PACKAGED_APP));
304   ASSERT_TRUE(menu->HasCommandWithId(IDC_CONTENT_CONTEXT_UNDO));
305   ASSERT_TRUE(menu->HasCommandWithId(IDC_CONTENT_CONTEXT_COPY));
306   ASSERT_FALSE(menu->HasCommandWithId(IDC_BACK));
307   ASSERT_FALSE(menu->HasCommandWithId(IDC_SAVE_PAGE));
308 }
309 
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,AppWithContextMenuSelection)310 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, AppWithContextMenuSelection) {
311   LoadAndLaunchPlatformApp("context_menu", "Launched");
312 
313   // The context_menu app has one context menu item. This, along with a
314   // separator and the developer tools, is all that should be in the menu.
315   WebContents* web_contents = GetFirstAppWindowWebContents();
316   ASSERT_TRUE(web_contents);
317   content::ContextMenuParams params;
318   params.selection_text = base::ASCIIToUTF16("Hello World");
319   scoped_ptr<PlatformAppContextMenu> menu;
320   menu.reset(new PlatformAppContextMenu(web_contents->GetMainFrame(), params));
321   menu->Init();
322   ASSERT_TRUE(menu->HasCommandWithId(IDC_EXTENSIONS_CONTEXT_CUSTOM_FIRST));
323   ASSERT_TRUE(menu->HasCommandWithId(IDC_CONTENT_CONTEXT_INSPECTELEMENT));
324   ASSERT_TRUE(
325       menu->HasCommandWithId(IDC_CONTENT_CONTEXT_INSPECTBACKGROUNDPAGE));
326   ASSERT_TRUE(menu->HasCommandWithId(IDC_CONTENT_CONTEXT_RELOAD_PACKAGED_APP));
327   ASSERT_FALSE(menu->HasCommandWithId(IDC_CONTENT_CONTEXT_UNDO));
328   ASSERT_TRUE(menu->HasCommandWithId(IDC_CONTENT_CONTEXT_COPY));
329   ASSERT_FALSE(menu->HasCommandWithId(IDC_BACK));
330   ASSERT_FALSE(menu->HasCommandWithId(IDC_SAVE_PAGE));
331 }
332 
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,AppWithContextMenuClicked)333 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, AppWithContextMenuClicked) {
334   LoadAndLaunchPlatformApp("context_menu_click", "Launched");
335 
336   // Test that the menu item shows up
337   WebContents* web_contents = GetFirstAppWindowWebContents();
338   ASSERT_TRUE(web_contents);
339   content::ContextMenuParams params;
340   params.page_url = GURL("http://foo.bar");
341   scoped_ptr<PlatformAppContextMenu> menu;
342   menu.reset(new PlatformAppContextMenu(web_contents->GetMainFrame(), params));
343   menu->Init();
344   ASSERT_TRUE(menu->HasCommandWithId(IDC_EXTENSIONS_CONTEXT_CUSTOM_FIRST));
345 
346   // Execute the menu item
347   ExtensionTestMessageListener onclicked_listener("onClicked fired for id1",
348                                                   false);
349   menu->ExecuteCommand(IDC_EXTENSIONS_CONTEXT_CUSTOM_FIRST, 0);
350 
351   ASSERT_TRUE(onclicked_listener.WaitUntilSatisfied());
352 }
353 
354 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA)
355 // TODO(erg): linux_aura bringup: http://crbug.com/163931
356 #define MAYBE_DisallowNavigation DISABLED_DisallowNavigation
357 #else
358 #define MAYBE_DisallowNavigation DisallowNavigation
359 #endif
360 
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,MAYBE_DisallowNavigation)361 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, MAYBE_DisallowNavigation) {
362   TabsAddedNotificationObserver observer(2);
363 
364   ASSERT_TRUE(StartEmbeddedTestServer());
365   ASSERT_TRUE(RunPlatformAppTest("platform_apps/navigation")) << message_;
366 
367   observer.Wait();
368   ASSERT_EQ(2U, observer.tabs().size());
369   EXPECT_EQ(std::string(chrome::kExtensionInvalidRequestURL),
370             observer.tabs()[0]->GetURL().spec());
371   EXPECT_EQ("http://chromium.org/",
372             observer.tabs()[1]->GetURL().spec());
373 }
374 
375 // Failing on some Win and Linux buildbots.  See crbug.com/354425.
376 #if (defined(OS_WIN) || defined(OS_LINUX)) && defined(ARCH_CPU_X86)
377 #define MAYBE_Iframes DISABLED_Iframes
378 #else
379 #define MAYBE_Iframes Iframes
380 #endif
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,MAYBE_Iframes)381 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, MAYBE_Iframes) {
382   ASSERT_TRUE(StartEmbeddedTestServer());
383   ASSERT_TRUE(RunPlatformAppTest("platform_apps/iframes")) << message_;
384 }
385 
386 // Tests that localStorage and WebSQL are disabled for platform apps.
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,DisallowStorage)387 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, DisallowStorage) {
388   ASSERT_TRUE(RunPlatformAppTest("platform_apps/storage")) << message_;
389 }
390 
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,Restrictions)391 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, Restrictions) {
392   ASSERT_TRUE(RunPlatformAppTest("platform_apps/restrictions")) << message_;
393 }
394 
395 // Tests that extensions can't use platform-app-only APIs.
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,PlatformAppsOnly)396 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, PlatformAppsOnly) {
397   ASSERT_TRUE(RunExtensionTestIgnoreManifestWarnings(
398       "platform_apps/apps_only")) << message_;
399 }
400 
401 // Tests that platform apps have isolated storage by default.
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,Isolation)402 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, Isolation) {
403   ASSERT_TRUE(StartEmbeddedTestServer());
404 
405   // Load a (non-app) page under the "localhost" origin that sets a cookie.
406   GURL set_cookie_url = embedded_test_server()->GetURL(
407       "/extensions/platform_apps/isolation/set_cookie.html");
408   GURL::Replacements replace_host;
409   std::string host_str("localhost");  // Must stay in scope with replace_host.
410   replace_host.SetHostStr(host_str);
411   set_cookie_url = set_cookie_url.ReplaceComponents(replace_host);
412 
413   ui_test_utils::NavigateToURLWithDisposition(
414       browser(), set_cookie_url,
415       CURRENT_TAB, ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
416 
417   // Make sure the cookie is set.
418   int cookie_size;
419   std::string cookie_value;
420   ui_test_utils::GetCookies(
421       set_cookie_url,
422       browser()->tab_strip_model()->GetWebContentsAt(0),
423       &cookie_size,
424       &cookie_value);
425   ASSERT_EQ("testCookie=1", cookie_value);
426 
427   // Let the platform app request the same URL, and make sure that it doesn't
428   // see the cookie.
429   ASSERT_TRUE(RunPlatformAppTest("platform_apps/isolation")) << message_;
430 }
431 
432 // See crbug.com/248441
433 #if defined(OS_WIN)
434 #define MAYBE_ExtensionWindowingApis DISABLED_ExtensionWindowingApis
435 #else
436 #define MAYBE_ExtensionWindowingApis ExtensionWindowingApis
437 #endif
438 
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,MAYBE_ExtensionWindowingApis)439 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, MAYBE_ExtensionWindowingApis) {
440   // Initially there should be just the one browser window visible to the
441   // extensions API.
442   const Extension* extension = LoadExtension(
443       test_data_dir_.AppendASCII("common/background_page"));
444   ASSERT_EQ(1U, RunGetWindowsFunctionForExtension(extension));
445 
446   // And no app windows.
447   ASSERT_EQ(0U, GetAppWindowCount());
448 
449   // Launch a platform app that shows a window.
450   LoadAndLaunchPlatformApp("minimal", "Launched");
451   ASSERT_EQ(1U, GetAppWindowCount());
452   int app_window_id = GetFirstAppWindow()->session_id().id();
453 
454   // But it's not visible to the extensions API, it still thinks there's just
455   // one browser window.
456   ASSERT_EQ(1U, RunGetWindowsFunctionForExtension(extension));
457   // It can't look it up by ID either
458   ASSERT_FALSE(RunGetWindowFunctionForExtension(app_window_id, extension));
459 
460   // The app can also only see one window (its own).
461   // TODO(jeremya): add an extension function to get an app window by ID, and
462   // to get a list of all the app windows, so we can test this.
463 
464   // Launch another platform app that also shows a window.
465   LoadAndLaunchPlatformApp("context_menu", "Launched");
466 
467   // There are two total app windows, but each app can only see its own.
468   ASSERT_EQ(2U, GetAppWindowCount());
469   // TODO(jeremya): as above, this requires more extension functions.
470 }
471 
472 // ChromeOS does not support passing arguments on the command line, so the tests
473 // that rely on this functionality are disabled.
474 #if !defined(OS_CHROMEOS)
475 // Tests that command line parameters get passed through to platform apps
476 // via launchData correctly when launching with a file.
477 // TODO(benwells/jeremya): tests need a way to specify a handler ID.
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,LaunchWithFile)478 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, LaunchWithFile) {
479   SetCommandLineArg(kTestFilePath);
480   ASSERT_TRUE(RunPlatformAppTest("platform_apps/launch_file"))
481       << message_;
482 }
483 
484 // Tests that relative paths can be passed through to the platform app.
485 // This test doesn't use the normal test infrastructure as it needs to open
486 // the application differently to all other platform app tests, by setting
487 // the AppLaunchParams.current_directory field.
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,LaunchWithRelativeFile)488 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, LaunchWithRelativeFile) {
489   // Setup the command line
490   ClearCommandLineArgs();
491   CommandLine* command_line = CommandLine::ForCurrentProcess();
492   base::FilePath relative_test_doc =
493       base::FilePath::FromUTF8Unsafe(kTestFilePath);
494   relative_test_doc = relative_test_doc.NormalizePathSeparators();
495   command_line->AppendArgPath(relative_test_doc);
496 
497   // Load the extension
498   ResultCatcher catcher;
499   const Extension* extension = LoadExtension(
500       test_data_dir_.AppendASCII("platform_apps/launch_file"));
501   ASSERT_TRUE(extension);
502 
503   // Run the test
504   AppLaunchParams params(
505       browser()->profile(), extension, LAUNCH_CONTAINER_NONE, NEW_WINDOW);
506   params.command_line = *CommandLine::ForCurrentProcess();
507   params.current_directory = test_data_dir_;
508   OpenApplication(params);
509 
510   if (!catcher.GetNextResult()) {
511     message_ = catcher.message();
512     ASSERT_TRUE(0);
513   }
514 }
515 
516 // Tests that launch data is sent through if the file extension matches.
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,LaunchWithFileExtension)517 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, LaunchWithFileExtension) {
518   SetCommandLineArg(kTestFilePath);
519   ASSERT_TRUE(RunPlatformAppTest("platform_apps/launch_file_by_extension"))
520       << message_;
521 }
522 
523 // Tests that launch data is sent through to a whitelisted extension if the file
524 // extension matches.
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,LaunchWhiteListedExtensionWithFile)525 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,
526                        LaunchWhiteListedExtensionWithFile) {
527   SetCommandLineArg(kTestFilePath);
528   ASSERT_TRUE(RunPlatformAppTest(
529       "platform_apps/launch_whitelisted_ext_with_file"))
530           << message_;
531 }
532 
533 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA)
534 // TODO(erg): linux_aura bringup: http://crbug.com/163931
535 #define MAYBE_LaunchWithFileExtensionAndMimeType DISABLED_LaunchWithFileExtensionAndMimeType
536 #else
537 #define MAYBE_LaunchWithFileExtensionAndMimeType LaunchWithFileExtensionAndMimeType
538 #endif
539 
540 // Tests that launch data is sent through if the file extension and MIME type
541 // both match.
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,MAYBE_LaunchWithFileExtensionAndMimeType)542 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,
543                        MAYBE_LaunchWithFileExtensionAndMimeType) {
544   SetCommandLineArg(kTestFilePath);
545   ASSERT_TRUE(RunPlatformAppTest(
546       "platform_apps/launch_file_by_extension_and_type")) << message_;
547 }
548 
549 // Tests that launch data is sent through for a file with no extension if a
550 // handler accepts "".
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,LaunchWithFileWithoutExtension)551 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, LaunchWithFileWithoutExtension) {
552   SetCommandLineArg("platform_apps/launch_files/test");
553   ASSERT_TRUE(RunPlatformAppTest("platform_apps/launch_file_with_no_extension"))
554       << message_;
555 }
556 
557 #if !defined(OS_WIN)
558 // Tests that launch data is sent through for a file with an empty extension if
559 // a handler accepts "".
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,LaunchWithFileEmptyExtension)560 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, LaunchWithFileEmptyExtension) {
561   base::ScopedTempDir temp_dir;
562   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
563   ClearCommandLineArgs();
564   ASSERT_TRUE(CopyTestDataAndSetCommandLineArg(
565       test_data_dir_.AppendASCII(kTestFilePath),
566       temp_dir.path(),
567       "test."));
568   ASSERT_TRUE(RunPlatformAppTest("platform_apps/launch_file_with_no_extension"))
569       << message_;
570 }
571 
572 // Tests that launch data is sent through for a file with an empty extension if
573 // a handler accepts *.
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,LaunchWithFileEmptyExtensionAcceptAny)574 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,
575                        LaunchWithFileEmptyExtensionAcceptAny) {
576   base::ScopedTempDir temp_dir;
577   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
578   ClearCommandLineArgs();
579   ASSERT_TRUE(CopyTestDataAndSetCommandLineArg(
580       test_data_dir_.AppendASCII(kTestFilePath),
581       temp_dir.path(),
582       "test."));
583   ASSERT_TRUE(RunPlatformAppTest(
584       "platform_apps/launch_file_with_any_extension")) << message_;
585 }
586 #endif
587 
588 // Tests that launch data is sent through for a file with no extension if a
589 // handler accepts *.
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,LaunchWithFileWithoutExtensionAcceptAny)590 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,
591                        LaunchWithFileWithoutExtensionAcceptAny) {
592   SetCommandLineArg("platform_apps/launch_files/test");
593   ASSERT_TRUE(RunPlatformAppTest(
594       "platform_apps/launch_file_with_any_extension")) << message_;
595 }
596 
597 // Tests that launch data is sent through for a file with an extension if a
598 // handler accepts *.
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,LaunchWithFileAcceptAnyExtension)599 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,
600                        LaunchWithFileAcceptAnyExtension) {
601   SetCommandLineArg(kTestFilePath);
602   ASSERT_TRUE(RunPlatformAppTest(
603       "platform_apps/launch_file_with_any_extension")) << message_;
604 }
605 
606 // Tests that no launch data is sent through if the file has the wrong
607 // extension.
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,LaunchWithWrongExtension)608 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, LaunchWithWrongExtension) {
609   SetCommandLineArg(kTestFilePath);
610   ASSERT_TRUE(RunPlatformAppTest("platform_apps/launch_wrong_extension"))
611       << message_;
612 }
613 
614 // Tests that no launch data is sent through if the file has no extension but
615 // the handler requires a specific extension.
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,LaunchWithWrongEmptyExtension)616 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, LaunchWithWrongEmptyExtension) {
617   SetCommandLineArg("platform_apps/launch_files/test");
618   ASSERT_TRUE(RunPlatformAppTest("platform_apps/launch_wrong_extension"))
619       << message_;
620 }
621 
622 // Tests that no launch data is sent through if the file is of the wrong MIME
623 // type.
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,LaunchWithWrongType)624 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, LaunchWithWrongType) {
625   SetCommandLineArg(kTestFilePath);
626   ASSERT_TRUE(RunPlatformAppTest("platform_apps/launch_wrong_type"))
627       << message_;
628 }
629 
630 // Tests that no launch data is sent through if the platform app does not
631 // provide an intent.
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,LaunchWithNoIntent)632 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, LaunchWithNoIntent) {
633   SetCommandLineArg(kTestFilePath);
634   ASSERT_TRUE(RunPlatformAppTest("platform_apps/launch_no_intent"))
635       << message_;
636 }
637 
638 // Tests that launch data is sent through when the file has unknown extension
639 // but the MIME type can be sniffed and the sniffed type matches.
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,LaunchWithSniffableType)640 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, LaunchWithSniffableType) {
641   SetCommandLineArg("platform_apps/launch_files/test.unknownextension");
642   ASSERT_TRUE(RunPlatformAppTest(
643       "platform_apps/launch_file_by_extension_and_type")) << message_;
644 }
645 
646 // Tests that launch data is sent through with the MIME type set to
647 // application/octet-stream if the file MIME type cannot be read.
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,LaunchNoType)648 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, LaunchNoType) {
649   SetCommandLineArg("platform_apps/launch_files/test_binary.unknownextension");
650   ASSERT_TRUE(RunPlatformAppTest(
651       "platform_apps/launch_application_octet_stream")) << message_;
652 }
653 
654 // Tests that no launch data is sent through if the file does not exist.
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,LaunchNoFile)655 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, LaunchNoFile) {
656   SetCommandLineArg("platform_apps/launch_files/doesnotexist.txt");
657   ASSERT_TRUE(RunPlatformAppTest("platform_apps/launch_invalid"))
658       << message_;
659 }
660 
661 // Tests that no launch data is sent through if the argument is a directory.
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,LaunchWithDirectory)662 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, LaunchWithDirectory) {
663   SetCommandLineArg("platform_apps/launch_files");
664   ASSERT_TRUE(RunPlatformAppTest("platform_apps/launch_invalid"))
665       << message_;
666 }
667 
668 // Tests that no launch data is sent through if there are no arguments passed
669 // on the command line
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,LaunchWithNothing)670 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, LaunchWithNothing) {
671   ClearCommandLineArgs();
672   ASSERT_TRUE(RunPlatformAppTest("platform_apps/launch_nothing"))
673       << message_;
674 }
675 
676 // Test that platform apps can use the chrome.fileSystem.getDisplayPath
677 // function to get the native file system path of a file they are launched with.
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,GetDisplayPath)678 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, GetDisplayPath) {
679   SetCommandLineArg(kTestFilePath);
680   ASSERT_TRUE(RunPlatformAppTest("platform_apps/get_display_path"))
681       << message_;
682 }
683 
684 // Tests that the file is created if the file does not exist and the app has the
685 // fileSystem.write permission.
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,LaunchNewFile)686 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, LaunchNewFile) {
687   base::ScopedTempDir temp_dir;
688   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
689   ClearCommandLineArgs();
690   CommandLine* command_line = CommandLine::ForCurrentProcess();
691   command_line->AppendArgPath(temp_dir.path().AppendASCII("new_file.txt"));
692   ASSERT_TRUE(RunPlatformAppTest("platform_apps/launch_new_file")) << message_;
693 }
694 
695 #endif  // !defined(OS_CHROMEOS)
696 
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,OpenLink)697 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, OpenLink) {
698   ASSERT_TRUE(StartEmbeddedTestServer());
699   content::WindowedNotificationObserver observer(
700       chrome::NOTIFICATION_TAB_ADDED,
701       content::Source<content::WebContentsDelegate>(browser()));
702   LoadAndLaunchPlatformApp("open_link", "Launched");
703   observer.Wait();
704   ASSERT_EQ(2, browser()->tab_strip_model()->count());
705 }
706 
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,MutationEventsDisabled)707 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, MutationEventsDisabled) {
708   ASSERT_TRUE(RunPlatformAppTest("platform_apps/mutation_events")) << message_;
709 }
710 
711 // This appears to be unreliable on linux.
712 // TODO(stevenjb): Investigate and enable
713 #if defined(OS_LINUX) && !defined(USE_ASH)
714 #define MAYBE_AppWindowRestoreState DISABLED_AppWindowRestoreState
715 #else
716 #define MAYBE_AppWindowRestoreState AppWindowRestoreState
717 #endif
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,MAYBE_AppWindowRestoreState)718 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, MAYBE_AppWindowRestoreState) {
719   ASSERT_TRUE(RunPlatformAppTest("platform_apps/restore_state"));
720 }
721 
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,AppWindowAdjustBoundsToBeVisibleOnScreen)722 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,
723                        AppWindowAdjustBoundsToBeVisibleOnScreen) {
724   const Extension* extension = LoadAndLaunchPlatformApp("minimal", "Launched");
725 
726   AppWindow* window = CreateAppWindow(extension);
727 
728   // The screen bounds didn't change, the cached bounds didn't need to adjust.
729   gfx::Rect cached_bounds(80, 100, 400, 400);
730   gfx::Rect cached_screen_bounds(0, 0, 1600, 900);
731   gfx::Rect current_screen_bounds(0, 0, 1600, 900);
732   gfx::Size minimum_size(200, 200);
733   gfx::Rect bounds;
734   CallAdjustBoundsToBeVisibleOnScreenForAppWindow(window,
735                                                   cached_bounds,
736                                                   cached_screen_bounds,
737                                                   current_screen_bounds,
738                                                   minimum_size,
739                                                   &bounds);
740   EXPECT_EQ(bounds, cached_bounds);
741 
742   // We have an empty screen bounds, the cached bounds didn't need to adjust.
743   gfx::Rect empty_screen_bounds;
744   CallAdjustBoundsToBeVisibleOnScreenForAppWindow(window,
745                                                   cached_bounds,
746                                                   empty_screen_bounds,
747                                                   current_screen_bounds,
748                                                   minimum_size,
749                                                   &bounds);
750   EXPECT_EQ(bounds, cached_bounds);
751 
752   // Cached bounds is completely off the new screen bounds in horizontal
753   // locations. Expect to reposition the bounds.
754   gfx::Rect horizontal_out_of_screen_bounds(-800, 100, 400, 400);
755   CallAdjustBoundsToBeVisibleOnScreenForAppWindow(
756       window,
757       horizontal_out_of_screen_bounds,
758       gfx::Rect(-1366, 0, 1600, 900),
759       current_screen_bounds,
760       minimum_size,
761       &bounds);
762   EXPECT_EQ(bounds, gfx::Rect(0, 100, 400, 400));
763 
764   // Cached bounds is completely off the new screen bounds in vertical
765   // locations. Expect to reposition the bounds.
766   gfx::Rect vertical_out_of_screen_bounds(10, 1000, 400, 400);
767   CallAdjustBoundsToBeVisibleOnScreenForAppWindow(
768       window,
769       vertical_out_of_screen_bounds,
770       gfx::Rect(-1366, 0, 1600, 900),
771       current_screen_bounds,
772       minimum_size,
773       &bounds);
774   EXPECT_EQ(bounds, gfx::Rect(10, 500, 400, 400));
775 
776   // From a large screen resulotion to a small one. Expect it fit on screen.
777   gfx::Rect big_cache_bounds(10, 10, 1000, 1000);
778   CallAdjustBoundsToBeVisibleOnScreenForAppWindow(window,
779                                                   big_cache_bounds,
780                                                   gfx::Rect(0, 0, 1600, 1000),
781                                                   gfx::Rect(0, 0, 800, 600),
782                                                   minimum_size,
783                                                   &bounds);
784   EXPECT_EQ(bounds, gfx::Rect(0, 0, 800, 600));
785 
786   // Don't resize the bounds smaller than minimum size, when the minimum size is
787   // larger than the screen.
788   CallAdjustBoundsToBeVisibleOnScreenForAppWindow(window,
789                                                   big_cache_bounds,
790                                                   gfx::Rect(0, 0, 1600, 1000),
791                                                   gfx::Rect(0, 0, 800, 600),
792                                                   gfx::Size(900, 900),
793                                                   &bounds);
794   EXPECT_EQ(bounds, gfx::Rect(0, 0, 900, 900));
795 }
796 
797 namespace {
798 
799 class PlatformAppDevToolsBrowserTest : public PlatformAppBrowserTest {
800  protected:
801   enum TestFlags {
802     RELAUNCH = 0x1,
803     HAS_ID = 0x2,
804   };
805   // Runs a test inside a harness that opens DevTools on an app window.
806   void RunTestWithDevTools(const char* name, int test_flags);
807 };
808 
RunTestWithDevTools(const char * name,int test_flags)809 void PlatformAppDevToolsBrowserTest::RunTestWithDevTools(
810     const char* name, int test_flags) {
811   using content::DevToolsAgentHost;
812   const Extension* extension = LoadAndLaunchPlatformApp(name, "Launched");
813   ASSERT_TRUE(extension);
814   AppWindow* window = GetFirstAppWindow();
815   ASSERT_TRUE(window);
816   ASSERT_EQ(window->window_key().empty(), (test_flags & HAS_ID) == 0);
817   content::RenderViewHost* rvh = window->web_contents()->GetRenderViewHost();
818   ASSERT_TRUE(rvh);
819 
820   // Ensure no DevTools open for the AppWindow, then open one.
821   ASSERT_FALSE(DevToolsAgentHost::HasFor(rvh));
822   DevToolsWindow::OpenDevToolsWindow(rvh);
823   ASSERT_TRUE(DevToolsAgentHost::HasFor(rvh));
824 
825   if (test_flags & RELAUNCH) {
826     // Close the AppWindow, and ensure it is gone.
827     CloseAppWindow(window);
828     ASSERT_FALSE(GetFirstAppWindow());
829 
830     // Relaunch the app and get a new AppWindow.
831     content::WindowedNotificationObserver app_loaded_observer(
832         content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME,
833         content::NotificationService::AllSources());
834     OpenApplication(AppLaunchParams(
835         browser()->profile(), extension, LAUNCH_CONTAINER_NONE, NEW_WINDOW));
836     app_loaded_observer.Wait();
837     window = GetFirstAppWindow();
838     ASSERT_TRUE(window);
839 
840     // DevTools should have reopened with the relaunch.
841     rvh = window->web_contents()->GetRenderViewHost();
842     ASSERT_TRUE(rvh);
843     ASSERT_TRUE(DevToolsAgentHost::HasFor(rvh));
844   }
845 }
846 
847 }  // namespace
848 
849 // http://crbug.com/246634
850 #if defined(OS_CHROMEOS)
851 #define MAYBE_ReOpenedWithID DISABLED_ReOpenedWithID
852 #else
853 #define MAYBE_ReOpenedWithID ReOpenedWithID
854 #endif
IN_PROC_BROWSER_TEST_F(PlatformAppDevToolsBrowserTest,MAYBE_ReOpenedWithID)855 IN_PROC_BROWSER_TEST_F(PlatformAppDevToolsBrowserTest, MAYBE_ReOpenedWithID) {
856 #if defined(OS_WIN) && defined(USE_ASH)
857   // Disable this test in Metro+Ash for now (http://crbug.com/262796).
858   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
859     return;
860 #endif
861   RunTestWithDevTools("minimal_id", RELAUNCH | HAS_ID);
862 }
863 
864 // http://crbug.com/246999
865 #if defined(OS_CHROMEOS) || defined(OS_WIN)
866 #define MAYBE_ReOpenedWithURL DISABLED_ReOpenedWithURL
867 #else
868 #define MAYBE_ReOpenedWithURL ReOpenedWithURL
869 #endif
IN_PROC_BROWSER_TEST_F(PlatformAppDevToolsBrowserTest,MAYBE_ReOpenedWithURL)870 IN_PROC_BROWSER_TEST_F(PlatformAppDevToolsBrowserTest, MAYBE_ReOpenedWithURL) {
871   RunTestWithDevTools("minimal", RELAUNCH);
872 }
873 
874 // Test that showing a permission request as a constrained window works and is
875 // correctly parented.
876 #if defined(OS_MACOSX)
877 #define MAYBE_ConstrainedWindowRequest DISABLED_ConstrainedWindowRequest
878 #else
879 // TODO(sail): Enable this on other platforms once http://crbug.com/95455 is
880 // fixed.
881 #define MAYBE_ConstrainedWindowRequest DISABLED_ConstrainedWindowRequest
882 #endif
883 
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,MAYBE_ConstrainedWindowRequest)884 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, MAYBE_ConstrainedWindowRequest) {
885   PermissionsRequestFunction::SetIgnoreUserGestureForTests(true);
886   const Extension* extension =
887       LoadAndLaunchPlatformApp("optional_permission_request", "Launched");
888   ASSERT_TRUE(extension) << "Failed to load extension.";
889 
890   WebContents* web_contents = GetFirstAppWindowWebContents();
891   ASSERT_TRUE(web_contents);
892 
893   // Verify that the app window has a dialog attached.
894   WebContentsModalDialogManager* web_contents_modal_dialog_manager =
895       WebContentsModalDialogManager::FromWebContents(web_contents);
896   EXPECT_TRUE(web_contents_modal_dialog_manager->IsDialogActive());
897 
898   // Close the constrained window and wait for the reply to the permission
899   // request.
900   ExtensionTestMessageListener listener("PermissionRequestDone", false);
901   WebContentsModalDialogManager::TestApi test_api(
902       web_contents_modal_dialog_manager);
903   test_api.CloseAllDialogs();
904   ASSERT_TRUE(listener.WaitUntilSatisfied());
905 }
906 
907 // Tests that an app calling chrome.runtime.reload will reload the app and
908 // relaunch it if it was running.
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,ReloadRelaunches)909 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, ReloadRelaunches) {
910   ExtensionTestMessageListener launched_listener("Launched", true);
911   const Extension* extension =
912       LoadAndLaunchPlatformApp("reload", &launched_listener);
913   ASSERT_TRUE(extension);
914   ASSERT_TRUE(GetFirstAppWindow());
915 
916   // Now tell the app to reload itself
917   ExtensionTestMessageListener launched_listener2("Launched", false);
918   launched_listener.Reply("reload");
919   ASSERT_TRUE(launched_listener2.WaitUntilSatisfied());
920   ASSERT_TRUE(GetFirstAppWindow());
921 }
922 
923 namespace {
924 
925 // Simple observer to check for NOTIFICATION_EXTENSION_INSTALLED_DEPRECATED
926 // events to
927 // ensure installation does or does not occur in certain scenarios.
928 class CheckExtensionInstalledObserver : public content::NotificationObserver {
929  public:
CheckExtensionInstalledObserver()930   CheckExtensionInstalledObserver() : seen_(false) {
931     registrar_.Add(this,
932                    chrome::NOTIFICATION_EXTENSION_INSTALLED_DEPRECATED,
933                    content::NotificationService::AllSources());
934   }
935 
seen() const936   bool seen() const {
937     return seen_;
938   };
939 
940   // NotificationObserver:
Observe(int type,const content::NotificationSource & source,const content::NotificationDetails & details)941   virtual void Observe(int type,
942                        const content::NotificationSource& source,
943                        const content::NotificationDetails& details) OVERRIDE {
944     EXPECT_FALSE(seen_);
945     seen_ = true;
946   }
947 
948  private:
949   bool seen_;
950   content::NotificationRegistrar registrar_;
951 };
952 
953 }  // namespace
954 
955 // Component App Test 1 of 3: ensure that the initial load of a component
956 // extension utilizing a background page (e.g. a v2 platform app) has its
957 // background page run and is launchable. Waits for the Launched response from
958 // the script resource in the opened app window.
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,PRE_PRE_ComponentAppBackgroundPage)959 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,
960                        PRE_PRE_ComponentAppBackgroundPage) {
961   CheckExtensionInstalledObserver should_install;
962 
963   // Ensure that we wait until the background page is run (to register the
964   // OnLaunched listener) before trying to open the application. This is similar
965   // to LoadAndLaunchPlatformApp, but we want to load as a component extension.
966   content::WindowedNotificationObserver app_loaded_observer(
967       content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME,
968       content::NotificationService::AllSources());
969 
970   const Extension* extension = LoadExtensionAsComponent(
971       test_data_dir_.AppendASCII("platform_apps").AppendASCII("component"));
972   ASSERT_TRUE(extension);
973 
974   app_loaded_observer.Wait();
975   ASSERT_TRUE(should_install.seen());
976 
977   ExtensionTestMessageListener launched_listener("Launched", false);
978   OpenApplication(AppLaunchParams(
979       browser()->profile(), extension, LAUNCH_CONTAINER_NONE, NEW_WINDOW));
980 
981   ASSERT_TRUE(launched_listener.WaitUntilSatisfied());
982 }
983 
984 // Component App Test 2 of 3: ensure an installed component app can be launched
985 // on a subsequent browser start, without requiring any install/upgrade logic
986 // to be run, then perform setup for step 3.
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,PRE_ComponentAppBackgroundPage)987 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,
988                        PRE_ComponentAppBackgroundPage) {
989 
990   // Since the component app is now installed, re-adding it in the same profile
991   // should not cause it to be re-installed. Instead, we wait for the OnLaunched
992   // in a different observer (which would timeout if not the app was not
993   // previously installed properly) and then check this observer to make sure it
994   // never saw the NOTIFICATION_EXTENSION_INSTALLED_DEPRECATED event.
995   CheckExtensionInstalledObserver should_not_install;
996   const Extension* extension = LoadExtensionAsComponent(
997       test_data_dir_.AppendASCII("platform_apps").AppendASCII("component"));
998   ASSERT_TRUE(extension);
999 
1000   ExtensionTestMessageListener launched_listener("Launched", false);
1001   OpenApplication(AppLaunchParams(
1002       browser()->profile(), extension, LAUNCH_CONTAINER_NONE, NEW_WINDOW));
1003 
1004   ASSERT_TRUE(launched_listener.WaitUntilSatisfied());
1005   ASSERT_FALSE(should_not_install.seen());
1006 
1007   // Simulate a "downgrade" from version 2 in the test manifest.json to 1.
1008   ExtensionPrefs* extension_prefs = ExtensionPrefs::Get(browser()->profile());
1009 
1010   // Clear the registered events to ensure they are updated.
1011   extensions::EventRouter::Get(browser()->profile())
1012       ->SetRegisteredEvents(extension->id(), std::set<std::string>());
1013 
1014   DictionaryPrefUpdate update(extension_prefs->pref_service(),
1015                               extensions::pref_names::kExtensions);
1016   base::DictionaryValue* dict = update.Get();
1017   std::string key(extension->id());
1018   key += ".manifest.version";
1019   dict->SetString(key, "1");
1020 }
1021 
1022 // Component App Test 3 of 3: simulate a component extension upgrade that
1023 // re-adds the OnLaunched event, and allows the app to be launched.
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,ComponentAppBackgroundPage)1024 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, ComponentAppBackgroundPage) {
1025   CheckExtensionInstalledObserver should_install;
1026   // Since we are forcing an upgrade, we need to wait for the load again.
1027   content::WindowedNotificationObserver app_loaded_observer(
1028       content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME,
1029       content::NotificationService::AllSources());
1030 
1031   const Extension* extension = LoadExtensionAsComponent(
1032       test_data_dir_.AppendASCII("platform_apps").AppendASCII("component"));
1033   ASSERT_TRUE(extension);
1034   app_loaded_observer.Wait();
1035   ASSERT_TRUE(should_install.seen());
1036 
1037   ExtensionTestMessageListener launched_listener("Launched", false);
1038   OpenApplication(AppLaunchParams(
1039       browser()->profile(), extension, LAUNCH_CONTAINER_NONE, NEW_WINDOW));
1040 
1041   ASSERT_TRUE(launched_listener.WaitUntilSatisfied());
1042 }
1043 
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,Messaging)1044 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, Messaging) {
1045   ExtensionApiTest::ResultCatcher result_catcher;
1046   LoadAndLaunchPlatformApp("messaging/app2", "Launched");
1047   LoadAndLaunchPlatformApp("messaging/app1", "Launched");
1048   EXPECT_TRUE(result_catcher.GetNextResult());
1049 }
1050 
1051 // TODO(linux_aura) http://crbug.com/163931
1052 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA)
1053 #define MAYBE_WebContentsHasFocus DISABLED_WebContentsHasFocus
1054 #else
1055 // This test depends on focus and so needs to be in interactive_ui_tests.
1056 // http://crbug.com/227041
1057 #define MAYBE_WebContentsHasFocus DISABLED_WebContentsHasFocus
1058 #endif
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,MAYBE_WebContentsHasFocus)1059 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, MAYBE_WebContentsHasFocus) {
1060   LoadAndLaunchPlatformApp("minimal", "Launched");
1061 
1062   EXPECT_EQ(1LU, GetAppWindowCount());
1063   EXPECT_TRUE(GetFirstAppWindow()
1064                   ->web_contents()
1065                   ->GetRenderWidgetHostView()
1066                   ->HasFocus());
1067 }
1068 
1069 #if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_MACOSX)
1070 #define MAYBE_WindowDotPrintShouldBringUpPrintPreview \
1071     DISABLED_WindowDotPrintShouldBringUpPrintPreview
1072 #else
1073 #define MAYBE_WindowDotPrintShouldBringUpPrintPreview \
1074     WindowDotPrintShouldBringUpPrintPreview
1075 #endif
1076 
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,MAYBE_WindowDotPrintShouldBringUpPrintPreview)1077 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,
1078                        MAYBE_WindowDotPrintShouldBringUpPrintPreview) {
1079   ScopedPreviewTestingDelegate preview_delegate(true);
1080   ASSERT_TRUE(RunPlatformAppTest("platform_apps/print_api")) << message_;
1081   preview_delegate.WaitUntilPreviewIsReady();
1082 }
1083 
1084 // This test verifies that http://crbug.com/297179 is fixed.
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,DISABLED_ClosingWindowWhilePrintingShouldNotCrash)1085 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,
1086                        DISABLED_ClosingWindowWhilePrintingShouldNotCrash) {
1087   ScopedPreviewTestingDelegate preview_delegate(false);
1088   ASSERT_TRUE(RunPlatformAppTest("platform_apps/print_api")) << message_;
1089   preview_delegate.WaitUntilPreviewIsReady();
1090   GetFirstAppWindow()->GetBaseWindow()->Close();
1091 }
1092 
1093 // This test currently only passes on OS X (on other platforms the print preview
1094 // dialog's size is limited by the size of the window being printed).
1095 #if !defined(OS_MACOSX)
1096 #define MAYBE_PrintPreviewShouldNotBeTooSmall \
1097     DISABLED_PrintPreviewShouldNotBeTooSmall
1098 #else
1099 #define MAYBE_PrintPreviewShouldNotBeTooSmall \
1100     PrintPreviewShouldNotBeTooSmall
1101 #endif
1102 
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,MAYBE_PrintPreviewShouldNotBeTooSmall)1103 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,
1104                        MAYBE_PrintPreviewShouldNotBeTooSmall) {
1105   // Print preview dialogs with widths less than 410 pixels will have preview
1106   // areas that are too small, and ones with heights less than 191 pixels will
1107   // have vertical scrollers for their controls that are too small.
1108   gfx::Size minimum_dialog_size(410, 191);
1109   ScopedPreviewTestingDelegate preview_delegate(false);
1110   ASSERT_TRUE(RunPlatformAppTest("platform_apps/print_api")) << message_;
1111   preview_delegate.WaitUntilPreviewIsReady();
1112   EXPECT_GE(preview_delegate.dialog_size().width(),
1113             minimum_dialog_size.width());
1114   EXPECT_GE(preview_delegate.dialog_size().height(),
1115             minimum_dialog_size.height());
1116   GetFirstAppWindow()->GetBaseWindow()->Close();
1117 }
1118 
1119 
1120 #if defined(OS_CHROMEOS)
1121 
1122 class PlatformAppIncognitoBrowserTest : public PlatformAppBrowserTest,
1123                                         public AppWindowRegistry::Observer {
1124  public:
SetUpCommandLine(CommandLine * command_line)1125   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
1126     // Tell chromeos to launch in Guest mode, aka incognito.
1127     command_line->AppendSwitch(switches::kIncognito);
1128     PlatformAppBrowserTest::SetUpCommandLine(command_line);
1129   }
SetUp()1130   virtual void SetUp() OVERRIDE {
1131     // Make sure the file manager actually gets loaded.
1132     ComponentLoader::EnableBackgroundExtensionsForTesting();
1133     PlatformAppBrowserTest::SetUp();
1134   }
1135 
1136   // AppWindowRegistry::Observer implementation.
OnAppWindowAdded(AppWindow * app_window)1137   virtual void OnAppWindowAdded(AppWindow* app_window) OVERRIDE {
1138     opener_app_ids_.insert(app_window->extension_id());
1139   }
1140 
1141  protected:
1142   // A set of ids of apps we've seen open a app window.
1143   std::set<std::string> opener_app_ids_;
1144 };
1145 
IN_PROC_BROWSER_TEST_F(PlatformAppIncognitoBrowserTest,IncognitoComponentApp)1146 IN_PROC_BROWSER_TEST_F(PlatformAppIncognitoBrowserTest, IncognitoComponentApp) {
1147   // Get the file manager app.
1148   const Extension* file_manager = extension_service()->GetExtensionById(
1149       "hhaomjibdihmijegdhdafkllkbggdgoj", false);
1150   ASSERT_TRUE(file_manager != NULL);
1151   Profile* incognito_profile = profile()->GetOffTheRecordProfile();
1152   ASSERT_TRUE(incognito_profile != NULL);
1153 
1154   // Wait until the file manager has had a chance to register its listener
1155   // for the launch event.
1156   EventRouter* router = EventRouter::Get(incognito_profile);
1157   ASSERT_TRUE(router != NULL);
1158   while (!router->ExtensionHasEventListener(
1159       file_manager->id(), app_runtime::OnLaunched::kEventName)) {
1160     content::RunAllPendingInMessageLoop();
1161   }
1162 
1163   // Listen for new app windows so we see the file manager app launch itself.
1164   AppWindowRegistry* registry = AppWindowRegistry::Get(incognito_profile);
1165   ASSERT_TRUE(registry != NULL);
1166   registry->AddObserver(this);
1167 
1168   OpenApplication(AppLaunchParams(
1169       incognito_profile, file_manager, 0, chrome::HOST_DESKTOP_TYPE_NATIVE));
1170 
1171   while (!ContainsKey(opener_app_ids_, file_manager->id())) {
1172     content::RunAllPendingInMessageLoop();
1173   }
1174 }
1175 
1176 class RestartDeviceTest : public PlatformAppBrowserTest {
1177  public:
RestartDeviceTest()1178   RestartDeviceTest()
1179       : power_manager_client_(NULL),
1180         mock_user_manager_(NULL) {}
~RestartDeviceTest()1181   virtual ~RestartDeviceTest() {}
1182 
1183   // PlatformAppBrowserTest overrides
SetUpInProcessBrowserTestFixture()1184   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
1185     PlatformAppBrowserTest::SetUpInProcessBrowserTestFixture();
1186 
1187     chromeos::FakeDBusThreadManager* dbus_manager =
1188         new chromeos::FakeDBusThreadManager;
1189     dbus_manager->SetFakeClients();
1190     power_manager_client_ = new chromeos::FakePowerManagerClient;
1191     dbus_manager->SetPowerManagerClient(
1192         scoped_ptr<chromeos::PowerManagerClient>(power_manager_client_));
1193     chromeos::DBusThreadManager::SetInstanceForTesting(dbus_manager);
1194   }
1195 
SetUpOnMainThread()1196   virtual void SetUpOnMainThread() OVERRIDE {
1197     PlatformAppBrowserTest::SetUpOnMainThread();
1198 
1199     mock_user_manager_ = new chromeos::MockUserManager;
1200     user_manager_enabler_.reset(
1201         new chromeos::ScopedUserManagerEnabler(mock_user_manager_));
1202 
1203     EXPECT_CALL(*mock_user_manager_, IsUserLoggedIn())
1204         .WillRepeatedly(testing::Return(true));
1205     EXPECT_CALL(*mock_user_manager_, IsLoggedInAsKioskApp())
1206         .WillRepeatedly(testing::Return(true));
1207   }
1208 
CleanUpOnMainThread()1209   virtual void CleanUpOnMainThread() OVERRIDE {
1210     user_manager_enabler_.reset();
1211     PlatformAppBrowserTest::CleanUpOnMainThread();
1212   }
1213 
TearDownInProcessBrowserTestFixture()1214   virtual void TearDownInProcessBrowserTestFixture() OVERRIDE {
1215     PlatformAppBrowserTest::TearDownInProcessBrowserTestFixture();
1216   }
1217 
num_request_restart_calls() const1218   int num_request_restart_calls() const {
1219     return power_manager_client_->num_request_restart_calls();
1220   }
1221 
1222  private:
1223   chromeos::FakePowerManagerClient* power_manager_client_;
1224   chromeos::MockUserManager* mock_user_manager_;
1225   scoped_ptr<chromeos::ScopedUserManagerEnabler> user_manager_enabler_;
1226 
1227   DISALLOW_COPY_AND_ASSIGN(RestartDeviceTest);
1228 };
1229 
1230 // Tests that chrome.runtime.restart would request device restart in
1231 // ChromeOS kiosk mode.
IN_PROC_BROWSER_TEST_F(RestartDeviceTest,Restart)1232 IN_PROC_BROWSER_TEST_F(RestartDeviceTest, Restart) {
1233   ASSERT_EQ(0, num_request_restart_calls());
1234 
1235   ExtensionTestMessageListener launched_listener("Launched", true);
1236   const Extension* extension = LoadAndLaunchPlatformApp("restart_device",
1237                                                         &launched_listener);
1238   ASSERT_TRUE(extension);
1239 
1240   launched_listener.Reply("restart");
1241   ExtensionTestMessageListener restart_requested_listener("restartRequested",
1242                                                           false);
1243   ASSERT_TRUE(restart_requested_listener.WaitUntilSatisfied());
1244 
1245   EXPECT_EQ(1, num_request_restart_calls());
1246 }
1247 
1248 #endif  // defined(OS_CHROMEOS)
1249 
1250 // Test that when an application is uninstalled and re-install it does not have
1251 // access to the previously set data.
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,ReinstallDataCleanup)1252 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, ReinstallDataCleanup) {
1253   // The application is installed and launched. After the 'Launched' message is
1254   // acknowledged by the browser process, the application will test that some
1255   // data are not installed and then install them. The application will then be
1256   // uninstalled and the same process will be repeated.
1257   std::string extension_id;
1258 
1259   {
1260     const Extension* extension =
1261         LoadAndLaunchPlatformApp("reinstall_data_cleanup", "Launched");
1262     ASSERT_TRUE(extension);
1263     extension_id = extension->id();
1264 
1265     ExtensionApiTest::ResultCatcher result_catcher;
1266     EXPECT_TRUE(result_catcher.GetNextResult());
1267   }
1268 
1269   UninstallExtension(extension_id);
1270   content::RunAllPendingInMessageLoop();
1271 
1272   {
1273     const Extension* extension =
1274         LoadAndLaunchPlatformApp("reinstall_data_cleanup", "Launched");
1275     ASSERT_TRUE(extension);
1276     ASSERT_EQ(extension_id, extension->id());
1277 
1278     ExtensionApiTest::ResultCatcher result_catcher;
1279     EXPECT_TRUE(result_catcher.GetNextResult());
1280   }
1281 }
1282 
1283 }  // namespace extensions
1284