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

Unified Diff: chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc

Issue 2052013002: Adding ChromeLauncherController interface. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@chrome_launcher_smaller_api
Patch Set: Rebase Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc
index 2c242238c3361af122a34588b0f2a8b9d8ecb3c2..fc449710294349a639917781960c42b219c9c39d 100644
--- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc
+++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc
@@ -4,1867 +4,12 @@
#include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h"
-#include <stddef.h>
-
-#include <vector>
-
-#include "ash/ash_switches.h"
-#include "ash/common/shelf/shelf_item_delegate_manager.h"
-#include "ash/common/shelf/shelf_model.h"
-#include "ash/common/system/tray/system_tray_delegate.h"
-#include "ash/common/wm_shell.h"
-#include "ash/desktop_background/desktop_background_controller.h"
-#include "ash/multi_profile_uma.h"
-#include "ash/root_window_controller.h"
-#include "ash/shelf/shelf.h"
-#include "ash/shell.h"
-#include "ash/wm/window_util.h"
-#include "base/command_line.h"
-#include "base/macros.h"
-#include "base/strings/pattern.h"
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/values.h"
-#include "build/build_config.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/chromeos/arc/arc_support_host.h"
-#include "chrome/browser/defaults.h"
-#include "chrome/browser/extensions/extension_app_icon_loader.h"
-#include "chrome/browser/extensions/extension_util.h"
-#include "chrome/browser/extensions/launch_util.h"
-#include "chrome/browser/prefs/incognito_mode_prefs.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/browser/ui/app_list/arc/arc_app_icon_loader.h"
-#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h"
-#include "chrome/browser/ui/app_list/arc/arc_app_utils.h"
-#include "chrome/browser/ui/ash/app_sync_ui_state.h"
-#include "chrome/browser/ui/ash/chrome_launcher_prefs.h"
-#include "chrome/browser/ui/ash/chrome_shell_delegate.h"
-#include "chrome/browser/ui/ash/launcher/app_shortcut_launcher_item_controller.h"
-#include "chrome/browser/ui/ash/launcher/app_window_launcher_controller.h"
-#include "chrome/browser/ui/ash/launcher/app_window_launcher_item_controller.h"
-#include "chrome/browser/ui/ash/launcher/arc_app_deferred_launcher_controller.h"
-#include "chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.h"
-#include "chrome/browser/ui/ash/launcher/browser_shortcut_launcher_item_controller.h"
-#include "chrome/browser/ui/ash/launcher/browser_status_monitor.h"
-#include "chrome/browser/ui/ash/launcher/chrome_launcher_app_menu_item.h"
-#include "chrome/browser/ui/ash/launcher/chrome_launcher_app_menu_item_browser.h"
-#include "chrome/browser/ui/ash/launcher/chrome_launcher_app_menu_item_tab.h"
-#include "chrome/browser/ui/ash/launcher/chrome_launcher_types.h"
-#include "chrome/browser/ui/ash/launcher/launcher_arc_app_updater.h"
-#include "chrome/browser/ui/ash/launcher/launcher_controller_helper.h"
-#include "chrome/browser/ui/ash/launcher/launcher_extension_app_updater.h"
-#include "chrome/browser/ui/ash/launcher/launcher_item_controller.h"
-#include "chrome/browser/ui/ash/launcher/multi_profile_app_window_launcher_controller.h"
-#include "chrome/browser/ui/ash/launcher/multi_profile_browser_status_monitor.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/browser.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/browser_window.h"
-#include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/browser/web_applications/web_app.h"
-#include "chrome/common/chrome_switches.h"
-#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
-#include "chrome/common/pref_names.h"
-#include "chrome/common/url_constants.h"
-#include "chrome/grit/generated_resources.h"
-#include "components/favicon/content/content_favicon_driver.h"
-#include "components/prefs/scoped_user_pref_update.h"
-#include "components/signin/core/account_id/account_id.h"
-#include "components/strings/grit/components_strings.h"
-#include "components/user_manager/user_manager.h"
-#include "content/public/browser/navigation_entry.h"
-#include "content/public/browser/web_contents.h"
-#include "extensions/browser/extension_prefs.h"
-#include "extensions/browser/extension_registry.h"
-#include "extensions/browser/extension_system.h"
-#include "extensions/browser/extension_util.h"
-#include "extensions/common/constants.h"
-#include "extensions/common/extension.h"
-#include "extensions/common/extension_resource.h"
-#include "extensions/common/manifest_handlers/icons_handler.h"
-#include "extensions/common/url_pattern.h"
-#include "grit/ash_resources.h"
-#include "grit/theme_resources.h"
-#include "ui/aura/window.h"
-#include "ui/aura/window_event_dispatcher.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "ui/base/window_open_disposition.h"
-#include "ui/keyboard/keyboard_util.h"
-#include "ui/resources/grit/ui_resources.h"
-#include "ui/wm/core/window_animations.h"
-
-using extensions::Extension;
-using extensions::UnloadedExtensionInfo;
-using extension_misc::kGmailAppId;
-using content::WebContents;
-
// static
-ChromeLauncherController* ChromeLauncherController::instance_ = NULL;
-
-namespace {
-
-int64_t GetDisplayIDForShelf(ash::Shelf* shelf) {
- aura::Window* root_window =
- shelf->shelf_widget()->GetNativeWindow()->GetRootWindow();
- display::Display display =
- display::Screen::GetScreen()->GetDisplayNearestWindow(root_window);
- DCHECK(display.is_valid());
- return display.id();
-}
-
-/*
- * Return whether an app is pinned only by user.
- * This function doesn't expect an app_id neither pinned by user nor by
- * policy, the app_id in the arguments list MUST be pinned by either of
- * those. Invalid input may lead to unexpected result.
- * If this app is pinned by policy, but not by user, false is returned.
- * If this app is pinned by both policy and user, false is returned.
- * If this app is pinned not by policy, but by user, true is returned.
- */
-bool IsAppForUserPinned(const std::string& app_id,
- const base::ListValue* pinned_apps_pref,
- const base::ListValue* policy_pinned_apps_pref) {
- for (size_t index = 0; index < pinned_apps_pref->GetSize(); ++index) {
- const base::DictionaryValue* app;
- if (pinned_apps_pref->GetDictionary(index, &app)) {
- std::string current_app_id;
- bool pinned_by_policy = false;
- if (app->GetString(ash::kPinnedAppsPrefAppIDPath, &current_app_id)) {
- if (app_id == current_app_id) {
- if (app->GetBoolean(ash::kPinnedAppsPrefPinnedByPolicy,
- &pinned_by_policy) &&
- pinned_by_policy) {
- // Pinned by policy in the past or present.
- // Need to check policy_pinned_apps to determine
- break;
- } else {
- // User Preference Already Pinned
- return true;
- }
- }
- }
- }
- }
- for (size_t index = 0; index < policy_pinned_apps_pref->GetSize(); ++index) {
- const base::DictionaryValue* app;
- if (policy_pinned_apps_pref->GetDictionary(index, &app)) {
- std::string app_id_;
- if (app->GetString(ash::kPinnedAppsPrefAppIDPath, &app_id_)) {
- // Only pinned by policy, which is not part of user-pinned
- if (app_id == app_id_)
- return false;
- }
- }
- }
- // Default, user added new pins
- return true;
-}
-
-const char* const kPinProhibitedExtensionIds[] = {
- ArcSupportHost::kHostAppId, arc::kPlayStoreAppId,
-};
-
-const size_t kPinProhibitedExtensionIdsLength =
- arraysize(kPinProhibitedExtensionIds);
-
-} // namespace
-
-// A class to get events from ChromeOS when a user gets changed or added.
-class ChromeLauncherControllerUserSwitchObserver
- : public user_manager::UserManager::UserSessionStateObserver {
- public:
- ChromeLauncherControllerUserSwitchObserver(
- ChromeLauncherController* controller)
- : controller_(controller) {
- DCHECK(user_manager::UserManager::IsInitialized());
- user_manager::UserManager::Get()->AddSessionStateObserver(this);
- }
- ~ChromeLauncherControllerUserSwitchObserver() override {
- user_manager::UserManager::Get()->RemoveSessionStateObserver(this);
- }
-
- // user_manager::UserManager::UserSessionStateObserver overrides:
- void UserAddedToSession(const user_manager::User* added_user) override;
-
- // ChromeLauncherControllerUserSwitchObserver:
- void OnUserProfileReadyToSwitch(Profile* profile);
-
- private:
- // Add a user to the session.
- void AddUser(Profile* profile);
-
- // The owning ChromeLauncherController.
- ChromeLauncherController* controller_;
-
- // Users which were just added to the system, but which profiles were not yet
- // (fully) loaded.
- std::set<std::string> added_user_ids_waiting_for_profiles_;
-
- DISALLOW_COPY_AND_ASSIGN(ChromeLauncherControllerUserSwitchObserver);
-};
-
-void ChromeLauncherControllerUserSwitchObserver::UserAddedToSession(
- const user_manager::User* active_user) {
- Profile* profile =
- multi_user_util::GetProfileFromAccountId(active_user->GetAccountId());
- // If we do not have a profile yet, we postpone forwarding the notification
- // until it is loaded.
- if (!profile)
- added_user_ids_waiting_for_profiles_.insert(active_user->email());
- else
- AddUser(profile);
-}
-
-void ChromeLauncherControllerUserSwitchObserver::OnUserProfileReadyToSwitch(
- Profile* profile) {
- if (!added_user_ids_waiting_for_profiles_.empty()) {
- // Check if the profile is from a user which was on the waiting list.
- std::string user_id =
- multi_user_util::GetAccountIdFromProfile(profile).GetUserEmail();
- std::set<std::string>::iterator it = std::find(
- added_user_ids_waiting_for_profiles_.begin(),
- added_user_ids_waiting_for_profiles_.end(),
- user_id);
- if (it != added_user_ids_waiting_for_profiles_.end()) {
- added_user_ids_waiting_for_profiles_.erase(it);
- AddUser(profile->GetOriginalProfile());
- }
- }
-}
-
-void ChromeLauncherControllerUserSwitchObserver::AddUser(Profile* profile) {
- if (chrome::MultiUserWindowManager::GetMultiProfileMode() ==
- chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED)
- chrome::MultiUserWindowManager::GetInstance()->AddUser(profile);
- controller_->AdditionalUserAddedToSession(profile->GetOriginalProfile());
-}
-
-ChromeLauncherController::ChromeLauncherController(Profile* profile,
- ash::ShelfModel* model)
- : model_(model),
- item_delegate_manager_(NULL),
- profile_(profile),
- app_sync_ui_state_(NULL),
- ignore_persist_pinned_state_change_(false) {
- if (!profile_) {
- // If no profile was passed, we take the currently active profile and use it
- // as the owner of the current desktop.
- // Use the original profile as on chromeos we may get a temporary off the
- // record profile, unless in guest session (where off the record profile is
- // the right one).
- profile_ = ProfileManager::GetActiveUserProfile();
- if (!profile_->IsGuestSession() && !profile_->IsSystemProfile())
- profile_ = profile_->GetOriginalProfile();
-
- app_sync_ui_state_ = AppSyncUIState::Get(profile_);
- if (app_sync_ui_state_)
- app_sync_ui_state_->AddObserver(this);
- }
-
- if (arc::ArcAuthService::IsAllowedForProfile(profile_)) {
- arc_deferred_launcher_.reset(new ArcAppDeferredLauncherController(this));
- }
-
- // All profile relevant settings get bound to the current profile.
- AttachProfile(profile_);
- model_->AddObserver(this);
-
- // In multi profile mode we might have a window manager. We try to create it
- // here. If the instantiation fails, the manager is not needed.
- chrome::MultiUserWindowManager::CreateInstance();
-
- // On Chrome OS using multi profile we want to switch the content of the shelf
- // with a user change. Note that for unit tests the instance can be NULL.
- if (chrome::MultiUserWindowManager::GetMultiProfileMode() !=
- chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_OFF) {
- user_switch_observer_.reset(
- new ChromeLauncherControllerUserSwitchObserver(this));
- }
-
- std::unique_ptr<AppWindowLauncherController> extension_app_window_controller;
- // Create our v1/v2 application / browser monitors which will inform the
- // launcher of status changes.
- if (chrome::MultiUserWindowManager::GetMultiProfileMode() ==
- chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED) {
- // If running in separated destkop mode, we create the multi profile version
- // of status monitor.
- browser_status_monitor_.reset(new MultiProfileBrowserStatusMonitor(this));
- extension_app_window_controller.reset(
- new MultiProfileAppWindowLauncherController(this));
- } else {
- // Create our v1/v2 application / browser monitors which will inform the
- // launcher of status changes.
- browser_status_monitor_.reset(new BrowserStatusMonitor(this));
- extension_app_window_controller.reset(
- new ExtensionAppWindowLauncherController(this));
- }
- app_window_controllers_.push_back(std::move(extension_app_window_controller));
-
- std::unique_ptr<AppWindowLauncherController> arc_app_window_controller;
- arc_app_window_controller.reset(new ArcAppWindowLauncherController(this));
- app_window_controllers_.push_back(std::move(arc_app_window_controller));
-
- // Right now ash::Shell isn't created for tests.
- // TODO(mukai): Allows it to observe display change and write tests.
- if (ash::Shell::HasInstance()) {
- ash::Shell::GetInstance()->window_tree_host_manager()->AddObserver(this);
- // If it got already set, we remove the observer first again and swap the
- // ItemDelegateManager.
- if (item_delegate_manager_)
- item_delegate_manager_->RemoveObserver(this);
- item_delegate_manager_ =
- ash::Shell::GetInstance()->shelf_item_delegate_manager();
- item_delegate_manager_->AddObserver(this);
- }
-}
+ChromeLauncherController* ChromeLauncherController::instance_ = nullptr;
ChromeLauncherController::~ChromeLauncherController() {
- if (item_delegate_manager_)
- item_delegate_manager_->RemoveObserver(this);
-
- // Reset the BrowserStatusMonitor as it has a weak pointer to this.
- browser_status_monitor_.reset();
-
- // Reset the app window controllers here since it has a weak pointer to this.
- app_window_controllers_.clear();
-
- model_->RemoveObserver(this);
- if (ash::Shell::HasInstance())
- ash::Shell::GetInstance()->window_tree_host_manager()->RemoveObserver(this);
- for (IDToItemControllerMap::iterator i = id_to_item_controller_map_.begin();
- i != id_to_item_controller_map_.end(); ++i) {
- int index = model_->ItemIndexByID(i->first);
- // A "browser proxy" is not known to the model and this removal does
- // therefore not need to be propagated to the model.
- if (index != -1 &&
- model_->items()[index].type != ash::TYPE_BROWSER_SHORTCUT)
- model_->RemoveItemAt(index);
- }
-
- // Release all profile dependent resources.
- ReleaseProfile();
if (instance_ == this)
- instance_ = NULL;
-
- // Get rid of the multi user window manager instance.
- chrome::MultiUserWindowManager::DeleteInstance();
-}
-
-// static
-ChromeLauncherController* ChromeLauncherController::CreateInstance(
- Profile* profile,
- ash::ShelfModel* model) {
- // We do not check here for re-creation of the ChromeLauncherController since
- // it appears that it might be intentional that the ChromeLauncherController
- // can be re-created.
- instance_ = new ChromeLauncherController(profile, model);
- return instance_;
-}
-
-void ChromeLauncherController::Init() {
- CreateBrowserShortcutLauncherItem();
- UpdateAppLaunchersFromPref();
-
- // TODO(sky): update unit test so that this test isn't necessary.
- if (ash::Shell::HasInstance())
- SetVirtualKeyboardBehaviorFromPrefs();
-
- prefs_observer_ =
- ash::ChromeLauncherPrefsObserver::CreateIfNecessary(profile_);
-}
-
-ash::ShelfID ChromeLauncherController::CreateAppLauncherItem(
- LauncherItemController* controller,
- const std::string& app_id,
- ash::ShelfItemStatus status) {
- CHECK(controller);
- int index = 0;
- // Panels are inserted on the left so as not to push all existing panels over.
- if (controller->GetShelfItemType() != ash::TYPE_APP_PANEL)
- index = model_->item_count();
- return InsertAppLauncherItem(controller,
- app_id,
- status,
- index,
- controller->GetShelfItemType());
-}
-
-void ChromeLauncherController::SetItemStatus(ash::ShelfID id,
- ash::ShelfItemStatus status) {
- int index = model_->ItemIndexByID(id);
- ash::ShelfItemStatus old_status = model_->items()[index].status;
- // Since ordinary browser windows are not registered, we might get a negative
- // index here.
- if (index >= 0 && old_status != status) {
- ash::ShelfItem item = model_->items()[index];
- item.status = status;
- model_->Set(index, item);
- }
-}
-
-void ChromeLauncherController::SetItemController(
- ash::ShelfID id,
- LauncherItemController* controller) {
- CHECK(controller);
- IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id);
- CHECK(iter != id_to_item_controller_map_.end());
- controller->set_shelf_id(id);
- iter->second = controller;
- // Existing controller is destroyed and replaced by registering again.
- SetShelfItemDelegate(id, controller);
-}
-
-void ChromeLauncherController::CloseLauncherItem(ash::ShelfID id) {
- CHECK(id);
- if (IsPinned(id)) {
- // Create a new shortcut controller.
- IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id);
- CHECK(iter != id_to_item_controller_map_.end());
- SetItemStatus(id, ash::STATUS_CLOSED);
- std::string app_id = iter->second->app_id();
- iter->second = AppShortcutLauncherItemController::Create(app_id, this);
- iter->second->set_shelf_id(id);
- // Existing controller is destroyed and replaced by registering again.
- SetShelfItemDelegate(id, iter->second);
- } else {
- LauncherItemClosed(id);
- }
-}
-
-AppListControllerDelegate::Pinnable ChromeLauncherController::GetPinnable(
- const std::string& app_id) {
- for (size_t i = 0; i < kPinProhibitedExtensionIdsLength; ++i) {
- if (kPinProhibitedExtensionIds[i] == app_id)
- return AppListControllerDelegate::NO_PIN;
- }
-
- const base::ListValue* pref =
- profile_->GetPrefs()->GetList(prefs::kPolicyPinnedLauncherApps);
- if (!pref)
- return AppListControllerDelegate::PIN_EDITABLE;
-
- // Pinned ARC apps policy defines the package name of the apps, that must
- // be pinned. All the launch activities of any package in policy are pinned.
- // In turn the input parameter to this function is app_id, which
- // is 32 chars hash. In case of ARC app this is a hash of
- // (package name + activity). This means that we must identify the package
- // from the hash, and check if this package is pinned by policy.
- const ArcAppListPrefs* const arc_prefs = ArcAppListPrefs::Get(profile());
- std::string arc_app_packege_name;
- if (arc_prefs) {
- std::unique_ptr<ArcAppListPrefs::AppInfo> app_info =
- arc_prefs->GetApp(app_id);
- if (app_info)
- arc_app_packege_name = app_info->package_name;
- }
-
- for (size_t index = 0; index < pref->GetSize(); ++index) {
- const base::DictionaryValue* app = nullptr;
- std::string app_id_or_package;
- if (pref->GetDictionary(index, &app) &&
- app->GetString(ash::kPinnedAppsPrefAppIDPath, &app_id_or_package) &&
- (app_id == app_id_or_package ||
- arc_app_packege_name == app_id_or_package)) {
- return AppListControllerDelegate::PIN_FIXED;
- }
- }
- return AppListControllerDelegate::PIN_EDITABLE;
-}
-
-void ChromeLauncherController::Pin(ash::ShelfID id) {
- DCHECK(HasShelfIDToAppIDMapping(id));
-
- int index = model_->ItemIndexByID(id);
- DCHECK_GE(index, 0);
-
- ash::ShelfItem item = model_->items()[index];
-
- if (item.type == ash::TYPE_PLATFORM_APP ||
- item.type == ash::TYPE_WINDOWED_APP) {
- item.type = ash::TYPE_APP_SHORTCUT;
- model_->Set(index, item);
- } else if (item.type != ash::TYPE_APP_SHORTCUT) {
- return;
- }
-
- if (GetLauncherItemController(id)->CanPin())
- PersistPinnedState();
-}
-
-void ChromeLauncherController::Unpin(ash::ShelfID id) {
- LauncherItemController* controller = GetLauncherItemController(id);
- CHECK(controller);
- const bool can_pin = controller->CanPin();
-
- if (controller->type() == LauncherItemController::TYPE_APP ||
- controller->locked()) {
- UnpinRunningAppInternal(model_->ItemIndexByID(id));
- } else {
- LauncherItemClosed(id);
- }
- if (can_pin)
- PersistPinnedState();
-}
-
-bool ChromeLauncherController::IsPinned(ash::ShelfID id) {
- int index = model_->ItemIndexByID(id);
- if (index < 0)
- return false;
- ash::ShelfItemType type = model_->items()[index].type;
- return (type == ash::TYPE_APP_SHORTCUT || type == ash::TYPE_BROWSER_SHORTCUT);
-}
-
-void ChromeLauncherController::TogglePinned(ash::ShelfID id) {
- if (!HasShelfIDToAppIDMapping(id))
- return; // May happen if item closed with menu open.
-
- if (IsPinned(id))
- Unpin(id);
- else
- Pin(id);
-}
-
-bool ChromeLauncherController::IsPinnable(ash::ShelfID id) const {
- int index = model_->ItemIndexByID(id);
- if (index == -1)
- return false;
-
- ash::ShelfItemType type = model_->items()[index].type;
- std::string app_id;
- return ((type == ash::TYPE_APP_SHORTCUT || type == ash::TYPE_PLATFORM_APP ||
- type == ash::TYPE_WINDOWED_APP) &&
- item_delegate_manager_->GetShelfItemDelegate(id)->CanPin());
-}
-
-void ChromeLauncherController::LockV1AppWithID(const std::string& app_id) {
- ash::ShelfID id = GetShelfIDForAppID(app_id);
- if (!IsPinned(id) && !IsWindowedAppInLauncher(app_id)) {
- CreateAppShortcutLauncherItemWithType(app_id,
- model_->item_count(),
- ash::TYPE_WINDOWED_APP);
- id = GetShelfIDForAppID(app_id);
- }
- CHECK(id);
- id_to_item_controller_map_[id]->lock();
-}
-
-void ChromeLauncherController::UnlockV1AppWithID(const std::string& app_id) {
- ash::ShelfID id = GetShelfIDForAppID(app_id);
- CHECK(id);
- CHECK(IsPinned(id) || IsWindowedAppInLauncher(app_id));
- LauncherItemController* controller = id_to_item_controller_map_[id];
- controller->unlock();
- if (!controller->locked() && !IsPinned(id))
- CloseLauncherItem(id);
-}
-
-void ChromeLauncherController::Launch(ash::ShelfID id, int event_flags) {
- LauncherItemController* controller = GetLauncherItemController(id);
- if (!controller)
- return; // In case invoked from menu and item closed while menu up.
- controller->Launch(ash::LAUNCH_FROM_UNKNOWN, event_flags);
-}
-
-void ChromeLauncherController::Close(ash::ShelfID id) {
- LauncherItemController* controller = GetLauncherItemController(id);
- if (!controller)
- return; // May happen if menu closed.
- controller->Close();
-}
-
-bool ChromeLauncherController::IsOpen(ash::ShelfID id) {
- LauncherItemController* controller = GetLauncherItemController(id);
- if (!controller)
- return false;
- return controller->IsOpen();
-}
-
-bool ChromeLauncherController::IsPlatformApp(ash::ShelfID id) {
- if (!HasShelfIDToAppIDMapping(id))
- return false;
-
- std::string app_id = GetAppIDForShelfID(id);
- const Extension* extension = GetExtensionForAppID(app_id);
- // An extension can be synced / updated at any time and therefore not be
- // available.
- return extension ? extension->is_platform_app() : false;
-}
-
-void ChromeLauncherController::LaunchApp(const std::string& app_id,
- ash::LaunchSource source,
- int event_flags) {
- launcher_controller_helper_->LaunchApp(app_id, source, event_flags);
-}
-
-void ChromeLauncherController::ActivateApp(const std::string& app_id,
- ash::LaunchSource source,
- int event_flags) {
- // If there is an existing non-shortcut controller for this app, open it.
- ash::ShelfID id = GetShelfIDForAppID(app_id);
- if (id) {
- LauncherItemController* controller = GetLauncherItemController(id);
- controller->Activate(source);
- return;
- }
-
- // Create a temporary application launcher item and use it to see if there are
- // running instances.
- std::unique_ptr<AppShortcutLauncherItemController> app_controller(
- AppShortcutLauncherItemController::Create(app_id, this));
- if (!app_controller->GetRunningApplications().empty())
- app_controller->Activate(source);
- else
- LaunchApp(app_id, source, event_flags);
-}
-
-extensions::LaunchType ChromeLauncherController::GetLaunchType(
- ash::ShelfID id) {
- const Extension* extension = GetExtensionForAppID(GetAppIDForShelfID(id));
-
- // An extension can be unloaded/updated/unavailable at any time.
- if (!extension)
- return extensions::LAUNCH_TYPE_DEFAULT;
-
- return extensions::GetLaunchType(extensions::ExtensionPrefs::Get(profile_),
- extension);
-}
-
-ash::ShelfID ChromeLauncherController::GetShelfIDForAppID(
- const std::string& app_id) {
- for (IDToItemControllerMap::const_iterator i =
- id_to_item_controller_map_.begin();
- i != id_to_item_controller_map_.end(); ++i) {
- if (i->second->type() == LauncherItemController::TYPE_APP_PANEL)
- continue; // Don't include panels
- if (i->second->app_id() == app_id)
- return i->first;
- }
- return 0;
-}
-
-bool ChromeLauncherController::HasShelfIDToAppIDMapping(ash::ShelfID id) const {
- return id_to_item_controller_map_.find(id) !=
- id_to_item_controller_map_.end();
-}
-
-const std::string& ChromeLauncherController::GetAppIDForShelfID(
- ash::ShelfID id) {
- LauncherItemController* controller = GetLauncherItemController(id);
- return controller ? controller->app_id() : base::EmptyString();
-}
-
-void ChromeLauncherController::OnAppImageUpdated(const std::string& id,
- const gfx::ImageSkia& image) {
- // TODO: need to get this working for shortcuts.
- for (IDToItemControllerMap::const_iterator i =
- id_to_item_controller_map_.begin();
- i != id_to_item_controller_map_.end(); ++i) {
- LauncherItemController* controller = i->second;
- if (controller->app_id() != id)
- continue;
- if (controller->image_set_by_controller())
- continue;
- int index = model_->ItemIndexByID(i->first);
- if (index == -1)
- continue;
- ash::ShelfItem item = model_->items()[index];
- item.image = image;
- model_->Set(index, item);
- // It's possible we're waiting on more than one item, so don't break.
- }
-}
-
-void ChromeLauncherController::SetLauncherItemImage(
- ash::ShelfID shelf_id,
- const gfx::ImageSkia& image) {
- int index = model_->ItemIndexByID(shelf_id);
- if (index == -1)
- return;
- ash::ShelfItem item = model_->items()[index];
- item.image = image;
- model_->Set(index, item);
-}
-
-bool ChromeLauncherController::IsAppPinned(const std::string& app_id) {
- for (IDToItemControllerMap::const_iterator i =
- id_to_item_controller_map_.begin();
- i != id_to_item_controller_map_.end(); ++i) {
- if (IsPinned(i->first) && i->second->app_id() == app_id)
- return true;
- }
- return false;
-}
-
-bool ChromeLauncherController::IsWindowedAppInLauncher(
- const std::string& app_id) {
- int index = model_->ItemIndexByID(GetShelfIDForAppID(app_id));
- if (index < 0)
- return false;
-
- ash::ShelfItemType type = model_->items()[index].type;
- return type == ash::TYPE_WINDOWED_APP;
-}
-
-void ChromeLauncherController::PinAppWithID(const std::string& app_id) {
- if (GetPinnable(app_id) == AppListControllerDelegate::PIN_EDITABLE)
- DoPinAppWithID(app_id);
- else
- NOTREACHED();
-}
-
-void ChromeLauncherController::SetLaunchType(
- ash::ShelfID id,
- extensions::LaunchType launch_type) {
- LauncherItemController* controller = GetLauncherItemController(id);
- if (!controller)
- return;
-
- extensions::SetLaunchType(profile_, controller->app_id(), launch_type);
-}
-
-void ChromeLauncherController::UnpinAppWithID(const std::string& app_id) {
- if (GetPinnable(app_id) == AppListControllerDelegate::PIN_EDITABLE)
- DoUnpinAppWithID(app_id);
- else
- NOTREACHED();
-}
-
-void ChromeLauncherController::OnSetShelfItemDelegate(
- ash::ShelfID id,
- ash::ShelfItemDelegate* item_delegate) {
- // TODO(skuhne): This fixes crbug.com/429870, but it does not answer why we
- // get into this state in the first place.
- IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id);
- if (iter == id_to_item_controller_map_.end() || item_delegate == iter->second)
- return;
- LOG(ERROR) << "Unexpected change of shelf item id: " << id;
- id_to_item_controller_map_.erase(iter);
-}
-
-void ChromeLauncherController::PersistPinnedState() {
- if (ignore_persist_pinned_state_change_)
- return;
- // It is a coding error to call PersistPinnedState() if the pinned apps are
- // not user-editable. The code should check earlier and not perform any
- // modification actions that trigger persisting the state.
- // Mutating kPinnedLauncherApps is going to notify us and trigger us to
- // process the change. We don't want that to happen so remove ourselves as a
- // listener.
- pref_change_registrar_.Remove(prefs::kPinnedLauncherApps);
- {
- std::unique_ptr<const base::ListValue> pinned_apps_pref =
- profile_->GetPrefs()
- ->GetList(prefs::kPinnedLauncherApps)
- ->CreateDeepCopy();
-
- const base::ListValue* policy_pinned_apps_pref =
- profile_->GetPrefs()->GetList(prefs::kPolicyPinnedLauncherApps);
-
- ListPrefUpdate updater(profile_->GetPrefs(), prefs::kPinnedLauncherApps);
- updater->Clear();
- for (size_t i = 0; i < model_->items().size(); ++i) {
- if (model_->items()[i].type == ash::TYPE_APP_SHORTCUT) {
- ash::ShelfID id = model_->items()[i].id;
- LauncherItemController* controller = GetLauncherItemController(id);
- // Don't persist pinning state for apps that are handled internally and
- // have pinnable state AppListControllerDelegate::NO_PIN.
- if (controller && IsPinned(id) &&
- GetPinnable(controller->app_id()) !=
- AppListControllerDelegate::NO_PIN) {
- base::DictionaryValue* app_value = ash::CreateAppDict(
- controller->app_id());
- if (app_value) {
- if (!IsAppForUserPinned(controller->app_id(),
- pinned_apps_pref.get(),
- policy_pinned_apps_pref))
- app_value->SetBoolean(ash::kPinnedAppsPrefPinnedByPolicy, true);
- updater->Append(app_value);
- }
- }
- } else if (model_->items()[i].type == ash::TYPE_BROWSER_SHORTCUT) {
- PersistChromeItemIndex(i);
- } else if (model_->items()[i].type == ash::TYPE_APP_LIST) {
- base::DictionaryValue* app_value =
- ash::CreateAppDict(ash::kPinnedAppsPlaceholder);
- if (app_value)
- updater->Append(app_value);
- }
- }
- }
- pref_change_registrar_.Add(
- prefs::kPinnedLauncherApps,
- base::Bind(&ChromeLauncherController::UpdateAppLaunchersFromPref,
- base::Unretained(this)));
-}
-
-Profile* ChromeLauncherController::profile() {
- return profile_;
-}
-
-void ChromeLauncherController::UpdateAppState(content::WebContents* contents,
- AppState app_state) {
- std::string app_id = launcher_controller_helper_->GetAppID(contents);
-
- // Check if the gMail app is loaded and it matches the given content.
- // This special treatment is needed to address crbug.com/234268.
- if (app_id.empty() && ContentCanBeHandledByGmailApp(contents))
- app_id = kGmailAppId;
-
- // Check the old |app_id| for a tab. If the contents has changed we need to
- // remove it from the previous app.
- if (web_contents_to_app_id_.find(contents) != web_contents_to_app_id_.end()) {
- std::string last_app_id = web_contents_to_app_id_[contents];
- if (last_app_id != app_id) {
- ash::ShelfID id = GetShelfIDForAppID(last_app_id);
- if (id) {
- // Since GetAppState() will use |web_contents_to_app_id_| we remove
- // the connection before calling it.
- web_contents_to_app_id_.erase(contents);
- SetItemStatus(id, GetAppState(last_app_id));
- }
- }
- }
-
- if (app_state == APP_STATE_REMOVED)
- web_contents_to_app_id_.erase(contents);
- else
- web_contents_to_app_id_[contents] = app_id;
-
- ash::ShelfID id = GetShelfIDForAppID(app_id);
- if (id) {
- SetItemStatus(id, (app_state == APP_STATE_WINDOW_ACTIVE ||
- app_state == APP_STATE_ACTIVE) ? ash::STATUS_ACTIVE :
- GetAppState(app_id));
- }
-}
-
-ash::ShelfID ChromeLauncherController::GetShelfIDForWebContents(
- content::WebContents* contents) {
- DCHECK(contents);
-
- std::string app_id = launcher_controller_helper_->GetAppID(contents);
-
- if (app_id.empty() && ContentCanBeHandledByGmailApp(contents))
- app_id = kGmailAppId;
-
- ash::ShelfID id = GetShelfIDForAppID(app_id);
-
- if (app_id.empty() || !id) {
- int browser_index = model_->GetItemIndexForType(ash::TYPE_BROWSER_SHORTCUT);
- return model_->items()[browser_index].id;
- }
-
- return id;
-}
-
-void ChromeLauncherController::SetRefocusURLPatternForTest(ash::ShelfID id,
- const GURL& url) {
- LauncherItemController* controller = GetLauncherItemController(id);
- DCHECK(controller);
-
- int index = model_->ItemIndexByID(id);
- if (index == -1) {
- NOTREACHED() << "Invalid launcher id";
- return;
- }
-
- ash::ShelfItemType type = model_->items()[index].type;
- if (type == ash::TYPE_APP_SHORTCUT || type == ash::TYPE_WINDOWED_APP) {
- AppShortcutLauncherItemController* app_controller =
- static_cast<AppShortcutLauncherItemController*>(controller);
- app_controller->set_refocus_url(url);
- } else {
- NOTREACHED() << "Invalid launcher type";
- }
-}
-
-const Extension* ChromeLauncherController::GetExtensionForAppID(
- const std::string& app_id) const {
- return extensions::ExtensionRegistry::Get(profile_)->GetExtensionById(
- app_id, extensions::ExtensionRegistry::EVERYTHING);
-}
-
-ash::ShelfItemDelegate::PerformedAction
-ChromeLauncherController::ActivateWindowOrMinimizeIfActive(
- ui::BaseWindow* window,
- bool allow_minimize) {
- // In separated desktop mode we might have to teleport a window back to the
- // current user.
- if (chrome::MultiUserWindowManager::GetMultiProfileMode() ==
- chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED) {
- aura::Window* native_window = window->GetNativeWindow();
- const AccountId& current_account_id =
- multi_user_util::GetAccountIdFromProfile(profile());
- chrome::MultiUserWindowManager* manager =
- chrome::MultiUserWindowManager::GetInstance();
- if (!manager->IsWindowOnDesktopOfUser(native_window, current_account_id)) {
- ash::MultiProfileUMA::RecordTeleportAction(
- ash::MultiProfileUMA::TELEPORT_WINDOW_RETURN_BY_LAUNCHER);
- manager->ShowWindowForUser(native_window, current_account_id);
- window->Activate();
- return ash::ShelfItemDelegate::kExistingWindowActivated;
- }
- }
-
- if (window->IsActive() && allow_minimize) {
- window->Minimize();
- return ash::ShelfItemDelegate::kNoAction;
- }
-
- window->Show();
- window->Activate();
- return ash::ShelfItemDelegate::kExistingWindowActivated;
-}
-
-void ChromeLauncherController::OnShelfCreated(ash::Shelf* shelf) {
- PrefService* prefs = profile_->GetPrefs();
- const int64_t display = GetDisplayIDForShelf(shelf);
-
- shelf->SetAutoHideBehavior(ash::GetShelfAutoHideBehaviorPref(prefs, display));
-
- if (ash::ShelfWidget::ShelfAlignmentAllowed())
- shelf->SetAlignment(ash::GetShelfAlignmentPref(prefs, display));
+ instance_ = nullptr;
}
-void ChromeLauncherController::OnShelfDestroyed(ash::Shelf* shelf) {}
-
-void ChromeLauncherController::OnShelfAlignmentChanged(ash::Shelf* shelf) {
- ash::SetShelfAlignmentPref(profile_->GetPrefs(), GetDisplayIDForShelf(shelf),
- shelf->alignment());
-}
-
-void ChromeLauncherController::OnShelfAutoHideBehaviorChanged(
- ash::Shelf* shelf) {
- ash::SetShelfAutoHideBehaviorPref(profile_->GetPrefs(),
- GetDisplayIDForShelf(shelf),
- shelf->auto_hide_behavior());
-}
-
-void ChromeLauncherController::OnShelfAutoHideStateChanged(ash::Shelf* shelf) {}
-
-void ChromeLauncherController::OnShelfVisibilityStateChanged(
- ash::Shelf* shelf) {}
-
-void ChromeLauncherController::ShelfItemAdded(int index) {
- // The app list launcher can get added to the shelf after we applied the
- // preferences. In that case the item might be at the wrong spot. As such we
- // call the function again.
- if (model_->items()[index].type == ash::TYPE_APP_LIST)
- UpdateAppLaunchersFromPref();
-}
-
-void ChromeLauncherController::ShelfItemRemoved(int index, ash::ShelfID id) {
- // TODO(skuhne): This fixes crbug.com/429870, but it does not answer why we
- // get into this state in the first place.
- IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id);
- if (iter == id_to_item_controller_map_.end())
- return;
-
- LOG(ERROR) << "Unexpected change of shelf item id: " << id;
-
- id_to_item_controller_map_.erase(iter);
-}
-
-void ChromeLauncherController::ShelfItemMoved(int start_index,
- int target_index) {
- const ash::ShelfItem& item = model_->items()[target_index];
- // We remember the moved item position if it is either pinnable or
- // it is the app list with the alternate shelf layout.
- if ((HasShelfIDToAppIDMapping(item.id) && IsPinned(item.id)) ||
- item.type == ash::TYPE_APP_LIST)
- PersistPinnedState();
-}
-
-void ChromeLauncherController::ShelfItemChanged(
- int index,
- const ash::ShelfItem& old_item) {}
-
-void ChromeLauncherController::ActiveUserChanged(
- const std::string& user_email) {
- // Store the order of running applications for the user which gets inactive.
- RememberUnpinnedRunningApplicationOrder();
- // Coming here the default profile is already switched. All profile specific
- // resources get released and the new profile gets attached instead.
- ReleaseProfile();
- // When coming here, the active user has already be changed so that we can
- // set it as active.
- AttachProfile(ProfileManager::GetActiveUserProfile());
- // Update the V1 applications.
- browser_status_monitor_->ActiveUserChanged(user_email);
- // Switch the running applications to the new user.
- for (auto& controller : app_window_controllers_)
- controller->ActiveUserChanged(user_email);
- // Update the user specific shell properties from the new user profile.
- UpdateAppLaunchersFromPref();
- SetShelfBehaviorsFromPrefs();
- SetVirtualKeyboardBehaviorFromPrefs();
-
- // Restore the order of running, but unpinned applications for the activated
- // user.
- RestoreUnpinnedRunningApplicationOrder(user_email);
- // Inform the system tray of the change.
- ash::WmShell::Get()->system_tray_delegate()->ActiveUserWasChanged();
- // Force on-screen keyboard to reset.
- if (keyboard::IsKeyboardEnabled())
- ash::Shell::GetInstance()->CreateKeyboard();
-}
-
-void ChromeLauncherController::AdditionalUserAddedToSession(Profile* profile) {
- // Switch the running applications to the new user.
- for (auto& controller : app_window_controllers_)
- controller->AdditionalUserAddedToSession(profile);
-}
-
-void ChromeLauncherController::OnAppInstalled(
- content::BrowserContext* browser_context,
- const std::string& app_id) {
- if (IsAppPinned(app_id)) {
- // Clear and re-fetch to ensure icon is up-to-date.
- AppIconLoader* app_icon_loader = GetAppIconLoaderForApp(app_id);
- if (app_icon_loader) {
- app_icon_loader->ClearImage(app_id);
- app_icon_loader->FetchImage(app_id);
- }
- }
-
- UpdateAppLaunchersFromPref();
-}
-
-void ChromeLauncherController::OnAppUpdated(
- content::BrowserContext* browser_context,
- const std::string& app_id) {
- AppIconLoader* app_icon_loader = GetAppIconLoaderForApp(app_id);
- if (app_icon_loader)
- app_icon_loader->UpdateImage(app_id);
-}
-
-void ChromeLauncherController::OnAppUninstalled(
- content::BrowserContext* browser_context,
- const std::string& app_id) {
- // Since we might have windowed apps of this type which might have
- // outstanding locks which needs to be removed.
- const Profile* profile = Profile::FromBrowserContext(browser_context);
- if (GetShelfIDForAppID(app_id))
- CloseWindowedAppsFromRemovedExtension(app_id, profile);
-
- if (IsAppPinned(app_id)) {
- if (profile == profile_)
- DoUnpinAppWithID(app_id);
- AppIconLoader* app_icon_loader = GetAppIconLoaderForApp(app_id);
- if (app_icon_loader)
- app_icon_loader->ClearImage(app_id);
- }
-}
-
-void ChromeLauncherController::OnDisplayConfigurationChanged() {
- SetShelfBehaviorsFromPrefs();
-}
-
-void ChromeLauncherController::OnAppSyncUIStatusChanged() {
- if (app_sync_ui_state_->status() == AppSyncUIState::STATUS_SYNCING)
- model_->set_status(ash::ShelfModel::STATUS_LOADING);
- else
- model_->set_status(ash::ShelfModel::STATUS_NORMAL);
-}
-
-ChromeLauncherAppMenuItems ChromeLauncherController::GetApplicationList(
- const ash::ShelfItem& item,
- int event_flags) {
- // Make sure that there is a controller associated with the id and that the
- // extension itself is a valid application and not a panel.
- LauncherItemController* controller = GetLauncherItemController(item.id);
- if (!controller || !GetShelfIDForAppID(controller->app_id()))
- return ChromeLauncherAppMenuItems();
-
- return controller->GetApplicationList(event_flags);
-}
-
-std::vector<content::WebContents*>
-ChromeLauncherController::GetV1ApplicationsFromAppId(
- const std::string& app_id) {
- ash::ShelfID id = GetShelfIDForAppID(app_id);
-
- // If there is no such an item pinned to the launcher, no menu gets created.
- if (id) {
- LauncherItemController* controller = GetLauncherItemController(id);
- DCHECK(controller);
- if (controller->type() == LauncherItemController::TYPE_SHORTCUT)
- return GetV1ApplicationsFromController(controller);
- }
- return std::vector<content::WebContents*>();
-}
-
-void ChromeLauncherController::ActivateShellApp(const std::string& app_id,
- int index) {
- ash::ShelfID id = GetShelfIDForAppID(app_id);
- if (id) {
- LauncherItemController* controller = GetLauncherItemController(id);
- if (controller && controller->type() == LauncherItemController::TYPE_APP) {
- AppWindowLauncherItemController* app_window_controller =
- static_cast<AppWindowLauncherItemController*>(controller);
- app_window_controller->ActivateIndexedApp(index);
- }
- }
-}
-
-bool ChromeLauncherController::IsWebContentHandledByApplication(
- content::WebContents* web_contents,
- const std::string& app_id) {
- if ((web_contents_to_app_id_.find(web_contents) !=
- web_contents_to_app_id_.end()) &&
- (web_contents_to_app_id_[web_contents] == app_id))
- return true;
- return (app_id == kGmailAppId && ContentCanBeHandledByGmailApp(web_contents));
-}
-
-bool ChromeLauncherController::ContentCanBeHandledByGmailApp(
- content::WebContents* web_contents) {
- ash::ShelfID id = GetShelfIDForAppID(kGmailAppId);
- if (id) {
- const GURL url = web_contents->GetURL();
- // We need to extend the application matching for the gMail app beyond the
- // manifest file's specification. This is required because of the namespace
- // overlap with the offline app ("/mail/mu/").
- if (!base::MatchPattern(url.path(), "/mail/mu/*") &&
- base::MatchPattern(url.path(), "/mail/*") &&
- GetExtensionForAppID(kGmailAppId) &&
- GetExtensionForAppID(kGmailAppId)->OverlapsWithOrigin(url))
- return true;
- }
- return false;
-}
-
-gfx::Image ChromeLauncherController::GetAppListIcon(
- content::WebContents* web_contents) const {
- ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
- if (IsIncognito(web_contents))
- return rb.GetImageNamed(IDR_ASH_SHELF_LIST_INCOGNITO_BROWSER);
- favicon::FaviconDriver* favicon_driver =
- favicon::ContentFaviconDriver::FromWebContents(web_contents);
- gfx::Image result = favicon_driver->GetFavicon();
- if (result.IsEmpty())
- return rb.GetImageNamed(IDR_DEFAULT_FAVICON);
- return result;
-}
-
-base::string16 ChromeLauncherController::GetAppListTitle(
- content::WebContents* web_contents) const {
- base::string16 title = web_contents->GetTitle();
- if (!title.empty())
- return title;
- WebContentsToAppIDMap::const_iterator iter =
- web_contents_to_app_id_.find(web_contents);
- if (iter != web_contents_to_app_id_.end()) {
- std::string app_id = iter->second;
- const extensions::Extension* extension = GetExtensionForAppID(app_id);
- if (extension)
- return base::UTF8ToUTF16(extension->name());
- }
- return l10n_util::GetStringUTF16(IDS_NEW_TAB_TITLE);
-}
-
-ash::ShelfID ChromeLauncherController::CreateAppShortcutLauncherItem(
- const std::string& app_id,
- int index) {
- return CreateAppShortcutLauncherItemWithType(app_id,
- index,
- ash::TYPE_APP_SHORTCUT);
-}
-
-void ChromeLauncherController::SetLauncherControllerHelperForTest(
- LauncherControllerHelper* helper) {
- launcher_controller_helper_.reset(helper);
-}
-
-void ChromeLauncherController::SetAppIconLoadersForTest(
- std::vector<std::unique_ptr<AppIconLoader>>& loaders) {
- app_icon_loaders_.clear();
- for (auto& loader : loaders)
- app_icon_loaders_.push_back(std::move(loader));
-}
-
-const std::string& ChromeLauncherController::GetAppIdFromShelfIdForTest(
- ash::ShelfID id) {
- return id_to_item_controller_map_[id]->app_id();
-}
-
-bool ChromeLauncherController::GetAppIDForShelfIDConst(
- ash::ShelfID id,
- std::string* app_id) const {
- auto app = id_to_item_controller_map_.find(id);
- if (app == id_to_item_controller_map_.end()) {
- return false;
- } else {
- *app_id = app->second->app_id();
- return true;
- }
-}
-
-void ChromeLauncherController::SetShelfItemDelegateManagerForTest(
- ash::ShelfItemDelegateManager* manager) {
- if (item_delegate_manager_)
- item_delegate_manager_->RemoveObserver(this);
-
- item_delegate_manager_ = manager;
-
- if (item_delegate_manager_)
- item_delegate_manager_->AddObserver(this);
-}
-
-void ChromeLauncherController::RememberUnpinnedRunningApplicationOrder() {
- RunningAppListIds list;
- for (int i = 0; i < model_->item_count(); i++) {
- ash::ShelfItemType type = model_->items()[i].type;
- if (type == ash::TYPE_WINDOWED_APP || type == ash::TYPE_PLATFORM_APP)
- list.push_back(GetAppIDForShelfID(model_->items()[i].id));
- }
- const std::string user_email =
- multi_user_util::GetAccountIdFromProfile(profile_).GetUserEmail();
- last_used_running_application_order_[user_email] = list;
-}
-
-void ChromeLauncherController::RestoreUnpinnedRunningApplicationOrder(
- const std::string& user_id) {
- const RunningAppListIdMap::iterator app_id_list =
- last_used_running_application_order_.find(user_id);
- if (app_id_list == last_used_running_application_order_.end())
- return;
-
- // Find the first insertion point for running applications.
- int running_index = model_->FirstRunningAppIndex();
- for (RunningAppListIds::iterator app_id = app_id_list->second.begin();
- app_id != app_id_list->second.end(); ++app_id) {
- ash::ShelfID shelf_id = GetShelfIDForAppID(*app_id);
- if (shelf_id) {
- int app_index = model_->ItemIndexByID(shelf_id);
- DCHECK_GE(app_index, 0);
- ash::ShelfItemType type = model_->items()[app_index].type;
- if (type == ash::TYPE_WINDOWED_APP || type == ash::TYPE_PLATFORM_APP) {
- if (running_index != app_index)
- model_->Move(running_index, app_index);
- running_index++;
- }
- }
- }
-}
-
-ash::ShelfID ChromeLauncherController::CreateAppShortcutLauncherItemWithType(
- const std::string& app_id,
- int index,
- ash::ShelfItemType shelf_item_type) {
- AppShortcutLauncherItemController* controller =
- AppShortcutLauncherItemController::Create(app_id, this);
- ash::ShelfID shelf_id = InsertAppLauncherItem(
- controller, app_id, ash::STATUS_CLOSED, index, shelf_item_type);
- return shelf_id;
-}
-
-LauncherItemController* ChromeLauncherController::GetLauncherItemController(
- const ash::ShelfID id) {
- if (!HasShelfIDToAppIDMapping(id))
- return NULL;
- return id_to_item_controller_map_[id];
-}
-
-bool ChromeLauncherController::IsBrowserFromActiveUser(Browser* browser) {
- // If running multi user mode with separate desktops, we have to check if the
- // browser is from the active user.
- if (chrome::MultiUserWindowManager::GetMultiProfileMode() !=
- chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED)
- return true;
- return multi_user_util::IsProfileFromActiveUser(browser->profile());
-}
-
-bool ChromeLauncherController::ShelfBoundsChangesProbablyWithUser(
- ash::Shelf* shelf,
- const std::string& user_id) const {
- Profile* other_profile = multi_user_util::GetProfileFromAccountId(
- AccountId::FromUserEmail(user_id));
- if (other_profile == profile_)
- return false;
-
- // Note: The Auto hide state from preferences is not the same as the actual
- // visibility of the shelf. Depending on all the various states (full screen,
- // no window on desktop, multi user, ..) the shelf could be shown - or not.
- PrefService* prefs = profile_->GetPrefs();
- PrefService* other_prefs = other_profile->GetPrefs();
- const int64_t display = GetDisplayIDForShelf(shelf);
- bool currently_shown = ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER ==
- ash::GetShelfAutoHideBehaviorPref(prefs, display);
- bool other_shown = ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER ==
- ash::GetShelfAutoHideBehaviorPref(other_prefs, display);
-
- return currently_shown != other_shown ||
- ash::GetShelfAlignmentPref(prefs, display) !=
- ash::GetShelfAlignmentPref(other_prefs, display);
-}
-
-void ChromeLauncherController::OnUserProfileReadyToSwitch(Profile* profile) {
- if (user_switch_observer_.get())
- user_switch_observer_->OnUserProfileReadyToSwitch(profile);
-}
-
-void ChromeLauncherController::LauncherItemClosed(ash::ShelfID id) {
- IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id);
- CHECK(iter != id_to_item_controller_map_.end());
- CHECK(iter->second);
- const std::string& app_id = iter->second->app_id();
- AppIconLoader* app_icon_loader = GetAppIconLoaderForApp(app_id);
- if (app_icon_loader)
- app_icon_loader->ClearImage(app_id);
- id_to_item_controller_map_.erase(iter);
- int index = model_->ItemIndexByID(id);
- // A "browser proxy" is not known to the model and this removal does
- // therefore not need to be propagated to the model.
- if (index != -1)
- model_->RemoveItemAt(index);
-}
-
-void ChromeLauncherController::DoPinAppWithID(const std::string& app_id) {
- // If there is an item, do nothing and return.
- if (IsAppPinned(app_id))
- return;
-
- ash::ShelfID shelf_id = GetShelfIDForAppID(app_id);
- if (shelf_id) {
- // App item exists, pin it
- Pin(shelf_id);
- } else {
- // Otherwise, create a shortcut item for it.
- shelf_id = CreateAppShortcutLauncherItem(app_id, model_->item_count());
- if (GetPinnable(app_id) == AppListControllerDelegate::PIN_EDITABLE)
- PersistPinnedState();
- }
-}
-
-void ChromeLauncherController::DoUnpinAppWithID(const std::string& app_id) {
- ash::ShelfID shelf_id = GetShelfIDForAppID(app_id);
- if (shelf_id && IsPinned(shelf_id))
- Unpin(shelf_id);
-}
-
-int ChromeLauncherController::PinRunningAppInternal(int index,
- ash::ShelfID shelf_id) {
- int running_index = model_->ItemIndexByID(shelf_id);
- ash::ShelfItem item = model_->items()[running_index];
- DCHECK(item.type == ash::TYPE_WINDOWED_APP ||
- item.type == ash::TYPE_PLATFORM_APP);
- item.type = ash::TYPE_APP_SHORTCUT;
- model_->Set(running_index, item);
- // The |ShelfModel|'s weight system might reposition the item to a
- // new index, so we get the index again.
- running_index = model_->ItemIndexByID(shelf_id);
- if (running_index < index)
- --index;
- if (running_index != index)
- model_->Move(running_index, index);
- return index;
-}
-
-void ChromeLauncherController::UnpinRunningAppInternal(int index) {
- DCHECK_GE(index, 0);
- ash::ShelfItem item = model_->items()[index];
- DCHECK_EQ(item.type, ash::TYPE_APP_SHORTCUT);
- item.type = ash::TYPE_WINDOWED_APP;
- // A platform app and a windowed app are sharing TYPE_APP_SHORTCUT. As such
- // we have to check here what this was before it got a shortcut.
- LauncherItemController* controller = GetLauncherItemController(item.id);
- if (controller && controller->type() == LauncherItemController::TYPE_APP)
- item.type = ash::TYPE_PLATFORM_APP;
- model_->Set(index, item);
-}
-
-void ChromeLauncherController::UpdateAppLaunchersFromPref() {
- // There are various functions which will trigger a |PersistPinnedState| call
- // like a direct call to |DoPinAppWithID|, or an indirect call to the menu
- // model which will use weights to re-arrange the icons to new positions.
- // Since this function is meant to synchronize the "is state" with the
- // "sync state", it makes no sense to store any changes by this function back
- // into the pref state. Therefore we tell |persistPinnedState| to ignore any
- // invocations while we are running.
- base::AutoReset<bool> auto_reset(&ignore_persist_pinned_state_change_, true);
- std::vector<std::string> pinned_apps = ash::GetPinnedAppsFromPrefs(
- profile_->GetPrefs(), launcher_controller_helper_.get());
-
- int index = 0;
- int max_index = model_->item_count();
-
- // When one of the two special items cannot be moved (and we do not know where
- // yet), we remember the current location in one of these variables.
- int chrome_index = -1;
- int app_list_index = -1;
-
- // Walk the model and |pinned_apps| from the pref lockstep, adding and
- // removing items as necessary. NB: This code uses plain old indexing instead
- // of iterators because of model mutations as part of the loop.
- std::vector<std::string>::const_iterator pref_app_id(pinned_apps.begin());
- for (; index < max_index && pref_app_id != pinned_apps.end(); ++index) {
- // Check if we have an item which we need to handle.
- if (*pref_app_id == extension_misc::kChromeAppId ||
- *pref_app_id == ash::kPinnedAppsPlaceholder ||
- IsAppPinned(*pref_app_id)) {
- for (; index < max_index; ++index) {
- const ash::ShelfItem& item(model_->items()[index]);
- bool is_app_list = item.type == ash::TYPE_APP_LIST;
- bool is_chrome = item.type == ash::TYPE_BROWSER_SHORTCUT;
- if (item.type != ash::TYPE_APP_SHORTCUT && !is_app_list && !is_chrome)
- continue;
- LauncherItemController* controller = GetLauncherItemController(item.id);
- if ((ash::kPinnedAppsPlaceholder == *pref_app_id && is_app_list) ||
- (extension_misc::kChromeAppId == *pref_app_id && is_chrome) ||
- (controller && controller->app_id() == *pref_app_id)) {
- // Check if an item needs to be moved here.
- MoveChromeOrApplistToFinalPosition(
- is_chrome, is_app_list, index, &chrome_index, &app_list_index);
- ++pref_app_id;
- break;
- } else {
- if (is_chrome || is_app_list) {
- // We cannot delete any of these shortcuts. As such we remember
- // their positions and move them later where they belong.
- if (is_chrome)
- chrome_index = index;
- else
- app_list_index = index;
- // And skip the item - or exit the loop if end is reached (note that
- // in that case we will reduce the index again by one and this only
- // compensates for it).
- if (index >= max_index - 1)
- break;
- ++index;
- } else {
- // Check if this is a platform or a windowed app.
- if (item.type == ash::TYPE_APP_SHORTCUT &&
- controller &&
- (controller->locked() ||
- controller->type() == LauncherItemController::TYPE_APP)) {
- // Note: This will not change the amount of items (|max_index|).
- // Even changes to the actual |index| due to item weighting
- // changes should be fine.
- UnpinRunningAppInternal(index);
- } else {
- if (controller)
- LauncherItemClosed(item.id);
- --max_index;
- }
- }
- --index;
- }
- }
- // If the item wasn't found, that means id_to_item_controller_map_
- // is out of sync.
- DCHECK(index <= max_index);
- } else {
- // Check if the item was already running but not yet pinned.
- ash::ShelfID shelf_id = GetShelfIDForAppID(*pref_app_id);
- if (shelf_id) {
- // This app is running but not yet pinned. So pin and move it.
- index = PinRunningAppInternal(index, shelf_id);
- } else {
- // This app wasn't pinned before, insert a new entry.
- shelf_id = CreateAppShortcutLauncherItem(*pref_app_id, index);
- ++max_index;
- index = model_->ItemIndexByID(shelf_id);
- }
- ++pref_app_id;
- }
- }
-
- // Remove any trailing existing items.
- while (index < model_->item_count()) {
- const ash::ShelfItem& item(model_->items()[index]);
- if (item.type == ash::TYPE_APP_SHORTCUT) {
- LauncherItemController* controller = GetLauncherItemController(item.id);
- if (controller) {
- if (controller->locked() ||
- controller->type() == LauncherItemController::TYPE_APP) {
- UnpinRunningAppInternal(index);
- } else {
- LauncherItemClosed(item.id);
- }
- }
- } else {
- if (item.type == ash::TYPE_BROWSER_SHORTCUT)
- chrome_index = index;
- else if (item.type == ash::TYPE_APP_LIST)
- app_list_index = index;
- ++index;
- }
- }
-
- // Append unprocessed items from the pref to the end of the model.
- for (; pref_app_id != pinned_apps.end(); ++pref_app_id) {
- // All items but the chrome and / or app list shortcut needs to be added.
- bool is_chrome = *pref_app_id == extension_misc::kChromeAppId;
- bool is_app_list = *pref_app_id == ash::kPinnedAppsPlaceholder;
- // Coming here we know the next item which can be finalized, either the
- // chrome item or the app launcher. The final position is the end of the
- // list. The menu model will make sure that the item is grouped according
- // to its weight (which we do not know here).
- if (!is_chrome && !is_app_list) {
- DoPinAppWithID(*pref_app_id);
- int target_index = FindInsertionPoint(false);
- ash::ShelfID id = GetShelfIDForAppID(*pref_app_id);
- int source_index = model_->ItemIndexByID(id);
- if (source_index != target_index)
- model_->Move(source_index, target_index);
-
- // Needed for the old layout - the weight might force it to be lower in
- // rank.
- if (app_list_index != -1 && target_index <= app_list_index)
- ++app_list_index;
- } else {
- int target_index = FindInsertionPoint(is_app_list);
- MoveChromeOrApplistToFinalPosition(
- is_chrome, is_app_list, target_index, &chrome_index, &app_list_index);
- }
- }
-}
-
-void ChromeLauncherController::SetShelfAutoHideBehaviorFromPrefs() {
- for (auto* window : ash::Shell::GetAllRootWindows()) {
- ash::Shelf* shelf = ash::Shelf::ForWindow(window);
- if (shelf) {
- shelf->SetAutoHideBehavior(ash::GetShelfAutoHideBehaviorPref(
- profile_->GetPrefs(), GetDisplayIDForShelf(shelf)));
- }
- }
-}
-
-void ChromeLauncherController::SetShelfAlignmentFromPrefs() {
- if (!ash::ShelfWidget::ShelfAlignmentAllowed())
- return;
-
- for (auto* window : ash::Shell::GetAllRootWindows()) {
- ash::Shelf* shelf = ash::Shelf::ForWindow(window);
- if (shelf) {
- shelf->SetAlignment(ash::GetShelfAlignmentPref(
- profile_->GetPrefs(), GetDisplayIDForShelf(shelf)));
- }
- }
-}
-
-void ChromeLauncherController::SetShelfBehaviorsFromPrefs() {
- SetShelfAutoHideBehaviorFromPrefs();
- SetShelfAlignmentFromPrefs();
-}
-
-void ChromeLauncherController::SetVirtualKeyboardBehaviorFromPrefs() {
- const PrefService* service = profile_->GetPrefs();
- const bool was_enabled = keyboard::IsKeyboardEnabled();
- if (!service->HasPrefPath(prefs::kTouchVirtualKeyboardEnabled)) {
- keyboard::SetKeyboardShowOverride(keyboard::KEYBOARD_SHOW_OVERRIDE_NONE);
- } else {
- const bool enable = service->GetBoolean(
- prefs::kTouchVirtualKeyboardEnabled);
- keyboard::SetKeyboardShowOverride(
- enable ? keyboard::KEYBOARD_SHOW_OVERRIDE_ENABLED
- : keyboard::KEYBOARD_SHOW_OVERRIDE_DISABLED);
- }
- const bool is_enabled = keyboard::IsKeyboardEnabled();
- if (was_enabled && !is_enabled)
- ash::Shell::GetInstance()->DeactivateKeyboard();
- else if (is_enabled && !was_enabled)
- ash::Shell::GetInstance()->CreateKeyboard();
-}
-
-ash::ShelfItemStatus ChromeLauncherController::GetAppState(
- const std::string& app_id) {
- ash::ShelfItemStatus status = ash::STATUS_CLOSED;
- for (WebContentsToAppIDMap::iterator it = web_contents_to_app_id_.begin();
- it != web_contents_to_app_id_.end();
- ++it) {
- if (it->second == app_id) {
- Browser* browser = chrome::FindBrowserWithWebContents(it->first);
- // Usually there should never be an item in our |web_contents_to_app_id_|
- // list which got deleted already. However - in some situations e.g.
- // Browser::SwapTabContent there is temporarily no associated browser.
- if (!browser)
- continue;
- if (browser->window()->IsActive()) {
- return browser->tab_strip_model()->GetActiveWebContents() == it->first ?
- ash::STATUS_ACTIVE : ash::STATUS_RUNNING;
- } else {
- status = ash::STATUS_RUNNING;
- }
- }
- }
- return status;
-}
-
-ash::ShelfID ChromeLauncherController::InsertAppLauncherItem(
- LauncherItemController* controller,
- const std::string& app_id,
- ash::ShelfItemStatus status,
- int index,
- ash::ShelfItemType shelf_item_type) {
- ash::ShelfID id = model_->next_id();
- CHECK(!HasShelfIDToAppIDMapping(id));
- CHECK(controller);
- id_to_item_controller_map_[id] = controller;
- controller->set_shelf_id(id);
-
- ash::ShelfItem item;
- item.type = shelf_item_type;
- item.image = extensions::util::GetDefaultAppIcon();
-
- ash::ShelfItemStatus new_state = GetAppState(app_id);
- if (new_state != ash::STATUS_CLOSED)
- status = new_state;
-
- item.status = status;
-
- model_->AddAt(index, item);
-
- AppIconLoader* app_icon_loader = GetAppIconLoaderForApp(app_id);
- if (app_icon_loader) {
- app_icon_loader->FetchImage(app_id);
- app_icon_loader->UpdateImage(app_id);
- }
-
- SetShelfItemDelegate(id, controller);
-
- return id;
-}
-
-std::vector<content::WebContents*>
-ChromeLauncherController::GetV1ApplicationsFromController(
- LauncherItemController* controller) {
- DCHECK(controller->type() == LauncherItemController::TYPE_SHORTCUT);
- AppShortcutLauncherItemController* app_controller =
- static_cast<AppShortcutLauncherItemController*>(controller);
- return app_controller->GetRunningApplications();
-}
-
-BrowserShortcutLauncherItemController*
-ChromeLauncherController::GetBrowserShortcutLauncherItemController() {
- for (IDToItemControllerMap::iterator i = id_to_item_controller_map_.begin();
- i != id_to_item_controller_map_.end(); ++i) {
- int index = model_->ItemIndexByID(i->first);
- const ash::ShelfItem& item = model_->items()[index];
- if (item.type == ash::TYPE_BROWSER_SHORTCUT)
- return static_cast<BrowserShortcutLauncherItemController*>(i->second);
- }
- NOTREACHED()
- << "There should be always be a BrowserShortcutLauncherItemController.";
- return nullptr;
-}
-
-ash::ShelfID ChromeLauncherController::CreateBrowserShortcutLauncherItem() {
- ash::ShelfItem browser_shortcut;
- browser_shortcut.type = ash::TYPE_BROWSER_SHORTCUT;
- ResourceBundle& rb = ResourceBundle::GetSharedInstance();
- browser_shortcut.image = *rb.GetImageSkiaNamed(IDR_PRODUCT_LOGO_32);
- ash::ShelfID id = model_->next_id();
- size_t index = GetChromeIconIndexForCreation();
- model_->AddAt(index, browser_shortcut);
- id_to_item_controller_map_[id] =
- new BrowserShortcutLauncherItemController(this, model_);
- id_to_item_controller_map_[id]->set_shelf_id(id);
- // ShelfItemDelegateManager owns BrowserShortcutLauncherItemController.
- SetShelfItemDelegate(id, id_to_item_controller_map_[id]);
- return id;
-}
-
-void ChromeLauncherController::PersistChromeItemIndex(int index) {
- profile_->GetPrefs()->SetInteger(prefs::kShelfChromeIconIndex, index);
-}
-
-void ChromeLauncherController::MoveChromeOrApplistToFinalPosition(
- bool is_chrome,
- bool is_app_list,
- int target_index,
- int* chrome_index,
- int* app_list_index) {
- if (is_chrome && *chrome_index != -1) {
- model_->Move(*chrome_index, target_index);
- if (*app_list_index != -1 &&
- *chrome_index < *app_list_index &&
- target_index > *app_list_index)
- --(*app_list_index);
- *chrome_index = -1;
- } else if (is_app_list && *app_list_index != -1) {
- model_->Move(*app_list_index, target_index);
- if (*chrome_index != -1 &&
- *app_list_index < *chrome_index &&
- target_index > *chrome_index)
- --(*chrome_index);
- *app_list_index = -1;
- }
-}
-
-int ChromeLauncherController::FindInsertionPoint(bool is_app_list) {
- // Keeping this change small to backport to M33&32 (see crbug.com/329597).
- // TODO(skuhne): With the removal of the legacy shelf layout we should remove
- // the ability to move the app list item since this was never used. We should
- // instead ask the ShelfModel::ValidateInsertionIndex or similir for an index.
- if (is_app_list)
- return 0;
-
- for (int i = model_->item_count() - 1; i > 0; --i) {
- ash::ShelfItemType type = model_->items()[i].type;
- if (type == ash::TYPE_APP_SHORTCUT ||
- (is_app_list && type == ash::TYPE_APP_LIST) ||
- type == ash::TYPE_BROWSER_SHORTCUT) {
- return i;
- }
- }
- return 0;
-}
-
-int ChromeLauncherController::GetChromeIconIndexForCreation() {
- // We get the list of pinned apps as they currently would get pinned.
- // Within this list the chrome icon will be the correct location.
- std::vector<std::string> pinned_apps = ash::GetPinnedAppsFromPrefs(
- profile_->GetPrefs(), launcher_controller_helper_.get());
-
- std::vector<std::string>::iterator it =
- std::find(pinned_apps.begin(),
- pinned_apps.end(),
- std::string(extension_misc::kChromeAppId));
- DCHECK(it != pinned_apps.end());
- int index = it - pinned_apps.begin();
-
- // We should do here a comparison between the is state and the "want to be"
- // state since some apps might be able to pin but are not yet. Instead - for
- // the time being we clamp against the amount of known items and wait for the
- // next |UpdateAppLaunchersFromPref()| call to correct it - it will come since
- // the pinning will be done then.
- return std::min(model_->item_count(), index);
-}
-
-bool ChromeLauncherController::IsIncognito(
- const content::WebContents* web_contents) const {
- const Profile* profile =
- Profile::FromBrowserContext(web_contents->GetBrowserContext());
- return profile->IsOffTheRecord() && !profile->IsGuestSession() &&
- !profile->IsSystemProfile();
-}
-
-void ChromeLauncherController::CloseWindowedAppsFromRemovedExtension(
- const std::string& app_id,
- const Profile* profile) {
- // This function cannot rely on the controller's enumeration functionality
- // since the extension has already be unloaded.
- const BrowserList* browser_list = BrowserList::GetInstance();
- std::vector<Browser*> browser_to_close;
- for (BrowserList::const_reverse_iterator it =
- browser_list->begin_last_active();
- it != browser_list->end_last_active(); ++it) {
- Browser* browser = *it;
- if (!browser->is_type_tabbed() && browser->is_type_popup() &&
- browser->is_app() &&
- app_id ==
- web_app::GetExtensionIdFromApplicationName(browser->app_name()) &&
- profile == browser->profile()) {
- browser_to_close.push_back(browser);
- }
- }
- while (!browser_to_close.empty()) {
- TabStripModel* tab_strip = browser_to_close.back()->tab_strip_model();
- tab_strip->CloseWebContentsAt(0, TabStripModel::CLOSE_NONE);
- browser_to_close.pop_back();
- }
-}
-
-void ChromeLauncherController::SetShelfItemDelegate(
- ash::ShelfID id,
- ash::ShelfItemDelegate* item_delegate) {
- DCHECK_GT(id, 0);
- DCHECK(item_delegate);
- DCHECK(item_delegate_manager_);
- item_delegate_manager_->SetShelfItemDelegate(
- id, std::unique_ptr<ash::ShelfItemDelegate>(item_delegate));
-}
-
-void ChromeLauncherController::AttachProfile(Profile* profile) {
- profile_ = profile;
- // Either add the profile to the list of known profiles and make it the active
- // one for some functions of LauncherControllerHelper or create a new one.
- if (!launcher_controller_helper_.get())
- launcher_controller_helper_.reset(new LauncherControllerHelper(profile_));
- else
- launcher_controller_helper_->SetCurrentUser(profile_);
- // TODO(skuhne): The AppIconLoaderImpl has the same problem. Each loaded
- // image is associated with a profile (its loader requires the profile).
- // Since icon size changes are possible, the icon could be requested to be
- // reloaded. However - having it not multi profile aware would cause problems
- // if the icon cache gets deleted upon user switch.
- std::unique_ptr<AppIconLoader> extension_app_icon_loader(
- new extensions::ExtensionAppIconLoader(
- profile_, extension_misc::EXTENSION_ICON_SMALL, this));
- app_icon_loaders_.push_back(std::move(extension_app_icon_loader));
-
- if (arc::ArcAuthService::IsAllowedForProfile(profile_)) {
- DCHECK(arc_deferred_launcher());
- std::unique_ptr<AppIconLoader> arc_app_icon_loader(
- new ArcAppIconLoader(profile_, extension_misc::EXTENSION_ICON_SMALL,
- arc_deferred_launcher(), this));
- app_icon_loaders_.push_back(std::move(arc_app_icon_loader));
- }
-
- pref_change_registrar_.Init(profile_->GetPrefs());
- pref_change_registrar_.Add(
- prefs::kPinnedLauncherApps,
- base::Bind(&ChromeLauncherController::UpdateAppLaunchersFromPref,
- base::Unretained(this)));
- pref_change_registrar_.Add(
- prefs::kPolicyPinnedLauncherApps,
- base::Bind(&ChromeLauncherController::UpdateAppLaunchersFromPref,
- base::Unretained(this)));
- pref_change_registrar_.Add(
- prefs::kShelfAlignmentLocal,
- base::Bind(&ChromeLauncherController::SetShelfAlignmentFromPrefs,
- base::Unretained(this)));
- pref_change_registrar_.Add(
- prefs::kShelfAutoHideBehaviorLocal,
- base::Bind(&ChromeLauncherController::
- SetShelfAutoHideBehaviorFromPrefs,
- base::Unretained(this)));
- pref_change_registrar_.Add(
- prefs::kShelfPreferences,
- base::Bind(&ChromeLauncherController::SetShelfBehaviorsFromPrefs,
- base::Unretained(this)));
- pref_change_registrar_.Add(
- prefs::kTouchVirtualKeyboardEnabled,
- base::Bind(&ChromeLauncherController::SetVirtualKeyboardBehaviorFromPrefs,
- base::Unretained(this)));
-
- std::unique_ptr<LauncherAppUpdater> extension_app_updater(
- new LauncherExtensionAppUpdater(this, profile_));
- app_updaters_.push_back(std::move(extension_app_updater));
-
- if (arc::ArcAuthService::IsAllowedForProfile(profile_)) {
- std::unique_ptr<LauncherAppUpdater> arc_app_updater(
- new LauncherArcAppUpdater(this, profile_));
- app_updaters_.push_back(std::move(arc_app_updater));
- }
-}
-
-void ChromeLauncherController::ReleaseProfile() {
- if (app_sync_ui_state_)
- app_sync_ui_state_->RemoveObserver(this);
-
- app_updaters_.clear();
-
- prefs_observer_.reset();
-
- pref_change_registrar_.RemoveAll();
-}
-
-AppIconLoader* ChromeLauncherController::GetAppIconLoaderForApp(
- const std::string& app_id) {
- for (const auto& app_icon_loader : app_icon_loaders_) {
- if (app_icon_loader->CanLoadImageForApp(app_id))
- return app_icon_loader.get();
- }
-
- return nullptr;
-}
+ChromeLauncherController::ChromeLauncherController() {}

Powered by Google App Engine
This is Rietveld 408576698