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

Side by Side Diff: chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc

Issue 83173007: Fixing M32 crasher where closing of a windowed V1 app on a visiting desktop will cause crashes late… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 1 month 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 | Annotate | Revision Log
OLDNEW
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 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" 5 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 #include "ui/views/test/test_views_delegate.h" 70 #include "ui/views/test/test_views_delegate.h"
71 #endif 71 #endif
72 72
73 using extensions::Extension; 73 using extensions::Extension;
74 using extensions::Manifest; 74 using extensions::Manifest;
75 using extensions::UnloadedExtensionInfo; 75 using extensions::UnloadedExtensionInfo;
76 76
77 namespace { 77 namespace {
78 const char* offline_gmail_url = "https://mail.google.com/mail/mu/u"; 78 const char* offline_gmail_url = "https://mail.google.com/mail/mu/u";
79 const char* gmail_url = "https://mail.google.com/mail/u"; 79 const char* gmail_url = "https://mail.google.com/mail/u";
80 const char* kGmailLaunchURL = "https://mail.google.com/mail/ca";
80 81
81 // As defined in /chromeos/dbus/cryptohome_client.cc. 82 // As defined in /chromeos/dbus/cryptohome_client.cc.
82 const char kUserIdHashSuffix[] = "-hash"; 83 const char kUserIdHashSuffix[] = "-hash";
83 84
84 // An extension prefix. 85 // An extension prefix.
85 const char kCrxAppPrefix[] = "_crx_"; 86 const char kCrxAppPrefix[] = "_crx_";
86 }
87
88 namespace {
89 87
90 // ShelfModelObserver implementation that tracks what messages are invoked. 88 // ShelfModelObserver implementation that tracks what messages are invoked.
91 class TestShelfModelObserver : public ash::ShelfModelObserver { 89 class TestShelfModelObserver : public ash::ShelfModelObserver {
92 public: 90 public:
93 TestShelfModelObserver() 91 TestShelfModelObserver()
94 : added_(0), 92 : added_(0),
95 removed_(0), 93 removed_(0),
96 changed_(0) { 94 changed_(0) {
97 } 95 }
98 96
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", 305 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
308 &error); 306 &error);
309 // Fake gmail extension. 307 // Fake gmail extension.
310 DictionaryValue manifest_gmail; 308 DictionaryValue manifest_gmail;
311 manifest_gmail.SetString(extensions::manifest_keys::kName, 309 manifest_gmail.SetString(extensions::manifest_keys::kName,
312 "Gmail launcher controller test extension"); 310 "Gmail launcher controller test extension");
313 manifest_gmail.SetString(extensions::manifest_keys::kVersion, "1"); 311 manifest_gmail.SetString(extensions::manifest_keys::kVersion, "1");
314 manifest_gmail.SetString(extensions::manifest_keys::kDescription, 312 manifest_gmail.SetString(extensions::manifest_keys::kDescription,
315 "for testing pinned Gmail"); 313 "for testing pinned Gmail");
316 manifest_gmail.SetString(extensions::manifest_keys::kLaunchWebURL, 314 manifest_gmail.SetString(extensions::manifest_keys::kLaunchWebURL,
317 "https://mail.google.com/mail/ca"); 315 kGmailLaunchURL);
318 ListValue* list = new ListValue(); 316 ListValue* list = new ListValue();
319 list->Append(Value::CreateStringValue("*://mail.google.com/mail/ca")); 317 list->Append(Value::CreateStringValue("*://mail.google.com/mail/ca"));
320 manifest_gmail.Set(extensions::manifest_keys::kWebURLs, list); 318 manifest_gmail.Set(extensions::manifest_keys::kWebURLs, list);
321 319
322 extension3_ = Extension::Create(base::FilePath(), Manifest::UNPACKED, 320 extension3_ = Extension::Create(base::FilePath(), Manifest::UNPACKED,
323 manifest_gmail, 321 manifest_gmail,
324 Extension::NO_FLAGS, 322 Extension::NO_FLAGS,
325 extension_misc::kGmailAppId, 323 extension_misc::kGmailAppId,
326 &error); 324 &error);
327 325
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after
714 content::WebContents* web_contents) OVERRIDE { 712 content::WebContents* web_contents) OVERRIDE {
715 message_loop_runner_->Quit(); 713 message_loop_runner_->Quit();
716 } 714 }
717 715
718 scoped_refptr<content::MessageLoopRunner> message_loop_runner_; 716 scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
719 717
720 DISALLOW_COPY_AND_ASSIGN(WebContentsDestroyedWatcher); 718 DISALLOW_COPY_AND_ASSIGN(WebContentsDestroyedWatcher);
721 }; 719 };
722 720
723 // A V1 windowed application. 721 // A V1 windowed application.
724 class V1App { 722 class V1App : public TestBrowserWindow {
725 public: 723 public:
726 V1App(Profile* profile, const std::string& app_name) { 724 V1App(Profile* profile, const std::string& app_name) {
725 // Create a window.
726 native_window_.reset(new aura::Window(NULL));
727 native_window_->set_id(0);
728 native_window_->SetType(aura::client::WINDOW_TYPE_POPUP);
729 native_window_->Init(ui::LAYER_TEXTURED);
730 native_window_->Show();
731
727 Browser::CreateParams params = Browser::CreateParams::CreateForApp( 732 Browser::CreateParams params = Browser::CreateParams::CreateForApp(
728 Browser::TYPE_POPUP, 733 Browser::TYPE_POPUP,
729 kCrxAppPrefix + app_name, 734 kCrxAppPrefix + app_name,
730 gfx::Rect(), 735 gfx::Rect(),
731 profile, 736 profile,
732 chrome::HOST_DESKTOP_TYPE_ASH); 737 chrome::HOST_DESKTOP_TYPE_ASH);
733 browser_.reset(chrome::CreateBrowserWithTestWindowForParams(&params)); 738 params.window = this;
739 browser_.reset(new Browser(params));
734 chrome::AddTabAt(browser_.get(), GURL(), 0, true); 740 chrome::AddTabAt(browser_.get(), GURL(), 0, true);
735 } 741 }
736 742
737 virtual ~V1App() { 743 virtual ~V1App() {
738 // close all tabs. Note that we do not need to destroy the browser itself. 744 // close all tabs. Note that we do not need to destroy the browser itself.
739 browser_->tab_strip_model()->CloseAllTabs(); 745 browser_->tab_strip_model()->CloseAllTabs();
740 } 746 }
741 747
742 Browser* browser() { return browser_.get(); } 748 Browser* browser() { return browser_.get(); }
743 749
750 // TestBrowserWindow override:
751 virtual gfx::NativeWindow GetNativeWindow() OVERRIDE {
752 return native_window_.get();
753 }
754
744 private: 755 private:
745 // The associated browser with this app. 756 // The associated browser with this app.
746 scoped_ptr<Browser> browser_; 757 scoped_ptr<Browser> browser_;
747 758
759 // The native window we use.
760 scoped_ptr<aura::Window> native_window_;
761
748 DISALLOW_COPY_AND_ASSIGN(V1App); 762 DISALLOW_COPY_AND_ASSIGN(V1App);
749 }; 763 };
750 764
751 // A V2 application which gets created with an |extension| and for a |profile|. 765 // A V2 application which gets created with an |extension| and for a |profile|.
752 // Upon destruction it will properly close the application. 766 // Upon destruction it will properly close the application.
753 class V2App { 767 class V2App {
754 public: 768 public:
755 V2App(Profile* profile, const extensions::Extension* extension) { 769 V2App(Profile* profile, const extensions::Extension* extension) {
756 window_ = new apps::ShellWindow(profile, 770 window_ = new apps::ShellWindow(profile,
757 new ChromeShellWindowDelegate(), 771 new ChromeShellWindowDelegate(),
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
880 Browser* browser = chrome::CreateBrowserWithTestWindowForParams(&params); 894 Browser* browser = chrome::CreateBrowserWithTestWindowForParams(&params);
881 chrome::NewTab(browser); 895 chrome::NewTab(browser);
882 896
883 BrowserList::SetLastActive(browser); 897 BrowserList::SetLastActive(browser);
884 NavigateAndCommitActiveTabWithTitle( 898 NavigateAndCommitActiveTabWithTitle(
885 browser, GURL(url), ASCIIToUTF16(title)); 899 browser, GURL(url), ASCIIToUTF16(title));
886 return browser; 900 return browser;
887 } 901 }
888 902
889 // Creates a running V1 application. 903 // Creates a running V1 application.
904 // Note that with the use of the app_tab_helper as done below, this is only
905 // usable with a single v1 application.
890 V1App* CreateRunningV1App(Profile* profile, 906 V1App* CreateRunningV1App(Profile* profile,
891 const std::string& app_name, 907 const std::string& app_name,
892 const std::string& url) { 908 const std::string& url) {
893 V1App* v1_app = new V1App(profile, app_name); 909 V1App* v1_app = new V1App(profile, app_name);
910 // Create a new app tab helper and assign it to the launcher so that this
911 // app gets properly detected.
912 // TODO(skuhne): Create a more intelligent app tab helper which is able to
913 // detect all running apps properly.
914 TestAppTabHelperImpl* app_tab_helper = new TestAppTabHelperImpl;
915 app_tab_helper->SetAppID(
916 v1_app->browser()->tab_strip_model()->GetWebContentsAt(0),
917 app_name);
918 SetAppTabHelper(app_tab_helper);
919
894 NavigateAndCommitActiveTabWithTitle( 920 NavigateAndCommitActiveTabWithTitle(
895 v1_app->browser(), GURL(url), ASCIIToUTF16("")); 921 v1_app->browser(), GURL(url), ASCIIToUTF16(""));
896 return v1_app; 922 return v1_app;
897 } 923 }
898 924
899 ash::test::TestSessionStateDelegate* 925 ash::test::TestSessionStateDelegate*
900 session_delegate() { return session_delegate_; } 926 session_delegate() { return session_delegate_; }
901 ash::test::TestShellDelegate* shell_delegate() { return shell_delegate_; } 927 ash::test::TestShellDelegate* shell_delegate() { return shell_delegate_; }
902 928
903 // Override BrowserWithTestWindowTest: 929 // Override BrowserWithTestWindowTest:
(...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after
1501 EXPECT_EQ(2, model_->item_count()); 1527 EXPECT_EQ(2, model_->item_count());
1502 // Note: the closure ends and the browser will go away. 1528 // Note: the closure ends and the browser will go away.
1503 } 1529 }
1504 EXPECT_EQ(2, model_->item_count()); 1530 EXPECT_EQ(2, model_->item_count());
1505 SwitchActiveUser(profile2->GetProfileName()); 1531 SwitchActiveUser(profile2->GetProfileName());
1506 EXPECT_EQ(2, model_->item_count()); 1532 EXPECT_EQ(2, model_->item_count());
1507 SwitchActiveUser(profile()->GetProfileName()); 1533 SwitchActiveUser(profile()->GetProfileName());
1508 EXPECT_EQ(2, model_->item_count()); 1534 EXPECT_EQ(2, model_->item_count());
1509 } 1535 }
1510 1536
1537 // Check edge case where a visiting V1 app gets closed (crbug.com/321374).
1538 TEST_F(MultiProfileMultiBrowserShelfLayoutChromeLauncherControllerTest,
1539 V1CloseOnVisitingDesktop) {
1540 // Create a browser item in the LauncherController.
1541 InitLauncherController();
1542
1543 chrome::MultiUserWindowManager* manager =
1544 chrome::MultiUserWindowManager::GetInstance();
1545
1546 // First test: Create an app when the user is not active.
James Cook 2013/11/22 19:06:09 nit: Where does the second test begin? Or is this
Mr4D (OOO till 08-26) 2013/11/22 19:17:00 Changed the comment(s). Thanks!
1547 std::string user2 = "user2";
1548 TestingProfile* profile2 = CreateMultiUserProfile(user2);
1549 {
1550 // Create a "windowed gmail app".
1551 scoped_ptr<V1App> v1_app(CreateRunningV1App(
1552 profile(),
1553 extension_misc::kGmailAppId,
1554 kGmailLaunchURL));
1555 // Trigger an update on the launcher item.
James Cook 2013/11/22 19:06:09 Is this a leftover comment?
Mr4D (OOO till 08-26) 2013/11/22 19:17:00 In deed. Done
1556 EXPECT_EQ(3, model_->item_count());
1557
1558 // Transfer the app to the other screen and switch users.
1559 manager->ShowWindowForUser(v1_app->browser()->window()->GetNativeWindow(),
1560 user2);
1561 EXPECT_EQ(3, model_->item_count());
1562 SwitchActiveUser(profile2->GetProfileName());
1563 EXPECT_EQ(2, model_->item_count());
1564 }
1565 // Switching back caused a crash in the past.
1566 SwitchActiveUser(profile()->GetProfileName());
1567 EXPECT_EQ(2, model_->item_count());
1568 {
1569 // Create a "windowed gmail app".
1570 scoped_ptr<V1App> v1_app(CreateRunningV1App(
1571 profile(),
1572 extension_misc::kGmailAppId,
1573 kGmailLaunchURL));
1574 EXPECT_EQ(3, model_->item_count());
1575 }
1576 SwitchActiveUser(profile2->GetProfileName());
1577 EXPECT_EQ(2, model_->item_count());
1578 }
1579
1580 // Check edge cases with multi profile V1 apps in the shelf.
1581 TEST_F(MultiProfileMultiBrowserShelfLayoutChromeLauncherControllerTest,
1582 V1AppUpdateOnUserSwitchEdgecases2) {
1583 // Create a browser item in the LauncherController.
1584 InitLauncherController();
1585 TestAppTabHelperImpl* app_tab_helper = new TestAppTabHelperImpl;
1586 SetAppTabHelper(app_tab_helper);
1587
1588 // First test: Create an app when the user is not active.
1589 std::string user2 = "user2";
1590 TestingProfile* profile2 = CreateMultiUserProfile(user2);
1591 SwitchActiveUser(profile2->GetProfileName());
1592 {
1593 // Create a "windowed gmail app".
1594 scoped_ptr<V1App> v1_app(CreateRunningV1App(
1595 profile(), extension_misc::kGmailAppId, gmail_url));
1596 EXPECT_EQ(2, model_->item_count());
1597
1598 // However - switching to the user should show it.
1599 SwitchActiveUser(profile()->GetProfileName());
1600 EXPECT_EQ(3, model_->item_count());
1601
1602 // Second test: Remove the app when the user is not active and see that it
1603 // works.
1604 SwitchActiveUser(profile2->GetProfileName());
1605 EXPECT_EQ(2, model_->item_count());
1606 // Note: the closure ends and the browser will go away.
James Cook 2013/11/22 19:06:09 nit: This might be a little clearer if you elimina
Mr4D (OOO till 08-26) 2013/11/22 19:17:00 Done.
1607 }
1608 EXPECT_EQ(2, model_->item_count());
1609 SwitchActiveUser(profile()->GetProfileName());
1610 EXPECT_EQ(2, model_->item_count());
1611 SwitchActiveUser(profile2->GetProfileName());
1612 EXPECT_EQ(2, model_->item_count());
1613 }
1614
1511 // Check that activating an item which is on another user's desktop, will bring 1615 // Check that activating an item which is on another user's desktop, will bring
1512 // it back. 1616 // it back.
1513 TEST_F(MultiProfileMultiBrowserShelfLayoutChromeLauncherControllerTest, 1617 TEST_F(MultiProfileMultiBrowserShelfLayoutChromeLauncherControllerTest,
1514 TestLauncherActivationPullsBackWindow) { 1618 TestLauncherActivationPullsBackWindow) {
1515 // Create a browser item in the LauncherController. 1619 // Create a browser item in the LauncherController.
1516 InitLauncherController(); 1620 InitLauncherController();
1517 chrome::MultiUserWindowManager* manager = 1621 chrome::MultiUserWindowManager* manager =
1518 chrome::MultiUserWindowManager::GetInstance(); 1622 chrome::MultiUserWindowManager::GetInstance();
1519 1623
1520 // Add two users to the window manager. 1624 // Add two users to the window manager.
(...skipping 1092 matching lines...) Expand 10 before | Expand all | Expand 10 after
2613 2717
2614 EXPECT_EQ(1, app_icon_loader->fetch_count()); 2718 EXPECT_EQ(1, app_icon_loader->fetch_count());
2615 ASSERT_EQ(initial_size + 1, model_->items().size()); 2719 ASSERT_EQ(initial_size + 1, model_->items().size());
2616 EXPECT_TRUE(launcher_controller_->IsAppPinned("1")); 2720 EXPECT_TRUE(launcher_controller_->IsAppPinned("1"));
2617 EXPECT_FALSE(launcher_controller_->IsAppPinned("0")); 2721 EXPECT_FALSE(launcher_controller_->IsAppPinned("0"));
2618 EXPECT_EQ(ash::TYPE_APP_SHORTCUT, model_->items()[app_index].type); 2722 EXPECT_EQ(ash::TYPE_APP_SHORTCUT, model_->items()[app_index].type);
2619 2723
2620 launcher_controller_->UnpinAppWithID("1"); 2724 launcher_controller_->UnpinAppWithID("1");
2621 ASSERT_EQ(initial_size, model_->items().size()); 2725 ASSERT_EQ(initial_size, model_->items().size());
2622 } 2726 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698