Index: chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl_unittest.cc |
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl_unittest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl_unittest.cc |
deleted file mode 100644 |
index 9fc4dae8193220e7bbabe799be508c12d0afe6a6..0000000000000000000000000000000000000000 |
--- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl_unittest.cc |
+++ /dev/null |
@@ -1,4315 +0,0 @@ |
-// Copyright 2013 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl.h" |
- |
-#include <stddef.h> |
- |
-#include <algorithm> |
-#include <map> |
-#include <memory> |
-#include <set> |
-#include <string> |
-#include <utility> |
-#include <vector> |
- |
-#include "ash/display/display_configuration_controller.h" |
-#include "ash/display/screen_orientation_controller_chromeos.h" |
-#include "ash/public/cpp/app_launch_id.h" |
-#include "ash/public/cpp/shelf_item.h" |
-#include "ash/public/cpp/shelf_item_delegate.h" |
-#include "ash/shelf/shelf_application_menu_model.h" |
-#include "ash/shelf/shelf_constants.h" |
-#include "ash/shelf/shelf_controller.h" |
-#include "ash/shelf/shelf_model.h" |
-#include "ash/shelf/shelf_model_observer.h" |
-#include "ash/shell.h" |
-#include "ash/test/ash_test_helper.h" |
-#include "ash/test/shell_test_api.h" |
-#include "ash/test/test_shell_delegate.h" |
-#include "ash/wm/maximize_mode/maximize_mode_controller.h" |
-#include "ash/wm/window_util.h" |
-#include "base/command_line.h" |
-#include "base/compiler_specific.h" |
-#include "base/files/file_path.h" |
-#include "base/json/json_string_value_serializer.h" |
-#include "base/location.h" |
-#include "base/macros.h" |
-#include "base/memory/ptr_util.h" |
-#include "base/run_loop.h" |
-#include "base/single_thread_task_runner.h" |
-#include "base/strings/utf_string_conversions.h" |
-#include "base/values.h" |
-#include "build/build_config.h" |
-#include "chrome/browser/chromeos/arc/arc_support_host.h" |
-#include "chrome/browser/chromeos/arc/arc_util.h" |
-#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" |
-#include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" |
-#include "chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h" |
-#include "chrome/browser/extensions/extension_service.h" |
-#include "chrome/browser/extensions/test_extension_system.h" |
-#include "chrome/browser/lifetime/scoped_keep_alive.h" |
-#include "chrome/browser/prefs/browser_prefs.h" |
-#include "chrome/browser/ui/app_list/app_list_syncable_service_factory.h" |
-#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" |
-#include "chrome/browser/ui/app_list/arc/arc_app_test.h" |
-#include "chrome/browser/ui/app_list/arc/arc_app_utils.h" |
-#include "chrome/browser/ui/app_list/arc/arc_default_app_list.h" |
-#include "chrome/browser/ui/apps/chrome_app_delegate.h" |
-#include "chrome/browser/ui/ash/chrome_launcher_prefs.h" |
-#include "chrome/browser/ui/ash/launcher/app_window_launcher_controller.h" |
-#include "chrome/browser/ui/ash/launcher/arc_app_deferred_launcher_controller.h" |
-#include "chrome/browser/ui/ash/launcher/browser_status_monitor.h" |
-#include "chrome/browser/ui/ash/launcher/chrome_launcher_controller_util.h" |
-#include "chrome/browser/ui/ash/launcher/extension_app_window_launcher_item_controller.h" |
-#include "chrome/browser/ui/ash/launcher/launcher_controller_helper.h" |
-#include "chrome/browser/ui/ash/multi_user/multi_user_util.h" |
-#include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h" |
-#include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.h" |
-#include "chrome/browser/ui/browser.h" |
-#include "chrome/browser/ui/browser_commands.h" |
-#include "chrome/browser/ui/browser_finder.h" |
-#include "chrome/browser/ui/browser_list.h" |
-#include "chrome/browser/ui/browser_tabstrip.h" |
-#include "chrome/browser/ui/tabs/tab_strip_model.h" |
-#include "chrome/common/chrome_constants.h" |
-#include "chrome/common/chrome_switches.h" |
-#include "chrome/common/extensions/extension_constants.h" |
-#include "chrome/common/pref_names.h" |
-#include "chrome/test/base/browser_with_test_window_test.h" |
-#include "chrome/test/base/test_browser_window_aura.h" |
-#include "chrome/test/base/testing_browser_process.h" |
-#include "chrome/test/base/testing_profile.h" |
-#include "chrome/test/base/testing_profile_manager.h" |
-#include "chromeos/chromeos_switches.h" |
-#include "components/arc/arc_util.h" |
-#include "components/arc/common/app.mojom.h" |
-#include "components/arc/test/fake_app_instance.h" |
-#include "components/exo/shell_surface.h" |
-#include "components/prefs/pref_notifier_impl.h" |
-#include "components/signin/core/account_id/account_id.h" |
-#include "components/sync/model/attachments/attachment_service_proxy_for_test.h" |
-#include "components/sync/model/fake_sync_change_processor.h" |
-#include "components/sync/model/sync_error_factory_mock.h" |
-#include "components/sync/protocol/sync.pb.h" |
-#include "components/sync_preferences/pref_model_associator.h" |
-#include "components/sync_preferences/testing_pref_service_syncable.h" |
-#include "components/user_manager/fake_user_manager.h" |
-#include "content/public/browser/web_contents.h" |
-#include "content/public/browser/web_contents_observer.h" |
-#include "content/public/test/test_utils.h" |
-#include "content/public/test/web_contents_tester.h" |
-#include "extensions/browser/app_window/app_window_contents.h" |
-#include "extensions/browser/app_window/app_window_registry.h" |
-#include "extensions/browser/app_window/native_app_window.h" |
-#include "extensions/common/extension.h" |
-#include "extensions/common/manifest_constants.h" |
-#include "testing/gtest/include/gtest/gtest.h" |
-#include "ui/aura/client/window_parenting_client.h" |
-#include "ui/aura/window.h" |
-#include "ui/base/models/menu_model.h" |
-#include "ui/display/display.h" |
-#include "ui/display/display_switches.h" |
-#include "ui/display/screen.h" |
-#include "ui/events/base_event_utils.h" |
-#include "ui/events/event_constants.h" |
-#include "ui/views/widget/widget.h" |
- |
-using base::ASCIIToUTF16; |
-using extensions::Extension; |
-using extensions::Manifest; |
-using extensions::UnloadedExtensionInfo; |
-using arc::mojom::OrientationLock; |
- |
-namespace { |
-const char* offline_gmail_url = "https://mail.google.com/mail/mu/u"; |
-const char* gmail_url = "https://mail.google.com/mail/u"; |
-const char* kGmailLaunchURL = "https://mail.google.com/mail/ca"; |
- |
-// An extension prefix. |
-const char kCrxAppPrefix[] = "_crx_"; |
- |
-// Dummy app id is used to put at least one pin record to prevent initializing |
-// pin model with default apps that can affect some tests. |
-const char kDummyAppId[] = "dummyappid_dummyappid_dummyappid"; |
- |
-// ShelfModelObserver implementation that tracks what messages are invoked. |
-class TestShelfModelObserver : public ash::ShelfModelObserver { |
- public: |
- TestShelfModelObserver() {} |
- ~TestShelfModelObserver() override {} |
- |
- // Overridden from ash::ShelfModelObserver: |
- void ShelfItemAdded(int index) override { |
- ++added_; |
- last_index_ = index; |
- } |
- |
- void ShelfItemRemoved(int index, const ash::ShelfItem& old_item) override { |
- ++removed_; |
- last_index_ = index; |
- } |
- |
- void ShelfItemChanged(int index, const ash::ShelfItem& old_item) override { |
- ++changed_; |
- last_index_ = index; |
- } |
- |
- void ShelfItemMoved(int start_index, int target_index) override { |
- last_index_ = target_index; |
- } |
- |
- void clear_counts() { |
- added_ = 0; |
- removed_ = 0; |
- changed_ = 0; |
- last_index_ = 0; |
- } |
- |
- int added() const { return added_; } |
- int removed() const { return removed_; } |
- int changed() const { return changed_; } |
- int last_index() const { return last_index_; } |
- |
- private: |
- int added_ = 0; |
- int removed_ = 0; |
- int changed_ = 0; |
- int last_index_ = 0; |
- |
- DISALLOW_COPY_AND_ASSIGN(TestShelfModelObserver); |
-}; |
- |
-// Test implementation of AppIconLoader. |
-class TestAppIconLoaderImpl : public AppIconLoader { |
- public: |
- TestAppIconLoaderImpl() = default; |
- ~TestAppIconLoaderImpl() override = default; |
- |
- void AddSupportedApp(const std::string& id) { supported_apps_.insert(id); } |
- |
- // AppIconLoader implementation: |
- bool CanLoadImageForApp(const std::string& id) override { |
- return supported_apps_.find(id) != supported_apps_.end(); |
- } |
- void FetchImage(const std::string& id) override { ++fetch_count_; } |
- void ClearImage(const std::string& id) override { ++clear_count_; } |
- void UpdateImage(const std::string& id) override {} |
- |
- int fetch_count() const { return fetch_count_; } |
- int clear_count() const { return clear_count_; } |
- |
- private: |
- int fetch_count_ = 0; |
- int clear_count_ = 0; |
- std::set<std::string> supported_apps_; |
- |
- DISALLOW_COPY_AND_ASSIGN(TestAppIconLoaderImpl); |
-}; |
- |
-// Test implementation of LauncherControllerHelper. |
-class TestLauncherControllerHelper : public LauncherControllerHelper { |
- public: |
- TestLauncherControllerHelper() : LauncherControllerHelper(nullptr) {} |
- explicit TestLauncherControllerHelper(Profile* profile) |
- : LauncherControllerHelper(profile) {} |
- ~TestLauncherControllerHelper() override {} |
- |
- // Sets the id for the specified tab. |
- void SetAppID(content::WebContents* tab, const std::string& id) { |
- tab_id_map_[tab] = id; |
- } |
- |
- // Returns true if there is an id registered for |tab|. |
- bool HasAppID(content::WebContents* tab) const { |
- return tab_id_map_.find(tab) != tab_id_map_.end(); |
- } |
- |
- // LauncherControllerHelper: |
- std::string GetAppID(content::WebContents* tab) override { |
- return tab_id_map_.find(tab) != tab_id_map_.end() ? tab_id_map_[tab] : |
- std::string(); |
- } |
- |
- bool IsValidIDForCurrentUser(const std::string& id) const override { |
- for (TabToStringMap::const_iterator i = tab_id_map_.begin(); |
- i != tab_id_map_.end(); ++i) { |
- if (i->second == id) |
- return true; |
- } |
- return false; |
- } |
- |
- ArcAppListPrefs* GetArcAppListPrefs() const override { return nullptr; } |
- |
- private: |
- typedef std::map<content::WebContents*, std::string> TabToStringMap; |
- |
- TabToStringMap tab_id_map_; |
- |
- DISALLOW_COPY_AND_ASSIGN(TestLauncherControllerHelper); |
-}; |
- |
-// Test implementation of a V2 app launcher item controller. |
-class TestV2AppLauncherItemController : public ash::ShelfItemDelegate { |
- public: |
- explicit TestV2AppLauncherItemController(const std::string& app_id) |
- : ash::ShelfItemDelegate(ash::AppLaunchId(app_id)) {} |
- |
- ~TestV2AppLauncherItemController() override {} |
- |
- // Override for ash::ShelfItemDelegate: |
- void ItemSelected(std::unique_ptr<ui::Event> event, |
- int64_t display_id, |
- ash::ShelfLaunchSource source, |
- const ItemSelectedCallback& callback) override { |
- callback.Run(ash::SHELF_ACTION_WINDOW_ACTIVATED, base::nullopt); |
- } |
- void ExecuteCommand(uint32_t command_id, int32_t event_flags) override {} |
- void Close() override {} |
- |
- private: |
- DISALLOW_COPY_AND_ASSIGN(TestV2AppLauncherItemController); |
-}; |
- |
-// A test ShelfController implementation that tracks alignment and auto-hide. |
-class TestShelfController : public ash::mojom::ShelfController { |
- public: |
- TestShelfController() : binding_(this) {} |
- ~TestShelfController() override {} |
- |
- ash::ShelfAlignment alignment() const { return alignment_; } |
- ash::ShelfAutoHideBehavior auto_hide() const { return auto_hide_; } |
- |
- size_t alignment_change_count() const { return alignment_change_count_; } |
- size_t auto_hide_change_count() const { return auto_hide_change_count_; } |
- |
- ash::mojom::ShelfControllerPtr CreateInterfacePtrAndBind() { |
- return binding_.CreateInterfacePtrAndBind(); |
- } |
- |
- // ash::mojom::ShelfController: |
- void AddObserver( |
- ash::mojom::ShelfObserverAssociatedPtrInfo observer) override { |
- observer_.Bind(std::move(observer)); |
- } |
- void SetAlignment(ash::ShelfAlignment alignment, |
- int64_t display_id) override { |
- alignment_change_count_++; |
- alignment_ = alignment; |
- observer_->OnAlignmentChanged(alignment_, display_id); |
- } |
- void SetAutoHideBehavior(ash::ShelfAutoHideBehavior auto_hide, |
- int64_t display_id) override { |
- auto_hide_change_count_++; |
- auto_hide_ = auto_hide; |
- observer_->OnAutoHideBehaviorChanged(auto_hide_, display_id); |
- } |
- void PinItem( |
- const ash::ShelfItem& item, |
- ash::mojom::ShelfItemDelegateAssociatedPtrInfo delegate) override {} |
- void UnpinItem(const std::string& app_id) override {} |
- void SetItemImage(const std::string& app_id, const SkBitmap& image) override { |
- } |
- |
- private: |
- ash::ShelfAlignment alignment_ = ash::SHELF_ALIGNMENT_BOTTOM_LOCKED; |
- ash::ShelfAutoHideBehavior auto_hide_ = ash::SHELF_AUTO_HIDE_ALWAYS_HIDDEN; |
- |
- size_t alignment_change_count_ = 0; |
- size_t auto_hide_change_count_ = 0; |
- |
- ash::mojom::ShelfObserverAssociatedPtr observer_; |
- mojo::Binding<ash::mojom::ShelfController> binding_; |
- |
- DISALLOW_COPY_AND_ASSIGN(TestShelfController); |
-}; |
- |
-// A callback that does nothing after shelf item selection handling. |
-void NoopCallback(ash::ShelfAction action, base::Optional<ash::MenuItemList>) {} |
- |
-// Simulates selection of the shelf item. |
-void SelectItem(ash::ShelfItemDelegate* delegate) { |
- std::unique_ptr<ui::Event> event = base::MakeUnique<ui::MouseEvent>( |
- ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(), ui::EventTimeForNow(), |
- ui::EF_NONE, 0); |
- delegate->ItemSelected(std::move(event), display::kInvalidDisplayId, |
- ash::LAUNCH_FROM_UNKNOWN, base::Bind(&NoopCallback)); |
-} |
- |
-} // namespace |
- |
-// A test ChromeLauncherControllerImpl subclass that uses TestShelfController. |
-class TestChromeLauncherControllerImpl : public ChromeLauncherControllerImpl { |
- public: |
- TestChromeLauncherControllerImpl(Profile* profile, ash::ShelfModel* model) |
- : ChromeLauncherControllerImpl(profile, model) {} |
- |
- // ChromeLauncherControllerImpl: |
- using ChromeLauncherControllerImpl::ReleaseProfile; |
- bool ConnectToShelfController() override { |
- // Set the shelf controller pointer to a test instance; this is run in init. |
- if (!shelf_controller_.is_bound()) |
- shelf_controller_ = test_shelf_controller_.CreateInterfacePtrAndBind(); |
- return true; |
- } |
- |
- TestShelfController* test_shelf_controller() { |
- return &test_shelf_controller_; |
- } |
- |
- private: |
- TestShelfController test_shelf_controller_; |
- |
- DISALLOW_COPY_AND_ASSIGN(TestChromeLauncherControllerImpl); |
-}; |
- |
-// A shell delegate that owns a ChromeLauncherController, like production. |
-// TODO(msw): Refine ChromeLauncherControllerImpl lifetime management. |
-// TODO(msw): Avoid relying on TestShellDelegate's ShelfInitializer. |
-class ChromeLauncherTestShellDelegate : public ash::test::TestShellDelegate { |
- public: |
- ChromeLauncherTestShellDelegate() {} |
- |
- // Create a ChromeLauncherControllerImpl instance. |
- ChromeLauncherControllerImpl* CreateLauncherController(Profile* profile) { |
- launcher_controller_ = base::MakeUnique<ChromeLauncherControllerImpl>( |
- profile, ash::Shell::Get()->shelf_model()); |
- return launcher_controller_.get(); |
- } |
- |
- // Create a TestChromeLauncherControllerImpl instance. |
- TestChromeLauncherControllerImpl* CreateTestLauncherController( |
- Profile* profile) { |
- auto controller = base::MakeUnique<TestChromeLauncherControllerImpl>( |
- profile, ash::Shell::Get()->shelf_model()); |
- TestChromeLauncherControllerImpl* controller_weak = controller.get(); |
- launcher_controller_ = std::move(controller); |
- launcher_controller_->Init(); |
- return controller_weak; |
- } |
- |
- // ash::test::TestShellDelegate: |
- void ShelfShutdown() override { launcher_controller_.reset(); } |
- |
- private: |
- std::unique_ptr<ChromeLauncherControllerImpl> launcher_controller_; |
- |
- DISALLOW_COPY_AND_ASSIGN(ChromeLauncherTestShellDelegate); |
-}; |
- |
-class ChromeLauncherControllerImplTest : public BrowserWithTestWindowTest { |
- protected: |
- ChromeLauncherControllerImplTest() |
- : BrowserWithTestWindowTest(Browser::TYPE_TABBED, false) {} |
- |
- ~ChromeLauncherControllerImplTest() override {} |
- |
- void SetUp() override { |
- base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
- command_line->AppendSwitch(switches::kUseFirstDisplayAsInternal); |
- |
- app_list::AppListSyncableServiceFactory::SetUseInTesting(); |
- |
- shell_delegate_ = new ChromeLauncherTestShellDelegate(); |
- ash_test_helper()->set_test_shell_delegate(shell_delegate_); |
- |
- BrowserWithTestWindowTest::SetUp(); |
- |
- if (!profile_manager_) { |
- profile_manager_.reset( |
- new TestingProfileManager(TestingBrowserProcess::GetGlobal())); |
- ASSERT_TRUE(profile_manager_->SetUp()); |
- } |
- |
- model_ = ash::Shell::Get()->shelf_controller()->model(); |
- model_observer_.reset(new TestShelfModelObserver); |
- model_->AddObserver(model_observer_.get()); |
- |
- base::DictionaryValue manifest; |
- manifest.SetString(extensions::manifest_keys::kName, |
- "launcher controller test extension"); |
- manifest.SetString(extensions::manifest_keys::kVersion, "1"); |
- manifest.SetString(extensions::manifest_keys::kDescription, |
- "for testing pinned apps"); |
- |
- base::DictionaryValue manifest_platform_app; |
- manifest_platform_app.SetString(extensions::manifest_keys::kName, |
- "launcher controller test platform app"); |
- manifest_platform_app.SetString(extensions::manifest_keys::kVersion, "1"); |
- manifest_platform_app.SetString(extensions::manifest_keys::kDescription, |
- "for testing pinned platform apps"); |
- manifest_platform_app.SetString(extensions::manifest_keys::kApp, "true"); |
- manifest_platform_app.Set(extensions::manifest_keys::kPlatformAppBackground, |
- base::MakeUnique<base::DictionaryValue>()); |
- auto scripts = base::MakeUnique<base::ListValue>(); |
- scripts->AppendString("main.js"); |
- manifest_platform_app.Set( |
- extensions::manifest_keys::kPlatformAppBackgroundScripts, |
- std::move(scripts)); |
- |
- extensions::TestExtensionSystem* extension_system( |
- static_cast<extensions::TestExtensionSystem*>( |
- extensions::ExtensionSystem::Get(profile()))); |
- extension_service_ = extension_system->CreateExtensionService( |
- base::CommandLine::ForCurrentProcess(), base::FilePath(), false); |
- extension_service_->Init(); |
- |
- if (auto_start_arc_test_) |
- arc_test_.SetUp(profile()); |
- |
- // Wait until |extension_system| is signaled as started. |
- base::RunLoop run_loop; |
- extension_system->ready().Post(FROM_HERE, run_loop.QuitClosure()); |
- run_loop.Run(); |
- |
- app_service_ = |
- app_list::AppListSyncableServiceFactory::GetForProfile(profile()); |
- StartAppSyncService(syncer::SyncDataList()); |
- |
- std::string error; |
- extension_chrome_ = Extension::Create(base::FilePath(), Manifest::UNPACKED, |
- manifest, Extension::NO_FLAGS, |
- extension_misc::kChromeAppId, &error); |
- extension1_ = Extension::Create(base::FilePath(), Manifest::UNPACKED, |
- manifest, Extension::NO_FLAGS, |
- "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", &error); |
- extension2_ = Extension::Create(base::FilePath(), Manifest::UNPACKED, |
- manifest, Extension::NO_FLAGS, |
- "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", &error); |
- // Fake gmail extension. |
- base::DictionaryValue manifest_gmail; |
- manifest_gmail.SetString(extensions::manifest_keys::kName, |
- "Gmail launcher controller test extension"); |
- manifest_gmail.SetString(extensions::manifest_keys::kVersion, "1"); |
- manifest_gmail.SetString(extensions::manifest_keys::kDescription, |
- "for testing pinned Gmail"); |
- manifest_gmail.SetString(extensions::manifest_keys::kLaunchWebURL, |
- kGmailLaunchURL); |
- auto list = base::MakeUnique<base::ListValue>(); |
- list->AppendString("*://mail.google.com/mail/ca"); |
- manifest_gmail.Set(extensions::manifest_keys::kWebURLs, std::move(list)); |
- |
- extension3_ = Extension::Create(base::FilePath(), Manifest::UNPACKED, |
- manifest_gmail, Extension::NO_FLAGS, |
- extension_misc::kGmailAppId, &error); |
- |
- // Fake google docs extension. |
- extension4_ = Extension::Create(base::FilePath(), Manifest::UNPACKED, |
- manifest, Extension::NO_FLAGS, |
- extension_misc::kGoogleDocAppId, &error); |
- extension5_ = Extension::Create(base::FilePath(), Manifest::UNPACKED, |
- manifest, Extension::NO_FLAGS, |
- "cccccccccccccccccccccccccccccccc", &error); |
- extension6_ = Extension::Create(base::FilePath(), Manifest::UNPACKED, |
- manifest, Extension::NO_FLAGS, |
- "dddddddddddddddddddddddddddddddd", &error); |
- extension7_ = Extension::Create(base::FilePath(), Manifest::UNPACKED, |
- manifest, Extension::NO_FLAGS, |
- "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", &error); |
- extension8_ = Extension::Create(base::FilePath(), Manifest::UNPACKED, |
- manifest, Extension::NO_FLAGS, |
- "ffffffffffffffffffffffffffffffff", &error); |
- extension_platform_app_ = Extension::Create( |
- base::FilePath(), Manifest::UNPACKED, manifest_platform_app, |
- Extension::NO_FLAGS, "gggggggggggggggggggggggggggggggg", &error); |
- arc_support_host_ = Extension::Create(base::FilePath(), Manifest::UNPACKED, |
- manifest, Extension::NO_FLAGS, |
- ArcSupportHost::kHostAppId, &error); |
- extension_service_->AddExtension(extension_chrome_.get()); |
- } |
- |
- // Creates a running platform V2 app (not pinned) of type |app_id|. |
- virtual void CreateRunningV2App(const std::string& app_id) { |
- DCHECK(!test_controller_); |
- // Change the created launcher controller into a V2 app controller. |
- std::unique_ptr<TestV2AppLauncherItemController> controller = |
- base::MakeUnique<TestV2AppLauncherItemController>(app_id); |
- test_controller_ = controller.get(); |
- ash::ShelfID id = launcher_controller_->InsertAppLauncherItem( |
- std::move(controller), ash::STATUS_RUNNING, model_->item_count(), |
- ash::TYPE_APP); |
- DCHECK(launcher_controller_->IsPlatformApp(id)); |
- } |
- |
- // Sets the stage for a multi user test. |
- virtual void SetUpMultiUserScenario(syncer::SyncChangeList* user_a, |
- syncer::SyncChangeList* user_b) { |
- InitLauncherController(); |
- EXPECT_EQ("AppList, Chrome", GetPinnedAppStatus()); |
- |
- // Set an empty pinned pref to begin with. |
- syncer::SyncChangeList sync_list; |
- InsertAddPinChange(&sync_list, 0, extension_misc::kChromeAppId); |
- SendPinChanges(sync_list, true); |
- EXPECT_EQ("AppList, Chrome", GetPinnedAppStatus()); |
- |
- // Assume all applications have been added already. |
- extension_service_->AddExtension(extension1_.get()); |
- extension_service_->AddExtension(extension2_.get()); |
- extension_service_->AddExtension(extension3_.get()); |
- extension_service_->AddExtension(extension4_.get()); |
- extension_service_->AddExtension(extension5_.get()); |
- extension_service_->AddExtension(extension6_.get()); |
- extension_service_->AddExtension(extension7_.get()); |
- extension_service_->AddExtension(extension8_.get()); |
- extension_service_->AddExtension(extension_platform_app_.get()); |
- // There should be nothing in the list by now. |
- EXPECT_EQ("AppList, Chrome", GetPinnedAppStatus()); |
- |
- // Set user a preferences. |
- InsertAddPinChange(user_a, 0, extension1_->id()); |
- InsertAddPinChange(user_a, 1, extension2_->id()); |
- InsertAddPinChange(user_a, 2, extension3_->id()); |
- InsertAddPinChange(user_a, 3, extension_platform_app_->id()); |
- InsertAddPinChange(user_a, 4, extension4_->id()); |
- InsertAddPinChange(user_a, 5, extension5_->id()); |
- InsertAddPinChange(user_a, 6, extension_misc::kChromeAppId); |
- |
- // Set user b preferences. |
- InsertAddPinChange(user_b, 0, extension6_->id()); |
- InsertAddPinChange(user_b, 1, extension7_->id()); |
- InsertAddPinChange(user_b, 2, extension8_->id()); |
- InsertAddPinChange(user_b, 3, extension_misc::kChromeAppId); |
- } |
- |
- void TearDown() override { |
- arc_test_.TearDown(); |
- model_->RemoveObserver(model_observer_.get()); |
- model_observer_.reset(); |
- launcher_controller_ = nullptr; |
- BrowserWithTestWindowTest::TearDown(); |
- } |
- |
- BrowserWindow* CreateBrowserWindow() override { |
- return CreateTestBrowserWindowAura(); |
- } |
- |
- std::unique_ptr<Browser> CreateBrowserWithTestWindowForProfile( |
- Profile* profile) { |
- TestBrowserWindow* browser_window = CreateTestBrowserWindowAura(); |
- new TestBrowserWindowOwner(browser_window); |
- return base::WrapUnique( |
- CreateBrowser(profile, Browser::TYPE_TABBED, false, browser_window)); |
- } |
- |
- void AddAppListLauncherItem() { |
- ash::ShelfItem app_list; |
- app_list.type = ash::TYPE_APP_LIST; |
- model_->Add(app_list); |
- } |
- |
- // Create a launcher controller instance, owned by the test shell delegate. |
- // Returns a pointer to the uninitialized controller. |
- ChromeLauncherControllerImpl* CreateLauncherController() { |
- launcher_controller_ = shell_delegate_->CreateLauncherController(profile()); |
- return launcher_controller_; |
- } |
- |
- // Create and initialize the controller, owned by the test shell delegate. |
- void InitLauncherController() { CreateLauncherController()->Init(); } |
- |
- // Create and initialize the controller; create a tab and show the browser. |
- void InitLauncherControllerWithBrowser() { |
- InitLauncherController(); |
- chrome::NewTab(browser()); |
- browser()->window()->Show(); |
- } |
- |
- // Destroy the launcher controller instance and clear the local pointer. |
- void ResetLauncherController() { |
- launcher_controller_ = nullptr; |
- shell_delegate_->ShelfShutdown(); |
- } |
- |
- // Destroy and recreate the controller; clear and reinitialize the ShelfModel. |
- // Returns a pointer to the uninitialized controller, owned by shell delegate. |
- // TODO(msw): This does not accurately represent ChromeLauncherControllerImpl |
- // lifetime or usage in production, and does not accurately simulate restarts. |
- ChromeLauncherControllerImpl* RecreateLauncherController() { |
- // Destroy any existing controller first; only one may exist at a time. |
- ResetLauncherController(); |
- while (model_->item_count() > 0) |
- model_->RemoveItemAt(0); |
- AddAppListLauncherItem(); |
- return CreateLauncherController(); |
- } |
- |
- void StartAppSyncService(const syncer::SyncDataList& init_sync_list) { |
- app_service_->MergeDataAndStartSyncing( |
- syncer::APP_LIST, init_sync_list, |
- base::MakeUnique<syncer::FakeSyncChangeProcessor>(), |
- base::MakeUnique<syncer::SyncErrorFactoryMock>()); |
- EXPECT_EQ(init_sync_list.size(), app_service_->sync_items().size()); |
- } |
- |
- void StopAppSyncService() { app_service_->StopSyncing(syncer::APP_LIST); } |
- |
- sync_preferences::PrefModelAssociator* GetPrefSyncService() { |
- sync_preferences::PrefServiceSyncable* pref_sync = |
- profile()->GetTestingPrefService(); |
- sync_preferences::PrefModelAssociator* pref_sync_service = |
- reinterpret_cast<sync_preferences::PrefModelAssociator*>( |
- pref_sync->GetSyncableService(syncer::PREFERENCES)); |
- return pref_sync_service; |
- } |
- |
- void StartPrefSyncService(const syncer::SyncDataList& init_sync_list) { |
- syncer::SyncMergeResult r = GetPrefSyncService()->MergeDataAndStartSyncing( |
- syncer::PREFERENCES, init_sync_list, |
- base::MakeUnique<syncer::FakeSyncChangeProcessor>(), |
- base::MakeUnique<syncer::SyncErrorFactoryMock>()); |
- EXPECT_FALSE(r.error().IsSet()); |
- } |
- |
- void StartPrefSyncServiceForPins(const base::ListValue& init_value) { |
- syncer::SyncDataList init_sync_list; |
- std::string serialized; |
- JSONStringValueSerializer json(&serialized); |
- json.Serialize(init_value); |
- sync_pb::EntitySpecifics one; |
- sync_pb::PreferenceSpecifics* pref_one = one.mutable_preference(); |
- pref_one->set_name(prefs::kPinnedLauncherApps); |
- pref_one->set_value(serialized); |
- init_sync_list.push_back(syncer::SyncData::CreateRemoteData( |
- 1, one, base::Time(), syncer::AttachmentIdList(), |
- syncer::AttachmentServiceProxyForTest::Create())); |
- StartPrefSyncService(init_sync_list); |
- } |
- |
- void StopPrefSyncService() { |
- GetPrefSyncService()->StopSyncing(syncer::PREFERENCES); |
- } |
- |
- void SetAppIconLoader(std::unique_ptr<AppIconLoader> loader) { |
- std::vector<std::unique_ptr<AppIconLoader>> loaders; |
- loaders.push_back(std::move(loader)); |
- launcher_controller_->SetAppIconLoadersForTest(loaders); |
- } |
- |
- void SetAppIconLoaders(std::unique_ptr<AppIconLoader> loader1, |
- std::unique_ptr<AppIconLoader> loader2) { |
- std::vector<std::unique_ptr<AppIconLoader>> loaders; |
- loaders.push_back(std::move(loader1)); |
- loaders.push_back(std::move(loader2)); |
- launcher_controller_->SetAppIconLoadersForTest(loaders); |
- } |
- |
- void SetLauncherControllerHelper(LauncherControllerHelper* helper) { |
- launcher_controller_->SetLauncherControllerHelperForTest( |
- base::WrapUnique<LauncherControllerHelper>(helper)); |
- } |
- |
- void InsertPrefValue(base::ListValue* pref_value, |
- int index, |
- const std::string& extension_id) { |
- auto entry = base::MakeUnique<base::DictionaryValue>(); |
- entry->SetString(ash::launcher::kPinnedAppsPrefAppIDPath, extension_id); |
- pref_value->Insert(index, std::move(entry)); |
- } |
- |
- void InsertRemoveAllPinsChange(syncer::SyncChangeList* list) { |
- for (const auto& sync_peer : app_service_->sync_items()) { |
- sync_pb::EntitySpecifics specifics; |
- sync_pb::AppListSpecifics* app_list_specifics = |
- specifics.mutable_app_list(); |
- app_list_specifics->set_item_id(sync_peer.first); |
- app_list_specifics->set_item_type(sync_pb::AppListSpecifics::TYPE_APP); |
- syncer::SyncData sync_data = |
- syncer::SyncData::CreateLocalData(sync_peer.first, "Test", specifics); |
- list->push_back(syncer::SyncChange( |
- FROM_HERE, syncer::SyncChange::ACTION_DELETE, sync_data)); |
- } |
- } |
- |
- syncer::StringOrdinal GeneratePinPosition(int position) { |
- syncer::StringOrdinal ordinal_position = |
- syncer::StringOrdinal::CreateInitialOrdinal(); |
- for (int i = 0; i < position; ++i) |
- ordinal_position = ordinal_position.CreateAfter(); |
- return ordinal_position; |
- } |
- |
- void InsertPinChange(syncer::SyncChangeList* list, |
- int position, |
- bool add_pin_change, |
- const std::string& app_id, |
- syncer::SyncChange::SyncChangeType type) { |
- sync_pb::EntitySpecifics specifics; |
- sync_pb::AppListSpecifics* app_list_specifics = |
- specifics.mutable_app_list(); |
- app_list_specifics->set_item_id(app_id); |
- app_list_specifics->set_item_type(sync_pb::AppListSpecifics::TYPE_APP); |
- if (add_pin_change) { |
- if (position >= 0) { |
- app_list_specifics->set_item_pin_ordinal( |
- GeneratePinPosition(position).ToInternalValue()); |
- } else { |
- app_list_specifics->set_item_pin_ordinal(std::string()); |
- } |
- } |
- syncer::SyncData sync_data = |
- syncer::SyncData::CreateLocalData(app_id, "Test", specifics); |
- list->push_back(syncer::SyncChange(FROM_HERE, type, sync_data)); |
- } |
- |
- void InsertAddPinChange(syncer::SyncChangeList* list, |
- int position, |
- const std::string& app_id) { |
- InsertPinChange(list, position, true, app_id, |
- syncer::SyncChange::ACTION_ADD); |
- } |
- |
- void InsertUpdatePinChange(syncer::SyncChangeList* list, |
- int position, |
- const std::string& app_id) { |
- InsertPinChange(list, position, true, app_id, |
- syncer::SyncChange::ACTION_UPDATE); |
- } |
- |
- void InsertRemovePinChange(syncer::SyncChangeList* list, |
- const std::string& app_id) { |
- InsertPinChange(list, -1, true, app_id, syncer::SyncChange::ACTION_UPDATE); |
- } |
- |
- void InsertLegacyPinChange(syncer::SyncChangeList* list, |
- const std::string& app_id) { |
- InsertPinChange(list, -1, false, app_id, syncer::SyncChange::ACTION_UPDATE); |
- } |
- |
- void ResetPinModel() { |
- syncer::SyncChangeList sync_list; |
- InsertRemoveAllPinsChange(&sync_list); |
- InsertAddPinChange(&sync_list, 0, kDummyAppId); |
- app_service_->ProcessSyncChanges(FROM_HERE, sync_list); |
- } |
- |
- void SendPinChanges(const syncer::SyncChangeList& sync_list, |
- bool reset_pin_model) { |
- if (!reset_pin_model) { |
- app_service_->ProcessSyncChanges(FROM_HERE, sync_list); |
- } else { |
- syncer::SyncChangeList combined_sync_list; |
- InsertRemoveAllPinsChange(&combined_sync_list); |
- combined_sync_list.insert(combined_sync_list.end(), sync_list.begin(), |
- sync_list.end()); |
- app_service_->ProcessSyncChanges(FROM_HERE, combined_sync_list); |
- } |
- } |
- |
- // Set the index at which the chrome icon should be. |
- void SetShelfChromeIconIndex(int index) { |
- DCHECK( |
- app_service_->GetPinPosition(extension_misc::kChromeAppId).IsValid()); |
- syncer::StringOrdinal chrome_position; |
- chrome_position = index == 0 ? GeneratePinPosition(0).CreateBefore() |
- : GeneratePinPosition(index - 1).CreateBetween( |
- GeneratePinPosition(index)); |
- |
- syncer::SyncChangeList sync_list; |
- sync_pb::EntitySpecifics specifics; |
- sync_pb::AppListSpecifics* app_list_specifics = |
- specifics.mutable_app_list(); |
- app_list_specifics->set_item_id(extension_misc::kChromeAppId); |
- app_list_specifics->set_item_type(sync_pb::AppListSpecifics::TYPE_APP); |
- app_list_specifics->set_item_pin_ordinal(chrome_position.ToInternalValue()); |
- syncer::SyncData sync_data = syncer::SyncData::CreateLocalData( |
- extension_misc::kChromeAppId, "Test", specifics); |
- sync_list.push_back(syncer::SyncChange( |
- FROM_HERE, syncer::SyncChange::ACTION_UPDATE, sync_data)); |
- app_service_->ProcessSyncChanges(FROM_HERE, sync_list); |
- } |
- |
- // Gets the IDs of the currently pinned app items. |
- void GetPinnedAppIds(ChromeLauncherControllerImpl* controller, |
- std::vector<std::string>* app_ids) { |
- app_ids->clear(); |
- for (const auto& item : model_->items()) { |
- if (item.type == ash::TYPE_PINNED_APP) |
- app_ids->push_back(item.app_launch_id.app_id()); |
- } |
- } |
- |
- // Get the setup of the currently shown launcher items in one string. |
- // Each pinned element will start with a big letter, each running but not |
- // pinned V1 app will start with a small letter and each running but not |
- // pinned V2 app will start with a '*' + small letter. |
- std::string GetPinnedAppStatus() { |
- std::string result; |
- for (int i = 0; i < model_->item_count(); i++) { |
- if (!result.empty()) |
- result.append(", "); |
- switch (model_->items()[i].type) { |
- case ash::TYPE_APP: { |
- if (launcher_controller_->IsPlatformApp(model_->items()[i].id)) |
- result += "*"; |
- const std::string& app = |
- launcher_controller_->GetAppIDForShelfID(model_->items()[i].id); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(app)); |
- if (app == extension1_->id()) { |
- result += "app1"; |
- } else if (app == extension2_->id()) { |
- result += "app2"; |
- } else if (app == extension3_->id()) { |
- result += "app3"; |
- } else if (app == extension4_->id()) { |
- result += "app4"; |
- } else if (app == extension5_->id()) { |
- result += "app5"; |
- } else if (app == extension6_->id()) { |
- result += "app6"; |
- } else if (app == extension7_->id()) { |
- result += "app7"; |
- } else if (app == extension8_->id()) { |
- result += "app8"; |
- } else if (app == extension_platform_app_->id()) { |
- result += "platform_app"; |
- } else { |
- result += "unknown"; |
- } |
- break; |
- } |
- case ash::TYPE_PINNED_APP: { |
- if (launcher_controller_->IsPlatformApp(model_->items()[i].id)) |
- result += "*"; |
- const std::string& app = |
- launcher_controller_->GetAppIDForShelfID(model_->items()[i].id); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(app)); |
- if (app == extension1_->id()) { |
- result += "App1"; |
- } else if (app == extension2_->id()) { |
- result += "App2"; |
- } else if (app == extension3_->id()) { |
- result += "App3"; |
- } else if (app == extension4_->id()) { |
- result += "App4"; |
- } else if (app == extension5_->id()) { |
- result += "App5"; |
- } else if (app == extension6_->id()) { |
- result += "App6"; |
- } else if (app == extension7_->id()) { |
- result += "App7"; |
- } else if (app == extension8_->id()) { |
- result += "App8"; |
- } else if (app == extension_platform_app_->id()) { |
- result += "Platform_App"; |
- } else if (app == arc_support_host_->id()) { |
- result += "Play Store"; |
- } else { |
- bool arc_app_found = false; |
- for (const auto& arc_app : arc_test_.fake_apps()) { |
- if (app == ArcAppTest::GetAppId(arc_app)) { |
- result += arc_app.name; |
- arc_app_found = true; |
- break; |
- } |
- } |
- if (!arc_app_found) |
- result += "unknown"; |
- } |
- break; |
- } |
- case ash::TYPE_BROWSER_SHORTCUT: |
- result += "Chrome"; |
- break; |
- case ash::TYPE_APP_LIST: |
- result += "AppList"; |
- break; |
- default: |
- result += "Unknown"; |
- break; |
- } |
- } |
- return result; |
- } |
- |
- // Remember the order of unpinned but running applications for the current |
- // user. |
- void RememberUnpinnedRunningApplicationOrder() { |
- launcher_controller_->RememberUnpinnedRunningApplicationOrder(); |
- } |
- |
- // Restore the order of running but unpinned applications for a given user. |
- void RestoreUnpinnedRunningApplicationOrder(const AccountId& account_id) { |
- launcher_controller_->RestoreUnpinnedRunningApplicationOrder( |
- account_id.GetUserEmail()); |
- } |
- |
- void SendListOfArcApps() { |
- arc_test_.app_instance()->RefreshAppList(); |
- arc_test_.app_instance()->SendRefreshAppList(arc_test_.fake_apps()); |
- } |
- |
- void SendListOfArcShortcuts() { |
- arc_test_.app_instance()->SendInstallShortcuts(arc_test_.fake_shortcuts()); |
- } |
- |
- void UninstallArcApps() { |
- arc_test_.app_instance()->RefreshAppList(); |
- arc_test_.app_instance()->SendRefreshAppList( |
- std::vector<arc::mojom::AppInfo>()); |
- } |
- |
- // TODO(victorhsieh): Add test coverage for when ARC is started regardless |
- // Play Store opt-in status, and the followed opt-in and opt-out. |
- void EnablePlayStore(bool enabled) { |
- arc::SetArcPlayStoreEnabledForProfile(profile(), enabled); |
- base::RunLoop().RunUntilIdle(); |
- } |
- |
- void EnableTabletMode(bool enable) { |
- ash::MaximizeModeController* controller = |
- ash::Shell::Get()->maximize_mode_controller(); |
- controller->EnableMaximizeModeWindowManager(enable); |
- } |
- |
- void ValidateArcState(bool arc_enabled, |
- bool arc_managed, |
- arc::ArcSessionManager::State state, |
- const std::string& pin_status) { |
- EXPECT_EQ(arc_enabled, arc::IsArcPlayStoreEnabledForProfile(profile())); |
- EXPECT_EQ(arc_managed, |
- arc::IsArcPlayStoreEnabledPreferenceManagedForProfile(profile())); |
- EXPECT_EQ(state, arc_test_.arc_session_manager()->state()); |
- EXPECT_EQ(pin_status, GetPinnedAppStatus()); |
- } |
- |
- // Creates app window and set optional ARC application id. |
- views::Widget* CreateArcWindow(const std::string& window_app_id) { |
- views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); |
- params.bounds = gfx::Rect(5, 5, 20, 20); |
- params.context = GetContext(); |
- views::Widget* widget = new views::Widget(); |
- widget->Init(params); |
- // Set ARC id before showing the window to be recognized in |
- // ArcAppWindowLauncherController. |
- exo::ShellSurface::SetApplicationId(widget->GetNativeWindow(), |
- window_app_id); |
- widget->Show(); |
- widget->Activate(); |
- return widget; |
- } |
- |
- arc::mojom::AppInfo CreateAppInfo(const std::string& name, |
- const std::string& activity, |
- const std::string& package_name, |
- OrientationLock lock) { |
- arc::mojom::AppInfo appinfo; |
- appinfo.name = name; |
- appinfo.package_name = package_name; |
- appinfo.activity = activity; |
- appinfo.orientation_lock = lock; |
- return appinfo; |
- } |
- |
- std::string AddArcAppAndShortcut(const arc::mojom::AppInfo& app_info) { |
- ArcAppListPrefs* const prefs = arc_test_.arc_app_list_prefs(); |
- // Adding app to the prefs, and check that the app is accessible by id. |
- prefs->AddAppAndShortcut( |
- true /* app_ready */, app_info.name, app_info.package_name, |
- app_info.activity, std::string() /* intent_uri */, |
- std::string() /* icon_resource_id */, false /* sticky */, |
- true /* notifications_enabled */, false /* shortcut */, |
- true /* launchable */, app_info.orientation_lock); |
- const std::string app_id = |
- ArcAppListPrefs::GetAppId(app_info.package_name, app_info.activity); |
- EXPECT_TRUE(prefs->GetApp(app_id)); |
- return app_id; |
- } |
- |
- void NotifyOnTaskCreated(const arc::mojom::AppInfo& appinfo, |
- int32_t task_id) { |
- ArcAppListPrefs* const prefs = arc_test_.arc_app_list_prefs(); |
- prefs->OnTaskCreated(task_id, appinfo.package_name, appinfo.activity, |
- appinfo.name, std::string()); |
- } |
- |
- void NotifyOnTaskOrientationLockRequested(int32_t task_id, |
- OrientationLock lock) { |
- ArcAppListPrefs* const prefs = arc_test_.arc_app_list_prefs(); |
- prefs->OnTaskOrientationLockRequested(task_id, lock); |
- } |
- |
- // Needed for extension service & friends to work. |
- scoped_refptr<Extension> extension_chrome_; |
- scoped_refptr<Extension> extension1_; |
- scoped_refptr<Extension> extension2_; |
- scoped_refptr<Extension> extension3_; |
- scoped_refptr<Extension> extension4_; |
- scoped_refptr<Extension> extension5_; |
- scoped_refptr<Extension> extension6_; |
- scoped_refptr<Extension> extension7_; |
- scoped_refptr<Extension> extension8_; |
- scoped_refptr<Extension> extension_platform_app_; |
- scoped_refptr<Extension> arc_support_host_; |
- |
- ArcAppTest arc_test_; |
- bool auto_start_arc_test_ = false; |
- ChromeLauncherControllerImpl* launcher_controller_ = nullptr; |
- ChromeLauncherTestShellDelegate* shell_delegate_ = nullptr; |
- std::unique_ptr<TestShelfModelObserver> model_observer_; |
- ash::ShelfModel* model_ = nullptr; |
- std::unique_ptr<TestingProfileManager> profile_manager_; |
- |
- // |item_delegate_manager_| owns |test_controller_|. |
- ash::ShelfItemDelegate* test_controller_ = nullptr; |
- |
- ExtensionService* extension_service_ = nullptr; |
- |
- app_list::AppListSyncableService* app_service_ = nullptr; |
- |
- private: |
- TestBrowserWindow* CreateTestBrowserWindowAura() { |
- std::unique_ptr<aura::Window> window(new aura::Window(nullptr)); |
- window->set_id(0); |
- window->SetType(ui::wm::WINDOW_TYPE_NORMAL); |
- window->Init(ui::LAYER_TEXTURED); |
- aura::client::ParentWindowWithContext(window.get(), GetContext(), |
- gfx::Rect(200, 200)); |
- |
- return new TestBrowserWindowAura(std::move(window)); |
- } |
- |
- DISALLOW_COPY_AND_ASSIGN(ChromeLauncherControllerImplTest); |
-}; |
- |
-class ChromeLauncherControllerImplWithArcTest |
- : public ChromeLauncherControllerImplTest, |
- public ::testing::WithParamInterface<bool> { |
- protected: |
- ChromeLauncherControllerImplWithArcTest() { auto_start_arc_test_ = true; } |
- ~ChromeLauncherControllerImplWithArcTest() override {} |
- |
- void SetUp() override { |
- if (GetParam()) |
- arc::SetArcAlwaysStartForTesting(); |
- ChromeLauncherControllerImplTest::SetUp(); |
- } |
- |
- private: |
- DISALLOW_COPY_AND_ASSIGN(ChromeLauncherControllerImplWithArcTest); |
-}; |
- |
-INSTANTIATE_TEST_CASE_P(, |
- ChromeLauncherControllerImplWithArcTest, |
- ::testing::Bool()); |
- |
-// Watches WebContents and blocks until it is destroyed. This is needed for |
-// the destruction of a V2 application. |
-class WebContentsDestroyedWatcher : public content::WebContentsObserver { |
- public: |
- explicit WebContentsDestroyedWatcher(content::WebContents* web_contents) |
- : content::WebContentsObserver(web_contents), |
- message_loop_runner_(new content::MessageLoopRunner) { |
- EXPECT_TRUE(web_contents != NULL); |
- } |
- ~WebContentsDestroyedWatcher() override {} |
- |
- // Waits until the WebContents is destroyed. |
- void Wait() { |
- message_loop_runner_->Run(); |
- } |
- |
- private: |
- // Overridden WebContentsObserver methods. |
- void WebContentsDestroyed() override { message_loop_runner_->Quit(); } |
- |
- scoped_refptr<content::MessageLoopRunner> message_loop_runner_; |
- |
- DISALLOW_COPY_AND_ASSIGN(WebContentsDestroyedWatcher); |
-}; |
- |
-// A V1 windowed application. |
-class V1App : public TestBrowserWindow { |
- public: |
- V1App(Profile* profile, const std::string& app_name) { |
- Browser::CreateParams params = Browser::CreateParams::CreateForApp( |
- kCrxAppPrefix + app_name, true /* trusted_source */, gfx::Rect(), |
- profile, true); |
- params.window = this; |
- browser_.reset(new Browser(params)); |
- chrome::AddTabAt(browser_.get(), GURL(), 0, true); |
- } |
- |
- ~V1App() override { |
- // close all tabs. Note that we do not need to destroy the browser itself. |
- browser_->tab_strip_model()->CloseAllTabs(); |
- } |
- |
- Browser* browser() { return browser_.get(); } |
- |
- private: |
- // The associated browser with this app. |
- std::unique_ptr<Browser> browser_; |
- |
- DISALLOW_COPY_AND_ASSIGN(V1App); |
-}; |
- |
-// A V2 application window created with an |extension| and for a |profile|. |
-// Upon destruction it will properly close the application; supports panels too. |
-class V2App { |
- public: |
- V2App(Profile* profile, |
- const extensions::Extension* extension, |
- extensions::AppWindow::WindowType window_type = |
- extensions::AppWindow::WINDOW_TYPE_DEFAULT) |
- : creator_web_contents_( |
- content::WebContentsTester::CreateTestWebContents(profile, |
- nullptr)) { |
- window_ = new extensions::AppWindow(profile, new ChromeAppDelegate(true), |
- extension); |
- extensions::AppWindow::CreateParams params; |
- params.window_type = window_type; |
- // Note: normally, the creator RFH is the background page of the |
- // app/extension |
- // calling chrome.app.window.create. For unit testing purposes, just passing |
- // in a random RenderFrameHost is Good Enoughâ„¢. |
- window_->Init(GURL(std::string()), |
- new extensions::AppWindowContentsImpl(window_), |
- creator_web_contents_->GetMainFrame(), params); |
- } |
- |
- virtual ~V2App() { |
- WebContentsDestroyedWatcher destroyed_watcher(window_->web_contents()); |
- window_->GetBaseWindow()->Close(); |
- destroyed_watcher.Wait(); |
- } |
- |
- extensions::AppWindow* window() { return window_; } |
- |
- private: |
- std::unique_ptr<content::WebContents> creator_web_contents_; |
- |
- // The app window which represents the application. Note that the window |
- // deletes itself asynchronously after window_->GetBaseWindow()->Close() gets |
- // called. |
- extensions::AppWindow* window_; |
- |
- DISALLOW_COPY_AND_ASSIGN(V2App); |
-}; |
- |
-// The testing framework to test multi profile scenarios. |
-class MultiProfileMultiBrowserShelfLayoutChromeLauncherControllerImplTest |
- : public ChromeLauncherControllerImplTest { |
- protected: |
- MultiProfileMultiBrowserShelfLayoutChromeLauncherControllerImplTest() {} |
- |
- ~MultiProfileMultiBrowserShelfLayoutChromeLauncherControllerImplTest() |
- override {} |
- |
- // Overwrite the Setup function to enable multi profile and needed objects. |
- void SetUp() override { |
- profile_manager_.reset( |
- new TestingProfileManager(TestingBrowserProcess::GetGlobal())); |
- |
- ASSERT_TRUE(profile_manager_->SetUp()); |
- |
- // AvatarMenu and multiple profiles works after user logged in. |
- profile_manager_->SetLoggedIn(true); |
- |
- // Initialize the UserManager singleton to a fresh FakeUserManager instance. |
- user_manager_enabler_.reset(new chromeos::ScopedUserManagerEnabler( |
- new chromeos::FakeChromeUserManager)); |
- |
- // Initialize the WallpaperManager singleton. |
- chromeos::WallpaperManager::Initialize(); |
- |
- // Initialize the rest. |
- ChromeLauncherControllerImplTest::SetUp(); |
- shell_delegate_->set_multi_profiles_enabled(true); |
- } |
- |
- void TearDown() override { |
- ChromeLauncherControllerImplTest::TearDown(); |
- user_manager_enabler_.reset(); |
- for (ProfileToNameMap::iterator it = created_profiles_.begin(); |
- it != created_profiles_.end(); ++it) |
- profile_manager_->DeleteTestingProfile(it->second); |
- chromeos::WallpaperManager::Shutdown(); |
- |
- // A Task is leaked if we don't destroy everything, then run the message |
- // loop. |
- base::RunLoop().RunUntilIdle(); |
- } |
- |
- // Creates a profile for a given |user_name|. Note that this class will keep |
- // the ownership of the created object. |
- TestingProfile* CreateMultiUserProfile(const std::string& user_name) { |
- const std::string email_string = user_name + "@example.com"; |
- const AccountId account_id(AccountId::FromUserEmail(email_string)); |
- // Add a user to the fake user manager. |
- GetFakeUserManager()->AddUser(account_id); |
- |
- GetFakeUserManager()->LoginUser(account_id); |
- |
- TestingProfile* profile = |
- profile_manager()->CreateTestingProfile(account_id.GetUserEmail()); |
- EXPECT_TRUE(profile); |
- |
- // Remember the profile name so that we can destroy it upon destruction. |
- created_profiles_[profile] = account_id.GetUserEmail(); |
- if (chrome::MultiUserWindowManager::GetInstance()) |
- chrome::MultiUserWindowManager::GetInstance()->AddUser(profile); |
- if (launcher_controller_) |
- launcher_controller_->AdditionalUserAddedToSession(profile); |
- return profile; |
- } |
- |
- // Switch to another user. |
- void SwitchActiveUser(const AccountId& account_id) { |
- GetFakeUserManager()->SwitchActiveUser(account_id); |
- chrome::MultiUserWindowManagerChromeOS* manager = |
- static_cast<chrome::MultiUserWindowManagerChromeOS*>( |
- chrome::MultiUserWindowManager::GetInstance()); |
- manager->SetAnimationSpeedForTest( |
- chrome::MultiUserWindowManagerChromeOS::ANIMATION_SPEED_DISABLED); |
- manager->ActiveUserChanged(GetFakeUserManager()->FindUser(account_id)); |
- launcher_controller_->browser_status_monitor_for_test()->ActiveUserChanged( |
- account_id.GetUserEmail()); |
- |
- for (const auto& controller : |
- launcher_controller_->app_window_controllers_for_test()) { |
- controller->ActiveUserChanged(account_id.GetUserEmail()); |
- } |
- } |
- |
- // Creates a browser with a |profile| and load a tab with a |title| and |url|. |
- std::unique_ptr<Browser> CreateBrowserAndTabWithProfile( |
- Profile* profile, |
- const std::string& title, |
- const std::string& url) { |
- std::unique_ptr<Browser> browser( |
- CreateBrowserWithTestWindowForProfile(profile)); |
- chrome::NewTab(browser.get()); |
- |
- browser->window()->Show(); |
- NavigateAndCommitActiveTabWithTitle(browser.get(), GURL(url), |
- ASCIIToUTF16(title)); |
- return browser; |
- } |
- |
- // Creates a running V1 application. |
- // Note that with the use of the launcher_controller_helper as done below, |
- // this is only usable with a single v1 application. |
- V1App* CreateRunningV1App(Profile* profile, |
- const std::string& app_name, |
- const std::string& url) { |
- V1App* v1_app = new V1App(profile, app_name); |
- NavigateAndCommitActiveTabWithTitle(v1_app->browser(), GURL(url), |
- base::string16()); |
- return v1_app; |
- } |
- |
- // Override BrowserWithTestWindowTest: |
- TestingProfile* CreateProfile() override { |
- return CreateMultiUserProfile("user1"); |
- } |
- void DestroyProfile(TestingProfile* profile) override { |
- // Delete the profile through our profile manager. |
- ProfileToNameMap::iterator it = created_profiles_.find(profile); |
- DCHECK(it != created_profiles_.end()); |
- profile_manager_->DeleteTestingProfile(it->second); |
- created_profiles_.erase(it); |
- } |
- |
- private: |
- typedef std::map<Profile*, std::string> ProfileToNameMap; |
- TestingProfileManager* profile_manager() { return profile_manager_.get(); } |
- |
- chromeos::FakeChromeUserManager* GetFakeUserManager() { |
- return static_cast<chromeos::FakeChromeUserManager*>( |
- user_manager::UserManager::Get()); |
- } |
- |
- std::unique_ptr<chromeos::ScopedUserManagerEnabler> user_manager_enabler_; |
- |
- ProfileToNameMap created_profiles_; |
- |
- DISALLOW_COPY_AND_ASSIGN( |
- MultiProfileMultiBrowserShelfLayoutChromeLauncherControllerImplTest); |
-}; |
- |
-class ChromeLauncherControllerImplMultiProfileWithArcTest |
- : public MultiProfileMultiBrowserShelfLayoutChromeLauncherControllerImplTest, // NOLINT(whitespace/line_length) |
- public ::testing::WithParamInterface<bool> { |
- protected: |
- ChromeLauncherControllerImplMultiProfileWithArcTest() { |
- auto_start_arc_test_ = true; |
- } |
- ~ChromeLauncherControllerImplMultiProfileWithArcTest() override {} |
- |
- void SetUp() override { |
- if (GetParam()) |
- arc::SetArcAlwaysStartForTesting(); |
- MultiProfileMultiBrowserShelfLayoutChromeLauncherControllerImplTest:: |
- SetUp(); |
- } |
- |
- private: |
- DISALLOW_COPY_AND_ASSIGN(ChromeLauncherControllerImplMultiProfileWithArcTest); |
-}; |
- |
-INSTANTIATE_TEST_CASE_P(, |
- ChromeLauncherControllerImplMultiProfileWithArcTest, |
- ::testing::Bool()); |
- |
-TEST_F(ChromeLauncherControllerImplTest, DefaultApps) { |
- InitLauncherController(); |
- // The model should only contain the browser shortcut and app list items. |
- EXPECT_EQ(2, model_->item_count()); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension1_->id())); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension2_->id())); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension3_->id())); |
- |
- // Installing |extension3_| should add it to the launcher - behind the |
- // chrome icon. |
- extension_service_->AddExtension(extension3_.get()); |
- EXPECT_EQ("AppList, Chrome, App3", GetPinnedAppStatus()); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension1_->id())); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension2_->id())); |
-} |
- |
-TEST_P(ChromeLauncherControllerImplWithArcTest, |
- ArcAppPinCrossPlatformWorkflow) { |
- // Work on ARC disabled platform first. |
- const std::string arc_app_id1 = |
- ArcAppTest::GetAppId(arc_test_.fake_apps()[0]); |
- const std::string arc_app_id2 = |
- ArcAppTest::GetAppId(arc_test_.fake_apps()[1]); |
- const std::string arc_app_id3 = |
- ArcAppTest::GetAppId(arc_test_.fake_apps()[2]); |
- |
- InitLauncherController(); |
- |
- extension_service_->AddExtension(extension1_.get()); |
- extension_service_->AddExtension(extension2_.get()); |
- extension_service_->AddExtension(extension3_.get()); |
- |
- // extension 1, 3 are pinned by user |
- syncer::SyncChangeList sync_list; |
- InsertAddPinChange(&sync_list, 0, extension1_->id()); |
- InsertAddPinChange(&sync_list, 1, arc_app_id1); |
- InsertAddPinChange(&sync_list, 2, extension2_->id()); |
- InsertAddPinChange(&sync_list, 3, arc_app_id2); |
- InsertAddPinChange(&sync_list, 4, extension3_->id()); |
- SendPinChanges(sync_list, true); |
- SetShelfChromeIconIndex(1); |
- |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension1_->id())); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(arc_app_id1)); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension2_->id())); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(arc_app_id2)); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension3_->id())); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(arc_app_id3)); |
- EXPECT_EQ("AppList, App1, Chrome, App2, App3", GetPinnedAppStatus()); |
- |
- // Persist pin state, we don't have active pin for ARC apps yet, but pin |
- // model should have it. |
- syncer::SyncDataList copy_sync_list = |
- app_service_->GetAllSyncData(syncer::APP_LIST); |
- |
- ResetLauncherController(); |
- SendPinChanges(syncer::SyncChangeList(), true); |
- StopAppSyncService(); |
- EXPECT_EQ(0U, app_service_->sync_items().size()); |
- |
- // Move to ARC enabled platform, restart syncing with stored data. |
- StartAppSyncService(copy_sync_list); |
- RecreateLauncherController()->Init(); |
- |
- // Pins must be automatically updated. |
- SendListOfArcApps(); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension1_->id())); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(arc_app_id1)); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension2_->id())); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(arc_app_id2)); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension3_->id())); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(arc_app_id3)); |
- |
- EXPECT_EQ("AppList, App1, Chrome, Fake App 0, App2, Fake App 1, App3", |
- GetPinnedAppStatus()); |
- |
- // Now move pins on ARC enabled platform. |
- model_->Move(1, 4); |
- model_->Move(3, 1); |
- model_->Move(3, 5); |
- model_->Move(4, 2); |
- EXPECT_EQ("AppList, App2, Fake App 1, Chrome, App1, Fake App 0, App3", |
- GetPinnedAppStatus()); |
- |
- copy_sync_list = app_service_->GetAllSyncData(syncer::APP_LIST); |
- |
- ResetLauncherController(); |
- ResetPinModel(); |
- |
- SendPinChanges(syncer::SyncChangeList(), true); |
- StopAppSyncService(); |
- EXPECT_EQ(0U, app_service_->sync_items().size()); |
- |
- // Move back to ARC disabled platform. |
- // TODO(victorhsieh): Implement opt-out. |
- if (arc::ShouldArcAlwaysStart()) |
- return; |
- EnablePlayStore(false); |
- StartAppSyncService(copy_sync_list); |
- RecreateLauncherController()->Init(); |
- |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension1_->id())); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(arc_app_id1)); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension2_->id())); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(arc_app_id2)); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension3_->id())); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(arc_app_id3)); |
- EXPECT_EQ("AppList, App2, Chrome, App1, App3", GetPinnedAppStatus()); |
- |
- // Now move/remove pins on ARC disabled platform. |
- model_->Move(4, 2); |
- launcher_controller_->UnpinAppWithID(extension2_->id()); |
- EXPECT_EQ("AppList, App3, Chrome, App1", GetPinnedAppStatus()); |
- EnablePlayStore(true); |
- |
- SendListOfArcApps(); |
- |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension1_->id())); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(arc_app_id1)); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension2_->id())); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(arc_app_id2)); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension3_->id())); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(arc_app_id3)); |
- EXPECT_EQ("AppList, Fake App 1, App3, Chrome, App1, Fake App 0", |
- GetPinnedAppStatus()); |
-} |
- |
-/* |
- * Test ChromeLauncherControllerImpl correctly merges policy pinned apps |
- * and user pinned apps |
- */ |
-TEST_F(ChromeLauncherControllerImplTest, MergePolicyAndUserPrefPinnedApps) { |
- InitLauncherController(); |
- |
- extension_service_->AddExtension(extension1_.get()); |
- extension_service_->AddExtension(extension3_.get()); |
- extension_service_->AddExtension(extension4_.get()); |
- extension_service_->AddExtension(extension5_.get()); |
- // extension 1, 3 are pinned by user |
- syncer::SyncChangeList sync_list; |
- InsertAddPinChange(&sync_list, 0, extension1_->id()); |
- InsertAddPinChange(&sync_list, 1, extension_misc::kChromeAppId); |
- InsertAddPinChange(&sync_list, 2, extension3_->id()); |
- SendPinChanges(sync_list, true); |
- |
- base::ListValue policy_value; |
- // extension 2 4 are pinned by policy |
- InsertPrefValue(&policy_value, 0, extension2_->id()); |
- InsertPrefValue(&policy_value, 1, extension4_->id()); |
- profile()->GetTestingPrefService()->SetManagedPref( |
- prefs::kPolicyPinnedLauncherApps, policy_value.CreateDeepCopy()); |
- |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension1_->id())); |
- // 2 is not pinned as it's not installed |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension2_->id())); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension3_->id())); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension4_->id())); |
- // install extension 2 and check |
- extension_service_->AddExtension(extension2_.get()); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension2_->id())); |
- |
- // Check user can manually pin or unpin these apps |
- EXPECT_EQ(AppListControllerDelegate::PIN_EDITABLE, |
- GetPinnableForAppID(extension1_->id(), profile())); |
- EXPECT_EQ(AppListControllerDelegate::PIN_FIXED, |
- GetPinnableForAppID(extension2_->id(), profile())); |
- EXPECT_EQ(AppListControllerDelegate::PIN_EDITABLE, |
- GetPinnableForAppID(extension3_->id(), profile())); |
- EXPECT_EQ(AppListControllerDelegate::PIN_FIXED, |
- GetPinnableForAppID(extension4_->id(), profile())); |
- |
- // Check the order of shelf pinned apps |
- EXPECT_EQ("AppList, App2, App4, App1, Chrome, App3", GetPinnedAppStatus()); |
-} |
- |
-// Check that the restauration of launcher items is happening in the same order |
-// as the user has pinned them (on another system) when they are synced reverse |
-// order. |
-TEST_F(ChromeLauncherControllerImplTest, RestoreDefaultAppsReverseOrder) { |
- InitLauncherController(); |
- |
- syncer::SyncChangeList sync_list; |
- InsertAddPinChange(&sync_list, 0, extension1_->id()); |
- InsertAddPinChange(&sync_list, 1, extension2_->id()); |
- InsertAddPinChange(&sync_list, 2, extension3_->id()); |
- SendPinChanges(sync_list, true); |
- |
- // The model should only contain the browser shortcut and app list items. |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension1_->id())); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension2_->id())); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension3_->id())); |
- EXPECT_EQ("AppList, Chrome", GetPinnedAppStatus()); |
- |
- // Installing |extension3_| should add it to the shelf - behind the |
- // chrome icon. |
- ash::ShelfItem item; |
- extension_service_->AddExtension(extension3_.get()); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension1_->id())); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension2_->id())); |
- EXPECT_EQ("AppList, Chrome, App3", GetPinnedAppStatus()); |
- |
- // Installing |extension2_| should add it to the launcher - behind the |
- // chrome icon, but in first location. |
- extension_service_->AddExtension(extension2_.get()); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension1_->id())); |
- EXPECT_EQ("AppList, Chrome, App2, App3", GetPinnedAppStatus()); |
- |
- // Installing |extension1_| should add it to the launcher - behind the |
- // chrome icon, but in first location. |
- extension_service_->AddExtension(extension1_.get()); |
- EXPECT_EQ("AppList, Chrome, App1, App2, App3", GetPinnedAppStatus()); |
-} |
- |
-// Check that the restauration of launcher items is happening in the same order |
-// as the user has pinned them (on another system) when they are synced random |
-// order. |
-TEST_F(ChromeLauncherControllerImplTest, RestoreDefaultAppsRandomOrder) { |
- InitLauncherController(); |
- |
- syncer::SyncChangeList sync_list; |
- InsertAddPinChange(&sync_list, 0, extension1_->id()); |
- InsertAddPinChange(&sync_list, 1, extension2_->id()); |
- InsertAddPinChange(&sync_list, 2, extension3_->id()); |
- SendPinChanges(sync_list, true); |
- |
- // The model should only contain the browser shortcut and app list items. |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension1_->id())); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension2_->id())); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension3_->id())); |
- EXPECT_EQ("AppList, Chrome", GetPinnedAppStatus()); |
- |
- // Installing |extension2_| should add it to the launcher - behind the |
- // chrome icon. |
- extension_service_->AddExtension(extension2_.get()); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension1_->id())); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension3_->id())); |
- EXPECT_EQ("AppList, Chrome, App2", GetPinnedAppStatus()); |
- |
- // Installing |extension1_| should add it to the launcher - behind the |
- // chrome icon, but in first location. |
- extension_service_->AddExtension(extension1_.get()); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension3_->id())); |
- EXPECT_EQ("AppList, Chrome, App1, App2", GetPinnedAppStatus()); |
- |
- // Installing |extension3_| should add it to the launcher - behind the |
- // chrome icon, but in first location. |
- extension_service_->AddExtension(extension3_.get()); |
- EXPECT_EQ("AppList, Chrome, App1, App2, App3", GetPinnedAppStatus()); |
-} |
- |
-// Check that the restauration of launcher items is happening in the same order |
-// as the user has pinned / moved them (on another system) when they are synced |
-// random order - including the chrome icon. |
-TEST_F(ChromeLauncherControllerImplTest, |
- RestoreDefaultAppsRandomOrderChromeMoved) { |
- InitLauncherController(); |
- |
- syncer::SyncChangeList sync_list; |
- InsertAddPinChange(&sync_list, 0, extension1_->id()); |
- InsertAddPinChange(&sync_list, 1, extension_misc::kChromeAppId); |
- InsertAddPinChange(&sync_list, 2, extension2_->id()); |
- InsertAddPinChange(&sync_list, 3, extension3_->id()); |
- SendPinChanges(sync_list, true); |
- |
- // The model should only contain the browser shortcut and app list items. |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension1_->id())); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension2_->id())); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension3_->id())); |
- EXPECT_EQ("AppList, Chrome", GetPinnedAppStatus()); |
- |
- // Installing |extension2_| should add it to the shelf - behind the |
- // chrome icon. |
- ash::ShelfItem item; |
- extension_service_->AddExtension(extension2_.get()); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension1_->id())); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension3_->id())); |
- EXPECT_EQ("AppList, Chrome, App2", GetPinnedAppStatus()); |
- |
- // Installing |extension1_| should add it to the launcher - behind the |
- // chrome icon, but in first location. |
- extension_service_->AddExtension(extension1_.get()); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension3_->id())); |
- EXPECT_EQ("AppList, App1, Chrome, App2", GetPinnedAppStatus()); |
- |
- // Installing |extension3_| should add it to the launcher - behind the |
- // chrome icon, but in first location. |
- extension_service_->AddExtension(extension3_.get()); |
- EXPECT_EQ("AppList, App1, Chrome, App2, App3", GetPinnedAppStatus()); |
-} |
- |
-// Check that syncing to a different state does the correct thing. |
-TEST_F(ChromeLauncherControllerImplTest, RestoreDefaultAppsResyncOrder) { |
- InitLauncherController(); |
- |
- syncer::SyncChangeList sync_list0; |
- InsertAddPinChange(&sync_list0, 0, extension1_->id()); |
- InsertAddPinChange(&sync_list0, 1, extension2_->id()); |
- InsertAddPinChange(&sync_list0, 2, extension3_->id()); |
- SendPinChanges(sync_list0, true); |
- |
- // The shelf layout has always one static item at the beginning (App List). |
- extension_service_->AddExtension(extension2_.get()); |
- EXPECT_EQ("AppList, Chrome, App2", GetPinnedAppStatus()); |
- extension_service_->AddExtension(extension1_.get()); |
- EXPECT_EQ("AppList, Chrome, App1, App2", GetPinnedAppStatus()); |
- extension_service_->AddExtension(extension3_.get()); |
- EXPECT_EQ("AppList, Chrome, App1, App2, App3", GetPinnedAppStatus()); |
- |
- // Change the order with increasing chrome position and decreasing position. |
- syncer::SyncChangeList sync_list1; |
- InsertAddPinChange(&sync_list1, 0, extension3_->id()); |
- InsertAddPinChange(&sync_list1, 1, extension1_->id()); |
- InsertAddPinChange(&sync_list1, 2, extension2_->id()); |
- InsertAddPinChange(&sync_list1, 3, extension_misc::kChromeAppId); |
- SendPinChanges(sync_list1, true); |
- EXPECT_EQ("AppList, App3, App1, App2, Chrome", GetPinnedAppStatus()); |
- |
- syncer::SyncChangeList sync_list2; |
- InsertAddPinChange(&sync_list2, 0, extension2_->id()); |
- InsertAddPinChange(&sync_list2, 1, extension3_->id()); |
- InsertAddPinChange(&sync_list2, 2, extension_misc::kChromeAppId); |
- InsertAddPinChange(&sync_list2, 3, extension1_->id()); |
- SendPinChanges(sync_list2, true); |
- EXPECT_EQ("AppList, App2, App3, Chrome, App1", GetPinnedAppStatus()); |
- |
- // Check that the chrome icon can also be at the first possible location. |
- syncer::SyncChangeList sync_list3; |
- InsertAddPinChange(&sync_list3, 0, extension3_->id()); |
- InsertAddPinChange(&sync_list3, 1, extension2_->id()); |
- InsertAddPinChange(&sync_list3, 2, extension1_->id()); |
- SendPinChanges(sync_list3, true); |
- EXPECT_EQ("AppList, Chrome, App3, App2, App1", GetPinnedAppStatus()); |
- |
- // Check that unloading of extensions works as expected. |
- extension_service_->UnloadExtension(extension1_->id(), |
- UnloadedExtensionInfo::REASON_UNINSTALL); |
- EXPECT_EQ("AppList, Chrome, App3, App2", GetPinnedAppStatus()); |
- |
- extension_service_->UnloadExtension(extension2_->id(), |
- UnloadedExtensionInfo::REASON_UNINSTALL); |
- EXPECT_EQ("AppList, Chrome, App3", GetPinnedAppStatus()); |
- |
- // Check that an update of an extension does not crash the system. |
- extension_service_->UnloadExtension(extension3_->id(), |
- UnloadedExtensionInfo::REASON_UPDATE); |
- EXPECT_EQ("AppList, Chrome, App3", GetPinnedAppStatus()); |
-} |
- |
-// Test the V1 app interaction flow: run it, activate it, close it. |
-TEST_F(ChromeLauncherControllerImplTest, V1AppRunActivateClose) { |
- InitLauncherController(); |
- // The model should only contain the browser shortcut and app list items. |
- EXPECT_EQ(2, model_->item_count()); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension1_->id())); |
- EXPECT_EQ(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(extension1_->id())); |
- |
- // Reporting that the app is running should create a new shelf item. |
- launcher_controller_->SetV1AppStatus(extension1_->id(), ash::STATUS_RUNNING); |
- EXPECT_EQ(3, model_->item_count()); |
- EXPECT_EQ(ash::TYPE_APP, model_->items()[2].type); |
- EXPECT_EQ(ash::STATUS_RUNNING, model_->items()[2].status); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension1_->id())); |
- EXPECT_NE(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(extension1_->id())); |
- |
- // Reporting an active status should just update the existing item. |
- launcher_controller_->SetV1AppStatus(extension1_->id(), ash::STATUS_ACTIVE); |
- EXPECT_EQ(3, model_->item_count()); |
- EXPECT_EQ(ash::STATUS_ACTIVE, model_->items()[2].status); |
- |
- // Reporting that the app is closed should remove its shelf item. |
- launcher_controller_->SetV1AppStatus(extension1_->id(), ash::STATUS_CLOSED); |
- EXPECT_EQ(2, model_->item_count()); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension1_->id())); |
- EXPECT_EQ(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(extension1_->id())); |
- |
- // Reporting that the app is closed again should have no effect. |
- launcher_controller_->SetV1AppStatus(extension1_->id(), ash::STATUS_CLOSED); |
- EXPECT_EQ(2, model_->item_count()); |
-} |
- |
-// Test the V1 app interaction flow: pin it, run it, close it, unpin it. |
-TEST_F(ChromeLauncherControllerImplTest, V1AppPinRunCloseUnpin) { |
- InitLauncherController(); |
- // The model should only contain the browser shortcut and app list items. |
- EXPECT_EQ(2, model_->item_count()); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension1_->id())); |
- EXPECT_EQ(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(extension1_->id())); |
- |
- // Pinning the app should create a new shelf item. |
- launcher_controller_->PinAppWithID(extension1_->id()); |
- EXPECT_EQ(3, model_->item_count()); |
- EXPECT_EQ(ash::TYPE_PINNED_APP, model_->items()[2].type); |
- EXPECT_EQ(ash::STATUS_CLOSED, model_->items()[2].status); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension1_->id())); |
- EXPECT_NE(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(extension1_->id())); |
- |
- // Reporting that the app is running should just update the existing item. |
- launcher_controller_->SetV1AppStatus(extension1_->id(), ash::STATUS_RUNNING); |
- EXPECT_EQ(3, model_->item_count()); |
- EXPECT_EQ(ash::TYPE_PINNED_APP, model_->items()[2].type); |
- EXPECT_EQ(ash::STATUS_RUNNING, model_->items()[2].status); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension1_->id())); |
- EXPECT_NE(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(extension1_->id())); |
- |
- // Reporting that the app is closed should just update the existing item. |
- launcher_controller_->SetV1AppStatus(extension1_->id(), ash::STATUS_CLOSED); |
- EXPECT_EQ(3, model_->item_count()); |
- EXPECT_EQ(ash::TYPE_PINNED_APP, model_->items()[2].type); |
- EXPECT_EQ(ash::STATUS_CLOSED, model_->items()[2].status); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension1_->id())); |
- EXPECT_NE(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(extension1_->id())); |
- |
- // Unpinning the app should remove its shelf item. |
- launcher_controller_->UnpinAppWithID(extension1_->id()); |
- EXPECT_EQ(2, model_->item_count()); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension1_->id())); |
- EXPECT_EQ(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(extension1_->id())); |
-} |
- |
-// Test the V1 app interaction flow: run it, pin it, close it, unpin it. |
-TEST_F(ChromeLauncherControllerImplTest, V1AppRunPinCloseUnpin) { |
- InitLauncherController(); |
- // The model should only contain the browser shortcut and app list items. |
- EXPECT_EQ(2, model_->item_count()); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension1_->id())); |
- EXPECT_EQ(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(extension1_->id())); |
- |
- // Reporting that the app is running should create a new shelf item. |
- launcher_controller_->SetV1AppStatus(extension1_->id(), ash::STATUS_RUNNING); |
- EXPECT_EQ(3, model_->item_count()); |
- EXPECT_EQ(ash::TYPE_APP, model_->items()[2].type); |
- EXPECT_EQ(ash::STATUS_RUNNING, model_->items()[2].status); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension1_->id())); |
- EXPECT_NE(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(extension1_->id())); |
- |
- // Pinning the app should just update the existing item. |
- launcher_controller_->PinAppWithID(extension1_->id()); |
- EXPECT_EQ(3, model_->item_count()); |
- EXPECT_EQ(ash::TYPE_PINNED_APP, model_->items()[2].type); |
- EXPECT_EQ(ash::STATUS_RUNNING, model_->items()[2].status); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension1_->id())); |
- EXPECT_NE(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(extension1_->id())); |
- |
- // Reporting that the app is closed should just update the existing item. |
- launcher_controller_->SetV1AppStatus(extension1_->id(), ash::STATUS_CLOSED); |
- EXPECT_EQ(3, model_->item_count()); |
- EXPECT_EQ(ash::TYPE_PINNED_APP, model_->items()[2].type); |
- EXPECT_EQ(ash::STATUS_CLOSED, model_->items()[2].status); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension1_->id())); |
- EXPECT_NE(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(extension1_->id())); |
- |
- // Unpinning the app should remove its shelf item. |
- launcher_controller_->UnpinAppWithID(extension1_->id()); |
- EXPECT_EQ(2, model_->item_count()); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension1_->id())); |
- EXPECT_EQ(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(extension1_->id())); |
-} |
- |
-// Test the V1 app interaction flow: pin it, run it, unpin it, close it. |
-TEST_F(ChromeLauncherControllerImplTest, V1AppPinRunUnpinClose) { |
- InitLauncherController(); |
- // The model should only contain the browser shortcut and app list items. |
- EXPECT_EQ(2, model_->item_count()); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension1_->id())); |
- EXPECT_EQ(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(extension1_->id())); |
- |
- // Pinning the app should create a new shelf item. |
- launcher_controller_->PinAppWithID(extension1_->id()); |
- EXPECT_EQ(3, model_->item_count()); |
- EXPECT_EQ(ash::TYPE_PINNED_APP, model_->items()[2].type); |
- EXPECT_EQ(ash::STATUS_CLOSED, model_->items()[2].status); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension1_->id())); |
- EXPECT_NE(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(extension1_->id())); |
- |
- // Reporting that the app is running should just update the existing item. |
- launcher_controller_->SetV1AppStatus(extension1_->id(), ash::STATUS_RUNNING); |
- EXPECT_EQ(3, model_->item_count()); |
- EXPECT_EQ(ash::TYPE_PINNED_APP, model_->items()[2].type); |
- EXPECT_EQ(ash::STATUS_RUNNING, model_->items()[2].status); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension1_->id())); |
- EXPECT_NE(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(extension1_->id())); |
- |
- // Unpinning the app should just update the existing item. |
- launcher_controller_->UnpinAppWithID(extension1_->id()); |
- EXPECT_EQ(3, model_->item_count()); |
- EXPECT_EQ(ash::TYPE_APP, model_->items()[2].type); |
- EXPECT_EQ(ash::STATUS_RUNNING, model_->items()[2].status); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension1_->id())); |
- EXPECT_NE(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(extension1_->id())); |
- |
- // Reporting that the app is closed should remove its shelf item. |
- launcher_controller_->SetV1AppStatus(extension1_->id(), ash::STATUS_CLOSED); |
- EXPECT_EQ(2, model_->item_count()); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension1_->id())); |
- EXPECT_EQ(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(extension1_->id())); |
-} |
- |
-// Ensure unpinned V1 app ordering is properly restored after user changes. |
-TEST_F(ChromeLauncherControllerImplTest, CheckRunningV1AppOrder) { |
- InitLauncherController(); |
- // The model should only contain the browser shortcut and app list items. |
- EXPECT_EQ(2, model_->item_count()); |
- |
- // Add a few running applications. |
- launcher_controller_->SetV1AppStatus(extension1_->id(), ash::STATUS_RUNNING); |
- launcher_controller_->SetV1AppStatus(extension2_->id(), ash::STATUS_RUNNING); |
- launcher_controller_->SetV1AppStatus(extension3_->id(), ash::STATUS_RUNNING); |
- EXPECT_EQ(5, model_->item_count()); |
- // Note that this not only checks the order of applications but also the |
- // running type. |
- EXPECT_EQ("AppList, Chrome, app1, app2, app3", GetPinnedAppStatus()); |
- |
- // Remember the current order of applications for the current user. |
- const AccountId& current_account_id = |
- multi_user_util::GetAccountIdFromProfile(profile()); |
- RememberUnpinnedRunningApplicationOrder(); |
- |
- // Switch some items and check that restoring a user which was not yet |
- // remembered changes nothing. |
- model_->Move(2, 3); |
- EXPECT_EQ("AppList, Chrome, app2, app1, app3", GetPinnedAppStatus()); |
- const AccountId second_fake_account_id( |
- AccountId::FromUserEmail("second-fake-user@fake.com")); |
- RestoreUnpinnedRunningApplicationOrder(second_fake_account_id); |
- EXPECT_EQ("AppList, Chrome, app2, app1, app3", GetPinnedAppStatus()); |
- |
- // Restoring the stored user should however do the right thing. |
- RestoreUnpinnedRunningApplicationOrder(current_account_id); |
- EXPECT_EQ("AppList, Chrome, app1, app2, app3", GetPinnedAppStatus()); |
- |
- // Switch again some items and even delete one - making sure that the missing |
- // item gets properly handled. |
- model_->Move(3, 4); |
- launcher_controller_->SetV1AppStatus(extension1_->id(), ash::STATUS_CLOSED); |
- EXPECT_EQ("AppList, Chrome, app3, app2", GetPinnedAppStatus()); |
- RestoreUnpinnedRunningApplicationOrder(current_account_id); |
- EXPECT_EQ("AppList, Chrome, app2, app3", GetPinnedAppStatus()); |
- |
- // Check that removing more items does not crash and changes nothing. |
- launcher_controller_->SetV1AppStatus(extension2_->id(), ash::STATUS_CLOSED); |
- RestoreUnpinnedRunningApplicationOrder(current_account_id); |
- EXPECT_EQ("AppList, Chrome, app3", GetPinnedAppStatus()); |
- launcher_controller_->SetV1AppStatus(extension3_->id(), ash::STATUS_CLOSED); |
- RestoreUnpinnedRunningApplicationOrder(current_account_id); |
- EXPECT_EQ("AppList, Chrome", GetPinnedAppStatus()); |
-} |
- |
-TEST_P(ChromeLauncherControllerImplWithArcTest, ArcDeferredLaunch) { |
- InitLauncherController(); |
- |
- const arc::mojom::AppInfo& app1 = arc_test_.fake_apps()[0]; |
- const arc::mojom::AppInfo& app2 = arc_test_.fake_apps()[1]; |
- const arc::mojom::AppInfo& app3 = arc_test_.fake_apps()[2]; |
- const arc::mojom::ShortcutInfo& shortcut = arc_test_.fake_shortcuts()[0]; |
- const std::string arc_app_id1 = ArcAppTest::GetAppId(app1); |
- const std::string arc_app_id2 = ArcAppTest::GetAppId(app2); |
- const std::string arc_app_id3 = ArcAppTest::GetAppId(app3); |
- const std::string arc_shortcut_id = ArcAppTest::GetAppId(shortcut); |
- |
- SendListOfArcApps(); |
- SendListOfArcShortcuts(); |
- |
- arc_test_.StopArcInstance(); |
- |
- EXPECT_EQ(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(arc_app_id1)); |
- EXPECT_EQ(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(arc_app_id2)); |
- EXPECT_EQ(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(arc_app_id3)); |
- EXPECT_EQ(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(arc_shortcut_id)); |
- |
- arc::LaunchApp(profile(), arc_app_id1, ui::EF_LEFT_MOUSE_BUTTON); |
- arc::LaunchApp(profile(), arc_app_id1, ui::EF_LEFT_MOUSE_BUTTON); |
- arc::LaunchApp(profile(), arc_app_id2, ui::EF_LEFT_MOUSE_BUTTON); |
- arc::LaunchApp(profile(), arc_app_id3, ui::EF_LEFT_MOUSE_BUTTON); |
- arc::LaunchApp(profile(), arc_shortcut_id, ui::EF_LEFT_MOUSE_BUTTON); |
- |
- const ash::ShelfID shelf_id_app_1 = |
- launcher_controller_->GetShelfIDForAppID(arc_app_id1); |
- const ash::ShelfID shelf_id_app_2 = |
- launcher_controller_->GetShelfIDForAppID(arc_app_id2); |
- const ash::ShelfID shelf_id_app_3 = |
- launcher_controller_->GetShelfIDForAppID(arc_app_id3); |
- const ash::ShelfID shelf_id_shortcut = |
- launcher_controller_->GetShelfIDForAppID(arc_shortcut_id); |
- EXPECT_NE(ash::kInvalidShelfID, shelf_id_app_1); |
- EXPECT_NE(ash::kInvalidShelfID, shelf_id_app_2); |
- EXPECT_NE(ash::kInvalidShelfID, shelf_id_app_3); |
- EXPECT_NE(ash::kInvalidShelfID, shelf_id_shortcut); |
- |
- // We activated arc_app_id1 twice but expect one close for item controller |
- // stops launching request. |
- ash::ShelfItemDelegate* item_delegate = |
- model_->GetShelfItemDelegate(shelf_id_app_1); |
- ASSERT_NE(nullptr, item_delegate); |
- item_delegate->Close(); |
- base::RunLoop().RunUntilIdle(); |
- |
- EXPECT_EQ(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(arc_app_id1)); |
- EXPECT_EQ(shelf_id_app_2, |
- launcher_controller_->GetShelfIDForAppID(arc_app_id2)); |
- EXPECT_EQ(shelf_id_app_3, |
- launcher_controller_->GetShelfIDForAppID(arc_app_id3)); |
- |
- arc_test_.RestartArcInstance(); |
- SendListOfArcApps(); |
- |
- base::RunLoop().RunUntilIdle(); |
- |
- // Now deferred contollers should go away together with shelf items and ARC |
- // app instance should receive request for launching apps and shortcuts. |
- EXPECT_EQ(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(arc_app_id1)); |
- EXPECT_EQ(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(arc_app_id2)); |
- EXPECT_EQ(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(arc_app_id3)); |
- |
- ASSERT_EQ(2U, arc_test_.app_instance()->launch_requests().size()); |
- ASSERT_EQ(1U, arc_test_.app_instance()->launch_intents().size()); |
- |
- const arc::FakeAppInstance::Request* request1 = |
- arc_test_.app_instance()->launch_requests()[0].get(); |
- const arc::FakeAppInstance::Request* request2 = |
- arc_test_.app_instance()->launch_requests()[1].get(); |
- |
- EXPECT_TRUE((request1->IsForApp(app2) && request2->IsForApp(app3)) || |
- (request1->IsForApp(app3) && request2->IsForApp(app2))); |
- EXPECT_EQ(arc_test_.app_instance()->launch_intents()[0].c_str(), |
- shortcut.intent_uri); |
-} |
- |
-// Ensure the deferred controller does not override the active app controller |
-// (crbug.com/701152). |
-TEST_P(ChromeLauncherControllerImplWithArcTest, ArcDeferredLaunchForActiveApp) { |
- InitLauncherController(); |
- SendListOfArcApps(); |
- arc_test_.StopArcInstance(); |
- |
- const arc::mojom::AppInfo& app = arc_test_.fake_apps()[0]; |
- const std::string app_id = ArcAppTest::GetAppId(app); |
- |
- launcher_controller_->PinAppWithID(app_id); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(app_id)); |
- const ash::ShelfID shelf_id = |
- launcher_controller_->GetShelfIDForAppID(app_id); |
- EXPECT_NE(ash::kInvalidShelfID, shelf_id); |
- |
- int item_index = model_->ItemIndexByID(shelf_id); |
- ASSERT_GE(item_index, 0); |
- |
- EXPECT_EQ(model_->items()[item_index].status, ash::STATUS_CLOSED); |
- EXPECT_EQ(model_->items()[item_index].type, ash::TYPE_PINNED_APP); |
- |
- // Play Store app is ARC app that might be represented by native Chrome |
- // platform app. |
- model_->SetShelfItemDelegate( |
- shelf_id, base::MakeUnique<ExtensionAppWindowLauncherItemController>( |
- ash::AppLaunchId(app_id))); |
- launcher_controller_->SetItemStatus(shelf_id, ash::STATUS_RUNNING); |
- |
- // This launch request should be ignored in case of active app. |
- arc::LaunchApp(profile(), app_id, ui::EF_LEFT_MOUSE_BUTTON); |
- EXPECT_FALSE(launcher_controller_->GetArcDeferredLauncher()->HasApp(app_id)); |
- |
- // Close app but shortcut should exist. |
- launcher_controller_->CloseLauncherItem(shelf_id); |
- EXPECT_EQ(shelf_id, launcher_controller_->GetShelfIDForAppID(app_id)); |
- |
- // This should switch shelf item into closed state. |
- item_index = model_->ItemIndexByID(shelf_id); |
- ASSERT_GE(item_index, 0); |
- EXPECT_EQ(model_->items()[item_index].status, ash::STATUS_CLOSED); |
- EXPECT_EQ(model_->items()[item_index].type, ash::TYPE_PINNED_APP); |
- |
- // Now launch request should not be ignored. |
- arc::LaunchApp(profile(), app_id, ui::EF_LEFT_MOUSE_BUTTON); |
- EXPECT_TRUE(launcher_controller_->GetArcDeferredLauncher()->HasApp(app_id)); |
-} |
- |
-TEST_P(ChromeLauncherControllerImplMultiProfileWithArcTest, ArcMultiUser) { |
- SendListOfArcApps(); |
- |
- InitLauncherController(); |
- // TODO(crbug.com/654622): This test breaks with a non-null static instance. |
- ChromeLauncherControllerImpl::set_instance_for_test(nullptr); |
- |
- SetLauncherControllerHelper(new TestLauncherControllerHelper); |
- |
- // App1 exists all the time. |
- // App2 is created when primary user is active and destroyed when secondary |
- // user is active. |
- // App3 created when secondary user is active. |
- |
- const std::string user2 = "user2"; |
- TestingProfile* profile2 = CreateMultiUserProfile(user2); |
- const AccountId account_id( |
- multi_user_util::GetAccountIdFromProfile(profile())); |
- const AccountId account_id2( |
- multi_user_util::GetAccountIdFromProfile(profile2)); |
- |
- const std::string arc_app_id1 = |
- ArcAppTest::GetAppId(arc_test_.fake_apps()[0]); |
- const std::string arc_app_id2 = |
- ArcAppTest::GetAppId(arc_test_.fake_apps()[1]); |
- const std::string arc_app_id3 = |
- ArcAppTest::GetAppId(arc_test_.fake_apps()[2]); |
- |
- std::string window_app_id1("org.chromium.arc.1"); |
- views::Widget* arc_window1 = CreateArcWindow(window_app_id1); |
- arc_test_.app_instance()->SendTaskCreated(1, arc_test_.fake_apps()[0], |
- std::string()); |
- EXPECT_NE(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(arc_app_id1)); |
- |
- std::string window_app_id2("org.chromium.arc.2"); |
- views::Widget* arc_window2 = CreateArcWindow(window_app_id2); |
- arc_test_.app_instance()->SendTaskCreated(2, arc_test_.fake_apps()[1], |
- std::string()); |
- EXPECT_NE(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(arc_app_id2)); |
- |
- launcher_controller_->SetProfileForTest(profile2); |
- SwitchActiveUser(account_id2); |
- |
- EXPECT_EQ(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(arc_app_id1)); |
- EXPECT_EQ(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(arc_app_id2)); |
- |
- std::string window_app_id3("org.chromium.arc.3"); |
- views::Widget* arc_window3 = CreateArcWindow(window_app_id3); |
- arc_test_.app_instance()->SendTaskCreated(3, arc_test_.fake_apps()[2], |
- std::string()); |
- EXPECT_EQ(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(arc_app_id3)); |
- |
- arc_window2->CloseNow(); |
- arc_test_.app_instance()->SendTaskDestroyed(2); |
- |
- launcher_controller_->SetProfileForTest(profile()); |
- SwitchActiveUser(account_id); |
- |
- EXPECT_NE(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(arc_app_id1)); |
- EXPECT_EQ(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(arc_app_id2)); |
- EXPECT_NE(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(arc_app_id3)); |
- |
- // Close active window to let test passes. |
- arc_window1->CloseNow(); |
- arc_window3->CloseNow(); |
-} |
- |
-TEST_P(ChromeLauncherControllerImplWithArcTest, ArcRunningApp) { |
- InitLauncherController(); |
- |
- const std::string arc_app_id = ArcAppTest::GetAppId(arc_test_.fake_apps()[0]); |
- SendListOfArcApps(); |
- EXPECT_EQ(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(arc_app_id)); |
- |
- // Normal flow, create/destroy tasks. |
- std::string window_app_id1("org.chromium.arc.1"); |
- std::string window_app_id2("org.chromium.arc.2"); |
- std::string window_app_id3("org.chromium.arc.3"); |
- CreateArcWindow(window_app_id1); |
- arc_test_.app_instance()->SendTaskCreated(1, arc_test_.fake_apps()[0], |
- std::string()); |
- EXPECT_NE(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(arc_app_id)); |
- CreateArcWindow(window_app_id2); |
- arc_test_.app_instance()->SendTaskCreated(2, arc_test_.fake_apps()[0], |
- std::string()); |
- EXPECT_NE(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(arc_app_id)); |
- arc_test_.app_instance()->SendTaskDestroyed(1); |
- EXPECT_NE(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(arc_app_id)); |
- arc_test_.app_instance()->SendTaskDestroyed(2); |
- EXPECT_EQ(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(arc_app_id)); |
- |
- // Stopping bridge removes apps. |
- CreateArcWindow(window_app_id3); |
- arc_test_.app_instance()->SendTaskCreated(3, arc_test_.fake_apps()[0], |
- std::string()); |
- EXPECT_NE(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(arc_app_id)); |
- arc_test_.StopArcInstance(); |
- base::RunLoop().RunUntilIdle(); |
- EXPECT_EQ(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(arc_app_id)); |
-} |
- |
-// Test race creation/deletion of ARC app. |
-// TODO(khmel): Remove after moving everything to wayland protocol. |
-TEST_P(ChromeLauncherControllerImplWithArcTest, ArcRaceCreateClose) { |
- InitLauncherController(); |
- |
- const std::string arc_app_id1 = |
- ArcAppTest::GetAppId(arc_test_.fake_apps()[0]); |
- const std::string arc_app_id2 = |
- ArcAppTest::GetAppId(arc_test_.fake_apps()[1]); |
- SendListOfArcApps(); |
- |
- // ARC window created before and closed after mojom notification. |
- std::string window_app_id1("org.chromium.arc.1"); |
- views::Widget* arc_window = CreateArcWindow(window_app_id1); |
- EXPECT_EQ(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(arc_app_id1)); |
- ASSERT_TRUE(arc_window); |
- arc_test_.app_instance()->SendTaskCreated(1, arc_test_.fake_apps()[0], |
- std::string()); |
- EXPECT_NE(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(arc_app_id1)); |
- arc_test_.app_instance()->SendTaskDestroyed(1); |
- EXPECT_EQ(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(arc_app_id1)); |
- arc_window->Close(); |
- base::RunLoop().RunUntilIdle(); |
- EXPECT_EQ(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(arc_app_id1)); |
- |
- // ARC window created after and closed before mojom notification. |
- std::string window_app_id2("org.chromium.arc.2"); |
- arc_test_.app_instance()->SendTaskCreated(2, arc_test_.fake_apps()[1], |
- std::string()); |
- EXPECT_NE(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(arc_app_id2)); |
- arc_window = CreateArcWindow(window_app_id2); |
- ASSERT_TRUE(arc_window); |
- EXPECT_NE(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(arc_app_id2)); |
- arc_window->Close(); |
- base::RunLoop().RunUntilIdle(); |
- // Closing window does not close shelf item. It is closed on task destroy. |
- EXPECT_NE(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(arc_app_id2)); |
- arc_test_.app_instance()->SendTaskDestroyed(2); |
- EXPECT_EQ(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(arc_app_id2)); |
-} |
- |
-TEST_P(ChromeLauncherControllerImplWithArcTest, ArcWindowRecreation) { |
- InitLauncherController(); |
- |
- const std::string arc_app_id = ArcAppTest::GetAppId(arc_test_.fake_apps()[0]); |
- SendListOfArcApps(); |
- |
- std::string window_app_id("org.chromium.arc.1"); |
- views::Widget* arc_window = CreateArcWindow(window_app_id); |
- ASSERT_TRUE(arc_window); |
- arc_test_.app_instance()->SendTaskCreated(1, arc_test_.fake_apps()[0], |
- std::string()); |
- const ash::ShelfID shelf_id = |
- launcher_controller_->GetShelfIDForAppID(arc_app_id); |
- EXPECT_NE(ash::kInvalidShelfID, shelf_id); |
- |
- for (int i = 0; i < 3; ++i) { |
- arc_window->Close(); |
- base::RunLoop().RunUntilIdle(); |
- EXPECT_EQ(shelf_id, launcher_controller_->GetShelfIDForAppID(arc_app_id)); |
- |
- arc_window = CreateArcWindow(window_app_id); |
- ASSERT_TRUE(arc_window); |
- base::RunLoop().RunUntilIdle(); |
- EXPECT_EQ(shelf_id, launcher_controller_->GetShelfIDForAppID(arc_app_id)); |
- } |
-} |
- |
-// Validate that ARC app is pinned correctly and pin is removed automatically |
-// once app is uninstalled. |
-TEST_P(ChromeLauncherControllerImplWithArcTest, ArcAppPin) { |
- InitLauncherController(); |
- |
- const std::string arc_app_id = ArcAppTest::GetAppId(arc_test_.fake_apps()[0]); |
- |
- SendListOfArcApps(); |
- extension_service_->AddExtension(extension1_.get()); |
- extension_service_->AddExtension(extension2_.get()); |
- |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension1_->id())); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(arc_app_id)); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension2_->id())); |
- |
- launcher_controller_->PinAppWithID(extension1_->id()); |
- launcher_controller_->PinAppWithID(arc_app_id); |
- launcher_controller_->PinAppWithID(extension2_->id()); |
- |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension1_->id())); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(arc_app_id)); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension2_->id())); |
- |
- EXPECT_EQ("AppList, Chrome, App1, Fake App 0, App2", GetPinnedAppStatus()); |
- // In opt-out mode, only system apps are available and can't be uninstalled. |
- // Skip the rest of the test. |
- if (arc::ShouldArcAlwaysStart()) |
- return; |
- UninstallArcApps(); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(arc_app_id)); |
- EXPECT_EQ("AppList, Chrome, App1, App2", GetPinnedAppStatus()); |
- SendListOfArcApps(); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(arc_app_id)); |
- EXPECT_EQ("AppList, Chrome, App1, App2", GetPinnedAppStatus()); |
- |
- // Opt-Out/Opt-In remove item from the shelf. |
- launcher_controller_->PinAppWithID(arc_app_id); |
- EXPECT_EQ("AppList, Chrome, App1, App2, Fake App 0", GetPinnedAppStatus()); |
- EnablePlayStore(false); |
- EXPECT_EQ("AppList, Chrome, App1, App2", GetPinnedAppStatus()); |
- EnablePlayStore(true); |
- EXPECT_EQ("AppList, Chrome, App1, App2", GetPinnedAppStatus()); |
- SendListOfArcApps(); |
- EXPECT_EQ("AppList, Chrome, App1, App2, Fake App 0", GetPinnedAppStatus()); |
-} |
- |
-// Validates that ARC app pins persist across OptOut/OptIn. |
-TEST_P(ChromeLauncherControllerImplWithArcTest, ArcAppPinOptOutOptIn) { |
- InitLauncherController(); |
- |
- const std::string arc_app_id1 = |
- ArcAppTest::GetAppId(arc_test_.fake_apps()[0]); |
- const std::string arc_app_id2 = |
- ArcAppTest::GetAppId(arc_test_.fake_apps()[1]); |
- |
- SendListOfArcApps(); |
- extension_service_->AddExtension(extension1_.get()); |
- extension_service_->AddExtension(extension2_.get()); |
- |
- launcher_controller_->PinAppWithID(extension1_->id()); |
- launcher_controller_->PinAppWithID(arc_app_id2); |
- launcher_controller_->PinAppWithID(extension2_->id()); |
- launcher_controller_->PinAppWithID(arc_app_id1); |
- |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension1_->id())); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(arc_app_id1)); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension2_->id())); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(arc_app_id2)); |
- EXPECT_EQ("AppList, Chrome, App1, Fake App 1, App2, Fake App 0", |
- GetPinnedAppStatus()); |
- |
- // TODO(victorhsieh): Implement opt-out. |
- if (arc::ShouldArcAlwaysStart()) |
- return; |
- EnablePlayStore(false); |
- |
- EXPECT_EQ("AppList, Chrome, App1, App2", GetPinnedAppStatus()); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension1_->id())); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(arc_app_id1)); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension2_->id())); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(arc_app_id2)); |
- |
- EnablePlayStore(true); |
- SendListOfArcApps(); |
- base::RunLoop().RunUntilIdle(); |
- |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension1_->id())); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(arc_app_id1)); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension2_->id())); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(arc_app_id2)); |
- |
- EXPECT_EQ("AppList, Chrome, App1, Fake App 1, App2, Fake App 0", |
- GetPinnedAppStatus()); |
-} |
- |
-// Check that with multi profile V1 apps are properly added / removed from the |
-// shelf. |
-TEST_F(MultiProfileMultiBrowserShelfLayoutChromeLauncherControllerImplTest, |
- V1AppUpdateOnUserSwitch) { |
- // Create a browser item in the LauncherController. |
- InitLauncherController(); |
- |
- EXPECT_EQ(2, model_->item_count()); |
- { |
- // Create a "windowed gmail app". |
- std::unique_ptr<V1App> v1_app( |
- CreateRunningV1App(profile(), extension_misc::kGmailAppId, gmail_url)); |
- EXPECT_EQ(3, model_->item_count()); |
- |
- // After switching to a second user the item should be gone. |
- std::string user2 = "user2"; |
- TestingProfile* profile2 = CreateMultiUserProfile(user2); |
- const AccountId account_id2( |
- multi_user_util::GetAccountIdFromProfile(profile2)); |
- const AccountId account_id( |
- multi_user_util::GetAccountIdFromProfile(profile())); |
- SwitchActiveUser(account_id2); |
- EXPECT_EQ(2, model_->item_count()); |
- |
- // After switching back the item should be back. |
- SwitchActiveUser(account_id); |
- EXPECT_EQ(3, model_->item_count()); |
- // Note we destroy now the gmail app with the closure end. |
- } |
- EXPECT_EQ(2, model_->item_count()); |
-} |
- |
-// Check edge cases with multi profile V1 apps in the shelf. |
-TEST_F(MultiProfileMultiBrowserShelfLayoutChromeLauncherControllerImplTest, |
- V1AppUpdateOnUserSwitchEdgecases) { |
- // Create a browser item in the LauncherController. |
- InitLauncherController(); |
- |
- // First test: Create an app when the user is not active. |
- std::string user2 = "user2"; |
- TestingProfile* profile2 = CreateMultiUserProfile(user2); |
- const AccountId account_id2( |
- multi_user_util::GetAccountIdFromProfile(profile2)); |
- const AccountId account_id( |
- multi_user_util::GetAccountIdFromProfile(profile())); |
- { |
- // Create a "windowed gmail app". |
- std::unique_ptr<V1App> v1_app( |
- CreateRunningV1App(profile2, extension_misc::kGmailAppId, gmail_url)); |
- EXPECT_EQ(2, model_->item_count()); |
- |
- // However - switching to the user should show it. |
- SwitchActiveUser(account_id2); |
- EXPECT_EQ(3, model_->item_count()); |
- |
- // Second test: Remove the app when the user is not active and see that it |
- // works. |
- SwitchActiveUser(account_id); |
- EXPECT_EQ(2, model_->item_count()); |
- // Note: the closure ends and the browser will go away. |
- } |
- EXPECT_EQ(2, model_->item_count()); |
- SwitchActiveUser(account_id2); |
- EXPECT_EQ(2, model_->item_count()); |
- SwitchActiveUser(account_id); |
- EXPECT_EQ(2, model_->item_count()); |
-} |
- |
-// Check edge case where a visiting V1 app gets closed (crbug.com/321374). |
-TEST_F(MultiProfileMultiBrowserShelfLayoutChromeLauncherControllerImplTest, |
- V1CloseOnVisitingDesktop) { |
- // Create a browser item in the LauncherController. |
- InitLauncherController(); |
- |
- chrome::MultiUserWindowManager* manager = |
- chrome::MultiUserWindowManager::GetInstance(); |
- |
- // First create an app when the user is active. |
- std::string user2 = "user2"; |
- TestingProfile* profile2 = CreateMultiUserProfile(user2); |
- const AccountId account_id( |
- multi_user_util::GetAccountIdFromProfile(profile())); |
- const AccountId account_id2( |
- multi_user_util::GetAccountIdFromProfile(profile2)); |
- { |
- // Create a "windowed gmail app". |
- std::unique_ptr<V1App> v1_app(CreateRunningV1App( |
- profile(), extension_misc::kGmailAppId, kGmailLaunchURL)); |
- EXPECT_EQ(3, model_->item_count()); |
- |
- // Transfer the app to the other screen and switch users. |
- manager->ShowWindowForUser(v1_app->browser()->window()->GetNativeWindow(), |
- account_id2); |
- EXPECT_EQ(3, model_->item_count()); |
- SwitchActiveUser(account_id2); |
- EXPECT_EQ(2, model_->item_count()); |
- } |
- // After the app was destroyed, switch back. (which caused already a crash). |
- SwitchActiveUser(account_id); |
- |
- // Create the same app again - which was also causing the crash. |
- EXPECT_EQ(2, model_->item_count()); |
- { |
- // Create a "windowed gmail app". |
- std::unique_ptr<V1App> v1_app(CreateRunningV1App( |
- profile(), extension_misc::kGmailAppId, kGmailLaunchURL)); |
- EXPECT_EQ(3, model_->item_count()); |
- } |
- SwitchActiveUser(account_id2); |
- EXPECT_EQ(2, model_->item_count()); |
-} |
- |
-// Check edge cases with multi profile V1 apps in the shelf. |
-TEST_F(MultiProfileMultiBrowserShelfLayoutChromeLauncherControllerImplTest, |
- V1AppUpdateOnUserSwitchEdgecases2) { |
- // Create a browser item in the LauncherController. |
- InitLauncherController(); |
- |
- // First test: Create an app when the user is not active. |
- std::string user2 = "user2"; |
- TestingProfile* profile2 = CreateMultiUserProfile(user2); |
- const AccountId account_id( |
- multi_user_util::GetAccountIdFromProfile(profile())); |
- const AccountId account_id2( |
- multi_user_util::GetAccountIdFromProfile(profile2)); |
- SwitchActiveUser(account_id2); |
- { |
- // Create a "windowed gmail app". |
- std::unique_ptr<V1App> v1_app( |
- CreateRunningV1App(profile(), extension_misc::kGmailAppId, gmail_url)); |
- EXPECT_EQ(2, model_->item_count()); |
- |
- // However - switching to the user should show it. |
- SwitchActiveUser(account_id); |
- EXPECT_EQ(3, model_->item_count()); |
- |
- // Second test: Remove the app when the user is not active and see that it |
- // works. |
- SwitchActiveUser(account_id2); |
- EXPECT_EQ(2, model_->item_count()); |
- v1_app.reset(); |
- } |
- EXPECT_EQ(2, model_->item_count()); |
- SwitchActiveUser(account_id); |
- EXPECT_EQ(2, model_->item_count()); |
- SwitchActiveUser(account_id2); |
- EXPECT_EQ(2, model_->item_count()); |
-} |
- |
-// Check that activating an item which is on another user's desktop, will bring |
-// it back. |
-TEST_F(MultiProfileMultiBrowserShelfLayoutChromeLauncherControllerImplTest, |
- TestLauncherActivationPullsBackWindow) { |
- // Create a browser item in the LauncherController. |
- InitLauncherController(); |
- chrome::MultiUserWindowManager* manager = |
- chrome::MultiUserWindowManager::GetInstance(); |
- |
- // Create a second test profile. The first is the one in profile() created in |
- // BrowserWithTestWindowTest::SetUp(). |
- // No need to add the profiles to the MultiUserWindowManager here. |
- // CreateMultiUserProfile() already does that. |
- TestingProfile* profile2 = CreateMultiUserProfile("user2"); |
- const AccountId current_user = |
- multi_user_util::GetAccountIdFromProfile(profile()); |
- |
- // Create a browser window with a native window for the current user. |
- std::unique_ptr<Browser> browser( |
- CreateBrowserWithTestWindowForProfile(profile())); |
- BrowserWindow* browser_window = browser->window(); |
- aura::Window* window = browser_window->GetNativeWindow(); |
- manager->SetWindowOwner(window, current_user); |
- |
- // Check that an activation of the window on its owner's desktop does not |
- // change the visibility to another user. |
- launcher_controller_->ActivateWindowOrMinimizeIfActive(browser_window, false); |
- EXPECT_TRUE(manager->IsWindowOnDesktopOfUser(window, current_user)); |
- |
- // Transfer the window to another user's desktop and check that activating it |
- // does pull it back to that user. |
- manager->ShowWindowForUser( |
- window, multi_user_util::GetAccountIdFromProfile(profile2)); |
- EXPECT_FALSE(manager->IsWindowOnDesktopOfUser(window, current_user)); |
- launcher_controller_->ActivateWindowOrMinimizeIfActive(browser_window, false); |
- EXPECT_TRUE(manager->IsWindowOnDesktopOfUser(window, current_user)); |
-} |
- |
-// Check that a running windowed V1 application will be properly pinned and |
-// unpinned when the order gets changed through a profile / policy change. |
-TEST_F(ChromeLauncherControllerImplTest, |
- RestoreDefaultAndRunningV1AppsResyncOrder) { |
- InitLauncherController(); |
- |
- syncer::SyncChangeList sync_list; |
- InsertAddPinChange(&sync_list, 0, extension1_->id()); |
- InsertAddPinChange(&sync_list, 1, extension3_->id()); |
- SendPinChanges(sync_list, true); |
- |
- // The shelf layout has always one static item at the beginning (App List). |
- extension_service_->AddExtension(extension1_.get()); |
- EXPECT_EQ("AppList, Chrome, App1", GetPinnedAppStatus()); |
- extension_service_->AddExtension(extension2_.get()); |
- // No new app icon will be generated. |
- EXPECT_EQ("AppList, Chrome, App1", GetPinnedAppStatus()); |
- |
- // Set the app status as running, which will add an unpinned item. |
- launcher_controller_->SetV1AppStatus(extension2_->id(), ash::STATUS_RUNNING); |
- EXPECT_EQ("AppList, Chrome, App1, app2", GetPinnedAppStatus()); |
- extension_service_->AddExtension(extension3_.get()); |
- EXPECT_EQ("AppList, Chrome, App1, App3, app2", GetPinnedAppStatus()); |
- |
- // Now request to pin all items, which will pin the running unpinned items. |
- syncer::SyncChangeList sync_list1; |
- InsertAddPinChange(&sync_list1, 0, extension3_->id()); |
- InsertAddPinChange(&sync_list1, 1, extension2_->id()); |
- InsertAddPinChange(&sync_list1, 2, extension1_->id()); |
- SendPinChanges(sync_list1, true); |
- EXPECT_EQ("AppList, Chrome, App3, App2, App1", GetPinnedAppStatus()); |
- |
- // Removing the requirement for app 2 to be pinned should convert it back to |
- // running but not pinned. It should move towards the end of the shelf, after |
- // the pinned items, as determined by the |ShelfModel|'s weight system. |
- syncer::SyncChangeList sync_list2; |
- InsertAddPinChange(&sync_list2, 0, extension3_->id()); |
- InsertAddPinChange(&sync_list2, 1, extension1_->id()); |
- SendPinChanges(sync_list2, true); |
- EXPECT_EQ("AppList, Chrome, App3, App1, app2", GetPinnedAppStatus()); |
- |
- // Removing an item should simply close it and everything should shift. |
- SendPinChanges(syncer::SyncChangeList(), true); |
- EXPECT_EQ("AppList, Chrome, App3, app2", GetPinnedAppStatus()); |
-} |
- |
-// Check that a running unpinned V2 application will be properly pinned and |
-// unpinned when the order gets changed through a profile / policy change. |
-TEST_F(ChromeLauncherControllerImplTest, |
- RestoreDefaultAndRunningV2AppsResyncOrder) { |
- InitLauncherController(); |
- syncer::SyncChangeList sync_list0; |
- InsertAddPinChange(&sync_list0, 0, extension1_->id()); |
- InsertAddPinChange(&sync_list0, 1, extension3_->id()); |
- SendPinChanges(sync_list0, true); |
- // The shelf layout has always one static item at the beginning (app List). |
- extension_service_->AddExtension(extension1_.get()); |
- EXPECT_EQ("AppList, Chrome, App1", GetPinnedAppStatus()); |
- extension_service_->AddExtension(extension_platform_app_.get()); |
- // No new app icon will be generated. |
- EXPECT_EQ("AppList, Chrome, App1", GetPinnedAppStatus()); |
- // Add an unpinned but running V2 app. |
- CreateRunningV2App(extension_platform_app_->id()); |
- EXPECT_EQ("AppList, Chrome, App1, *platform_app", GetPinnedAppStatus()); |
- extension_service_->AddExtension(extension3_.get()); |
- EXPECT_EQ("AppList, Chrome, App1, App3, *platform_app", GetPinnedAppStatus()); |
- |
- // Now request to pin all items, which should pin the running unpinned item. |
- syncer::SyncChangeList sync_list1; |
- InsertAddPinChange(&sync_list1, 0, extension3_->id()); |
- InsertAddPinChange(&sync_list1, 1, extension_platform_app_->id()); |
- InsertAddPinChange(&sync_list1, 2, extension1_->id()); |
- SendPinChanges(sync_list1, true); |
- EXPECT_EQ("AppList, Chrome, App3, *Platform_App, App1", GetPinnedAppStatus()); |
- |
- // Removing the requirement for app 2 to be pinned should convert it back to |
- // running but not pinned. It should move towards the end of the shelf, after |
- // the pinned items, as determined by the |ShelfModel|'s weight system. |
- syncer::SyncChangeList sync_list2; |
- InsertAddPinChange(&sync_list2, 0, extension3_->id()); |
- InsertAddPinChange(&sync_list2, 1, extension1_->id()); |
- SendPinChanges(sync_list2, true); |
- EXPECT_EQ("AppList, Chrome, App3, App1, *platform_app", GetPinnedAppStatus()); |
- |
- // Removing an item should simply close it and everything should shift. |
- syncer::SyncChangeList sync_list3; |
- InsertAddPinChange(&sync_list3, 0, extension3_->id()); |
- SendPinChanges(sync_list3, true); |
- EXPECT_EQ("AppList, Chrome, App3, *platform_app", GetPinnedAppStatus()); |
-} |
- |
-// Each user has a different set of applications pinned. Check that when |
-// switching between the two users, the state gets properly set. |
-TEST_F(ChromeLauncherControllerImplTest, UserSwitchIconRestore) { |
- syncer::SyncChangeList user_a; |
- syncer::SyncChangeList user_b; |
- |
- SetUpMultiUserScenario(&user_a, &user_b); |
- |
- // Show user 1. |
- SendPinChanges(user_a, true); |
- EXPECT_EQ("AppList, App1, App2, App3, *Platform_App, App4, App5, Chrome", |
- GetPinnedAppStatus()); |
- |
- // Show user 2. |
- SendPinChanges(user_b, true); |
- EXPECT_EQ("AppList, App6, App7, App8, Chrome", GetPinnedAppStatus()); |
- |
- // Switch back to 1. |
- SendPinChanges(user_a, true); |
- EXPECT_EQ("AppList, App1, App2, App3, *Platform_App, App4, App5, Chrome", |
- GetPinnedAppStatus()); |
- |
- // Switch back to 2. |
- SendPinChanges(user_b, true); |
- EXPECT_EQ("AppList, App6, App7, App8, Chrome", GetPinnedAppStatus()); |
-} |
- |
-// Each user has a different set of applications pinned, and one user has an |
-// application running. Check that when switching between the two users, the |
-// state gets properly set. |
-TEST_F(ChromeLauncherControllerImplTest, |
- UserSwitchIconRestoreWithRunningV2App) { |
- syncer::SyncChangeList user_a; |
- syncer::SyncChangeList user_b; |
- |
- SetUpMultiUserScenario(&user_a, &user_b); |
- |
- // Run the platform (V2) app. |
- CreateRunningV2App(extension_platform_app_->id()); |
- |
- // Show user 1. |
- SendPinChanges(user_a, true); |
- EXPECT_EQ("AppList, App1, App2, App3, *Platform_App, App4, App5, Chrome", |
- GetPinnedAppStatus()); |
- |
- // Show user 2. |
- SendPinChanges(user_b, true); |
- EXPECT_EQ("AppList, App6, App7, App8, Chrome, *platform_app", |
- GetPinnedAppStatus()); |
- |
- // Switch back to 1. |
- SendPinChanges(user_a, true); |
- EXPECT_EQ("AppList, App1, App2, App3, *Platform_App, App4, App5, Chrome", |
- GetPinnedAppStatus()); |
- |
- // Switch back to 2. |
- SendPinChanges(user_b, true); |
- EXPECT_EQ("AppList, App6, App7, App8, Chrome, *platform_app", |
- GetPinnedAppStatus()); |
-} |
- |
-// Each user has a different set of applications pinned, and one user has an |
-// application running. The chrome icon is not the last item in the list. |
-// Check that when switching between the two users, the state gets properly set. |
-// There was once a bug associated with this. |
-TEST_F(ChromeLauncherControllerImplTest, |
- UserSwitchIconRestoreWithRunningV2AppChromeInMiddle) { |
- syncer::SyncChangeList user_a; |
- syncer::SyncChangeList user_b; |
- SetUpMultiUserScenario(&user_a, &user_b); |
- |
- // Run the platform (V2) app. |
- CreateRunningV2App(extension_platform_app_->id()); |
- |
- // Show user 1. |
- SendPinChanges(user_a, true); |
- SetShelfChromeIconIndex(5); |
- EXPECT_EQ("AppList, App1, App2, App3, *Platform_App, App4, Chrome, App5", |
- GetPinnedAppStatus()); |
- |
- // Show user 2. |
- SendPinChanges(user_b, true); |
- SetShelfChromeIconIndex(4); |
- EXPECT_EQ("AppList, App6, App7, App8, Chrome, *platform_app", |
- GetPinnedAppStatus()); |
- |
- // Switch back to 1. |
- SendPinChanges(user_a, true); |
- SetShelfChromeIconIndex(5); |
- EXPECT_EQ("AppList, App1, App2, App3, *Platform_App, App4, Chrome, App5", |
- GetPinnedAppStatus()); |
-} |
- |
-TEST_F(ChromeLauncherControllerImplTest, Policy) { |
- extension_service_->AddExtension(extension1_.get()); |
- extension_service_->AddExtension(extension3_.get()); |
- |
- InitLauncherController(); |
- |
- syncer::SyncChangeList sync_list; |
- InsertAddPinChange(&sync_list, 0, extension_misc::kChromeAppId); |
- SendPinChanges(sync_list, true); |
- |
- base::ListValue policy_value; |
- InsertPrefValue(&policy_value, 0, extension1_->id()); |
- InsertPrefValue(&policy_value, 1, extension2_->id()); |
- profile()->GetTestingPrefService()->SetManagedPref( |
- prefs::kPolicyPinnedLauncherApps, policy_value.CreateDeepCopy()); |
- |
- // Only |extension1_| should get pinned. |extension2_| is specified but not |
- // installed, and |extension3_| is part of the default set, but that shouldn't |
- // take effect when the policy override is in place. |
- ASSERT_EQ(3, model_->item_count()); |
- EXPECT_EQ(ash::TYPE_PINNED_APP, model_->items()[1].type); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension1_->id())); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension2_->id())); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension3_->id())); |
- |
- // Installing |extension2_| should add it to the launcher. |
- extension_service_->AddExtension(extension2_.get()); |
- ASSERT_EQ(4, model_->item_count()); |
- EXPECT_EQ(ash::TYPE_PINNED_APP, model_->items()[1].type); |
- EXPECT_EQ(ash::TYPE_PINNED_APP, model_->items()[2].type); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension1_->id())); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension2_->id())); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension3_->id())); |
- |
- // Removing |extension1_| from the policy should not be reflected in the |
- // launcher and pin will exist. |
- policy_value.Remove(0, NULL); |
- profile()->GetTestingPrefService()->SetManagedPref( |
- prefs::kPolicyPinnedLauncherApps, policy_value.CreateDeepCopy()); |
- EXPECT_EQ(4, model_->item_count()); |
- EXPECT_EQ(ash::TYPE_PINNED_APP, model_->items()[2].type); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension1_->id())); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension2_->id())); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension3_->id())); |
-} |
- |
-TEST_F(ChromeLauncherControllerImplTest, UnpinWithUninstall) { |
- extension_service_->AddExtension(extension3_.get()); |
- extension_service_->AddExtension(extension4_.get()); |
- |
- InitLauncherController(); |
- |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension3_->id())); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension4_->id())); |
- |
- extension_service_->UnloadExtension(extension3_->id(), |
- UnloadedExtensionInfo::REASON_UNINSTALL); |
- |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension3_->id())); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension4_->id())); |
-} |
- |
-TEST_F(ChromeLauncherControllerImplTest, SyncUpdates) { |
- extension_service_->AddExtension(extension2_.get()); |
- extension_service_->AddExtension(extension3_.get()); |
- extension_service_->AddExtension(extension4_.get()); |
- |
- InitLauncherController(); |
- |
- syncer::SyncChangeList sync_list; |
- InsertAddPinChange(&sync_list, 10, extension_misc::kChromeAppId); |
- SendPinChanges(sync_list, true); |
- |
- std::vector<std::string> expected_pinned_apps; |
- std::vector<std::string> actual_pinned_apps; |
- GetPinnedAppIds(launcher_controller_, &actual_pinned_apps); |
- EXPECT_EQ(expected_pinned_apps, actual_pinned_apps); |
- |
- // Unavailable extensions don't create launcher items. |
- sync_list.clear(); |
- InsertAddPinChange(&sync_list, 0, extension1_->id()); |
- InsertAddPinChange(&sync_list, 1, extension2_->id()); |
- InsertAddPinChange(&sync_list, 3, extension4_->id()); |
- SendPinChanges(sync_list, false); |
- |
- expected_pinned_apps.push_back(extension2_->id()); |
- expected_pinned_apps.push_back(extension4_->id()); |
- GetPinnedAppIds(launcher_controller_, &actual_pinned_apps); |
- EXPECT_EQ(expected_pinned_apps, actual_pinned_apps); |
- |
- sync_list.clear(); |
- InsertAddPinChange(&sync_list, 2, extension3_->id()); |
- SendPinChanges(sync_list, false); |
- expected_pinned_apps.insert(expected_pinned_apps.begin() + 1, |
- extension3_->id()); |
- GetPinnedAppIds(launcher_controller_, &actual_pinned_apps); |
- EXPECT_EQ(expected_pinned_apps, actual_pinned_apps); |
- |
- sync_list.clear(); |
- InsertUpdatePinChange(&sync_list, 0, extension4_->id()); |
- InsertUpdatePinChange(&sync_list, 1, extension3_->id()); |
- InsertUpdatePinChange(&sync_list, 2, extension2_->id()); |
- SendPinChanges(sync_list, false); |
- std::reverse(expected_pinned_apps.begin(), expected_pinned_apps.end()); |
- GetPinnedAppIds(launcher_controller_, &actual_pinned_apps); |
- EXPECT_EQ(expected_pinned_apps, actual_pinned_apps); |
- |
- // Sending legacy sync change without pin info should not affect pin model. |
- sync_list.clear(); |
- InsertLegacyPinChange(&sync_list, extension4_->id()); |
- SendPinChanges(sync_list, false); |
- GetPinnedAppIds(launcher_controller_, &actual_pinned_apps); |
- EXPECT_EQ(expected_pinned_apps, actual_pinned_apps); |
- |
- sync_list.clear(); |
- InsertRemovePinChange(&sync_list, extension4_->id()); |
- SendPinChanges(sync_list, false); |
- expected_pinned_apps.erase(expected_pinned_apps.begin()); |
- GetPinnedAppIds(launcher_controller_, &actual_pinned_apps); |
- EXPECT_EQ(expected_pinned_apps, actual_pinned_apps); |
- |
- sync_list.clear(); |
- InsertRemovePinChange(&sync_list, extension3_->id()); |
- InsertRemovePinChange(&sync_list, extension2_->id()); |
- SendPinChanges(sync_list, false); |
- expected_pinned_apps.clear(); |
- GetPinnedAppIds(launcher_controller_, &actual_pinned_apps); |
- EXPECT_EQ(expected_pinned_apps, actual_pinned_apps); |
-} |
- |
-TEST_F(ChromeLauncherControllerImplTest, ImportLegacyPin) { |
- // Note extension3_ is actually Gmail app which is default pinned. |
- extension_service_->AddExtension(extension3_.get()); |
- InitLauncherController(); |
- |
- // Default pins should contain Gmail. Pref is not syncing now. |
- EXPECT_EQ("AppList, Chrome, App3", GetPinnedAppStatus()); |
- |
- extension_service_->AddExtension(extension2_.get()); |
- EXPECT_EQ("AppList, Chrome, App3", GetPinnedAppStatus()); |
- |
- // Initially pins are imported from legacy pref based model. |
- base::ListValue value; |
- InsertPrefValue(&value, 0, extension4_->id()); |
- InsertPrefValue(&value, 1, extension2_->id()); |
- InsertPrefValue(&value, 2, extension3_->id()); |
- StartPrefSyncServiceForPins(value); |
- |
- // Imported pins contain App2. App2 should be added to pins now. |
- EXPECT_EQ("AppList, Chrome, App2, App3", GetPinnedAppStatus()); |
- |
- // extension4_ is in the pin list. |
- extension_service_->AddExtension(extension4_.get()); |
- // extension5_ is not in the pin list. |
- extension_service_->AddExtension(extension5_.get()); |
- EXPECT_EQ("AppList, Chrome, App4, App2, App3", GetPinnedAppStatus()); |
- |
- // Apply app sync, unpin one app and pin new one. |
- syncer::SyncChangeList sync_list; |
- InsertAddPinChange(&sync_list, -1, extension3_->id()); |
- InsertAddPinChange(&sync_list, 3, extension5_->id()); |
- SendPinChanges(sync_list, false); |
- EXPECT_EQ("AppList, Chrome, App4, App2, App5", GetPinnedAppStatus()); |
- |
- // At this point changing old pref based model does not affect pin model. |
- InsertPrefValue(&value, 3, extension5_->id()); |
- StopPrefSyncService(); |
- StartPrefSyncServiceForPins(value); |
- EXPECT_EQ("AppList, Chrome, App4, App2, App5", GetPinnedAppStatus()); |
- |
- // Next Chrome start should preserve pins. |
- RecreateLauncherController()->Init(); |
- StopPrefSyncService(); |
- StartPrefSyncService(syncer::SyncDataList()); |
- EXPECT_EQ("AppList, Chrome, App4, App2, App5", GetPinnedAppStatus()); |
-} |
- |
-TEST_F(ChromeLauncherControllerImplTest, PendingInsertionOrder) { |
- extension_service_->AddExtension(extension1_.get()); |
- extension_service_->AddExtension(extension3_.get()); |
- |
- InitLauncherController(); |
- |
- syncer::SyncChangeList sync_list; |
- InsertAddPinChange(&sync_list, 0, extension1_->id()); |
- InsertAddPinChange(&sync_list, 1, extension2_->id()); |
- InsertAddPinChange(&sync_list, 2, extension3_->id()); |
- SendPinChanges(sync_list, true); |
- |
- std::vector<std::string> expected_pinned_apps; |
- expected_pinned_apps.push_back(extension1_->id()); |
- expected_pinned_apps.push_back(extension3_->id()); |
- std::vector<std::string> actual_pinned_apps; |
- |
- GetPinnedAppIds(launcher_controller_, &actual_pinned_apps); |
- EXPECT_EQ(expected_pinned_apps, actual_pinned_apps); |
- |
- // Install |extension2| and verify it shows up between the other two. |
- extension_service_->AddExtension(extension2_.get()); |
- expected_pinned_apps.insert(expected_pinned_apps.begin() + 1, |
- extension2_->id()); |
- GetPinnedAppIds(launcher_controller_, &actual_pinned_apps); |
- EXPECT_EQ(expected_pinned_apps, actual_pinned_apps); |
-} |
- |
-// Ensure |controller| creates the expected menu items for the given shelf item. |
-void CheckAppMenu(ChromeLauncherControllerImpl* controller, |
- const ash::ShelfItem& item, |
- size_t expected_item_count, |
- base::string16 expected_item_titles[]) { |
- ash::MenuItemList items = controller->GetAppMenuItemsForTesting(item); |
- ASSERT_EQ(expected_item_count, items.size()); |
- for (size_t i = 0; i < expected_item_count; i++) |
- EXPECT_EQ(expected_item_titles[i], items[i]->label); |
-} |
- |
-// Check that browsers get reflected correctly in the launcher menu. |
-TEST_F(ChromeLauncherControllerImplTest, BrowserMenuGeneration) { |
- EXPECT_EQ(1U, chrome::GetTotalBrowserCount()); |
- chrome::NewTab(browser()); |
- |
- InitLauncherController(); |
- |
- // Check that the browser list is empty at this time. |
- ash::ShelfItem item_browser; |
- item_browser.type = ash::TYPE_BROWSER_SHORTCUT; |
- item_browser.id = |
- launcher_controller_->GetShelfIDForAppID(extension_misc::kChromeAppId); |
- CheckAppMenu(launcher_controller_, item_browser, 0, nullptr); |
- |
- // Now make the created browser() visible by showing its browser window. |
- browser()->window()->Show(); |
- base::string16 title1 = ASCIIToUTF16("Test1"); |
- NavigateAndCommitActiveTabWithTitle(browser(), GURL("http://test1"), title1); |
- base::string16 one_menu_item[] = { title1 }; |
- |
- CheckAppMenu(launcher_controller_, item_browser, 1, one_menu_item); |
- |
- // Create one more browser/window and check that one more was added. |
- std::unique_ptr<Browser> browser2( |
- CreateBrowserWithTestWindowForProfile(profile())); |
- chrome::NewTab(browser2.get()); |
- browser2->window()->Show(); |
- base::string16 title2 = ASCIIToUTF16("Test2"); |
- NavigateAndCommitActiveTabWithTitle(browser2.get(), GURL("http://test2"), |
- title2); |
- |
- // Check that the list contains now two entries - make furthermore sure that |
- // the active item is the first entry. |
- base::string16 two_menu_items[] = {title1, title2}; |
- CheckAppMenu(launcher_controller_, item_browser, 2, two_menu_items); |
- |
- // Apparently we have to close all tabs we have. |
- chrome::CloseTab(browser2.get()); |
-} |
- |
-// Check the multi profile case where only user related browsers should show up. |
-TEST_F(MultiProfileMultiBrowserShelfLayoutChromeLauncherControllerImplTest, |
- BrowserMenuGenerationTwoUsers) { |
- // Create a browser item in the LauncherController. |
- InitLauncherController(); |
- |
- ash::ShelfItem item_browser; |
- item_browser.type = ash::TYPE_BROWSER_SHORTCUT; |
- item_browser.id = |
- launcher_controller_->GetShelfIDForAppID(extension_misc::kChromeAppId); |
- |
- // Check that the menu is empty. |
- chrome::NewTab(browser()); |
- CheckAppMenu(launcher_controller_, item_browser, 0, nullptr); |
- |
- // Show the created |browser()| by showing its window. |
- browser()->window()->Show(); |
- base::string16 title1 = ASCIIToUTF16("Test1"); |
- NavigateAndCommitActiveTabWithTitle(browser(), GURL("http://test1"), title1); |
- base::string16 one_menu_item1[] = { title1 }; |
- CheckAppMenu(launcher_controller_, item_browser, 1, one_menu_item1); |
- |
- // Create a browser for another user and check that it is not included in the |
- // users running browser list. |
- std::string user2 = "user2"; |
- TestingProfile* profile2 = CreateMultiUserProfile(user2); |
- const AccountId account_id2( |
- multi_user_util::GetAccountIdFromProfile(profile2)); |
- std::unique_ptr<Browser> browser2( |
- CreateBrowserAndTabWithProfile(profile2, user2, "http://test2")); |
- base::string16 one_menu_item2[] = { ASCIIToUTF16(user2) }; |
- CheckAppMenu(launcher_controller_, item_browser, 1, one_menu_item1); |
- |
- // Switch to the other user and make sure that only that browser window gets |
- // shown. |
- SwitchActiveUser(account_id2); |
- CheckAppMenu(launcher_controller_, item_browser, 1, one_menu_item2); |
- |
- // Transferred browsers of other users should not show up in the list. |
- chrome::MultiUserWindowManager::GetInstance()->ShowWindowForUser( |
- browser()->window()->GetNativeWindow(), account_id2); |
- CheckAppMenu(launcher_controller_, item_browser, 1, one_menu_item2); |
- |
- chrome::CloseTab(browser2.get()); |
-} |
- |
-// Check that V1 apps are correctly reflected in the launcher menu using the |
-// refocus logic. |
-// Note that the extension matching logic is tested by the extension system |
-// and does not need a separate test here. |
-TEST_F(ChromeLauncherControllerImplTest, V1AppMenuGeneration) { |
- EXPECT_EQ(1U, chrome::GetTotalBrowserCount()); |
- EXPECT_EQ(0, browser()->tab_strip_model()->count()); |
- |
- InitLauncherControllerWithBrowser(); |
- |
- // The model should only contain the browser shortcut and app list items. |
- EXPECT_EQ(2, model_->item_count()); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned(extension3_->id())); |
- |
- // Installing |extension3_| adds it to the launcher. |
- ash::ShelfID gmail_id = model_->next_id(); |
- extension_service_->AddExtension(extension3_.get()); |
- EXPECT_EQ(3, model_->item_count()); |
- int gmail_index = model_->ItemIndexByID(gmail_id); |
- EXPECT_EQ(ash::TYPE_PINNED_APP, model_->items()[gmail_index].type); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension3_->id())); |
- launcher_controller_->SetRefocusURLPatternForTest(gmail_id, GURL(gmail_url)); |
- |
- // Check the menu content. |
- ash::ShelfItem item_browser; |
- item_browser.type = ash::TYPE_BROWSER_SHORTCUT; |
- item_browser.id = |
- launcher_controller_->GetShelfIDForAppID(extension_misc::kChromeAppId); |
- |
- ash::ShelfItem item_gmail; |
- item_gmail.type = ash::TYPE_PINNED_APP; |
- item_gmail.id = gmail_id; |
- CheckAppMenu(launcher_controller_, item_gmail, 0, nullptr); |
- |
- // Set the gmail URL to a new tab. |
- base::string16 title1 = ASCIIToUTF16("Test1"); |
- NavigateAndCommitActiveTabWithTitle(browser(), GURL(gmail_url), title1); |
- |
- base::string16 one_menu_item[] = { title1 }; |
- CheckAppMenu(launcher_controller_, item_gmail, 1, one_menu_item); |
- |
- // Create one empty tab. |
- chrome::NewTab(browser()); |
- base::string16 title2 = ASCIIToUTF16("Test2"); |
- NavigateAndCommitActiveTabWithTitle( |
- browser(), |
- GURL("https://bla"), |
- title2); |
- |
- // and another one with another gmail instance. |
- chrome::NewTab(browser()); |
- base::string16 title3 = ASCIIToUTF16("Test3"); |
- NavigateAndCommitActiveTabWithTitle(browser(), GURL(gmail_url), title3); |
- base::string16 two_menu_items[] = {title1, title3}; |
- CheckAppMenu(launcher_controller_, item_gmail, 2, two_menu_items); |
- |
- // Even though the item is in the V1 app list, it should also be in the |
- // browser list. |
- base::string16 browser_menu_item[] = {title3}; |
- CheckAppMenu(launcher_controller_, item_browser, 1, browser_menu_item); |
- |
- // Test that closing of (all) the item(s) does work (and all menus get |
- // updated properly). |
- launcher_controller_->Close(item_gmail.id); |
- |
- CheckAppMenu(launcher_controller_, item_gmail, 0, nullptr); |
- base::string16 browser_menu_item2[] = { title2 }; |
- CheckAppMenu(launcher_controller_, item_browser, 1, browser_menu_item2); |
-} |
- |
-// Check the multi profile case where only user related apps should show up. |
-TEST_F(MultiProfileMultiBrowserShelfLayoutChromeLauncherControllerImplTest, |
- V1AppMenuGenerationTwoUsers) { |
- // Create a browser item in the LauncherController. |
- InitLauncherController(); |
- chrome::NewTab(browser()); |
- |
- // Installing |extension3_| adds it to the launcher. |
- ash::ShelfID gmail_id = model_->next_id(); |
- extension_service_->AddExtension(extension3_.get()); |
- EXPECT_EQ(3, model_->item_count()); |
- int gmail_index = model_->ItemIndexByID(gmail_id); |
- EXPECT_EQ(ash::TYPE_PINNED_APP, model_->items()[gmail_index].type); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension3_->id())); |
- launcher_controller_->SetRefocusURLPatternForTest(gmail_id, GURL(gmail_url)); |
- |
- // Check the menu content. |
- ash::ShelfItem item_browser; |
- item_browser.type = ash::TYPE_BROWSER_SHORTCUT; |
- item_browser.id = |
- launcher_controller_->GetShelfIDForAppID(extension_misc::kChromeAppId); |
- |
- ash::ShelfItem item_gmail; |
- item_gmail.type = ash::TYPE_PINNED_APP; |
- item_gmail.id = gmail_id; |
- CheckAppMenu(launcher_controller_, item_gmail, 0, nullptr); |
- |
- // Set the gmail URL to a new tab. |
- base::string16 title1 = ASCIIToUTF16("Test1"); |
- NavigateAndCommitActiveTabWithTitle(browser(), GURL(gmail_url), title1); |
- |
- base::string16 one_menu_item[] = { title1 }; |
- CheckAppMenu(launcher_controller_, item_gmail, 1, one_menu_item); |
- |
- // Create a second profile and switch to that user. |
- std::string user2 = "user2"; |
- TestingProfile* profile2 = CreateMultiUserProfile(user2); |
- const AccountId account_id2( |
- multi_user_util::GetAccountIdFromProfile(profile2)); |
- SwitchActiveUser(account_id2); |
- |
- // No item should have content yet. |
- CheckAppMenu(launcher_controller_, item_browser, 0, nullptr); |
- CheckAppMenu(launcher_controller_, item_gmail, 0, nullptr); |
- |
- // Transfer the browser of the first user - it should still not show up. |
- chrome::MultiUserWindowManager::GetInstance()->ShowWindowForUser( |
- browser()->window()->GetNativeWindow(), account_id2); |
- |
- CheckAppMenu(launcher_controller_, item_browser, 0, nullptr); |
- CheckAppMenu(launcher_controller_, item_gmail, 0, nullptr); |
-} |
- |
-// Check that V2 applications are creating items properly in the launcher when |
-// instantiated by the current user. |
-TEST_F(MultiProfileMultiBrowserShelfLayoutChromeLauncherControllerImplTest, |
- V2AppHandlingTwoUsers) { |
- InitLauncherController(); |
- // Create a profile for our second user (will be destroyed by the framework). |
- TestingProfile* profile2 = CreateMultiUserProfile("user2"); |
- const AccountId account_id( |
- multi_user_util::GetAccountIdFromProfile(profile())); |
- const AccountId account_id2( |
- multi_user_util::GetAccountIdFromProfile(profile2)); |
- // Check that there is a browser and a app launcher. |
- EXPECT_EQ(2, model_->item_count()); |
- |
- // Add a v2 app. |
- V2App v2_app(profile(), extension1_.get()); |
- EXPECT_EQ(3, model_->item_count()); |
- |
- // After switching users the item should go away. |
- SwitchActiveUser(account_id2); |
- EXPECT_EQ(2, model_->item_count()); |
- |
- // And it should come back when switching back. |
- SwitchActiveUser(account_id); |
- EXPECT_EQ(3, model_->item_count()); |
-} |
- |
-// Check that V2 applications are creating items properly in edge cases: |
-// a background user creates a V2 app, gets active and inactive again and then |
-// deletes the app. |
-TEST_F(MultiProfileMultiBrowserShelfLayoutChromeLauncherControllerImplTest, |
- V2AppHandlingTwoUsersEdgeCases) { |
- InitLauncherController(); |
- // Create a profile for our second user (will be destroyed by the framework). |
- TestingProfile* profile2 = CreateMultiUserProfile("user2"); |
- const AccountId account_id( |
- multi_user_util::GetAccountIdFromProfile(profile())); |
- const AccountId account_id2( |
- multi_user_util::GetAccountIdFromProfile(profile2)); |
- // Check that there is a browser and a app launcher. |
- EXPECT_EQ(2, model_->item_count()); |
- |
- // Switch to an inactive user. |
- SwitchActiveUser(account_id2); |
- EXPECT_EQ(2, model_->item_count()); |
- |
- // Add the v2 app to the inactive user and check that no item was added to |
- // the launcher. |
- { |
- V2App v2_app(profile(), extension1_.get()); |
- EXPECT_EQ(2, model_->item_count()); |
- |
- // Switch to the primary user and check that the item is shown. |
- SwitchActiveUser(account_id); |
- EXPECT_EQ(3, model_->item_count()); |
- |
- // Switch to the second user and check that the item goes away - even if the |
- // item gets closed. |
- SwitchActiveUser(account_id2); |
- EXPECT_EQ(2, model_->item_count()); |
- } |
- |
- // After the application was killed there should be still 2 items. |
- EXPECT_EQ(2, model_->item_count()); |
- |
- // Switching then back to the default user should not show the additional item |
- // anymore. |
- SwitchActiveUser(account_id); |
- EXPECT_EQ(2, model_->item_count()); |
-} |
- |
-// Check that V2 applications will be made visible on the target desktop if |
-// another window of the same type got previously teleported there. |
-TEST_F(MultiProfileMultiBrowserShelfLayoutChromeLauncherControllerImplTest, |
- V2AppFollowsTeleportedWindow) { |
- InitLauncherController(); |
- chrome::MultiUserWindowManager* manager = |
- chrome::MultiUserWindowManager::GetInstance(); |
- |
- // Create and add three users / profiles, and go to #1's desktop. |
- TestingProfile* profile1 = CreateMultiUserProfile("user-1"); |
- TestingProfile* profile2 = CreateMultiUserProfile("user-2"); |
- TestingProfile* profile3 = CreateMultiUserProfile("user-3"); |
- const AccountId account_id1( |
- multi_user_util::GetAccountIdFromProfile(profile1)); |
- const AccountId account_id2( |
- multi_user_util::GetAccountIdFromProfile(profile2)); |
- const AccountId account_id3( |
- multi_user_util::GetAccountIdFromProfile(profile3)); |
- SwitchActiveUser(account_id1); |
- |
- // A v2 app for user #1 should be shown first and get hidden when switching to |
- // desktop #2. |
- V2App v2_app_1(profile1, extension1_.get()); |
- EXPECT_TRUE(v2_app_1.window()->GetNativeWindow()->IsVisible()); |
- SwitchActiveUser(account_id2); |
- EXPECT_FALSE(v2_app_1.window()->GetNativeWindow()->IsVisible()); |
- |
- // Add a v2 app for user #1 while on desktop #2 should not be shown. |
- V2App v2_app_2(profile1, extension1_.get()); |
- EXPECT_FALSE(v2_app_1.window()->GetNativeWindow()->IsVisible()); |
- EXPECT_FALSE(v2_app_2.window()->GetNativeWindow()->IsVisible()); |
- |
- // Teleport the app from user #1 to the desktop #2 should show it. |
- manager->ShowWindowForUser(v2_app_1.window()->GetNativeWindow(), account_id2); |
- EXPECT_TRUE(v2_app_1.window()->GetNativeWindow()->IsVisible()); |
- EXPECT_FALSE(v2_app_2.window()->GetNativeWindow()->IsVisible()); |
- |
- // Creating a new application for user #1 on desktop #2 should teleport it |
- // there automatically. |
- V2App v2_app_3(profile1, extension1_.get()); |
- EXPECT_TRUE(v2_app_1.window()->GetNativeWindow()->IsVisible()); |
- EXPECT_FALSE(v2_app_2.window()->GetNativeWindow()->IsVisible()); |
- EXPECT_TRUE(v2_app_3.window()->GetNativeWindow()->IsVisible()); |
- |
- // Switching back to desktop#1 and creating an app for user #1 should move |
- // the app on desktop #1. |
- SwitchActiveUser(account_id1); |
- V2App v2_app_4(profile1, extension1_.get()); |
- EXPECT_FALSE(v2_app_1.window()->GetNativeWindow()->IsVisible()); |
- EXPECT_TRUE(v2_app_2.window()->GetNativeWindow()->IsVisible()); |
- EXPECT_FALSE(v2_app_3.window()->GetNativeWindow()->IsVisible()); |
- EXPECT_TRUE(v2_app_4.window()->GetNativeWindow()->IsVisible()); |
- |
- // Switching to desktop #3 and creating an app for user #1 should place it on |
- // that user's desktop (#1). |
- SwitchActiveUser(account_id3); |
- V2App v2_app_5(profile1, extension1_.get()); |
- EXPECT_FALSE(v2_app_5.window()->GetNativeWindow()->IsVisible()); |
- SwitchActiveUser(account_id1); |
- EXPECT_TRUE(v2_app_5.window()->GetNativeWindow()->IsVisible()); |
- |
- // Switching to desktop #2, hiding the app window and creating an app should |
- // teleport there automatically. |
- SwitchActiveUser(account_id2); |
- v2_app_1.window()->Hide(); |
- V2App v2_app_6(profile1, extension1_.get()); |
- EXPECT_FALSE(v2_app_1.window()->GetNativeWindow()->IsVisible()); |
- EXPECT_FALSE(v2_app_2.window()->GetNativeWindow()->IsVisible()); |
- EXPECT_TRUE(v2_app_6.window()->GetNativeWindow()->IsVisible()); |
-} |
- |
-// Check that V2 applications hide correctly on the shelf when the app window |
-// is hidden. |
-TEST_F(MultiProfileMultiBrowserShelfLayoutChromeLauncherControllerImplTest, |
- V2AppHiddenWindows) { |
- InitLauncherController(); |
- |
- TestingProfile* profile2 = CreateMultiUserProfile("user-2"); |
- const AccountId account_id( |
- multi_user_util::GetAccountIdFromProfile(profile())); |
- const AccountId account_id2( |
- multi_user_util::GetAccountIdFromProfile(profile2)); |
- SwitchActiveUser(account_id); |
- EXPECT_EQ(2, model_->item_count()); |
- |
- V2App v2_app_1(profile(), extension1_.get()); |
- EXPECT_EQ(3, model_->item_count()); |
- { |
- // Hide and show the app. |
- v2_app_1.window()->Hide(); |
- EXPECT_EQ(2, model_->item_count()); |
- |
- v2_app_1.window()->Show(extensions::AppWindow::SHOW_ACTIVE); |
- EXPECT_EQ(3, model_->item_count()); |
- } |
- { |
- // Switch user, hide and show the app and switch back. |
- SwitchActiveUser(account_id2); |
- EXPECT_EQ(2, model_->item_count()); |
- |
- v2_app_1.window()->Hide(); |
- EXPECT_EQ(2, model_->item_count()); |
- |
- v2_app_1.window()->Show(extensions::AppWindow::SHOW_ACTIVE); |
- EXPECT_EQ(2, model_->item_count()); |
- |
- SwitchActiveUser(account_id); |
- EXPECT_EQ(3, model_->item_count()); |
- } |
- { |
- // Switch user, hide the app, switch back and then show it again. |
- SwitchActiveUser(account_id2); |
- EXPECT_EQ(2, model_->item_count()); |
- |
- v2_app_1.window()->Hide(); |
- EXPECT_EQ(2, model_->item_count()); |
- |
- SwitchActiveUser(account_id); |
- // The following expectation does not work in current impl. It was working |
- // before because MultiUserWindowManagerChromeOS is not attached to user |
- // associated with profile() hence not actually handling windows for the |
- // user. It is a real bug. See http://crbug.com/693634 |
- // EXPECT_EQ(2, model_->item_count()); |
- |
- v2_app_1.window()->Show(extensions::AppWindow::SHOW_ACTIVE); |
- EXPECT_EQ(3, model_->item_count()); |
- } |
- { |
- // Create a second app, hide and show it and then hide both apps. |
- V2App v2_app_2(profile(), extension1_.get()); |
- EXPECT_EQ(3, model_->item_count()); |
- |
- v2_app_2.window()->Hide(); |
- EXPECT_EQ(3, model_->item_count()); |
- |
- v2_app_2.window()->Show(extensions::AppWindow::SHOW_ACTIVE); |
- EXPECT_EQ(3, model_->item_count()); |
- |
- v2_app_1.window()->Hide(); |
- v2_app_2.window()->Hide(); |
- EXPECT_EQ(2, model_->item_count()); |
- } |
-} |
- |
-// Checks that the generated menu list properly activates items. |
-TEST_F(ChromeLauncherControllerImplTest, V1AppMenuExecution) { |
- InitLauncherControllerWithBrowser(); |
- |
- // Add |extension3_| to the launcher and add two items. |
- GURL gmail = GURL("https://mail.google.com/mail/u"); |
- ash::ShelfID gmail_id = model_->next_id(); |
- extension_service_->AddExtension(extension3_.get()); |
- launcher_controller_->SetRefocusURLPatternForTest(gmail_id, GURL(gmail_url)); |
- base::string16 title1 = ASCIIToUTF16("Test1"); |
- NavigateAndCommitActiveTabWithTitle(browser(), GURL(gmail_url), title1); |
- chrome::NewTab(browser()); |
- base::string16 title2 = ASCIIToUTF16("Test2"); |
- NavigateAndCommitActiveTabWithTitle(browser(), GURL(gmail_url), title2); |
- |
- // Check that the menu is properly set. |
- ash::ShelfItem item_gmail; |
- item_gmail.type = ash::TYPE_PINNED_APP; |
- item_gmail.id = gmail_id; |
- base::string16 two_menu_items[] = {title1, title2}; |
- CheckAppMenu(launcher_controller_, item_gmail, 2, two_menu_items); |
- ash::ShelfItemDelegate* item_delegate = |
- model_->GetShelfItemDelegate(gmail_id); |
- ASSERT_TRUE(item_delegate); |
- EXPECT_EQ(1, browser()->tab_strip_model()->active_index()); |
- // Execute the second item in the menu, after the title and two separators, |
- // this shouldn't do anything since that item is already the active tab. |
- { |
- ash::ShelfApplicationMenuModel menu( |
- base::string16(), |
- launcher_controller_->GetAppMenuItemsForTesting(item_gmail), |
- item_delegate); |
- menu.ActivatedAt(4); |
- } |
- EXPECT_EQ(1, browser()->tab_strip_model()->active_index()); |
- |
- // Execute the first item in the menu, after the title and two separators, |
- // this should activate the other tab. |
- { |
- ash::ShelfApplicationMenuModel menu( |
- base::string16(), |
- launcher_controller_->GetAppMenuItemsForTesting(item_gmail), |
- item_delegate); |
- menu.ActivatedAt(3); |
- } |
- EXPECT_EQ(0, browser()->tab_strip_model()->active_index()); |
-} |
- |
-// Checks that the generated menu list properly deletes items. |
-TEST_F(ChromeLauncherControllerImplTest, V1AppMenuDeletionExecution) { |
- InitLauncherControllerWithBrowser(); |
- |
- // Add |extension3_| to the launcher and add two items. |
- GURL gmail = GURL("https://mail.google.com/mail/u"); |
- ash::ShelfID gmail_id = model_->next_id(); |
- extension_service_->AddExtension(extension3_.get()); |
- launcher_controller_->SetRefocusURLPatternForTest(gmail_id, GURL(gmail_url)); |
- base::string16 title1 = ASCIIToUTF16("Test1"); |
- NavigateAndCommitActiveTabWithTitle(browser(), GURL(gmail_url), title1); |
- chrome::NewTab(browser()); |
- base::string16 title2 = ASCIIToUTF16("Test2"); |
- NavigateAndCommitActiveTabWithTitle(browser(), GURL(gmail_url), title2); |
- |
- // Check that the menu is properly set. |
- ash::ShelfItem item_gmail; |
- item_gmail.type = ash::TYPE_PINNED_APP; |
- item_gmail.id = gmail_id; |
- base::string16 two_menu_items[] = {title1, title2}; |
- CheckAppMenu(launcher_controller_, item_gmail, 2, two_menu_items); |
- |
- ash::ShelfItemDelegate* item_delegate = |
- model_->GetShelfItemDelegate(gmail_id); |
- ASSERT_TRUE(item_delegate); |
- int tabs = browser()->tab_strip_model()->count(); |
- // Activate the proper tab through the menu item. |
- { |
- ash::MenuItemList items = |
- launcher_controller_->GetAppMenuItemsForTesting(item_gmail); |
- item_delegate->ExecuteCommand(items[1]->command_id, ui::EF_NONE); |
- EXPECT_EQ(tabs, browser()->tab_strip_model()->count()); |
- } |
- |
- // Delete one tab through the menu item. |
- { |
- ash::MenuItemList items = |
- launcher_controller_->GetAppMenuItemsForTesting(item_gmail); |
- item_delegate->ExecuteCommand(items[1]->command_id, ui::EF_SHIFT_DOWN); |
- EXPECT_EQ(--tabs, browser()->tab_strip_model()->count()); |
- } |
-} |
- |
-// Tests that panels create launcher items correctly |
-TEST_F(ChromeLauncherControllerImplTest, AppPanels) { |
- InitLauncherController(); |
- model_observer_->clear_counts(); |
- const std::string app_id = extension1_->id(); |
- |
- // app_icon_loader is owned by ChromeLauncherControllerImpl. |
- TestAppIconLoaderImpl* app_icon_loader = new TestAppIconLoaderImpl(); |
- app_icon_loader->AddSupportedApp(app_id); |
- SetAppIconLoader(std::unique_ptr<AppIconLoader>(app_icon_loader)); |
- |
- // Make an app panel; the ShelfItem is added by ash::ShelfWindowWatcher. |
- std::unique_ptr<V2App> app_panel1 = base::MakeUnique<V2App>( |
- profile(), extension1_.get(), extensions::AppWindow::WINDOW_TYPE_PANEL); |
- EXPECT_TRUE(app_panel1->window()->GetNativeWindow()->IsVisible()); |
- int panel_index = model_observer_->last_index(); |
- EXPECT_EQ(1, model_observer_->added()); |
- EXPECT_EQ(1, app_icon_loader->fetch_count()); |
- model_observer_->clear_counts(); |
- |
- // App panels should have a separate identifier than the app id |
- EXPECT_EQ(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(app_id)); |
- |
- // Setting the app image should not change the panel, which has a window icon. |
- gfx::ImageSkia image; |
- launcher_controller_->OnAppImageUpdated(app_id, image); |
- EXPECT_EQ(0, model_observer_->changed()); |
- model_observer_->clear_counts(); |
- |
- // Make a second app panel and verify that it gets the same index as the first |
- // panel, being added to the left of the existing panel. |
- std::unique_ptr<V2App> app_panel2 = base::MakeUnique<V2App>( |
- profile(), extension2_.get(), extensions::AppWindow::WINDOW_TYPE_PANEL); |
- EXPECT_EQ(panel_index, model_observer_->last_index()); |
- EXPECT_EQ(1, model_observer_->added()); |
- model_observer_->clear_counts(); |
- |
- app_panel1.reset(); |
- app_panel2.reset(); |
- EXPECT_EQ(2, model_observer_->removed()); |
-} |
- |
-// Tests that the Gmail extension matches more than the app itself claims with |
-// the manifest file. |
-TEST_F(ChromeLauncherControllerImplTest, GmailMatching) { |
- InitLauncherControllerWithBrowser(); |
- |
- // Create a Gmail browser tab. |
- chrome::NewTab(browser()); |
- base::string16 title = ASCIIToUTF16("Test"); |
- NavigateAndCommitActiveTabWithTitle(browser(), GURL(gmail_url), title); |
- content::WebContents* content = |
- browser()->tab_strip_model()->GetActiveWebContents(); |
- |
- // Check that the launcher controller does not recognize the running app. |
- EXPECT_FALSE(launcher_controller_->ContentCanBeHandledByGmailApp(content)); |
- |
- // Installing |extension3_| adds it to the launcher. |
- ash::ShelfID gmail_id = model_->next_id(); |
- extension_service_->AddExtension(extension3_.get()); |
- EXPECT_EQ(3, model_->item_count()); |
- int gmail_index = model_->ItemIndexByID(gmail_id); |
- EXPECT_EQ(ash::TYPE_PINNED_APP, model_->items()[gmail_index].type); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension3_->id())); |
- |
- // Check that it is now handled. |
- EXPECT_TRUE(launcher_controller_->ContentCanBeHandledByGmailApp(content)); |
- |
- // Check also that the app has detected that properly. |
- ash::ShelfItem item_gmail; |
- item_gmail.type = ash::TYPE_PINNED_APP; |
- item_gmail.id = gmail_id; |
- EXPECT_EQ(1U, |
- launcher_controller_->GetAppMenuItemsForTesting(item_gmail).size()); |
-} |
- |
-// Tests that the Gmail extension does not match the offline verison. |
-TEST_F(ChromeLauncherControllerImplTest, GmailOfflineMatching) { |
- InitLauncherControllerWithBrowser(); |
- |
- // Create a Gmail browser tab. |
- chrome::NewTab(browser()); |
- base::string16 title = ASCIIToUTF16("Test"); |
- NavigateAndCommitActiveTabWithTitle(browser(), |
- GURL(offline_gmail_url), |
- title); |
- content::WebContents* content = |
- browser()->tab_strip_model()->GetActiveWebContents(); |
- |
- // Installing |extension3_| adds it to the launcher. |
- ash::ShelfID gmail_id = model_->next_id(); |
- extension_service_->AddExtension(extension3_.get()); |
- EXPECT_EQ(3, model_->item_count()); |
- int gmail_index = model_->ItemIndexByID(gmail_id); |
- EXPECT_EQ(ash::TYPE_PINNED_APP, model_->items()[gmail_index].type); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(extension3_->id())); |
- |
- // The content should not be able to be handled by the app. |
- EXPECT_FALSE(launcher_controller_->ContentCanBeHandledByGmailApp(content)); |
-} |
- |
-// Verify that the launcher item positions are persisted and restored. |
-TEST_F(ChromeLauncherControllerImplTest, PersistLauncherItemPositions) { |
- InitLauncherController(); |
- |
- TestLauncherControllerHelper* helper = new TestLauncherControllerHelper; |
- SetLauncherControllerHelper(helper); |
- |
- EXPECT_EQ(ash::TYPE_APP_LIST, model_->items()[0].type); |
- EXPECT_EQ(ash::TYPE_BROWSER_SHORTCUT, model_->items()[1].type); |
- |
- TabStripModel* tab_strip_model = browser()->tab_strip_model(); |
- EXPECT_EQ(0, tab_strip_model->count()); |
- chrome::NewTab(browser()); |
- chrome::NewTab(browser()); |
- EXPECT_EQ(2, tab_strip_model->count()); |
- helper->SetAppID(tab_strip_model->GetWebContentsAt(0), "1"); |
- helper->SetAppID(tab_strip_model->GetWebContentsAt(1), "2"); |
- |
- EXPECT_FALSE(launcher_controller_->IsAppPinned("1")); |
- launcher_controller_->PinAppWithID("1"); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned("1")); |
- launcher_controller_->PinAppWithID("2"); |
- |
- EXPECT_EQ(ash::TYPE_APP_LIST, model_->items()[0].type); |
- EXPECT_EQ(ash::TYPE_BROWSER_SHORTCUT, model_->items()[1].type); |
- EXPECT_EQ(ash::TYPE_PINNED_APP, model_->items()[2].type); |
- EXPECT_EQ(ash::TYPE_PINNED_APP, model_->items()[3].type); |
- |
- // Move browser shortcut item from index 1 to index 3. |
- model_->Move(1, 3); |
- EXPECT_EQ(ash::TYPE_APP_LIST, model_->items()[0].type); |
- EXPECT_EQ(ash::TYPE_PINNED_APP, model_->items()[1].type); |
- EXPECT_EQ(ash::TYPE_PINNED_APP, model_->items()[2].type); |
- EXPECT_EQ(ash::TYPE_BROWSER_SHORTCUT, model_->items()[3].type); |
- |
- RecreateLauncherController(); |
- helper = new TestLauncherControllerHelper(profile()); |
- helper->SetAppID(tab_strip_model->GetWebContentsAt(0), "1"); |
- helper->SetAppID(tab_strip_model->GetWebContentsAt(1), "2"); |
- SetLauncherControllerHelper(helper); |
- launcher_controller_->Init(); |
- |
- // Check ShelfItems are restored after resetting ChromeLauncherControllerImpl. |
- EXPECT_EQ(ash::TYPE_APP_LIST, model_->items()[0].type); |
- EXPECT_EQ(ash::TYPE_PINNED_APP, model_->items()[1].type); |
- EXPECT_EQ(ash::TYPE_PINNED_APP, model_->items()[2].type); |
- EXPECT_EQ(ash::TYPE_BROWSER_SHORTCUT, model_->items()[3].type); |
-} |
- |
-// Verifies pinned apps are persisted and restored. |
-TEST_F(ChromeLauncherControllerImplTest, PersistPinned) { |
- InitLauncherControllerWithBrowser(); |
- size_t initial_size = model_->items().size(); |
- |
- TabStripModel* tab_strip_model = browser()->tab_strip_model(); |
- EXPECT_EQ(1, tab_strip_model->count()); |
- |
- TestLauncherControllerHelper* helper = new TestLauncherControllerHelper; |
- helper->SetAppID(tab_strip_model->GetWebContentsAt(0), "1"); |
- SetLauncherControllerHelper(helper); |
- |
- // app_icon_loader is owned by ChromeLauncherControllerImpl. |
- TestAppIconLoaderImpl* app_icon_loader = new TestAppIconLoaderImpl; |
- app_icon_loader->AddSupportedApp("1"); |
- SetAppIconLoader(std::unique_ptr<AppIconLoader>(app_icon_loader)); |
- EXPECT_EQ(0, app_icon_loader->fetch_count()); |
- |
- launcher_controller_->PinAppWithID("1"); |
- ash::ShelfID id = launcher_controller_->GetShelfIDForAppID("1"); |
- int app_index = model_->ItemIndexByID(id); |
- EXPECT_EQ(1, app_icon_loader->fetch_count()); |
- EXPECT_EQ(ash::TYPE_PINNED_APP, model_->items()[app_index].type); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned("1")); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned("0")); |
- EXPECT_EQ(initial_size + 1, model_->items().size()); |
- |
- RecreateLauncherController(); |
- helper = new TestLauncherControllerHelper(profile()); |
- helper->SetAppID(tab_strip_model->GetWebContentsAt(0), "1"); |
- SetLauncherControllerHelper(helper); |
- // app_icon_loader is owned by ChromeLauncherControllerImpl. |
- app_icon_loader = new TestAppIconLoaderImpl; |
- app_icon_loader->AddSupportedApp("1"); |
- SetAppIconLoader(std::unique_ptr<AppIconLoader>(app_icon_loader)); |
- launcher_controller_->Init(); |
- |
- EXPECT_EQ(1, app_icon_loader->fetch_count()); |
- ASSERT_EQ(initial_size + 1, model_->items().size()); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned("1")); |
- EXPECT_FALSE(launcher_controller_->IsAppPinned("0")); |
- EXPECT_EQ(ash::TYPE_PINNED_APP, model_->items()[app_index].type); |
- |
- launcher_controller_->UnpinAppWithID("1"); |
- ASSERT_EQ(initial_size, model_->items().size()); |
-} |
- |
-TEST_F(ChromeLauncherControllerImplTest, MultipleAppIconLoaders) { |
- InitLauncherControllerWithBrowser(); |
- |
- const std::string app_id1 = extension1_->id(); |
- const std::string app_id2 = extension2_->id(); |
- const std::string app_id3 = extension3_->id(); |
- // app_icon_loader1 and app_icon_loader2 are owned by |
- // ChromeLauncherControllerImpl. |
- TestAppIconLoaderImpl* app_icon_loader1 = new TestAppIconLoaderImpl(); |
- TestAppIconLoaderImpl* app_icon_loader2 = new TestAppIconLoaderImpl(); |
- app_icon_loader1->AddSupportedApp(app_id1); |
- app_icon_loader2->AddSupportedApp(app_id2); |
- SetAppIconLoaders(std::unique_ptr<AppIconLoader>(app_icon_loader1), |
- std::unique_ptr<AppIconLoader>(app_icon_loader2)); |
- |
- const ash::ShelfID shelfId3 = launcher_controller_->CreateAppLauncherItem( |
- base::MakeUnique<ExtensionAppWindowLauncherItemController>( |
- ash::AppLaunchId(app_id3)), |
- ash::STATUS_RUNNING); |
- EXPECT_EQ(0, app_icon_loader1->fetch_count()); |
- EXPECT_EQ(0, app_icon_loader1->clear_count()); |
- EXPECT_EQ(0, app_icon_loader2->fetch_count()); |
- EXPECT_EQ(0, app_icon_loader2->clear_count()); |
- |
- const ash::ShelfID shelfId2 = launcher_controller_->CreateAppLauncherItem( |
- base::MakeUnique<ExtensionAppWindowLauncherItemController>( |
- ash::AppLaunchId(app_id2)), |
- ash::STATUS_RUNNING); |
- EXPECT_EQ(0, app_icon_loader1->fetch_count()); |
- EXPECT_EQ(0, app_icon_loader1->clear_count()); |
- EXPECT_EQ(1, app_icon_loader2->fetch_count()); |
- EXPECT_EQ(0, app_icon_loader2->clear_count()); |
- |
- const ash::ShelfID shelfId1 = launcher_controller_->CreateAppLauncherItem( |
- base::MakeUnique<ExtensionAppWindowLauncherItemController>( |
- ash::AppLaunchId(app_id1)), |
- ash::STATUS_RUNNING); |
- EXPECT_EQ(1, app_icon_loader1->fetch_count()); |
- EXPECT_EQ(0, app_icon_loader1->clear_count()); |
- EXPECT_EQ(1, app_icon_loader2->fetch_count()); |
- EXPECT_EQ(0, app_icon_loader2->clear_count()); |
- |
- launcher_controller_->CloseLauncherItem(shelfId1); |
- EXPECT_EQ(1, app_icon_loader1->fetch_count()); |
- EXPECT_EQ(1, app_icon_loader1->clear_count()); |
- EXPECT_EQ(1, app_icon_loader2->fetch_count()); |
- EXPECT_EQ(0, app_icon_loader2->clear_count()); |
- |
- launcher_controller_->CloseLauncherItem(shelfId2); |
- EXPECT_EQ(1, app_icon_loader1->fetch_count()); |
- EXPECT_EQ(1, app_icon_loader1->clear_count()); |
- EXPECT_EQ(1, app_icon_loader2->fetch_count()); |
- EXPECT_EQ(1, app_icon_loader2->clear_count()); |
- |
- launcher_controller_->CloseLauncherItem(shelfId3); |
- EXPECT_EQ(1, app_icon_loader1->fetch_count()); |
- EXPECT_EQ(1, app_icon_loader1->clear_count()); |
- EXPECT_EQ(1, app_icon_loader2->fetch_count()); |
- EXPECT_EQ(1, app_icon_loader2->clear_count()); |
-} |
- |
-TEST_P(ChromeLauncherControllerImplWithArcTest, ArcAppPinPolicy) { |
- InitLauncherControllerWithBrowser(); |
- arc::mojom::AppInfo appinfo = CreateAppInfo( |
- "Some App", "SomeActivity", "com.example.app", OrientationLock::NONE); |
- const std::string app_id = AddArcAppAndShortcut(appinfo); |
- |
- // Set policy, that makes pins ARC app. Unlike native extension, for ARC app |
- // package_name (not hash) specified as id. In this test we check that |
- // by hash we can determine that appropriate package was set by policy. |
- base::ListValue policy_value; |
- InsertPrefValue(&policy_value, 0, appinfo.package_name); |
- profile()->GetTestingPrefService()->SetManagedPref( |
- prefs::kPolicyPinnedLauncherApps, policy_value.CreateDeepCopy()); |
- |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(app_id)); |
- EXPECT_EQ(AppListControllerDelegate::PIN_FIXED, |
- GetPinnableForAppID(app_id, profile())); |
-} |
- |
-TEST_P(ChromeLauncherControllerImplWithArcTest, ArcManaged) { |
- // TODO(victorhsieh): Implement opt-in and opt-out. |
- if (arc::ShouldArcAlwaysStart()) |
- return; |
- |
- extension_service_->AddExtension(arc_support_host_.get()); |
- // Test enables ARC, so turn it off for initial values. |
- EnablePlayStore(false); |
- |
- InitLauncherController(); |
- |
- // To prevent import legacy pins each time. |
- // Initially pins are imported from legacy pref based model. |
- StartPrefSyncService(syncer::SyncDataList()); |
- |
- // Initial run, ARC is not managed and disabled, Play Store pin should be |
- // available. |
- ValidateArcState(false, false, arc::ArcSessionManager::State::STOPPED, |
- "AppList, Chrome, Play Store"); |
- |
- // ARC is managed and enabled, Play Store pin should be available. |
- // Note: NEGOTIATING_TERMS_OF_SERVICE here means that opt-in flow starts. |
- profile()->GetTestingPrefService()->SetManagedPref( |
- prefs::kArcEnabled, base::MakeUnique<base::Value>(true)); |
- base::RunLoop().RunUntilIdle(); |
- ValidateArcState(true, true, |
- arc::ArcSessionManager::State::NEGOTIATING_TERMS_OF_SERVICE, |
- "AppList, Chrome, Play Store"); |
- |
- // ARC is managed and disabled, Play Store pin should not be available. |
- profile()->GetTestingPrefService()->SetManagedPref( |
- prefs::kArcEnabled, base::MakeUnique<base::Value>(false)); |
- base::RunLoop().RunUntilIdle(); |
- ValidateArcState(false, true, arc::ArcSessionManager::State::STOPPED, |
- "AppList, Chrome"); |
- |
- // ARC is not managed and disabled, Play Store pin should be available. |
- profile()->GetTestingPrefService()->RemoveManagedPref(prefs::kArcEnabled); |
- base::RunLoop().RunUntilIdle(); |
- ValidateArcState(false, false, arc::ArcSessionManager::State::STOPPED, |
- "AppList, Chrome, Play Store"); |
- |
- // ARC is not managed and enabled, Play Store pin should be available. |
- EnablePlayStore(true); |
- ValidateArcState(true, false, |
- arc::ArcSessionManager::State::NEGOTIATING_TERMS_OF_SERVICE, |
- "AppList, Chrome, Play Store"); |
- |
- // User disables ARC. ARC is not managed and disabled, Play Store pin should |
- // be automatically removed. |
- EnablePlayStore(false); |
- ValidateArcState(false, false, arc::ArcSessionManager::State::STOPPED, |
- "AppList, Chrome"); |
- |
- // Even if re-enable it again, Play Store pin does not appear automatically. |
- EnablePlayStore(true); |
- ValidateArcState(true, false, |
- arc::ArcSessionManager::State::NEGOTIATING_TERMS_OF_SERVICE, |
- "AppList, Chrome"); |
-} |
- |
-// Test the application menu of a shelf item with multiple ARC windows. |
-TEST_P(ChromeLauncherControllerImplWithArcTest, ShelfItemWithMultipleWindows) { |
- InitLauncherControllerWithBrowser(); |
- |
- arc::mojom::AppInfo appinfo = |
- CreateAppInfo("Test1", "test", "com.example.app", OrientationLock::NONE); |
- AddArcAppAndShortcut(appinfo); |
- |
- // Widgets will be deleted by the system. |
- NotifyOnTaskCreated(appinfo, 1 /* task_id */); |
- views::Widget* window1 = CreateArcWindow("org.chromium.arc.1"); |
- ASSERT_TRUE(window1); |
- EXPECT_TRUE(window1->IsActive()); |
- |
- NotifyOnTaskCreated(appinfo, 2 /* task_id */); |
- views::Widget* window2 = CreateArcWindow("org.chromium.arc.2"); |
- ASSERT_TRUE(window2); |
- |
- EXPECT_FALSE(window1->IsActive()); |
- EXPECT_TRUE(window2->IsActive()); |
- |
- const std::string app_id = ArcAppTest::GetAppId(appinfo); |
- |
- const ash::ShelfID shelf_id = |
- launcher_controller_->GetShelfIDForAppID(app_id); |
- ash::ShelfItemDelegate* item_delegate = |
- model_->GetShelfItemDelegate(shelf_id); |
- ASSERT_TRUE(item_delegate); |
- |
- // Selecting the item will show its application menu. It does not change the |
- // active window. |
- SelectItem(item_delegate); |
- EXPECT_FALSE(window1->IsActive()); |
- EXPECT_TRUE(window2->IsActive()); |
- |
- // Command ids are just app window indices. Note, apps are registered in |
- // opposite order. Last created goes in front. |
- ash::MenuItemList items = item_delegate->GetAppMenuItems(0); |
- ASSERT_EQ(items.size(), 2U); |
- EXPECT_EQ(items[0]->command_id, 0U); |
- EXPECT_EQ(items[1]->command_id, 1U); |
- |
- // Execute command to activate first window. |
- item_delegate->ExecuteCommand(items[1]->command_id, 0); |
- EXPECT_TRUE(window1->IsActive()); |
- EXPECT_FALSE(window2->IsActive()); |
- |
- // Selecting the item will show its application menu. It does not change the |
- // active window. |
- SelectItem(item_delegate); |
- EXPECT_TRUE(window1->IsActive()); |
- EXPECT_FALSE(window2->IsActive()); |
- |
- // Execute command to activate second window. |
- item_delegate->ExecuteCommand(items[0]->command_id, 0); |
- EXPECT_FALSE(window1->IsActive()); |
- EXPECT_TRUE(window2->IsActive()); |
-} |
- |
-namespace { |
- |
-class ChromeLauncherControllerOrientationTest |
- : public ChromeLauncherControllerImplWithArcTest { |
- public: |
- ChromeLauncherControllerOrientationTest() {} |
- ~ChromeLauncherControllerOrientationTest() override {} |
- |
- protected: |
- void InitApps() { |
- appinfo_none_ = |
- CreateAppInfo("None", "None", "com.example.app", OrientationLock::NONE); |
- appinfo_landscape_ = |
- CreateAppInfo("Landscape", "Landscape", "com.example.app", |
- OrientationLock::LANDSCAPE); |
- appinfo_portrait_ = CreateAppInfo("Portrait", "Portrait", "com.example.app", |
- OrientationLock::PORTRAIT); |
- appinfo_current_ = CreateAppInfo( |
- "LockCurrent", "current", "com.example.app", OrientationLock::CURRENT); |
- |
- AddArcAppAndShortcut(appinfo_none_); |
- AddArcAppAndShortcut(appinfo_landscape_); |
- AddArcAppAndShortcut(appinfo_portrait_); |
- AddArcAppAndShortcut(appinfo_current_); |
- |
- ash::ScreenOrientationController* controller = |
- ash::Shell::Get()->screen_orientation_controller(); |
- |
- // Creating a window with NONE orientation will not lock the screen. |
- window_none_ = CreateArcWindow(window_app_id_none_); |
- NotifyOnTaskCreated(appinfo_none_, task_id_none_); |
- EXPECT_FALSE(controller->rotation_locked()); |
- EXPECT_EQ(display::Display::ROTATE_0, |
- display::Screen::GetScreen()->GetPrimaryDisplay().rotation()); |
- |
- // Create a arc window with PORTRAIT orientation locks the screen to 90. |
- window_portrait_ = CreateArcWindow(window_app_id_portrait_); |
- NotifyOnTaskCreated(appinfo_portrait_, task_id_portrait_); |
- EXPECT_TRUE(controller->rotation_locked()); |
- EXPECT_EQ(display::Display::ROTATE_90, |
- display::Screen::GetScreen()->GetPrimaryDisplay().rotation()); |
- |
- // Create a arc window with LANDSCAPE orientation locks the screen to 0. |
- window_landscape_ = CreateArcWindow(window_app_id_landscape_); |
- NotifyOnTaskCreated(appinfo_landscape_, task_id_landscape_); |
- EXPECT_TRUE(controller->rotation_locked()); |
- EXPECT_EQ(display::Display::ROTATE_0, |
- display::Screen::GetScreen()->GetPrimaryDisplay().rotation()); |
- } |
- |
- int32_t task_id_none_ = 1; |
- int32_t task_id_landscape_ = 2; |
- int32_t task_id_portrait_ = 3; |
- int32_t task_id_current_ = 4; |
- |
- // This needs to be kept on the instance because window's property has |
- // refeference to this. |
- std::string window_app_id_none_ = {"org.chromium.arc.1"}; |
- std::string window_app_id_landscape_ = {"org.chromium.arc.2"}; |
- std::string window_app_id_portrait_ = {"org.chromium.arc.3"}; |
- std::string window_app_id_current_ = {"org.chromium.arc.4"}; |
- |
- arc::mojom::AppInfo appinfo_none_; |
- arc::mojom::AppInfo appinfo_landscape_; |
- arc::mojom::AppInfo appinfo_portrait_; |
- arc::mojom::AppInfo appinfo_current_; |
- |
- views::Widget* window_none_ = nullptr; |
- views::Widget* window_landscape_ = nullptr; |
- views::Widget* window_portrait_ = nullptr; |
- views::Widget* window_current_ = nullptr; |
- |
- private: |
- DISALLOW_COPY_AND_ASSIGN(ChromeLauncherControllerOrientationTest); |
-}; |
- |
-INSTANTIATE_TEST_CASE_P(, |
- ChromeLauncherControllerOrientationTest, |
- ::testing::Bool()); |
- |
-class ChromeLauncherControllerArcDefaultAppsTest |
- : public ChromeLauncherControllerImplTest, |
- public ::testing::WithParamInterface<bool> { |
- public: |
- ChromeLauncherControllerArcDefaultAppsTest() {} |
- ~ChromeLauncherControllerArcDefaultAppsTest() override {} |
- |
- protected: |
- void SetUp() override { |
- if (GetParam()) |
- arc::SetArcAlwaysStartForTesting(); |
- ArcDefaultAppList::UseTestAppsDirectory(); |
- ChromeLauncherControllerImplTest::SetUp(); |
- } |
- |
- private: |
- DISALLOW_COPY_AND_ASSIGN(ChromeLauncherControllerArcDefaultAppsTest); |
-}; |
- |
-INSTANTIATE_TEST_CASE_P(, |
- ChromeLauncherControllerArcDefaultAppsTest, |
- ::testing::Bool()); |
- |
-} // namespace |
- |
-TEST_P(ChromeLauncherControllerOrientationTest, |
- ArcOrientationLockBeforeWindowReady) { |
- ASSERT_TRUE(display::Display::HasInternalDisplay()); |
- |
- extension_service_->AddExtension(arc_support_host_.get()); |
- EnablePlayStore(true); |
- |
- InitLauncherController(); |
- |
- ash::ScreenOrientationController* controller = |
- ash::Shell::Get()->screen_orientation_controller(); |
- |
- std::string app_id1("org.chromium.arc.1"); |
- int task_id1 = 1; |
- arc::mojom::AppInfo appinfo1 = |
- CreateAppInfo("Test1", "test", "com.example.app", OrientationLock::NONE); |
- |
- AddArcAppAndShortcut(appinfo1); |
- NotifyOnTaskCreated(appinfo1, task_id1); |
- NotifyOnTaskOrientationLockRequested(task_id1, OrientationLock::PORTRAIT); |
- |
- // Widgets will be deleted by the system. |
- CreateArcWindow(app_id1); |
- |
- EXPECT_FALSE(controller->rotation_locked()); |
- |
- EnableTabletMode(true); |
- EXPECT_TRUE(controller->rotation_locked()); |
- EXPECT_EQ(display::Display::ROTATE_90, |
- display::Screen::GetScreen()->GetPrimaryDisplay().rotation()); |
- |
- std::string app_id2("org.chromium.arc.2"); |
- int task_id2 = 2; |
- arc::mojom::AppInfo appinfo2 = |
- CreateAppInfo("Test2", "test", "com.example.app", OrientationLock::NONE); |
- // Create in tablet mode. |
- AddArcAppAndShortcut(appinfo2); |
- NotifyOnTaskCreated(appinfo2, task_id2); |
- NotifyOnTaskOrientationLockRequested(task_id2, OrientationLock::LANDSCAPE); |
- EXPECT_TRUE(controller->rotation_locked()); |
- EXPECT_EQ(display::Display::ROTATE_90, |
- display::Screen::GetScreen()->GetPrimaryDisplay().rotation()); |
- |
- // The screen will be locked when the window is created. |
- CreateArcWindow(app_id2); |
- EXPECT_TRUE(controller->rotation_locked()); |
- EXPECT_EQ(display::Display::ROTATE_0, |
- display::Screen::GetScreen()->GetPrimaryDisplay().rotation()); |
-} |
- |
-TEST_P(ChromeLauncherControllerOrientationTest, ArcOrientationLock) { |
- ASSERT_TRUE(display::Display::HasInternalDisplay()); |
- |
- extension_service_->AddExtension(arc_support_host_.get()); |
- EnablePlayStore(true); |
- EnableTabletMode(true); |
- |
- InitLauncherController(); |
- |
- InitApps(); |
- ash::ScreenOrientationController* controller = |
- ash::Shell::Get()->screen_orientation_controller(); |
- |
- // Activating a window with NON orientation unlocks the screen. |
- window_none_->Activate(); |
- EXPECT_FALSE(controller->rotation_locked()); |
- EXPECT_EQ(display::Display::ROTATE_0, |
- display::Screen::GetScreen()->GetPrimaryDisplay().rotation()); |
- |
- // Activating a window with PORTRAIT orientation locks the screen to 90. |
- window_portrait_->Activate(); |
- EXPECT_TRUE(controller->rotation_locked()); |
- EXPECT_EQ(display::Display::ROTATE_90, |
- display::Screen::GetScreen()->GetPrimaryDisplay().rotation()); |
- |
- // Disable Tablet mode, and make sure the screen is unlocked. |
- EnableTabletMode(false); |
- EXPECT_FALSE(controller->rotation_locked()); |
- EXPECT_EQ(display::Display::ROTATE_0, |
- display::Screen::GetScreen()->GetPrimaryDisplay().rotation()); |
- |
- // Re-enable Tablet mode, and make sure the screen is locked to 90. |
- EnableTabletMode(true); |
- EXPECT_TRUE(controller->rotation_locked()); |
- EXPECT_EQ(display::Display::ROTATE_90, |
- display::Screen::GetScreen()->GetPrimaryDisplay().rotation()); |
- |
- window_portrait_->Activate(); |
- EXPECT_TRUE(controller->rotation_locked()); |
- EXPECT_EQ(display::Display::ROTATE_90, |
- display::Screen::GetScreen()->GetPrimaryDisplay().rotation()); |
- |
- window_landscape_->Activate(); |
- EXPECT_TRUE(controller->rotation_locked()); |
- EXPECT_EQ(display::Display::ROTATE_0, |
- display::Screen::GetScreen()->GetPrimaryDisplay().rotation()); |
- |
- // OnTaskOrientationLockRequested can overwrite the current lock. |
- NotifyOnTaskOrientationLockRequested(task_id_landscape_, |
- OrientationLock::NONE); |
- EXPECT_FALSE(controller->rotation_locked()); |
- EXPECT_EQ(display::Display::ROTATE_0, |
- display::Screen::GetScreen()->GetPrimaryDisplay().rotation()); |
- |
- NotifyOnTaskOrientationLockRequested(task_id_landscape_, |
- OrientationLock::PORTRAIT); |
- EXPECT_TRUE(controller->rotation_locked()); |
- EXPECT_EQ(display::Display::ROTATE_90, |
- display::Screen::GetScreen()->GetPrimaryDisplay().rotation()); |
- |
- // Non active window won't change the lock. |
- NotifyOnTaskOrientationLockRequested(task_id_none_, |
- OrientationLock::LANDSCAPE); |
- EXPECT_TRUE(controller->rotation_locked()); |
- EXPECT_EQ(display::Display::ROTATE_90, |
- display::Screen::GetScreen()->GetPrimaryDisplay().rotation()); |
- |
- // But activating it will change the locked orinetation. |
- window_none_->Activate(); |
- EXPECT_TRUE(controller->rotation_locked()); |
- EXPECT_EQ(display::Display::ROTATE_0, |
- display::Screen::GetScreen()->GetPrimaryDisplay().rotation()); |
- |
- // OnTaskOrientationLockRequested will not lock the screen in non Tablet mode. |
- EnableTabletMode(false); |
- EXPECT_FALSE(controller->rotation_locked()); |
- EXPECT_EQ(display::Display::ROTATE_0, |
- display::Screen::GetScreen()->GetPrimaryDisplay().rotation()); |
- |
- NotifyOnTaskOrientationLockRequested(task_id_none_, |
- OrientationLock::PORTRAIT); |
- EXPECT_FALSE(controller->rotation_locked()); |
- EXPECT_EQ(display::Display::ROTATE_0, |
- display::Screen::GetScreen()->GetPrimaryDisplay().rotation()); |
- |
- // But it remembers the orientation lock and use it when Tablet mode is |
- // enabled. |
- EnableTabletMode(true); |
- EXPECT_TRUE(controller->rotation_locked()); |
- EXPECT_EQ(display::Display::ROTATE_90, |
- display::Screen::GetScreen()->GetPrimaryDisplay().rotation()); |
- |
- // Manually unlock first. |
- NotifyOnTaskOrientationLockRequested(task_id_none_, OrientationLock::NONE); |
- EXPECT_FALSE(controller->rotation_locked()); |
-} |
- |
-TEST_P(ChromeLauncherControllerArcDefaultAppsTest, DefaultApps) { |
- arc_test_.SetUp(profile()); |
- InitLauncherController(); |
- // TODO(crbug.com/709297): Fix this workaround to prevent a TearDown crash. |
- std::vector<std::unique_ptr<AppIconLoader>> no_loaders; |
- launcher_controller_->SetAppIconLoadersForTest(no_loaders); |
- |
- ArcAppListPrefs* const prefs = arc_test_.arc_app_list_prefs(); |
- EnablePlayStore(false); |
- EXPECT_FALSE(arc::IsArcPlayStoreEnabledForProfile(profile())); |
- ASSERT_TRUE(prefs->GetAppIds().size()); |
- |
- const std::string app_id = |
- ArcAppTest::GetAppId(arc_test_.fake_default_apps()[0]); |
- EXPECT_EQ(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(app_id)); |
- EXPECT_TRUE(arc::LaunchApp(profile(), app_id, ui::EF_LEFT_MOUSE_BUTTON)); |
- EXPECT_TRUE(arc::IsArcPlayStoreEnabledForProfile(profile())); |
- EXPECT_NE(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(app_id)); |
- |
- // Stop ARC again. Shelf item should go away. |
- EnablePlayStore(false); |
- EXPECT_EQ(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(app_id)); |
- |
- EXPECT_TRUE(arc::LaunchApp(profile(), app_id, ui::EF_LEFT_MOUSE_BUTTON)); |
- EXPECT_TRUE(arc::IsArcPlayStoreEnabledForProfile(profile())); |
- |
- EXPECT_NE(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(app_id)); |
- EXPECT_TRUE(launcher_controller_->GetArcDeferredLauncher()->HasApp(app_id)); |
- |
- std::string window_app_id("org.chromium.arc.1"); |
- CreateArcWindow(window_app_id); |
- arc_test_.app_instance()->SendTaskCreated(1, arc_test_.fake_default_apps()[0], |
- std::string()); |
- |
- EXPECT_NE(ash::kInvalidShelfID, |
- launcher_controller_->GetShelfIDForAppID(app_id)); |
- EXPECT_FALSE(launcher_controller_->GetArcDeferredLauncher()->HasApp(app_id)); |
-} |
- |
-TEST_P(ChromeLauncherControllerArcDefaultAppsTest, PlayStoreDeferredLaunch) { |
- // Add ARC host app to enable Play Store default app. |
- extension_service_->AddExtension(arc_support_host_.get()); |
- arc_test_.SetUp(profile()); |
- ArcAppListPrefs* const prefs = arc_test_.arc_app_list_prefs(); |
- EXPECT_TRUE(prefs->IsRegistered(arc::kPlayStoreAppId)); |
- |
- InitLauncherController(); |
- |
- EnablePlayStore(true); |
- |
- // Pin Play Store. It should be pinned but not scheduled for deferred launch. |
- launcher_controller_->PinAppWithID(arc::kPlayStoreAppId); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(arc::kPlayStoreAppId)); |
- EXPECT_FALSE(launcher_controller_->GetArcDeferredLauncher()->HasApp( |
- arc::kPlayStoreAppId)); |
- |
- // Simulate click. This should schedule Play Store for deferred launch. |
- ash::ShelfItemDelegate* item_delegate = model_->GetShelfItemDelegate( |
- launcher_controller_->GetShelfIDForAppID(arc::kPlayStoreAppId)); |
- EXPECT_TRUE(item_delegate); |
- SelectItem(item_delegate); |
- EXPECT_TRUE(launcher_controller_->IsAppPinned(arc::kPlayStoreAppId)); |
- EXPECT_TRUE(launcher_controller_->GetArcDeferredLauncher()->HasApp( |
- arc::kPlayStoreAppId)); |
-} |
- |
-// Checks the case when several app items have the same ordinal position (which |
-// is valid case). |
-TEST_F(ChromeLauncherControllerImplTest, CheckPositionConflict) { |
- InitLauncherController(); |
- |
- extension_service_->AddExtension(extension1_.get()); |
- extension_service_->AddExtension(extension2_.get()); |
- extension_service_->AddExtension(extension3_.get()); |
- |
- syncer::SyncChangeList sync_list; |
- InsertAddPinChange(&sync_list, 0, extension_misc::kChromeAppId); |
- InsertAddPinChange(&sync_list, 1, extension1_->id()); |
- InsertAddPinChange(&sync_list, 1, extension2_->id()); |
- InsertAddPinChange(&sync_list, 1, extension3_->id()); |
- SendPinChanges(sync_list, true); |
- |
- EXPECT_EQ("AppList, Chrome, App1, App2, App3", GetPinnedAppStatus()); |
- |
- const syncer::StringOrdinal position_chrome = |
- app_service_->GetPinPosition(extension_misc::kChromeAppId); |
- const syncer::StringOrdinal position_1 = |
- app_service_->GetPinPosition(extension1_->id()); |
- const syncer::StringOrdinal position_2 = |
- app_service_->GetPinPosition(extension2_->id()); |
- const syncer::StringOrdinal position_3 = |
- app_service_->GetPinPosition(extension3_->id()); |
- EXPECT_TRUE(position_chrome.LessThan(position_1)); |
- EXPECT_TRUE(position_1.Equals(position_2)); |
- EXPECT_TRUE(position_2.Equals(position_3)); |
- |
- // Move Chrome between App1 and App2. |
- // Note, move target_index is in context when moved element is removed from |
- // array first. |
- model_->Move(1, 2); |
- EXPECT_EQ("AppList, App1, Chrome, App2, App3", GetPinnedAppStatus()); |
- |
- // Expect sync positions for only Chrome is updated and its resolution is |
- // after all duplicated ordinals. |
- EXPECT_TRUE(position_3.LessThan( |
- app_service_->GetPinPosition(extension_misc::kChromeAppId))); |
- EXPECT_TRUE( |
- position_1.Equals(app_service_->GetPinPosition(extension1_->id()))); |
- EXPECT_TRUE( |
- position_1.Equals(app_service_->GetPinPosition(extension1_->id()))); |
- EXPECT_TRUE( |
- position_2.Equals(app_service_->GetPinPosition(extension2_->id()))); |
- EXPECT_TRUE( |
- position_3.Equals(app_service_->GetPinPosition(extension3_->id()))); |
-} |
- |
-// Test the case when sync app is turned off and we need to use local copy to |
-// support user's pins. |
-TEST_F(ChromeLauncherControllerImplTest, SyncOffLocalUpdate) { |
- InitLauncherController(); |
- |
- extension_service_->AddExtension(extension1_.get()); |
- extension_service_->AddExtension(extension2_.get()); |
- |
- syncer::SyncChangeList sync_list; |
- InsertAddPinChange(&sync_list, 0, extension_misc::kChromeAppId); |
- InsertAddPinChange(&sync_list, 1, extension1_->id()); |
- InsertAddPinChange(&sync_list, 1, extension2_->id()); |
- SendPinChanges(sync_list, true); |
- |
- EXPECT_EQ("AppList, Chrome, App1, App2", GetPinnedAppStatus()); |
- |
- syncer::SyncDataList copy_sync_list = |
- app_service_->GetAllSyncData(syncer::APP_LIST); |
- |
- app_service_->StopSyncing(syncer::APP_LIST); |
- RecreateLauncherController()->Init(); |
- |
- // Pinned state should not change. |
- EXPECT_EQ("AppList, Chrome, App1, App2", GetPinnedAppStatus()); |
- launcher_controller_->UnpinAppWithID(extension2_->id()); |
- EXPECT_EQ("AppList, Chrome, App1", GetPinnedAppStatus()); |
- |
- // Resume syncing and sync information overrides local copy. |
- StartAppSyncService(copy_sync_list); |
- EXPECT_EQ("AppList, Chrome, App1, App2", GetPinnedAppStatus()); |
-} |
- |
-// Tests that shelf profile preferences are loaded on login. |
-TEST_F(ChromeLauncherControllerImplTest, PrefsLoadedOnLogin) { |
- PrefService* prefs = profile()->GetTestingPrefService(); |
- prefs->SetString(prefs::kShelfAlignmentLocal, "Left"); |
- prefs->SetString(prefs::kShelfAlignment, "Left"); |
- prefs->SetString(prefs::kShelfAutoHideBehaviorLocal, "Always"); |
- prefs->SetString(prefs::kShelfAutoHideBehavior, "Always"); |
- |
- TestChromeLauncherControllerImpl* test_launcher_controller = |
- shell_delegate_->CreateTestLauncherController(profile()); |
- |
- // Simulate login for the test controller. |
- test_launcher_controller->ReleaseProfile(); |
- test_launcher_controller->AttachProfile(profile()); |
- base::RunLoop().RunUntilIdle(); |
- |
- TestShelfController* shelf_controller = |
- test_launcher_controller->test_shelf_controller(); |
- ASSERT_TRUE(shelf_controller); |
- EXPECT_EQ(ash::SHELF_ALIGNMENT_LEFT, shelf_controller->alignment()); |
- EXPECT_EQ(1u, shelf_controller->alignment_change_count()); |
- EXPECT_EQ(ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, |
- shelf_controller->auto_hide()); |
- EXPECT_EQ(1u, shelf_controller->auto_hide_change_count()); |
-} |
- |
-// Tests that the shelf controller's changes are not wastefully echoed back. |
-TEST_F(ChromeLauncherControllerImplTest, DoNotEchoShelfControllerChanges) { |
- TestChromeLauncherControllerImpl* test_launcher_controller = |
- shell_delegate_->CreateTestLauncherController(profile()); |
- |
- // Simulate login for the test controller. |
- test_launcher_controller->ReleaseProfile(); |
- test_launcher_controller->AttachProfile(profile()); |
- base::RunLoop().RunUntilIdle(); |
- |
- TestShelfController* shelf_controller = |
- test_launcher_controller->test_shelf_controller(); |
- ASSERT_TRUE(shelf_controller); |
- EXPECT_EQ(ash::SHELF_ALIGNMENT_BOTTOM, shelf_controller->alignment()); |
- EXPECT_EQ(1u, shelf_controller->alignment_change_count()); |
- EXPECT_EQ(ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf_controller->auto_hide()); |
- EXPECT_EQ(1u, shelf_controller->auto_hide_change_count()); |
- |
- // Changing settings via the shelf controller causes the launcher controller |
- // to update profile prefs. The launcher controller's prefs observation should |
- // not cause those same changes to be echoed back to the shelf controller. |
- int64_t display_id = display::Screen::GetScreen()->GetPrimaryDisplay().id(); |
- shelf_controller->SetAlignment(ash::SHELF_ALIGNMENT_LEFT, display_id); |
- EXPECT_EQ(2u, shelf_controller->alignment_change_count()); |
- shelf_controller->SetAutoHideBehavior(ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, |
- display_id); |
- EXPECT_EQ(2u, shelf_controller->auto_hide_change_count()); |
- base::RunLoop().RunUntilIdle(); |
- |
- EXPECT_EQ(ash::SHELF_ALIGNMENT_LEFT, shelf_controller->alignment()); |
- EXPECT_EQ(2u, shelf_controller->alignment_change_count()); |
- EXPECT_EQ(ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, |
- shelf_controller->auto_hide()); |
- EXPECT_EQ(2u, shelf_controller->auto_hide_change_count()); |
- |
- PrefService* prefs = profile()->GetTestingPrefService(); |
- EXPECT_EQ("Left", prefs->GetString(prefs::kShelfAlignmentLocal)); |
- EXPECT_EQ("Left", prefs->GetString(prefs::kShelfAlignment)); |
- EXPECT_EQ("Always", prefs->GetString(prefs::kShelfAutoHideBehaviorLocal)); |
- EXPECT_EQ("Always", prefs->GetString(prefs::kShelfAutoHideBehavior)); |
-} |