1 // Copyright (c) 2012 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/native_app_window.h" 6 #include "apps/shell_window.h" 7 #include "apps/shell_window_registry.h" 8 #include "base/run_loop.h" 9 #include "base/strings/string_number_conversions.h" 10 #include "chrome/browser/extensions/extension_test_message_listener.h" 11 #include "chrome/browser/extensions/platform_app_browsertest_util.h" 12 #include "chrome/browser/ui/browser.h" 13 #include "chrome/test/base/testing_profile.h" 14 #include "ui/base/base_window.h" 15 #include "ui/gfx/rect.h" 16 17 #ifdef TOOLKIT_GTK 18 #include "content/public/test/test_utils.h" 19 #endif 20 21 using apps::ShellWindow; 22 23 namespace { 24 25 class TestShellWindowRegistryObserver 26 : public apps::ShellWindowRegistry::Observer { 27 public: 28 explicit TestShellWindowRegistryObserver(Profile* profile) 29 : profile_(profile), 30 icon_updates_(0) { 31 apps::ShellWindowRegistry::Get(profile_)->AddObserver(this); 32 } 33 virtual ~TestShellWindowRegistryObserver() { 34 apps::ShellWindowRegistry::Get(profile_)->RemoveObserver(this); 35 } 36 37 // Overridden from ShellWindowRegistry::Observer: 38 virtual void OnShellWindowAdded(ShellWindow* shell_window) OVERRIDE {} 39 virtual void OnShellWindowIconChanged(ShellWindow* shell_window) OVERRIDE { 40 ++icon_updates_; 41 } 42 virtual void OnShellWindowRemoved(ShellWindow* shell_window) OVERRIDE { 43 } 44 45 int icon_updates() { return icon_updates_; } 46 47 private: 48 Profile* profile_; 49 int icon_updates_; 50 51 DISALLOW_COPY_AND_ASSIGN(TestShellWindowRegistryObserver); 52 }; 53 54 } // namespace 55 56 namespace extensions { 57 58 // Flaky, http://crbug.com/164735 . 59 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, DISABLED_WindowsApiBounds) { 60 ExtensionTestMessageListener background_listener("background_ok", false); 61 ExtensionTestMessageListener ready_listener("ready", true /* will_reply */); 62 ExtensionTestMessageListener success_listener("success", false); 63 64 LoadAndLaunchPlatformApp("windows_api_bounds"); 65 ASSERT_TRUE(background_listener.WaitUntilSatisfied()); 66 ASSERT_TRUE(ready_listener.WaitUntilSatisfied()); 67 ShellWindow* window = GetFirstShellWindow(); 68 69 gfx::Rect new_bounds(100, 200, 300, 400); 70 new_bounds.Inset(-window->GetBaseWindow()->GetFrameInsets()); 71 window->GetBaseWindow()->SetBounds(new_bounds); 72 73 // TODO(jeremya/asargent) figure out why in GTK the window doesn't end up 74 // with exactly the bounds we set. Is it a bug in our shell window 75 // implementation? crbug.com/160252 76 #ifdef TOOLKIT_GTK 77 int slop = 50; 78 #else 79 int slop = 0; 80 #endif // !TOOLKIT_GTK 81 82 ready_listener.Reply(base::IntToString(slop)); 83 84 #ifdef TOOLKIT_GTK 85 // TODO(asargent)- this is here to help track down the root cause of 86 // crbug.com/164735. 87 { 88 gfx::Rect last_bounds; 89 while (!success_listener.was_satisfied()) { 90 gfx::Rect current_bounds = window->GetBaseWindow()->GetBounds(); 91 if (current_bounds != last_bounds) { 92 LOG(INFO) << "new bounds: " << current_bounds.ToString(); 93 } 94 last_bounds = current_bounds; 95 content::RunAllPendingInMessageLoop(); 96 } 97 } 98 #endif 99 100 ASSERT_TRUE(success_listener.WaitUntilSatisfied()); 101 } 102 103 // Tests chrome.app.window.setIcon. 104 IN_PROC_BROWSER_TEST_F(ExperimentalPlatformAppBrowserTest, WindowsApiSetIcon) { 105 scoped_ptr<TestShellWindowRegistryObserver> test_observer( 106 new TestShellWindowRegistryObserver(browser()->profile())); 107 ExtensionTestMessageListener listener("IconSet", false); 108 LoadAndLaunchPlatformApp("windows_api_set_icon"); 109 EXPECT_EQ(0, test_observer->icon_updates()); 110 // Wait until the icon load has been requested. 111 ASSERT_TRUE(listener.WaitUntilSatisfied()); 112 // Now wait until the WebContent has decoded the icon and chrome has 113 // processed it. This needs to be in a loop since the renderer runs in a 114 // different process. 115 while (test_observer->icon_updates() < 1) { 116 base::RunLoop run_loop; 117 run_loop.RunUntilIdle(); 118 } 119 ShellWindow* shell_window = GetFirstShellWindow(); 120 ASSERT_TRUE(shell_window); 121 EXPECT_NE(std::string::npos, 122 shell_window->app_icon_url().spec().find("icon.png")); 123 EXPECT_EQ(1, test_observer->icon_updates()); 124 } 125 126 // TODO(asargent) - Figure out what to do about the fact that minimize events 127 // don't work under ubuntu unity. 128 // (crbug.com/162794 and https://bugs.launchpad.net/unity/+bug/998073). 129 // TODO(linux_aura) http://crbug.com/163931 130 // Flaky on Mac, http://crbug.com/232330 131 #if defined(TOOLKIT_VIEWS) && !(defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA)) 132 133 IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, WindowsApiProperties) { 134 EXPECT_TRUE( 135 RunExtensionTest("platform_apps/windows_api_properties")) << message_; 136 } 137 138 #endif // defined(TOOLKIT_VIEWS) 139 140 } // namespace extensions 141