OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // This file tests whichever implementation of NativeAppWindow is used. | 5 // This file tests whichever implementation of NativeAppWindow is used. |
6 // I.e. it could be NativeAppWindowCocoa or ChromeNativeAppWindowViewsMac. | 6 // I.e. it could be NativeAppWindowCocoa or ChromeNativeAppWindowViewsMac. |
7 #include "extensions/browser/app_window/native_app_window.h" | 7 #include "extensions/browser/app_window/native_app_window.h" |
8 | 8 |
9 #import <Cocoa/Cocoa.h> | 9 #import <Cocoa/Cocoa.h> |
10 | 10 |
11 #include "base/mac/mac_util.h" | 11 #include "base/mac/mac_util.h" |
12 #include "base/mac/scoped_nsobject.h" | 12 #include "base/mac/scoped_nsobject.h" |
13 #include "base/mac/sdk_forward_declarations.h" | 13 #include "base/mac/sdk_forward_declarations.h" |
14 #include "chrome/browser/apps/app_browsertest_util.h" | 14 #include "chrome/browser/apps/app_browsertest_util.h" |
15 #include "chrome/browser/profiles/profile.h" | 15 #include "chrome/browser/profiles/profile.h" |
16 #include "chrome/browser/ui/extensions/app_launch_params.h" | 16 #include "chrome/browser/ui/extensions/app_launch_params.h" |
17 #include "chrome/browser/ui/extensions/application_launch.h" | 17 #include "chrome/browser/ui/extensions/application_launch.h" |
18 #include "content/public/browser/notification_service.h" | 18 #include "content/public/browser/notification_service.h" |
19 #include "content/public/test/test_utils.h" | 19 #include "content/public/test/test_utils.h" |
20 #include "extensions/browser/app_window/app_window_registry.h" | 20 #include "extensions/browser/app_window/app_window_registry.h" |
21 #include "extensions/common/constants.h" | 21 #include "extensions/common/constants.h" |
| 22 #import "ui/base/test/nswindow_fullscreen_notification_waiter.h" |
22 | 23 |
| 24 using extensions::AppWindow; |
23 using extensions::PlatformAppBrowserTest; | 25 using extensions::PlatformAppBrowserTest; |
24 | 26 |
25 namespace { | 27 namespace { |
26 | 28 |
27 class NativeAppWindowCocoaBrowserTest : public PlatformAppBrowserTest { | 29 class NativeAppWindowCocoaBrowserTest : public PlatformAppBrowserTest { |
28 protected: | 30 protected: |
29 NativeAppWindowCocoaBrowserTest() {} | 31 NativeAppWindowCocoaBrowserTest() {} |
30 | 32 |
31 void SetUpAppWithWindows(int num_windows) { | 33 void SetUpAppWithWindows(int num_windows) { |
32 app_ = InstallExtension( | 34 app_ = InstallExtension( |
(...skipping 18 matching lines...) Expand all Loading... |
51 }; | 53 }; |
52 | 54 |
53 } // namespace | 55 } // namespace |
54 | 56 |
55 // Test interaction of Hide/Show() with Hide/ShowWithApp(). | 57 // Test interaction of Hide/Show() with Hide/ShowWithApp(). |
56 IN_PROC_BROWSER_TEST_F(NativeAppWindowCocoaBrowserTest, HideShowWithApp) { | 58 IN_PROC_BROWSER_TEST_F(NativeAppWindowCocoaBrowserTest, HideShowWithApp) { |
57 SetUpAppWithWindows(2); | 59 SetUpAppWithWindows(2); |
58 extensions::AppWindowRegistry::AppWindowList windows = | 60 extensions::AppWindowRegistry::AppWindowList windows = |
59 extensions::AppWindowRegistry::Get(profile())->app_windows(); | 61 extensions::AppWindowRegistry::Get(profile())->app_windows(); |
60 | 62 |
61 extensions::AppWindow* app_window = windows.front(); | 63 AppWindow* app_window = windows.front(); |
62 extensions::NativeAppWindow* native_window = app_window->GetBaseWindow(); | 64 extensions::NativeAppWindow* native_window = app_window->GetBaseWindow(); |
63 NSWindow* ns_window = native_window->GetNativeWindow(); | 65 NSWindow* ns_window = native_window->GetNativeWindow(); |
64 | 66 |
65 extensions::AppWindow* other_app_window = windows.back(); | 67 AppWindow* other_app_window = windows.back(); |
66 extensions::NativeAppWindow* other_native_window = | 68 extensions::NativeAppWindow* other_native_window = |
67 other_app_window->GetBaseWindow(); | 69 other_app_window->GetBaseWindow(); |
68 NSWindow* other_ns_window = other_native_window->GetNativeWindow(); | 70 NSWindow* other_ns_window = other_native_window->GetNativeWindow(); |
69 | 71 |
70 // Normal Hide/Show. | 72 // Normal Hide/Show. |
71 app_window->Hide(); | 73 app_window->Hide(); |
72 EXPECT_FALSE([ns_window isVisible]); | 74 EXPECT_FALSE([ns_window isVisible]); |
73 app_window->Show(extensions::AppWindow::SHOW_ACTIVE); | 75 app_window->Show(AppWindow::SHOW_ACTIVE); |
74 EXPECT_TRUE([ns_window isVisible]); | 76 EXPECT_TRUE([ns_window isVisible]); |
75 | 77 |
76 // Normal Hide/ShowWithApp. | 78 // Normal Hide/ShowWithApp. |
77 native_window->HideWithApp(); | 79 native_window->HideWithApp(); |
78 EXPECT_FALSE([ns_window isVisible]); | 80 EXPECT_FALSE([ns_window isVisible]); |
79 native_window->ShowWithApp(); | 81 native_window->ShowWithApp(); |
80 EXPECT_TRUE([ns_window isVisible]); | 82 EXPECT_TRUE([ns_window isVisible]); |
81 | 83 |
82 // HideWithApp, Hide, ShowWithApp does not show. | 84 // HideWithApp, Hide, ShowWithApp does not show. |
83 native_window->HideWithApp(); | 85 native_window->HideWithApp(); |
84 app_window->Hide(); | 86 app_window->Hide(); |
85 native_window->ShowWithApp(); | 87 native_window->ShowWithApp(); |
86 EXPECT_FALSE([ns_window isVisible]); | 88 EXPECT_FALSE([ns_window isVisible]); |
87 | 89 |
88 // Hide, HideWithApp, ShowWithApp does not show. | 90 // Hide, HideWithApp, ShowWithApp does not show. |
89 native_window->HideWithApp(); | 91 native_window->HideWithApp(); |
90 native_window->ShowWithApp(); | 92 native_window->ShowWithApp(); |
91 EXPECT_FALSE([ns_window isVisible]); | 93 EXPECT_FALSE([ns_window isVisible]); |
92 | 94 |
93 // Return to shown state. | 95 // Return to shown state. |
94 app_window->Show(extensions::AppWindow::SHOW_ACTIVE); | 96 app_window->Show(AppWindow::SHOW_ACTIVE); |
95 EXPECT_TRUE([ns_window isVisible]); | 97 EXPECT_TRUE([ns_window isVisible]); |
96 | 98 |
97 // HideWithApp the other window. | 99 // HideWithApp the other window. |
98 EXPECT_TRUE([other_ns_window isVisible]); | 100 EXPECT_TRUE([other_ns_window isVisible]); |
99 other_native_window->HideWithApp(); | 101 other_native_window->HideWithApp(); |
100 EXPECT_FALSE([other_ns_window isVisible]); | 102 EXPECT_FALSE([other_ns_window isVisible]); |
101 | 103 |
102 // HideWithApp, Show shows all windows for this app. | 104 // HideWithApp, Show shows all windows for this app. |
103 native_window->HideWithApp(); | 105 native_window->HideWithApp(); |
104 EXPECT_FALSE([ns_window isVisible]); | 106 EXPECT_FALSE([ns_window isVisible]); |
105 app_window->Show(extensions::AppWindow::SHOW_ACTIVE); | 107 app_window->Show(AppWindow::SHOW_ACTIVE); |
106 EXPECT_TRUE([ns_window isVisible]); | 108 EXPECT_TRUE([ns_window isVisible]); |
107 EXPECT_TRUE([other_ns_window isVisible]); | 109 EXPECT_TRUE([other_ns_window isVisible]); |
108 | 110 |
109 // Hide the other window. | 111 // Hide the other window. |
110 other_app_window->Hide(); | 112 other_app_window->Hide(); |
111 EXPECT_FALSE([other_ns_window isVisible]); | 113 EXPECT_FALSE([other_ns_window isVisible]); |
112 | 114 |
113 // HideWithApp, ShowWithApp does not show the other window. | 115 // HideWithApp, ShowWithApp does not show the other window. |
114 native_window->HideWithApp(); | 116 native_window->HideWithApp(); |
115 EXPECT_FALSE([ns_window isVisible]); | 117 EXPECT_FALSE([ns_window isVisible]); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
154 | 156 |
155 @end | 157 @end |
156 | 158 |
157 // Test that NativeAppWindow and AppWindow fullscreen state is updated when | 159 // Test that NativeAppWindow and AppWindow fullscreen state is updated when |
158 // the window is fullscreened natively. | 160 // the window is fullscreened natively. |
159 IN_PROC_BROWSER_TEST_F(NativeAppWindowCocoaBrowserTest, Fullscreen) { | 161 IN_PROC_BROWSER_TEST_F(NativeAppWindowCocoaBrowserTest, Fullscreen) { |
160 if (!base::mac::IsOSLionOrLater()) | 162 if (!base::mac::IsOSLionOrLater()) |
161 return; | 163 return; |
162 | 164 |
163 SetUpAppWithWindows(1); | 165 SetUpAppWithWindows(1); |
164 extensions::AppWindow* app_window = GetFirstAppWindow(); | 166 AppWindow* app_window = GetFirstAppWindow(); |
165 extensions::NativeAppWindow* window = app_window->GetBaseWindow(); | 167 extensions::NativeAppWindow* window = app_window->GetBaseWindow(); |
166 NSWindow* ns_window = app_window->GetNativeWindow(); | 168 NSWindow* ns_window = app_window->GetNativeWindow(); |
167 base::scoped_nsobject<ScopedNotificationWatcher> watcher; | 169 base::scoped_nsobject<ScopedNotificationWatcher> watcher; |
168 | 170 |
169 EXPECT_EQ(extensions::AppWindow::FULLSCREEN_TYPE_NONE, | 171 EXPECT_EQ(AppWindow::FULLSCREEN_TYPE_NONE, |
170 app_window->fullscreen_types_for_test()); | 172 app_window->fullscreen_types_for_test()); |
171 EXPECT_FALSE(window->IsFullscreen()); | 173 EXPECT_FALSE(window->IsFullscreen()); |
172 EXPECT_FALSE([ns_window styleMask] & NSFullScreenWindowMask); | 174 EXPECT_FALSE([ns_window styleMask] & NSFullScreenWindowMask); |
173 | 175 |
174 watcher.reset([[ScopedNotificationWatcher alloc] | 176 watcher.reset([[ScopedNotificationWatcher alloc] |
175 initWithNotification:NSWindowDidEnterFullScreenNotification | 177 initWithNotification:NSWindowDidEnterFullScreenNotification |
176 andObject:ns_window]); | 178 andObject:ns_window]); |
177 [ns_window toggleFullScreen:nil]; | 179 [ns_window toggleFullScreen:nil]; |
178 [watcher waitForNotification]; | 180 [watcher waitForNotification]; |
179 EXPECT_TRUE(app_window->fullscreen_types_for_test() & | 181 EXPECT_TRUE(app_window->fullscreen_types_for_test() & |
180 extensions::AppWindow::FULLSCREEN_TYPE_OS); | 182 AppWindow::FULLSCREEN_TYPE_OS); |
181 EXPECT_TRUE(window->IsFullscreen()); | 183 EXPECT_TRUE(window->IsFullscreen()); |
182 EXPECT_TRUE([ns_window styleMask] & NSFullScreenWindowMask); | 184 EXPECT_TRUE([ns_window styleMask] & NSFullScreenWindowMask); |
183 | 185 |
184 watcher.reset([[ScopedNotificationWatcher alloc] | 186 watcher.reset([[ScopedNotificationWatcher alloc] |
185 initWithNotification:NSWindowDidExitFullScreenNotification | 187 initWithNotification:NSWindowDidExitFullScreenNotification |
186 andObject:ns_window]); | 188 andObject:ns_window]); |
187 app_window->Restore(); | 189 app_window->Restore(); |
188 EXPECT_FALSE(window->IsFullscreenOrPending()); | 190 EXPECT_FALSE(window->IsFullscreenOrPending()); |
189 [watcher waitForNotification]; | 191 [watcher waitForNotification]; |
190 EXPECT_EQ(extensions::AppWindow::FULLSCREEN_TYPE_NONE, | 192 EXPECT_EQ(AppWindow::FULLSCREEN_TYPE_NONE, |
191 app_window->fullscreen_types_for_test()); | 193 app_window->fullscreen_types_for_test()); |
192 EXPECT_FALSE(window->IsFullscreen()); | 194 EXPECT_FALSE(window->IsFullscreen()); |
193 EXPECT_FALSE([ns_window styleMask] & NSFullScreenWindowMask); | 195 EXPECT_FALSE([ns_window styleMask] & NSFullScreenWindowMask); |
194 | 196 |
195 watcher.reset([[ScopedNotificationWatcher alloc] | 197 watcher.reset([[ScopedNotificationWatcher alloc] |
196 initWithNotification:NSWindowDidEnterFullScreenNotification | 198 initWithNotification:NSWindowDidEnterFullScreenNotification |
197 andObject:ns_window]); | 199 andObject:ns_window]); |
198 app_window->Fullscreen(); | 200 app_window->Fullscreen(); |
199 EXPECT_TRUE(window->IsFullscreenOrPending()); | 201 EXPECT_TRUE(window->IsFullscreenOrPending()); |
200 [watcher waitForNotification]; | 202 [watcher waitForNotification]; |
201 EXPECT_TRUE(app_window->fullscreen_types_for_test() & | 203 EXPECT_TRUE(app_window->fullscreen_types_for_test() & |
202 extensions::AppWindow::FULLSCREEN_TYPE_WINDOW_API); | 204 AppWindow::FULLSCREEN_TYPE_WINDOW_API); |
203 EXPECT_TRUE(window->IsFullscreen()); | 205 EXPECT_TRUE(window->IsFullscreen()); |
204 EXPECT_TRUE([ns_window styleMask] & NSFullScreenWindowMask); | 206 EXPECT_TRUE([ns_window styleMask] & NSFullScreenWindowMask); |
205 | 207 |
206 watcher.reset([[ScopedNotificationWatcher alloc] | 208 watcher.reset([[ScopedNotificationWatcher alloc] |
207 initWithNotification:NSWindowDidExitFullScreenNotification | 209 initWithNotification:NSWindowDidExitFullScreenNotification |
208 andObject:ns_window]); | 210 andObject:ns_window]); |
209 [ns_window toggleFullScreen:nil]; | 211 [ns_window toggleFullScreen:nil]; |
210 [watcher waitForNotification]; | 212 [watcher waitForNotification]; |
211 EXPECT_EQ(extensions::AppWindow::FULLSCREEN_TYPE_NONE, | 213 EXPECT_EQ(AppWindow::FULLSCREEN_TYPE_NONE, |
212 app_window->fullscreen_types_for_test()); | 214 app_window->fullscreen_types_for_test()); |
213 EXPECT_FALSE(window->IsFullscreen()); | 215 EXPECT_FALSE(window->IsFullscreen()); |
214 EXPECT_FALSE([ns_window styleMask] & NSFullScreenWindowMask); | 216 EXPECT_FALSE([ns_window styleMask] & NSFullScreenWindowMask); |
215 } | 217 } |
216 | 218 |
217 // Test that, in frameless windows, the web contents has the same size as the | 219 // Test that, in frameless windows, the web contents has the same size as the |
218 // window. | 220 // window. |
219 IN_PROC_BROWSER_TEST_F(NativeAppWindowCocoaBrowserTest, Frameless) { | 221 IN_PROC_BROWSER_TEST_F(NativeAppWindowCocoaBrowserTest, Frameless) { |
220 extensions::AppWindow* app_window = | 222 AppWindow* app_window = CreateTestAppWindow("{\"frame\": \"none\"}"); |
221 CreateTestAppWindow("{\"frame\": \"none\"}"); | |
222 NSWindow* ns_window = app_window->GetNativeWindow(); | 223 NSWindow* ns_window = app_window->GetNativeWindow(); |
223 NSView* web_contents = app_window->web_contents()->GetNativeView(); | 224 NSView* web_contents = app_window->web_contents()->GetNativeView(); |
224 EXPECT_TRUE(NSEqualSizes(NSMakeSize(512, 384), [web_contents frame].size)); | 225 EXPECT_TRUE(NSEqualSizes(NSMakeSize(512, 384), [web_contents frame].size)); |
225 // Move and resize the window. | 226 // Move and resize the window. |
226 NSRect new_frame = NSMakeRect(50, 50, 200, 200); | 227 NSRect new_frame = NSMakeRect(50, 50, 200, 200); |
227 [ns_window setFrame:new_frame display:YES]; | 228 [ns_window setFrame:new_frame display:YES]; |
228 EXPECT_TRUE(NSEqualSizes(new_frame.size, [web_contents frame].size)); | 229 EXPECT_TRUE(NSEqualSizes(new_frame.size, [web_contents frame].size)); |
229 | 230 |
230 // Windows created with NSBorderlessWindowMask by default don't have shadow, | 231 // Windows created with NSBorderlessWindowMask by default don't have shadow, |
231 // but packaged apps should always have one. | 232 // but packaged apps should always have one. |
232 EXPECT_TRUE([ns_window hasShadow]); | 233 EXPECT_TRUE([ns_window hasShadow]); |
233 | 234 |
234 // Since the window has no constraints, it should have all of the following | 235 // Since the window has no constraints, it should have all of the following |
235 // style mask bits. | 236 // style mask bits. |
236 NSUInteger style_mask = NSTitledWindowMask | NSClosableWindowMask | | 237 NSUInteger style_mask = NSTitledWindowMask | NSClosableWindowMask | |
237 NSMiniaturizableWindowMask | NSResizableWindowMask | | 238 NSMiniaturizableWindowMask | NSResizableWindowMask | |
238 NSTexturedBackgroundWindowMask; | 239 NSTexturedBackgroundWindowMask; |
239 EXPECT_EQ(style_mask, [ns_window styleMask]); | 240 EXPECT_EQ(style_mask, [ns_window styleMask]); |
240 | 241 |
241 CloseAppWindow(app_window); | 242 CloseAppWindow(app_window); |
242 } | 243 } |
243 | 244 |
244 namespace { | 245 namespace { |
245 | 246 |
246 // Test that resize and fullscreen controls are correctly enabled/disabled. | 247 // Test that resize and fullscreen controls are correctly enabled/disabled. |
247 void TestControls(extensions::AppWindow* app_window) { | 248 void TestControls(AppWindow* app_window) { |
248 NSWindow* ns_window = app_window->GetNativeWindow(); | 249 NSWindow* ns_window = app_window->GetNativeWindow(); |
249 | 250 |
250 // The window is resizable. | 251 // The window is resizable. |
251 EXPECT_TRUE([ns_window styleMask] & NSResizableWindowMask); | 252 EXPECT_TRUE([ns_window styleMask] & NSResizableWindowMask); |
252 if (base::mac::IsOSSnowLeopard()) | 253 if (base::mac::IsOSSnowLeopard()) |
253 EXPECT_TRUE([ns_window showsResizeIndicator]); | 254 EXPECT_TRUE([ns_window showsResizeIndicator]); |
254 | 255 |
255 // Due to this bug: http://crbug.com/362039, which manifests on the Cocoa | 256 // Due to this bug: http://crbug.com/362039, which manifests on the Cocoa |
256 // implementation but not the views one, frameless windows should have | 257 // implementation but not the views one, frameless windows should have |
257 // fullscreen controls disabled. | 258 // fullscreen controls disabled. |
(...skipping 28 matching lines...) Expand all Loading... |
286 // Set a minimum size equal to the maximum size. | 287 // Set a minimum size equal to the maximum size. |
287 app_window->SetContentSizeConstraints(gfx::Size(200, 201), | 288 app_window->SetContentSizeConstraints(gfx::Size(200, 201), |
288 gfx::Size(200, 201)); | 289 gfx::Size(200, 201)); |
289 EXPECT_EQ(200, [ns_window contentMinSize].width); | 290 EXPECT_EQ(200, [ns_window contentMinSize].width); |
290 EXPECT_EQ(201, [ns_window contentMinSize].height); | 291 EXPECT_EQ(201, [ns_window contentMinSize].height); |
291 | 292 |
292 // No longer resizable. | 293 // No longer resizable. |
293 EXPECT_FALSE([ns_window styleMask] & NSResizableWindowMask); | 294 EXPECT_FALSE([ns_window styleMask] & NSResizableWindowMask); |
294 if (base::mac::IsOSSnowLeopard()) | 295 if (base::mac::IsOSSnowLeopard()) |
295 EXPECT_FALSE([ns_window showsResizeIndicator]); | 296 EXPECT_FALSE([ns_window showsResizeIndicator]); |
| 297 |
| 298 // If a window is made fullscreen by the API, fullscreen should be enabled so |
| 299 // the user can exit fullscreen. |
| 300 if (base::mac::IsOSLionOrLater()) { |
| 301 base::scoped_nsobject<NSWindowFullscreenNotificationWaiter> waiter([ |
| 302 [NSWindowFullscreenNotificationWaiter alloc] initWithWindow:ns_window]); |
| 303 app_window->SetFullscreen(AppWindow::FULLSCREEN_TYPE_WINDOW_API, true); |
| 304 [waiter waitForEnterCount:1 exitCount:0]; |
| 305 EXPECT_TRUE([ns_window collectionBehavior] & |
| 306 NSWindowCollectionBehaviorFullScreenPrimary); |
| 307 EXPECT_EQ(NSWidth([[ns_window contentView] frame]), |
| 308 NSWidth([ns_window frame])); |
| 309 // Once it leaves fullscreen, it is disabled again. |
| 310 app_window->SetFullscreen(AppWindow::FULLSCREEN_TYPE_WINDOW_API, false); |
| 311 [waiter waitForEnterCount:1 exitCount:1]; |
| 312 EXPECT_FALSE([ns_window collectionBehavior] & |
| 313 NSWindowCollectionBehaviorFullScreenPrimary); |
| 314 } |
296 } | 315 } |
297 | 316 |
298 } // namespace | 317 } // namespace |
299 | 318 |
300 IN_PROC_BROWSER_TEST_F(NativeAppWindowCocoaBrowserTest, Controls) { | 319 IN_PROC_BROWSER_TEST_F(NativeAppWindowCocoaBrowserTest, Controls) { |
301 TestControls(CreateTestAppWindow("{}")); | 320 TestControls(CreateTestAppWindow("{}")); |
302 } | 321 } |
303 | 322 |
304 IN_PROC_BROWSER_TEST_F(NativeAppWindowCocoaBrowserTest, ControlsFrameless) { | 323 IN_PROC_BROWSER_TEST_F(NativeAppWindowCocoaBrowserTest, ControlsFrameless) { |
305 TestControls(CreateTestAppWindow("{\"frame\": \"none\"}")); | 324 TestControls(CreateTestAppWindow("{\"frame\": \"none\"}")); |
306 } | 325 } |
OLD | NEW |