Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(311)

Side by Side Diff: chrome/browser/apps/app_shim/app_shim_interactive_uitest_mac.mm

Issue 1146873002: [MacViews] Enable dragging a window by its caption/draggable areas. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Sync and rebase Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | chrome/browser/ui/views/apps/chrome_native_app_window_views_mac.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 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 #import <Cocoa/Cocoa.h> 5 #import <Cocoa/Cocoa.h>
6 #include <vector> 6 #include <vector>
7 7
8 #include "apps/app_lifetime_monitor_factory.h" 8 #include "apps/app_lifetime_monitor_factory.h"
9 #include "apps/switches.h" 9 #include "apps/switches.h"
10 #include "base/auto_reset.h" 10 #include "base/auto_reset.h"
(...skipping 17 matching lines...) Expand all
28 #include "chrome/browser/ui/browser_list.h" 28 #include "chrome/browser/ui/browser_list.h"
29 #include "chrome/browser/ui/browser_window.h" 29 #include "chrome/browser/ui/browser_window.h"
30 #include "chrome/browser/web_applications/web_app_mac.h" 30 #include "chrome/browser/web_applications/web_app_mac.h"
31 #include "chrome/common/chrome_paths.h" 31 #include "chrome/common/chrome_paths.h"
32 #include "chrome/common/chrome_switches.h" 32 #include "chrome/common/chrome_switches.h"
33 #include "chrome/common/mac/app_mode_common.h" 33 #include "chrome/common/mac/app_mode_common.h"
34 #include "content/public/test/test_utils.h" 34 #include "content/public/test/test_utils.h"
35 #include "extensions/browser/app_window/native_app_window.h" 35 #include "extensions/browser/app_window/native_app_window.h"
36 #include "extensions/browser/extension_prefs.h" 36 #include "extensions/browser/extension_prefs.h"
37 #include "extensions/test/extension_test_message_listener.h" 37 #include "extensions/test/extension_test_message_listener.h"
38 #import "ui/base/test/windowed_nsnotification_observer.h"
38 #import "ui/events/test/cocoa_test_event_utils.h" 39 #import "ui/events/test/cocoa_test_event_utils.h"
39 40
40 namespace { 41 namespace {
41 42
42 // General end-to-end test for app shims. 43 // General end-to-end test for app shims.
43 class AppShimInteractiveTest : public extensions::PlatformAppBrowserTest { 44 class AppShimInteractiveTest : public extensions::PlatformAppBrowserTest {
44 protected: 45 protected:
45 AppShimInteractiveTest() 46 AppShimInteractiveTest()
46 : auto_reset_(&g_app_shims_allow_update_and_launch_in_tests, true) {} 47 : auto_reset_(&g_app_shims_allow_update_and_launch_in_tests, true) {}
47 48
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 const extensions::Extension* extension = 295 const extensions::Extension* extension =
295 apps::ExtensionAppShimHandler::MaybeGetAppForBrowser(browser); 296 apps::ExtensionAppShimHandler::MaybeGetAppForBrowser(browser);
296 if (extension && extension->is_hosted_app()) 297 if (extension && extension->is_hosted_app())
297 return browser; 298 return browser;
298 } 299 }
299 return nullptr; 300 return nullptr;
300 } 301 }
301 302
302 } // namespace 303 } // namespace
303 304
304 // Watches for NSNotifications from the shared workspace.
305 @interface WindowedNSNotificationObserver : NSObject {
306 @private
307 base::scoped_nsobject<NSString> bundleId_;
308 BOOL notificationReceived_;
309 scoped_ptr<base::RunLoop> runLoop_;
310 }
311
312 - (id)initForNotification:(NSString*)name
313 andBundleId:(NSString*)bundleId;
314 - (void)observe:(NSNotification*)notification;
315 - (void)wait;
316 @end
317
318 @implementation WindowedNSNotificationObserver
319
320 - (id)initForNotification:(NSString*)name
321 andBundleId:(NSString*)bundleId {
322 if (self = [super init]) {
323 bundleId_.reset([[bundleId copy] retain]);
324 [[[NSWorkspace sharedWorkspace] notificationCenter]
325 addObserver:self
326 selector:@selector(observe:)
327 name:name
328 object:nil];
329 }
330 return self;
331 }
332
333 - (void)observe:(NSNotification*)notification {
334 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
335
336 NSRunningApplication* application =
337 [[notification userInfo] objectForKey:NSWorkspaceApplicationKey];
338 if (![[application bundleIdentifier] isEqualToString:bundleId_])
339 return;
340
341 [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self];
342 notificationReceived_ = YES;
343 if (runLoop_.get())
344 runLoop_->Quit();
345 }
346
347 - (void)wait {
348 if (notificationReceived_)
349 return;
350
351 runLoop_.reset(new base::RunLoop);
352 runLoop_->Run();
353 }
354
355 @end
356
357 namespace apps { 305 namespace apps {
358 306
359 // Shims require static libraries http://crbug.com/386024. 307 // Shims require static libraries http://crbug.com/386024.
360 #if defined(COMPONENT_BUILD) 308 #if defined(COMPONENT_BUILD)
361 #define MAYBE_Launch DISABLED_Launch 309 #define MAYBE_Launch DISABLED_Launch
362 #define MAYBE_HostedAppLaunch DISABLED_HostedAppLaunch 310 #define MAYBE_HostedAppLaunch DISABLED_HostedAppLaunch
363 #define MAYBE_ShowWindow DISABLED_ShowWindow 311 #define MAYBE_ShowWindow DISABLED_ShowWindow
364 #define MAYBE_RebuildShim DISABLED_RebuildShim 312 #define MAYBE_RebuildShim DISABLED_RebuildShim
365 #else 313 #else
366 #define MAYBE_Launch Launch 314 #define MAYBE_Launch Launch
(...skipping 13 matching lines...) Expand all
380 NSString* bundle_id = GetBundleID(shim_path); 328 NSString* bundle_id = GetBundleID(shim_path);
381 329
382 // Explicitly set the launch type to open in a new window. 330 // Explicitly set the launch type to open in a new window.
383 extensions::SetLaunchType(profile(), app->id(), 331 extensions::SetLaunchType(profile(), app->id(),
384 extensions::LAUNCH_TYPE_WINDOW); 332 extensions::LAUNCH_TYPE_WINDOW);
385 333
386 // Case 1: Launch the hosted app, it should start the shim. 334 // Case 1: Launch the hosted app, it should start the shim.
387 { 335 {
388 base::scoped_nsobject<WindowedNSNotificationObserver> ns_observer; 336 base::scoped_nsobject<WindowedNSNotificationObserver> ns_observer;
389 ns_observer.reset([[WindowedNSNotificationObserver alloc] 337 ns_observer.reset([[WindowedNSNotificationObserver alloc]
390 initForNotification:NSWorkspaceDidLaunchApplicationNotification 338 initForWorkspaceNotification:NSWorkspaceDidLaunchApplicationNotification
391 andBundleId:bundle_id]); 339 bundleId:bundle_id]);
392 WindowedAppShimLaunchObserver observer(app->id()); 340 WindowedAppShimLaunchObserver observer(app->id());
393 LaunchHostedApp(app); 341 LaunchHostedApp(app);
394 [ns_observer wait]; 342 [ns_observer wait];
395 observer.Wait(); 343 observer.Wait();
396 344
397 EXPECT_TRUE(HasAppShimHost(profile(), app->id())); 345 EXPECT_TRUE(HasAppShimHost(profile(), app->id()));
398 EXPECT_TRUE(GetFirstHostedAppWindow()); 346 EXPECT_TRUE(GetFirstHostedAppWindow());
399 347
400 NSArray* running_shim = [NSRunningApplication 348 NSArray* running_shim = [NSRunningApplication
401 runningApplicationsWithBundleIdentifier:bundle_id]; 349 runningApplicationsWithBundleIdentifier:bundle_id];
402 ASSERT_EQ(1u, [running_shim count]); 350 ASSERT_EQ(1u, [running_shim count]);
403 351
404 ns_observer.reset([[WindowedNSNotificationObserver alloc] 352 ns_observer.reset([[WindowedNSNotificationObserver alloc]
405 initForNotification:NSWorkspaceDidTerminateApplicationNotification 353 initForWorkspaceNotification:
406 andBundleId:bundle_id]); 354 NSWorkspaceDidTerminateApplicationNotification
355 bundleId:bundle_id]);
407 [base::mac::ObjCCastStrict<NSRunningApplication>( 356 [base::mac::ObjCCastStrict<NSRunningApplication>(
408 [running_shim objectAtIndex:0]) terminate]; 357 [running_shim objectAtIndex:0]) terminate];
409 [ns_observer wait]; 358 [ns_observer wait];
410 359
411 EXPECT_FALSE(GetFirstHostedAppWindow()); 360 EXPECT_FALSE(GetFirstHostedAppWindow());
412 EXPECT_FALSE(HasAppShimHost(profile(), app->id())); 361 EXPECT_FALSE(HasAppShimHost(profile(), app->id()));
413 } 362 }
414 363
415 // Case 2: Launch the shim, it should start the hosted app. 364 // Case 2: Launch the shim, it should start the hosted app.
416 { 365 {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 EXPECT_FALSE(base::PathExists(shim_path)); 400 EXPECT_FALSE(base::PathExists(shim_path));
452 401
453 UpdateAppAndAwaitShimCreation(profile(), app, shim_path); 402 UpdateAppAndAwaitShimCreation(profile(), app, shim_path);
454 ASSERT_TRUE(base::PathExists(shim_path)); 403 ASSERT_TRUE(base::PathExists(shim_path));
455 NSString* bundle_id = GetBundleID(shim_path); 404 NSString* bundle_id = GetBundleID(shim_path);
456 405
457 // Case 1: Launch the app, it should start the shim. 406 // Case 1: Launch the app, it should start the shim.
458 { 407 {
459 base::scoped_nsobject<WindowedNSNotificationObserver> ns_observer; 408 base::scoped_nsobject<WindowedNSNotificationObserver> ns_observer;
460 ns_observer.reset([[WindowedNSNotificationObserver alloc] 409 ns_observer.reset([[WindowedNSNotificationObserver alloc]
461 initForNotification:NSWorkspaceDidLaunchApplicationNotification 410 initForWorkspaceNotification:NSWorkspaceDidLaunchApplicationNotification
462 andBundleId:bundle_id]); 411 bundleId:bundle_id]);
463 WindowedAppShimLaunchObserver observer(app->id()); 412 WindowedAppShimLaunchObserver observer(app->id());
464 LaunchPlatformApp(app); 413 LaunchPlatformApp(app);
465 [ns_observer wait]; 414 [ns_observer wait];
466 observer.Wait(); 415 observer.Wait();
467 416
468 EXPECT_TRUE(GetFirstAppWindow()); 417 EXPECT_TRUE(GetFirstAppWindow());
469 EXPECT_TRUE(HasAppShimHost(profile(), app->id())); 418 EXPECT_TRUE(HasAppShimHost(profile(), app->id()));
470 419
471 // Quitting the shim will eventually cause it to quit. It actually 420 // Quitting the shim will eventually cause it to quit. It actually
472 // intercepts the -terminate, sends an AppShimHostMsg_QuitApp to Chrome, 421 // intercepts the -terminate, sends an AppShimHostMsg_QuitApp to Chrome,
473 // and returns NSTerminateLater. Chrome responds by closing all windows of 422 // and returns NSTerminateLater. Chrome responds by closing all windows of
474 // the app. Once all windows are closed, Chrome closes the IPC channel, 423 // the app. Once all windows are closed, Chrome closes the IPC channel,
475 // which causes the shim to actually terminate. 424 // which causes the shim to actually terminate.
476 NSArray* running_shim = [NSRunningApplication 425 NSArray* running_shim = [NSRunningApplication
477 runningApplicationsWithBundleIdentifier:bundle_id]; 426 runningApplicationsWithBundleIdentifier:bundle_id];
478 ASSERT_EQ(1u, [running_shim count]); 427 ASSERT_EQ(1u, [running_shim count]);
479 428
480 ns_observer.reset([[WindowedNSNotificationObserver alloc] 429 ns_observer.reset([[WindowedNSNotificationObserver alloc]
481 initForNotification:NSWorkspaceDidTerminateApplicationNotification 430 initForWorkspaceNotification:
482 andBundleId:bundle_id]); 431 NSWorkspaceDidTerminateApplicationNotification
432 bundleId:bundle_id]);
483 [base::mac::ObjCCastStrict<NSRunningApplication>( 433 [base::mac::ObjCCastStrict<NSRunningApplication>(
484 [running_shim objectAtIndex:0]) terminate]; 434 [running_shim objectAtIndex:0]) terminate];
485 [ns_observer wait]; 435 [ns_observer wait];
486 436
487 EXPECT_FALSE(GetFirstAppWindow()); 437 EXPECT_FALSE(GetFirstAppWindow());
488 EXPECT_FALSE(HasAppShimHost(profile(), app->id())); 438 EXPECT_FALSE(HasAppShimHost(profile(), app->id()));
489 } 439 }
490 440
491 // Case 2: Launch the shim, it should start the app. 441 // Case 2: Launch the shim, it should start the app.
492 { 442 {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
539 EXPECT_TRUE(launched_listener.WaitUntilSatisfied()); 489 EXPECT_TRUE(launched_listener.WaitUntilSatisfied());
540 } 490 }
541 extensions::AppWindow* window_1 = GetFirstAppWindow(); 491 extensions::AppWindow* window_1 = GetFirstAppWindow();
542 ASSERT_TRUE(window_1); 492 ASSERT_TRUE(window_1);
543 EXPECT_TRUE(window_1->is_hidden()); 493 EXPECT_TRUE(window_1->is_hidden());
544 EXPECT_FALSE(HasAppShimHost(profile(), app->id())); 494 EXPECT_FALSE(HasAppShimHost(profile(), app->id()));
545 EXPECT_EQ(0, lifetime_observer.activated_count()); 495 EXPECT_EQ(0, lifetime_observer.activated_count());
546 496
547 // Showing the window causes the shim to launch. 497 // Showing the window causes the shim to launch.
548 { 498 {
549 base::scoped_nsobject<WindowedNSNotificationObserver> ns_observer( 499 base::scoped_nsobject<WindowedNSNotificationObserver>
550 [[WindowedNSNotificationObserver alloc] 500 ns_observer([[WindowedNSNotificationObserver alloc]
551 initForNotification:NSWorkspaceDidLaunchApplicationNotification 501 initForWorkspaceNotification:NSWorkspaceDidLaunchApplicationNotification
552 andBundleId:bundle_id]); 502 bundleId:bundle_id]);
553 WindowedAppShimLaunchObserver observer(app->id()); 503 WindowedAppShimLaunchObserver observer(app->id());
554 window_1->Show(extensions::AppWindow::SHOW_INACTIVE); 504 window_1->Show(extensions::AppWindow::SHOW_INACTIVE);
555 [ns_observer wait]; 505 [ns_observer wait];
556 observer.Wait(); 506 observer.Wait();
557 EXPECT_EQ(1, lifetime_observer.activated_count()); 507 EXPECT_EQ(1, lifetime_observer.activated_count());
558 EXPECT_TRUE(HasAppShimHost(profile(), app->id())); 508 EXPECT_TRUE(HasAppShimHost(profile(), app->id()));
559 } 509 }
560 510
561 // Hiding the window causes the shim to quit. 511 // Hiding the window causes the shim to quit.
562 { 512 {
563 base::scoped_nsobject<WindowedNSNotificationObserver> ns_observer( 513 base::scoped_nsobject<WindowedNSNotificationObserver> ns_observer(
564 [[WindowedNSNotificationObserver alloc] 514 [[WindowedNSNotificationObserver alloc]
565 initForNotification:NSWorkspaceDidTerminateApplicationNotification 515 initForWorkspaceNotification:
566 andBundleId:bundle_id]); 516 NSWorkspaceDidTerminateApplicationNotification
517 bundleId:bundle_id]);
567 window_1->Hide(); 518 window_1->Hide();
568 [ns_observer wait]; 519 [ns_observer wait];
569 EXPECT_FALSE(HasAppShimHost(profile(), app->id())); 520 EXPECT_FALSE(HasAppShimHost(profile(), app->id()));
570 } 521 }
571 522
572 // Launch a second window. It should not launch the shim. 523 // Launch a second window. It should not launch the shim.
573 { 524 {
574 ExtensionTestMessageListener launched_listener("Launched", false); 525 ExtensionTestMessageListener launched_listener("Launched", false);
575 LaunchPlatformApp(app); 526 LaunchPlatformApp(app);
576 EXPECT_TRUE(launched_listener.WaitUntilSatisfied()); 527 EXPECT_TRUE(launched_listener.WaitUntilSatisfied());
577 } 528 }
578 const extensions::AppWindowRegistry::AppWindowList& app_windows = 529 const extensions::AppWindowRegistry::AppWindowList& app_windows =
579 extensions::AppWindowRegistry::Get(profile())->app_windows(); 530 extensions::AppWindowRegistry::Get(profile())->app_windows();
580 EXPECT_EQ(2u, app_windows.size()); 531 EXPECT_EQ(2u, app_windows.size());
581 extensions::AppWindow* window_2 = app_windows.front(); 532 extensions::AppWindow* window_2 = app_windows.front();
582 EXPECT_NE(window_1, window_2); 533 EXPECT_NE(window_1, window_2);
583 ASSERT_TRUE(window_2); 534 ASSERT_TRUE(window_2);
584 EXPECT_TRUE(window_2->is_hidden()); 535 EXPECT_TRUE(window_2->is_hidden());
585 EXPECT_FALSE(HasAppShimHost(profile(), app->id())); 536 EXPECT_FALSE(HasAppShimHost(profile(), app->id()));
586 EXPECT_EQ(1, lifetime_observer.activated_count()); 537 EXPECT_EQ(1, lifetime_observer.activated_count());
587 538
588 // Showing one of the windows should launch the shim. 539 // Showing one of the windows should launch the shim.
589 { 540 {
590 base::scoped_nsobject<WindowedNSNotificationObserver> ns_observer( 541 base::scoped_nsobject<WindowedNSNotificationObserver>
591 [[WindowedNSNotificationObserver alloc] 542 ns_observer([[WindowedNSNotificationObserver alloc]
592 initForNotification:NSWorkspaceDidLaunchApplicationNotification 543 initForWorkspaceNotification:NSWorkspaceDidLaunchApplicationNotification
593 andBundleId:bundle_id]); 544 bundleId:bundle_id]);
594 WindowedAppShimLaunchObserver observer(app->id()); 545 WindowedAppShimLaunchObserver observer(app->id());
595 window_1->Show(extensions::AppWindow::SHOW_INACTIVE); 546 window_1->Show(extensions::AppWindow::SHOW_INACTIVE);
596 [ns_observer wait]; 547 [ns_observer wait];
597 observer.Wait(); 548 observer.Wait();
598 EXPECT_EQ(2, lifetime_observer.activated_count()); 549 EXPECT_EQ(2, lifetime_observer.activated_count());
599 EXPECT_TRUE(HasAppShimHost(profile(), app->id())); 550 EXPECT_TRUE(HasAppShimHost(profile(), app->id()));
600 EXPECT_TRUE(window_2->is_hidden()); 551 EXPECT_TRUE(window_2->is_hidden());
601 } 552 }
602 553
603 // Showing the other window does nothing. 554 // Showing the other window does nothing.
(...skipping 14 matching lines...) Expand all
618 window_1->Hide(); 569 window_1->Hide();
619 EXPECT_EQ(0, deactivate_observer.deactivated_count()); 570 EXPECT_EQ(0, deactivate_observer.deactivated_count());
620 } 571 }
621 572
622 // Hiding other window causes the shim to quit. 573 // Hiding other window causes the shim to quit.
623 { 574 {
624 AppLifetimeMonitorObserver deactivate_observer(profile()); 575 AppLifetimeMonitorObserver deactivate_observer(profile());
625 EXPECT_TRUE(HasAppShimHost(profile(), app->id())); 576 EXPECT_TRUE(HasAppShimHost(profile(), app->id()));
626 base::scoped_nsobject<WindowedNSNotificationObserver> ns_observer( 577 base::scoped_nsobject<WindowedNSNotificationObserver> ns_observer(
627 [[WindowedNSNotificationObserver alloc] 578 [[WindowedNSNotificationObserver alloc]
628 initForNotification:NSWorkspaceDidTerminateApplicationNotification 579 initForWorkspaceNotification:
629 andBundleId:bundle_id]); 580 NSWorkspaceDidTerminateApplicationNotification
581 bundleId:bundle_id]);
630 window_2->Hide(); 582 window_2->Hide();
631 [ns_observer wait]; 583 [ns_observer wait];
632 EXPECT_EQ(1, deactivate_observer.deactivated_count()); 584 EXPECT_EQ(1, deactivate_observer.deactivated_count());
633 EXPECT_FALSE(HasAppShimHost(profile(), app->id())); 585 EXPECT_FALSE(HasAppShimHost(profile(), app->id()));
634 } 586 }
635 } 587 }
636 588
637 #if defined(ARCH_CPU_64_BITS) 589 #if defined(ARCH_CPU_64_BITS)
638 590
639 // Tests that a 32 bit shim attempting to launch 64 bit Chrome will eventually 591 // Tests that a 32 bit shim attempting to launch 64 bit Chrome will eventually
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
717 // the shim is rebuilt. 669 // the shim is rebuilt.
718 WindowedAppShimLaunchObserver(app->id()).Wait(); 670 WindowedAppShimLaunchObserver(app->id()).Wait();
719 671
720 EXPECT_TRUE(GetFirstAppWindow()); 672 EXPECT_TRUE(GetFirstAppWindow());
721 EXPECT_TRUE(HasAppShimHost(profile(), app->id())); 673 EXPECT_TRUE(HasAppShimHost(profile(), app->id()));
722 } 674 }
723 675
724 #endif // defined(ARCH_CPU_64_BITS) 676 #endif // defined(ARCH_CPU_64_BITS)
725 677
726 } // namespace apps 678 } // namespace apps
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/ui/views/apps/chrome_native_app_window_views_mac.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698