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 #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 Loading... |
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 Loading... |
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 Loading... |
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(¶ms)); | 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 Loading... |
880 Browser* browser = chrome::CreateBrowserWithTestWindowForParams(¶ms); | 894 Browser* browser = chrome::CreateBrowserWithTestWindowForParams(¶ms); |
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 Loading... |
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 create an app when the user is active. |
| 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 EXPECT_EQ(3, model_->item_count()); |
| 1556 |
| 1557 // Transfer the app to the other screen and switch users. |
| 1558 manager->ShowWindowForUser(v1_app->browser()->window()->GetNativeWindow(), |
| 1559 user2); |
| 1560 EXPECT_EQ(3, model_->item_count()); |
| 1561 SwitchActiveUser(profile2->GetProfileName()); |
| 1562 EXPECT_EQ(2, model_->item_count()); |
| 1563 } |
| 1564 // After the app was destroyed, switch back. (which caused already a crash). |
| 1565 SwitchActiveUser(profile()->GetProfileName()); |
| 1566 |
| 1567 // Create the same app again - which was also causing the crash. |
| 1568 EXPECT_EQ(2, model_->item_count()); |
| 1569 { |
| 1570 // Create a "windowed gmail app". |
| 1571 scoped_ptr<V1App> v1_app(CreateRunningV1App( |
| 1572 profile(), |
| 1573 extension_misc::kGmailAppId, |
| 1574 kGmailLaunchURL)); |
| 1575 EXPECT_EQ(3, model_->item_count()); |
| 1576 } |
| 1577 SwitchActiveUser(profile2->GetProfileName()); |
| 1578 EXPECT_EQ(2, model_->item_count()); |
| 1579 } |
| 1580 |
| 1581 // Check edge cases with multi profile V1 apps in the shelf. |
| 1582 TEST_F(MultiProfileMultiBrowserShelfLayoutChromeLauncherControllerTest, |
| 1583 V1AppUpdateOnUserSwitchEdgecases2) { |
| 1584 // Create a browser item in the LauncherController. |
| 1585 InitLauncherController(); |
| 1586 TestAppTabHelperImpl* app_tab_helper = new TestAppTabHelperImpl; |
| 1587 SetAppTabHelper(app_tab_helper); |
| 1588 |
| 1589 // First test: Create an app when the user is not active. |
| 1590 std::string user2 = "user2"; |
| 1591 TestingProfile* profile2 = CreateMultiUserProfile(user2); |
| 1592 SwitchActiveUser(profile2->GetProfileName()); |
| 1593 { |
| 1594 // Create a "windowed gmail app". |
| 1595 scoped_ptr<V1App> v1_app(CreateRunningV1App( |
| 1596 profile(), extension_misc::kGmailAppId, gmail_url)); |
| 1597 EXPECT_EQ(2, model_->item_count()); |
| 1598 |
| 1599 // However - switching to the user should show it. |
| 1600 SwitchActiveUser(profile()->GetProfileName()); |
| 1601 EXPECT_EQ(3, model_->item_count()); |
| 1602 |
| 1603 // Second test: Remove the app when the user is not active and see that it |
| 1604 // works. |
| 1605 SwitchActiveUser(profile2->GetProfileName()); |
| 1606 EXPECT_EQ(2, model_->item_count()); |
| 1607 v1_app.reset(); |
| 1608 } |
| 1609 EXPECT_EQ(2, model_->item_count()); |
| 1610 SwitchActiveUser(profile()->GetProfileName()); |
| 1611 EXPECT_EQ(2, model_->item_count()); |
| 1612 SwitchActiveUser(profile2->GetProfileName()); |
| 1613 EXPECT_EQ(2, model_->item_count()); |
| 1614 } |
| 1615 |
1511 // Check that activating an item which is on another user's desktop, will bring | 1616 // Check that activating an item which is on another user's desktop, will bring |
1512 // it back. | 1617 // it back. |
1513 TEST_F(MultiProfileMultiBrowserShelfLayoutChromeLauncherControllerTest, | 1618 TEST_F(MultiProfileMultiBrowserShelfLayoutChromeLauncherControllerTest, |
1514 TestLauncherActivationPullsBackWindow) { | 1619 TestLauncherActivationPullsBackWindow) { |
1515 // Create a browser item in the LauncherController. | 1620 // Create a browser item in the LauncherController. |
1516 InitLauncherController(); | 1621 InitLauncherController(); |
1517 chrome::MultiUserWindowManager* manager = | 1622 chrome::MultiUserWindowManager* manager = |
1518 chrome::MultiUserWindowManager::GetInstance(); | 1623 chrome::MultiUserWindowManager::GetInstance(); |
1519 | 1624 |
1520 // Add two users to the window manager. | 1625 // Add two users to the window manager. |
(...skipping 1092 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2613 | 2718 |
2614 EXPECT_EQ(1, app_icon_loader->fetch_count()); | 2719 EXPECT_EQ(1, app_icon_loader->fetch_count()); |
2615 ASSERT_EQ(initial_size + 1, model_->items().size()); | 2720 ASSERT_EQ(initial_size + 1, model_->items().size()); |
2616 EXPECT_TRUE(launcher_controller_->IsAppPinned("1")); | 2721 EXPECT_TRUE(launcher_controller_->IsAppPinned("1")); |
2617 EXPECT_FALSE(launcher_controller_->IsAppPinned("0")); | 2722 EXPECT_FALSE(launcher_controller_->IsAppPinned("0")); |
2618 EXPECT_EQ(ash::TYPE_APP_SHORTCUT, model_->items()[app_index].type); | 2723 EXPECT_EQ(ash::TYPE_APP_SHORTCUT, model_->items()[app_index].type); |
2619 | 2724 |
2620 launcher_controller_->UnpinAppWithID("1"); | 2725 launcher_controller_->UnpinAppWithID("1"); |
2621 ASSERT_EQ(initial_size, model_->items().size()); | 2726 ASSERT_EQ(initial_size, model_->items().size()); |
2622 } | 2727 } |
OLD | NEW |