| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl.h" | 5 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 #include "ash/wm/window_util.h" | 21 #include "ash/wm/window_util.h" |
| 22 #include "base/command_line.h" | 22 #include "base/command_line.h" |
| 23 #include "base/macros.h" | 23 #include "base/macros.h" |
| 24 #include "base/strings/pattern.h" | 24 #include "base/strings/pattern.h" |
| 25 #include "base/strings/string_util.h" | 25 #include "base/strings/string_util.h" |
| 26 #include "base/strings/utf_string_conversions.h" | 26 #include "base/strings/utf_string_conversions.h" |
| 27 #include "base/values.h" | 27 #include "base/values.h" |
| 28 #include "build/build_config.h" | 28 #include "build/build_config.h" |
| 29 #include "chrome/browser/browser_process.h" | 29 #include "chrome/browser/browser_process.h" |
| 30 #include "chrome/browser/chrome_notification_types.h" | 30 #include "chrome/browser/chrome_notification_types.h" |
| 31 #include "chrome/browser/chromeos/arc/arc_support_host.h" | |
| 32 #include "chrome/browser/defaults.h" | 31 #include "chrome/browser/defaults.h" |
| 33 #include "chrome/browser/extensions/extension_app_icon_loader.h" | 32 #include "chrome/browser/extensions/extension_app_icon_loader.h" |
| 34 #include "chrome/browser/extensions/extension_util.h" | 33 #include "chrome/browser/extensions/extension_util.h" |
| 35 #include "chrome/browser/extensions/launch_util.h" | 34 #include "chrome/browser/extensions/launch_util.h" |
| 36 #include "chrome/browser/prefs/incognito_mode_prefs.h" | 35 #include "chrome/browser/prefs/incognito_mode_prefs.h" |
| 37 #include "chrome/browser/profiles/profile.h" | 36 #include "chrome/browser/profiles/profile.h" |
| 38 #include "chrome/browser/profiles/profile_manager.h" | 37 #include "chrome/browser/profiles/profile_manager.h" |
| 38 #include "chrome/browser/ui/app_list/app_list_syncable_service_factory.h" |
| 39 #include "chrome/browser/ui/app_list/arc/arc_app_icon_loader.h" | 39 #include "chrome/browser/ui/app_list/arc/arc_app_icon_loader.h" |
| 40 #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" | 40 #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" |
| 41 #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" | 41 #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" |
| 42 #include "chrome/browser/ui/ash/app_sync_ui_state.h" | 42 #include "chrome/browser/ui/ash/app_sync_ui_state.h" |
| 43 #include "chrome/browser/ui/ash/chrome_launcher_prefs.h" | 43 #include "chrome/browser/ui/ash/chrome_launcher_prefs.h" |
| 44 #include "chrome/browser/ui/ash/chrome_shell_delegate.h" | 44 #include "chrome/browser/ui/ash/chrome_shell_delegate.h" |
| 45 #include "chrome/browser/ui/ash/launcher/app_shortcut_launcher_item_controller.h
" | 45 #include "chrome/browser/ui/ash/launcher/app_shortcut_launcher_item_controller.h
" |
| 46 #include "chrome/browser/ui/ash/launcher/app_window_launcher_controller.h" | 46 #include "chrome/browser/ui/ash/launcher/app_window_launcher_controller.h" |
| 47 #include "chrome/browser/ui/ash/launcher/app_window_launcher_item_controller.h" | 47 #include "chrome/browser/ui/ash/launcher/app_window_launcher_item_controller.h" |
| 48 #include "chrome/browser/ui/ash/launcher/arc_app_deferred_launcher_controller.h" | 48 #include "chrome/browser/ui/ash/launcher/arc_app_deferred_launcher_controller.h" |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 109 | 109 |
| 110 int64_t GetDisplayIDForShelf(ash::Shelf* shelf) { | 110 int64_t GetDisplayIDForShelf(ash::Shelf* shelf) { |
| 111 aura::Window* root_window = | 111 aura::Window* root_window = |
| 112 shelf->shelf_widget()->GetNativeWindow()->GetRootWindow(); | 112 shelf->shelf_widget()->GetNativeWindow()->GetRootWindow(); |
| 113 display::Display display = | 113 display::Display display = |
| 114 display::Screen::GetScreen()->GetDisplayNearestWindow(root_window); | 114 display::Screen::GetScreen()->GetDisplayNearestWindow(root_window); |
| 115 DCHECK(display.is_valid()); | 115 DCHECK(display.is_valid()); |
| 116 return display.id(); | 116 return display.id(); |
| 117 } | 117 } |
| 118 | 118 |
| 119 /* | |
| 120 * Return whether an app is pinned only by user. | |
| 121 * This function doesn't expect an app_id neither pinned by user nor by | |
| 122 * policy, the app_id in the arguments list MUST be pinned by either of | |
| 123 * those. Invalid input may lead to unexpected result. | |
| 124 * If this app is pinned by policy, but not by user, false is returned. | |
| 125 * If this app is pinned by both policy and user, false is returned. | |
| 126 * If this app is pinned not by policy, but by user, true is returned. | |
| 127 */ | |
| 128 bool IsAppForUserPinned(const std::string& app_id, | |
| 129 const base::ListValue* pinned_apps_pref, | |
| 130 const base::ListValue* policy_pinned_apps_pref) { | |
| 131 for (size_t index = 0; index < pinned_apps_pref->GetSize(); ++index) { | |
| 132 const base::DictionaryValue* app; | |
| 133 if (pinned_apps_pref->GetDictionary(index, &app)) { | |
| 134 std::string current_app_id; | |
| 135 bool pinned_by_policy = false; | |
| 136 if (app->GetString(ash::kPinnedAppsPrefAppIDPath, ¤t_app_id)) { | |
| 137 if (app_id == current_app_id) { | |
| 138 if (app->GetBoolean(ash::kPinnedAppsPrefPinnedByPolicy, | |
| 139 &pinned_by_policy) && | |
| 140 pinned_by_policy) { | |
| 141 // Pinned by policy in the past or present. | |
| 142 // Need to check policy_pinned_apps to determine | |
| 143 break; | |
| 144 } else { | |
| 145 // User Preference Already Pinned | |
| 146 return true; | |
| 147 } | |
| 148 } | |
| 149 } | |
| 150 } | |
| 151 } | |
| 152 for (size_t index = 0; index < policy_pinned_apps_pref->GetSize(); ++index) { | |
| 153 const base::DictionaryValue* app; | |
| 154 if (policy_pinned_apps_pref->GetDictionary(index, &app)) { | |
| 155 std::string app_id_; | |
| 156 if (app->GetString(ash::kPinnedAppsPrefAppIDPath, &app_id_)) { | |
| 157 // Only pinned by policy, which is not part of user-pinned | |
| 158 if (app_id == app_id_) | |
| 159 return false; | |
| 160 } | |
| 161 } | |
| 162 } | |
| 163 // Default, user added new pins | |
| 164 return true; | |
| 165 } | |
| 166 | |
| 167 const char* const kPinProhibitedExtensionIds[] = { | |
| 168 ArcSupportHost::kHostAppId, arc::kPlayStoreAppId, | |
| 169 }; | |
| 170 | |
| 171 const size_t kPinProhibitedExtensionIdsLength = | |
| 172 arraysize(kPinProhibitedExtensionIds); | |
| 173 | |
| 174 } // namespace | 119 } // namespace |
| 175 | 120 |
| 176 // A class to get events from ChromeOS when a user gets changed or added. | 121 // A class to get events from ChromeOS when a user gets changed or added. |
| 177 class ChromeLauncherControllerUserSwitchObserver | 122 class ChromeLauncherControllerUserSwitchObserver |
| 178 : public user_manager::UserManager::UserSessionStateObserver { | 123 : public user_manager::UserManager::UserSessionStateObserver { |
| 179 public: | 124 public: |
| 180 ChromeLauncherControllerUserSwitchObserver( | 125 ChromeLauncherControllerUserSwitchObserver( |
| 181 ChromeLauncherControllerImpl* controller) | 126 ChromeLauncherControllerImpl* controller) |
| 182 : controller_(controller) { | 127 : controller_(controller) { |
| 183 DCHECK(user_manager::UserManager::IsInitialized()); | 128 DCHECK(user_manager::UserManager::IsInitialized()); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 void ChromeLauncherControllerUserSwitchObserver::AddUser(Profile* profile) { | 183 void ChromeLauncherControllerUserSwitchObserver::AddUser(Profile* profile) { |
| 239 if (chrome::MultiUserWindowManager::GetMultiProfileMode() == | 184 if (chrome::MultiUserWindowManager::GetMultiProfileMode() == |
| 240 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED) | 185 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED) |
| 241 chrome::MultiUserWindowManager::GetInstance()->AddUser(profile); | 186 chrome::MultiUserWindowManager::GetInstance()->AddUser(profile); |
| 242 controller_->AdditionalUserAddedToSession(profile->GetOriginalProfile()); | 187 controller_->AdditionalUserAddedToSession(profile->GetOriginalProfile()); |
| 243 } | 188 } |
| 244 | 189 |
| 245 ChromeLauncherControllerImpl::ChromeLauncherControllerImpl( | 190 ChromeLauncherControllerImpl::ChromeLauncherControllerImpl( |
| 246 Profile* profile, | 191 Profile* profile, |
| 247 ash::ShelfModel* model) | 192 ash::ShelfModel* model) |
| 248 : model_(model), | 193 : model_(model), profile_(profile) { |
| 249 item_delegate_manager_(NULL), | |
| 250 profile_(profile), | |
| 251 app_sync_ui_state_(NULL), | |
| 252 ignore_persist_pinned_state_change_(false) { | |
| 253 if (!profile_) { | 194 if (!profile_) { |
| 254 // If no profile was passed, we take the currently active profile and use it | 195 // If no profile was passed, we take the currently active profile and use it |
| 255 // as the owner of the current desktop. | 196 // as the owner of the current desktop. |
| 256 // Use the original profile as on chromeos we may get a temporary off the | 197 // Use the original profile as on chromeos we may get a temporary off the |
| 257 // record profile, unless in guest session (where off the record profile is | 198 // record profile, unless in guest session (where off the record profile is |
| 258 // the right one). | 199 // the right one). |
| 259 profile_ = ProfileManager::GetActiveUserProfile(); | 200 profile_ = ProfileManager::GetActiveUserProfile(); |
| 260 if (!profile_->IsGuestSession() && !profile_->IsSystemProfile()) | 201 if (!profile_->IsGuestSession() && !profile_->IsSystemProfile()) |
| 261 profile_ = profile_->GetOriginalProfile(); | 202 profile_ = profile_->GetOriginalProfile(); |
| 262 | 203 |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 368 | 309 |
| 369 void ChromeLauncherControllerImpl::Init() { | 310 void ChromeLauncherControllerImpl::Init() { |
| 370 CreateBrowserShortcutLauncherItem(); | 311 CreateBrowserShortcutLauncherItem(); |
| 371 UpdateAppLaunchersFromPref(); | 312 UpdateAppLaunchersFromPref(); |
| 372 | 313 |
| 373 // TODO(sky): update unit test so that this test isn't necessary. | 314 // TODO(sky): update unit test so that this test isn't necessary. |
| 374 if (ash::Shell::HasInstance()) | 315 if (ash::Shell::HasInstance()) |
| 375 SetVirtualKeyboardBehaviorFromPrefs(); | 316 SetVirtualKeyboardBehaviorFromPrefs(); |
| 376 | 317 |
| 377 prefs_observer_ = | 318 prefs_observer_ = |
| 378 ash::ChromeLauncherPrefsObserver::CreateIfNecessary(profile_); | 319 ash::launcher::ChromeLauncherPrefsObserver::CreateIfNecessary(profile_); |
| 379 } | 320 } |
| 380 | 321 |
| 381 ash::ShelfID ChromeLauncherControllerImpl::CreateAppLauncherItem( | 322 ash::ShelfID ChromeLauncherControllerImpl::CreateAppLauncherItem( |
| 382 LauncherItemController* controller, | 323 LauncherItemController* controller, |
| 383 const std::string& app_id, | 324 const std::string& app_id, |
| 384 ash::ShelfItemStatus status) { | 325 ash::ShelfItemStatus status) { |
| 385 CHECK(controller); | 326 CHECK(controller); |
| 386 int index = 0; | 327 int index = 0; |
| 387 // Panels are inserted on the left so as not to push all existing panels over. | 328 // Panels are inserted on the left so as not to push all existing panels over. |
| 388 if (controller->GetShelfItemType() != ash::TYPE_APP_PANEL) | 329 if (controller->GetShelfItemType() != ash::TYPE_APP_PANEL) |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 442 ash::ShelfItem item = model_->items()[index]; | 383 ash::ShelfItem item = model_->items()[index]; |
| 443 | 384 |
| 444 if (item.type == ash::TYPE_PLATFORM_APP || | 385 if (item.type == ash::TYPE_PLATFORM_APP || |
| 445 item.type == ash::TYPE_WINDOWED_APP) { | 386 item.type == ash::TYPE_WINDOWED_APP) { |
| 446 item.type = ash::TYPE_APP_SHORTCUT; | 387 item.type = ash::TYPE_APP_SHORTCUT; |
| 447 model_->Set(index, item); | 388 model_->Set(index, item); |
| 448 } else if (item.type != ash::TYPE_APP_SHORTCUT) { | 389 } else if (item.type != ash::TYPE_APP_SHORTCUT) { |
| 449 return; | 390 return; |
| 450 } | 391 } |
| 451 | 392 |
| 452 if (GetLauncherItemController(id)->CanPin()) | 393 SyncPinPosition(id); |
| 453 PersistPinnedState(); | |
| 454 } | 394 } |
| 455 | 395 |
| 456 void ChromeLauncherControllerImpl::Unpin(ash::ShelfID id) { | 396 void ChromeLauncherControllerImpl::Unpin(ash::ShelfID id) { |
| 457 LauncherItemController* controller = GetLauncherItemController(id); | 397 LauncherItemController* controller = GetLauncherItemController(id); |
| 458 CHECK(controller); | 398 CHECK(controller); |
| 459 const bool can_pin = controller->CanPin(); | 399 |
| 400 ash::launcher::RemovePinPosition(profile_, GetAppIDForShelfID(id)); |
| 460 | 401 |
| 461 if (controller->type() == LauncherItemController::TYPE_APP || | 402 if (controller->type() == LauncherItemController::TYPE_APP || |
| 462 controller->locked()) { | 403 controller->locked()) { |
| 463 UnpinRunningAppInternal(model_->ItemIndexByID(id)); | 404 UnpinRunningAppInternal(model_->ItemIndexByID(id)); |
| 464 } else { | 405 } else { |
| 465 LauncherItemClosed(id); | 406 LauncherItemClosed(id); |
| 466 } | 407 } |
| 467 if (can_pin) | |
| 468 PersistPinnedState(); | |
| 469 } | 408 } |
| 470 | 409 |
| 471 bool ChromeLauncherControllerImpl::IsPinned(ash::ShelfID id) { | 410 bool ChromeLauncherControllerImpl::IsPinned(ash::ShelfID id) { |
| 472 int index = model_->ItemIndexByID(id); | 411 int index = model_->ItemIndexByID(id); |
| 473 if (index < 0) | 412 if (index < 0) |
| 474 return false; | 413 return false; |
| 475 ash::ShelfItemType type = model_->items()[index].type; | 414 ash::ShelfItemType type = model_->items()[index].type; |
| 476 return (type == ash::TYPE_APP_SHORTCUT || type == ash::TYPE_BROWSER_SHORTCUT); | 415 return (type == ash::TYPE_APP_SHORTCUT || type == ash::TYPE_BROWSER_SHORTCUT); |
| 477 } | 416 } |
| 478 | 417 |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 615 void ChromeLauncherControllerImpl::SetLaunchType( | 554 void ChromeLauncherControllerImpl::SetLaunchType( |
| 616 ash::ShelfID id, | 555 ash::ShelfID id, |
| 617 extensions::LaunchType launch_type) { | 556 extensions::LaunchType launch_type) { |
| 618 LauncherItemController* controller = GetLauncherItemController(id); | 557 LauncherItemController* controller = GetLauncherItemController(id); |
| 619 if (!controller) | 558 if (!controller) |
| 620 return; | 559 return; |
| 621 | 560 |
| 622 extensions::SetLaunchType(profile_, controller->app_id(), launch_type); | 561 extensions::SetLaunchType(profile_, controller->app_id(), launch_type); |
| 623 } | 562 } |
| 624 | 563 |
| 625 void ChromeLauncherControllerImpl::PersistPinnedState() { | |
| 626 if (ignore_persist_pinned_state_change_) | |
| 627 return; | |
| 628 // It is a coding error to call PersistPinnedState() if the pinned apps are | |
| 629 // not user-editable. The code should check earlier and not perform any | |
| 630 // modification actions that trigger persisting the state. | |
| 631 // Mutating kPinnedLauncherApps is going to notify us and trigger us to | |
| 632 // process the change. We don't want that to happen so remove ourselves as a | |
| 633 // listener. | |
| 634 pref_change_registrar_.Remove(prefs::kPinnedLauncherApps); | |
| 635 { | |
| 636 std::unique_ptr<const base::ListValue> pinned_apps_pref = | |
| 637 profile_->GetPrefs() | |
| 638 ->GetList(prefs::kPinnedLauncherApps) | |
| 639 ->CreateDeepCopy(); | |
| 640 | |
| 641 const base::ListValue* policy_pinned_apps_pref = | |
| 642 profile_->GetPrefs()->GetList(prefs::kPolicyPinnedLauncherApps); | |
| 643 | |
| 644 ListPrefUpdate updater(profile_->GetPrefs(), prefs::kPinnedLauncherApps); | |
| 645 updater->Clear(); | |
| 646 for (size_t i = 0; i < model_->items().size(); ++i) { | |
| 647 if (model_->items()[i].type == ash::TYPE_APP_SHORTCUT) { | |
| 648 ash::ShelfID id = model_->items()[i].id; | |
| 649 LauncherItemController* controller = GetLauncherItemController(id); | |
| 650 // Don't persist pinning state for apps that are handled internally and | |
| 651 // have pinnable state AppListControllerDelegate::NO_PIN. | |
| 652 if (controller && IsPinned(id) && | |
| 653 GetPinnable(controller->app_id()) != | |
| 654 AppListControllerDelegate::NO_PIN) { | |
| 655 base::DictionaryValue* app_value = | |
| 656 ash::CreateAppDict(controller->app_id()); | |
| 657 if (app_value) { | |
| 658 if (!IsAppForUserPinned(controller->app_id(), | |
| 659 pinned_apps_pref.get(), | |
| 660 policy_pinned_apps_pref)) | |
| 661 app_value->SetBoolean(ash::kPinnedAppsPrefPinnedByPolicy, true); | |
| 662 updater->Append(app_value); | |
| 663 } | |
| 664 } | |
| 665 } else if (model_->items()[i].type == ash::TYPE_BROWSER_SHORTCUT) { | |
| 666 PersistChromeItemIndex(i); | |
| 667 } else if (model_->items()[i].type == ash::TYPE_APP_LIST) { | |
| 668 base::DictionaryValue* app_value = | |
| 669 ash::CreateAppDict(ash::kPinnedAppsPlaceholder); | |
| 670 if (app_value) | |
| 671 updater->Append(app_value); | |
| 672 } | |
| 673 } | |
| 674 } | |
| 675 pref_change_registrar_.Add( | |
| 676 prefs::kPinnedLauncherApps, | |
| 677 base::Bind(&ChromeLauncherControllerImpl::UpdateAppLaunchersFromPref, | |
| 678 base::Unretained(this))); | |
| 679 } | |
| 680 | |
| 681 Profile* ChromeLauncherControllerImpl::GetProfile() { | 564 Profile* ChromeLauncherControllerImpl::GetProfile() { |
| 682 return profile_; | 565 return profile_; |
| 683 } | 566 } |
| 684 | 567 |
| 685 void ChromeLauncherControllerImpl::UpdateAppState( | 568 void ChromeLauncherControllerImpl::UpdateAppState( |
| 686 content::WebContents* contents, | 569 content::WebContents* contents, |
| 687 AppState app_state) { | 570 AppState app_state) { |
| 688 std::string app_id = launcher_controller_helper_->GetAppID(contents); | 571 std::string app_id = launcher_controller_helper_->GetAppID(contents); |
| 689 | 572 |
| 690 // Check if the gMail app is loaded and it matches the given content. | 573 // Check if the gMail app is loaded and it matches the given content. |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 970 AccountId::FromUserEmail(user_id)); | 853 AccountId::FromUserEmail(user_id)); |
| 971 if (other_profile == profile_) | 854 if (other_profile == profile_) |
| 972 return false; | 855 return false; |
| 973 | 856 |
| 974 // Note: The Auto hide state from preferences is not the same as the actual | 857 // Note: The Auto hide state from preferences is not the same as the actual |
| 975 // visibility of the shelf. Depending on all the various states (full screen, | 858 // visibility of the shelf. Depending on all the various states (full screen, |
| 976 // no window on desktop, multi user, ..) the shelf could be shown - or not. | 859 // no window on desktop, multi user, ..) the shelf could be shown - or not. |
| 977 PrefService* prefs = profile_->GetPrefs(); | 860 PrefService* prefs = profile_->GetPrefs(); |
| 978 PrefService* other_prefs = other_profile->GetPrefs(); | 861 PrefService* other_prefs = other_profile->GetPrefs(); |
| 979 const int64_t display = GetDisplayIDForShelf(shelf); | 862 const int64_t display = GetDisplayIDForShelf(shelf); |
| 980 bool currently_shown = ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER == | 863 const bool currently_shown = |
| 981 ash::GetShelfAutoHideBehaviorPref(prefs, display); | 864 ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER == |
| 982 bool other_shown = ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER == | 865 ash::launcher::GetShelfAutoHideBehaviorPref(prefs, display); |
| 983 ash::GetShelfAutoHideBehaviorPref(other_prefs, display); | 866 const bool other_shown = |
| 867 ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER == |
| 868 ash::launcher::GetShelfAutoHideBehaviorPref(other_prefs, display); |
| 984 | 869 |
| 985 return currently_shown != other_shown || | 870 return currently_shown != other_shown || |
| 986 ash::GetShelfAlignmentPref(prefs, display) != | 871 ash::launcher::GetShelfAlignmentPref(prefs, display) != |
| 987 ash::GetShelfAlignmentPref(other_prefs, display); | 872 ash::launcher::GetShelfAlignmentPref(other_prefs, display); |
| 988 } | 873 } |
| 989 | 874 |
| 990 void ChromeLauncherControllerImpl::OnUserProfileReadyToSwitch( | 875 void ChromeLauncherControllerImpl::OnUserProfileReadyToSwitch( |
| 991 Profile* profile) { | 876 Profile* profile) { |
| 992 if (user_switch_observer_.get()) | 877 if (user_switch_observer_.get()) |
| 993 user_switch_observer_->OnUserProfileReadyToSwitch(profile); | 878 user_switch_observer_->OnUserProfileReadyToSwitch(profile); |
| 994 } | 879 } |
| 995 | 880 |
| 996 AppListControllerDelegate::Pinnable ChromeLauncherControllerImpl::GetPinnable( | 881 AppListControllerDelegate::Pinnable ChromeLauncherControllerImpl::GetPinnable( |
| 997 const std::string& app_id) { | 882 const std::string& app_id) { |
| 998 for (size_t i = 0; i < kPinProhibitedExtensionIdsLength; ++i) { | |
| 999 if (kPinProhibitedExtensionIds[i] == app_id) | |
| 1000 return AppListControllerDelegate::NO_PIN; | |
| 1001 } | |
| 1002 | |
| 1003 const base::ListValue* pref = | 883 const base::ListValue* pref = |
| 1004 profile_->GetPrefs()->GetList(prefs::kPolicyPinnedLauncherApps); | 884 profile_->GetPrefs()->GetList(prefs::kPolicyPinnedLauncherApps); |
| 1005 if (!pref) | 885 if (!pref) |
| 1006 return AppListControllerDelegate::PIN_EDITABLE; | 886 return AppListControllerDelegate::PIN_EDITABLE; |
| 1007 | 887 |
| 1008 // Pinned ARC apps policy defines the package name of the apps, that must | 888 // Pinned ARC apps policy defines the package name of the apps, that must |
| 1009 // be pinned. All the launch activities of any package in policy are pinned. | 889 // be pinned. All the launch activities of any package in policy are pinned. |
| 1010 // In turn the input parameter to this function is app_id, which | 890 // In turn the input parameter to this function is app_id, which |
| 1011 // is 32 chars hash. In case of ARC app this is a hash of | 891 // is 32 chars hash. In case of ARC app this is a hash of |
| 1012 // (package name + activity). This means that we must identify the package | 892 // (package name + activity). This means that we must identify the package |
| 1013 // from the hash, and check if this package is pinned by policy. | 893 // from the hash, and check if this package is pinned by policy. |
| 1014 const ArcAppListPrefs* const arc_prefs = ArcAppListPrefs::Get(GetProfile()); | 894 const ArcAppListPrefs* const arc_prefs = ArcAppListPrefs::Get(GetProfile()); |
| 1015 std::string arc_app_packege_name; | 895 std::string arc_app_packege_name; |
| 1016 if (arc_prefs) { | 896 if (arc_prefs) { |
| 1017 std::unique_ptr<ArcAppListPrefs::AppInfo> app_info = | 897 std::unique_ptr<ArcAppListPrefs::AppInfo> app_info = |
| 1018 arc_prefs->GetApp(app_id); | 898 arc_prefs->GetApp(app_id); |
| 1019 if (app_info) | 899 if (app_info) |
| 1020 arc_app_packege_name = app_info->package_name; | 900 arc_app_packege_name = app_info->package_name; |
| 1021 } | 901 } |
| 1022 | 902 |
| 1023 for (size_t index = 0; index < pref->GetSize(); ++index) { | 903 for (size_t index = 0; index < pref->GetSize(); ++index) { |
| 1024 const base::DictionaryValue* app = nullptr; | 904 const base::DictionaryValue* app = nullptr; |
| 1025 std::string app_id_or_package; | 905 std::string app_id_or_package; |
| 1026 if (pref->GetDictionary(index, &app) && | 906 if (pref->GetDictionary(index, &app) && |
| 1027 app->GetString(ash::kPinnedAppsPrefAppIDPath, &app_id_or_package) && | 907 app->GetString(ash::launcher::kPinnedAppsPrefAppIDPath, |
| 908 &app_id_or_package) && |
| 1028 (app_id == app_id_or_package || | 909 (app_id == app_id_or_package || |
| 1029 arc_app_packege_name == app_id_or_package)) { | 910 arc_app_packege_name == app_id_or_package)) { |
| 1030 return AppListControllerDelegate::PIN_FIXED; | 911 return AppListControllerDelegate::PIN_FIXED; |
| 1031 } | 912 } |
| 1032 } | 913 } |
| 1033 return AppListControllerDelegate::PIN_EDITABLE; | 914 return AppListControllerDelegate::PIN_EDITABLE; |
| 1034 } | 915 } |
| 1035 | 916 |
| 1036 ArcAppDeferredLauncherController* | 917 ArcAppDeferredLauncherController* |
| 1037 ChromeLauncherControllerImpl::GetArcDeferredLauncher() { | 918 ChromeLauncherControllerImpl::GetArcDeferredLauncher() { |
| 1038 return arc_deferred_launcher_.get(); | 919 return arc_deferred_launcher_.get(); |
| 1039 } | 920 } |
| 1040 | 921 |
| 1041 /////////////////////////////////////////////////////////////////////////////// | 922 /////////////////////////////////////////////////////////////////////////////// |
| 1042 // ash::ShelfDelegate: | 923 // ash::ShelfDelegate: |
| 1043 | 924 |
| 1044 void ChromeLauncherControllerImpl::OnShelfCreated(ash::Shelf* shelf) { | 925 void ChromeLauncherControllerImpl::OnShelfCreated(ash::Shelf* shelf) { |
| 1045 PrefService* prefs = profile_->GetPrefs(); | 926 PrefService* prefs = profile_->GetPrefs(); |
| 1046 const int64_t display = GetDisplayIDForShelf(shelf); | 927 const int64_t display = GetDisplayIDForShelf(shelf); |
| 1047 | 928 |
| 1048 shelf->SetAutoHideBehavior(ash::GetShelfAutoHideBehaviorPref(prefs, display)); | 929 shelf->SetAutoHideBehavior( |
| 930 ash::launcher::GetShelfAutoHideBehaviorPref(prefs, display)); |
| 1049 | 931 |
| 1050 if (ash::ShelfWidget::ShelfAlignmentAllowed()) | 932 if (ash::ShelfWidget::ShelfAlignmentAllowed()) |
| 1051 shelf->SetAlignment(ash::GetShelfAlignmentPref(prefs, display)); | 933 shelf->SetAlignment(ash::launcher::GetShelfAlignmentPref(prefs, display)); |
| 1052 } | 934 } |
| 1053 | 935 |
| 1054 void ChromeLauncherControllerImpl::OnShelfDestroyed(ash::Shelf* shelf) {} | 936 void ChromeLauncherControllerImpl::OnShelfDestroyed(ash::Shelf* shelf) {} |
| 1055 | 937 |
| 1056 void ChromeLauncherControllerImpl::OnShelfAlignmentChanged(ash::Shelf* shelf) { | 938 void ChromeLauncherControllerImpl::OnShelfAlignmentChanged(ash::Shelf* shelf) { |
| 1057 ash::SetShelfAlignmentPref(profile_->GetPrefs(), GetDisplayIDForShelf(shelf), | 939 ash::launcher::SetShelfAlignmentPref( |
| 1058 shelf->alignment()); | 940 profile_->GetPrefs(), GetDisplayIDForShelf(shelf), shelf->alignment()); |
| 1059 } | 941 } |
| 1060 | 942 |
| 1061 void ChromeLauncherControllerImpl::OnShelfAutoHideBehaviorChanged( | 943 void ChromeLauncherControllerImpl::OnShelfAutoHideBehaviorChanged( |
| 1062 ash::Shelf* shelf) { | 944 ash::Shelf* shelf) { |
| 1063 ash::SetShelfAutoHideBehaviorPref(profile_->GetPrefs(), | 945 ash::launcher::SetShelfAutoHideBehaviorPref(profile_->GetPrefs(), |
| 1064 GetDisplayIDForShelf(shelf), | 946 GetDisplayIDForShelf(shelf), |
| 1065 shelf->auto_hide_behavior()); | 947 shelf->auto_hide_behavior()); |
| 1066 } | 948 } |
| 1067 | 949 |
| 1068 void ChromeLauncherControllerImpl::OnShelfAutoHideStateChanged( | 950 void ChromeLauncherControllerImpl::OnShelfAutoHideStateChanged( |
| 1069 ash::Shelf* shelf) {} | 951 ash::Shelf* shelf) {} |
| 1070 | 952 |
| 1071 void ChromeLauncherControllerImpl::OnShelfVisibilityStateChanged( | 953 void ChromeLauncherControllerImpl::OnShelfVisibilityStateChanged( |
| 1072 ash::Shelf* shelf) {} | 954 ash::Shelf* shelf) {} |
| 1073 | 955 |
| 1074 ash::ShelfID ChromeLauncherControllerImpl::GetShelfIDForAppID( | 956 ash::ShelfID ChromeLauncherControllerImpl::GetShelfIDForAppID( |
| 1075 const std::string& app_id) { | 957 const std::string& app_id) { |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1275 if (IsAppPinned(app_id)) | 1157 if (IsAppPinned(app_id)) |
| 1276 return; | 1158 return; |
| 1277 | 1159 |
| 1278 ash::ShelfID shelf_id = GetShelfIDForAppID(app_id); | 1160 ash::ShelfID shelf_id = GetShelfIDForAppID(app_id); |
| 1279 if (shelf_id) { | 1161 if (shelf_id) { |
| 1280 // App item exists, pin it | 1162 // App item exists, pin it |
| 1281 Pin(shelf_id); | 1163 Pin(shelf_id); |
| 1282 } else { | 1164 } else { |
| 1283 // Otherwise, create a shortcut item for it. | 1165 // Otherwise, create a shortcut item for it. |
| 1284 shelf_id = CreateAppShortcutLauncherItem(app_id, model_->item_count()); | 1166 shelf_id = CreateAppShortcutLauncherItem(app_id, model_->item_count()); |
| 1285 if (GetPinnable(app_id) == AppListControllerDelegate::PIN_EDITABLE) | 1167 SyncPinPosition(shelf_id); |
| 1286 PersistPinnedState(); | |
| 1287 } | 1168 } |
| 1288 } | 1169 } |
| 1289 | 1170 |
| 1290 void ChromeLauncherControllerImpl::DoUnpinAppWithID(const std::string& app_id) { | 1171 void ChromeLauncherControllerImpl::DoUnpinAppWithID(const std::string& app_id) { |
| 1291 ash::ShelfID shelf_id = GetShelfIDForAppID(app_id); | 1172 ash::ShelfID shelf_id = GetShelfIDForAppID(app_id); |
| 1292 if (shelf_id && IsPinned(shelf_id)) | 1173 if (shelf_id && IsPinned(shelf_id)) |
| 1293 Unpin(shelf_id); | 1174 Unpin(shelf_id); |
| 1294 } | 1175 } |
| 1295 | 1176 |
| 1296 int ChromeLauncherControllerImpl::PinRunningAppInternal(int index, | 1177 int ChromeLauncherControllerImpl::PinRunningAppInternal(int index, |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1317 DCHECK_EQ(item.type, ash::TYPE_APP_SHORTCUT); | 1198 DCHECK_EQ(item.type, ash::TYPE_APP_SHORTCUT); |
| 1318 item.type = ash::TYPE_WINDOWED_APP; | 1199 item.type = ash::TYPE_WINDOWED_APP; |
| 1319 // A platform app and a windowed app are sharing TYPE_APP_SHORTCUT. As such | 1200 // A platform app and a windowed app are sharing TYPE_APP_SHORTCUT. As such |
| 1320 // we have to check here what this was before it got a shortcut. | 1201 // we have to check here what this was before it got a shortcut. |
| 1321 LauncherItemController* controller = GetLauncherItemController(item.id); | 1202 LauncherItemController* controller = GetLauncherItemController(item.id); |
| 1322 if (controller && controller->type() == LauncherItemController::TYPE_APP) | 1203 if (controller && controller->type() == LauncherItemController::TYPE_APP) |
| 1323 item.type = ash::TYPE_PLATFORM_APP; | 1204 item.type = ash::TYPE_PLATFORM_APP; |
| 1324 model_->Set(index, item); | 1205 model_->Set(index, item); |
| 1325 } | 1206 } |
| 1326 | 1207 |
| 1208 void ChromeLauncherControllerImpl::SyncPinPosition(ash::ShelfID shelf_id) { |
| 1209 DCHECK(shelf_id); |
| 1210 if (ignore_persist_pinned_state_change_) |
| 1211 return; |
| 1212 |
| 1213 const int max_index = model_->item_count(); |
| 1214 const int index = model_->ItemIndexByID(shelf_id); |
| 1215 DCHECK_GT(index, 0); |
| 1216 |
| 1217 const std::string& app_id = GetAppIDForShelfID(shelf_id); |
| 1218 DCHECK(!app_id.empty()); |
| 1219 |
| 1220 std::string app_id_before; |
| 1221 std::string app_id_after; |
| 1222 |
| 1223 for (int i = index - 1; i > 0; --i) { |
| 1224 const ash::ShelfID shelf_id_before = model_->items()[i].id; |
| 1225 if (IsPinned(shelf_id_before)) { |
| 1226 app_id_before = GetAppIDForShelfID(shelf_id_before); |
| 1227 DCHECK(!app_id_before.empty()); |
| 1228 break; |
| 1229 } |
| 1230 } |
| 1231 |
| 1232 for (int i = index + 1; i < max_index; ++i) { |
| 1233 const ash::ShelfID shelf_id_after = model_->items()[i].id; |
| 1234 if (IsPinned(shelf_id_after)) { |
| 1235 app_id_after = GetAppIDForShelfID(shelf_id_after); |
| 1236 DCHECK(!app_id_after.empty()); |
| 1237 break; |
| 1238 } |
| 1239 } |
| 1240 |
| 1241 ash::launcher::SetPinPosition(profile_, app_id, app_id_before, app_id_after); |
| 1242 } |
| 1243 |
| 1244 void ChromeLauncherControllerImpl::OnSyncModelUpdated() { |
| 1245 UpdateAppLaunchersFromPref(); |
| 1246 } |
| 1247 |
| 1327 void ChromeLauncherControllerImpl::UpdateAppLaunchersFromPref() { | 1248 void ChromeLauncherControllerImpl::UpdateAppLaunchersFromPref() { |
| 1328 // There are various functions which will trigger a |PersistPinnedState| call | 1249 // There are various functions which will trigger a |SyncPinPosition| call |
| 1329 // like a direct call to |DoPinAppWithID|, or an indirect call to the menu | 1250 // like a direct call to |DoPinAppWithID|, or an indirect call to the menu |
| 1330 // model which will use weights to re-arrange the icons to new positions. | 1251 // model which will use weights to re-arrange the icons to new positions. |
| 1331 // Since this function is meant to synchronize the "is state" with the | 1252 // Since this function is meant to synchronize the "is state" with the |
| 1332 // "sync state", it makes no sense to store any changes by this function back | 1253 // "sync state", it makes no sense to store any changes by this function back |
| 1333 // into the pref state. Therefore we tell |persistPinnedState| to ignore any | 1254 // into the pref state. Therefore we tell |persistPinnedState| to ignore any |
| 1334 // invocations while we are running. | 1255 // invocations while we are running. |
| 1335 base::AutoReset<bool> auto_reset(&ignore_persist_pinned_state_change_, true); | 1256 base::AutoReset<bool> auto_reset(&ignore_persist_pinned_state_change_, true); |
| 1336 std::vector<std::string> pinned_apps = ash::GetPinnedAppsFromPrefs( | 1257 std::vector<std::string> pinned_apps = ash::launcher::GetPinnedAppsFromPrefs( |
| 1337 profile_->GetPrefs(), launcher_controller_helper_.get()); | 1258 profile_->GetPrefs(), launcher_controller_helper_.get()); |
| 1338 | 1259 |
| 1339 int index = 0; | 1260 int index = 0; |
| 1340 int max_index = model_->item_count(); | 1261 int max_index = model_->item_count(); |
| 1262 int seen_chrome_index = -1; |
| 1341 | 1263 |
| 1342 // When one of the two special items cannot be moved (and we do not know where | 1264 // At least chrome browser shortcut should exist. |
| 1343 // yet), we remember the current location in one of these variables. | 1265 DCHECK_GT(max_index, 0); |
| 1344 int chrome_index = -1; | 1266 |
| 1345 int app_list_index = -1; | 1267 // Skip app list items if it exists. |
| 1268 if (model_->items()[0].type == ash::TYPE_APP_LIST) |
| 1269 ++index; |
| 1346 | 1270 |
| 1347 // Walk the model and |pinned_apps| from the pref lockstep, adding and | 1271 // Walk the model and |pinned_apps| from the pref lockstep, adding and |
| 1348 // removing items as necessary. NB: This code uses plain old indexing instead | 1272 // removing items as necessary. NB: This code uses plain old indexing instead |
| 1349 // of iterators because of model mutations as part of the loop. | 1273 // of iterators because of model mutations as part of the loop. |
| 1350 std::vector<std::string>::const_iterator pref_app_id(pinned_apps.begin()); | 1274 std::vector<std::string>::const_iterator pref_app_id(pinned_apps.begin()); |
| 1351 for (; index < max_index && pref_app_id != pinned_apps.end(); ++index) { | 1275 for (; index < max_index && pref_app_id != pinned_apps.end(); ++index) { |
| 1352 // Check if we have an item which we need to handle. | 1276 // Check if we have an item which we need to handle. |
| 1353 if (*pref_app_id == extension_misc::kChromeAppId || | 1277 if (IsAppPinned(*pref_app_id)) { |
| 1354 *pref_app_id == ash::kPinnedAppsPlaceholder || | 1278 if (seen_chrome_index >= 0 && |
| 1355 IsAppPinned(*pref_app_id)) { | 1279 *pref_app_id == extension_misc::kChromeAppId) { |
| 1280 // Current item is Chrome browser and we saw it before. |
| 1281 model_->Move(seen_chrome_index, index); |
| 1282 ++pref_app_id; |
| 1283 --index; |
| 1284 continue; |
| 1285 } |
| 1356 for (; index < max_index; ++index) { | 1286 for (; index < max_index; ++index) { |
| 1357 const ash::ShelfItem& item(model_->items()[index]); | 1287 const ash::ShelfItem& item(model_->items()[index]); |
| 1358 bool is_app_list = item.type == ash::TYPE_APP_LIST; | 1288 if (item.type != ash::TYPE_APP_SHORTCUT && |
| 1359 bool is_chrome = item.type == ash::TYPE_BROWSER_SHORTCUT; | 1289 item.type != ash::TYPE_BROWSER_SHORTCUT) { |
| 1360 if (item.type != ash::TYPE_APP_SHORTCUT && !is_app_list && !is_chrome) | |
| 1361 continue; | 1290 continue; |
| 1291 } |
| 1362 LauncherItemController* controller = GetLauncherItemController(item.id); | 1292 LauncherItemController* controller = GetLauncherItemController(item.id); |
| 1363 if ((ash::kPinnedAppsPlaceholder == *pref_app_id && is_app_list) || | 1293 if (controller && controller->app_id() == *pref_app_id) { |
| 1364 (extension_misc::kChromeAppId == *pref_app_id && is_chrome) || | |
| 1365 (controller && controller->app_id() == *pref_app_id)) { | |
| 1366 // Check if an item needs to be moved here. | |
| 1367 MoveChromeOrApplistToFinalPosition(is_chrome, is_app_list, index, | |
| 1368 &chrome_index, &app_list_index); | |
| 1369 ++pref_app_id; | 1294 ++pref_app_id; |
| 1370 break; | 1295 break; |
| 1296 } else if (item.type == ash::TYPE_BROWSER_SHORTCUT) { |
| 1297 // We cannot close browser shortcut. Remember its position. |
| 1298 seen_chrome_index = index; |
| 1371 } else { | 1299 } else { |
| 1372 if (is_chrome || is_app_list) { | 1300 // Check if this is a platform or a windowed app. |
| 1373 // We cannot delete any of these shortcuts. As such we remember | 1301 if (item.type == ash::TYPE_APP_SHORTCUT && controller && |
| 1374 // their positions and move them later where they belong. | 1302 (controller->locked() || |
| 1375 if (is_chrome) | 1303 controller->type() == LauncherItemController::TYPE_APP)) { |
| 1376 chrome_index = index; | 1304 // Note: This will not change the amount of items (|max_index|). |
| 1377 else | 1305 // Even changes to the actual |index| due to item weighting |
| 1378 app_list_index = index; | 1306 // changes should be fine. |
| 1379 // And skip the item - or exit the loop if end is reached (note that | 1307 UnpinRunningAppInternal(index); |
| 1380 // in that case we will reduce the index again by one and this only | |
| 1381 // compensates for it). | |
| 1382 if (index >= max_index - 1) | |
| 1383 break; | |
| 1384 ++index; | |
| 1385 } else { | 1308 } else { |
| 1386 // Check if this is a platform or a windowed app. | 1309 if (controller) |
| 1387 if (item.type == ash::TYPE_APP_SHORTCUT && controller && | 1310 LauncherItemClosed(item.id); |
| 1388 (controller->locked() || | 1311 --max_index; |
| 1389 controller->type() == LauncherItemController::TYPE_APP)) { | |
| 1390 // Note: This will not change the amount of items (|max_index|). | |
| 1391 // Even changes to the actual |index| due to item weighting | |
| 1392 // changes should be fine. | |
| 1393 UnpinRunningAppInternal(index); | |
| 1394 } else { | |
| 1395 if (controller) | |
| 1396 LauncherItemClosed(item.id); | |
| 1397 --max_index; | |
| 1398 } | |
| 1399 } | 1312 } |
| 1400 --index; | 1313 --index; |
| 1401 } | 1314 } |
| 1402 } | 1315 } |
| 1403 // If the item wasn't found, that means id_to_item_controller_map_ | 1316 // If the item wasn't found, that means id_to_item_controller_map_ |
| 1404 // is out of sync. | 1317 // is out of sync. |
| 1405 DCHECK(index <= max_index); | 1318 DCHECK(index <= max_index); |
| 1406 } else { | 1319 } else { |
| 1407 // Check if the item was already running but not yet pinned. | 1320 // Check if the item was already running but not yet pinned. |
| 1408 ash::ShelfID shelf_id = GetShelfIDForAppID(*pref_app_id); | 1321 ash::ShelfID shelf_id = GetShelfIDForAppID(*pref_app_id); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1426 LauncherItemController* controller = GetLauncherItemController(item.id); | 1339 LauncherItemController* controller = GetLauncherItemController(item.id); |
| 1427 if (controller) { | 1340 if (controller) { |
| 1428 if (controller->locked() || | 1341 if (controller->locked() || |
| 1429 controller->type() == LauncherItemController::TYPE_APP) { | 1342 controller->type() == LauncherItemController::TYPE_APP) { |
| 1430 UnpinRunningAppInternal(index); | 1343 UnpinRunningAppInternal(index); |
| 1431 } else { | 1344 } else { |
| 1432 LauncherItemClosed(item.id); | 1345 LauncherItemClosed(item.id); |
| 1433 } | 1346 } |
| 1434 } | 1347 } |
| 1435 } else { | 1348 } else { |
| 1436 if (item.type == ash::TYPE_BROWSER_SHORTCUT) | |
| 1437 chrome_index = index; | |
| 1438 else if (item.type == ash::TYPE_APP_LIST) | |
| 1439 app_list_index = index; | |
| 1440 ++index; | 1349 ++index; |
| 1441 } | 1350 } |
| 1442 } | 1351 } |
| 1443 | 1352 |
| 1444 // Append unprocessed items from the pref to the end of the model. | 1353 // Append unprocessed items from the pref to the end of the model. |
| 1445 for (; pref_app_id != pinned_apps.end(); ++pref_app_id) { | 1354 for (; pref_app_id != pinned_apps.end(); ++pref_app_id) { |
| 1446 // All items but the chrome and / or app list shortcut needs to be added. | 1355 if (*pref_app_id == extension_misc::kChromeAppId) { |
| 1447 bool is_chrome = *pref_app_id == extension_misc::kChromeAppId; | 1356 int target_index = FindInsertionPoint(); |
| 1448 bool is_app_list = *pref_app_id == ash::kPinnedAppsPlaceholder; | 1357 DCHECK(seen_chrome_index >= 0 && seen_chrome_index < target_index); |
| 1449 // Coming here we know the next item which can be finalized, either the | 1358 model_->Move(seen_chrome_index, target_index); |
| 1450 // chrome item or the app launcher. The final position is the end of the | 1359 } else { |
| 1451 // list. The menu model will make sure that the item is grouped according | |
| 1452 // to its weight (which we do not know here). | |
| 1453 if (!is_chrome && !is_app_list) { | |
| 1454 DoPinAppWithID(*pref_app_id); | 1360 DoPinAppWithID(*pref_app_id); |
| 1455 int target_index = FindInsertionPoint(false); | 1361 int target_index = FindInsertionPoint(); |
| 1456 ash::ShelfID id = GetShelfIDForAppID(*pref_app_id); | 1362 ash::ShelfID id = GetShelfIDForAppID(*pref_app_id); |
| 1457 int source_index = model_->ItemIndexByID(id); | 1363 int source_index = model_->ItemIndexByID(id); |
| 1458 if (source_index != target_index) | 1364 if (source_index != target_index) |
| 1459 model_->Move(source_index, target_index); | 1365 model_->Move(source_index, target_index); |
| 1460 | |
| 1461 // Needed for the old layout - the weight might force it to be lower in | |
| 1462 // rank. | |
| 1463 if (app_list_index != -1 && target_index <= app_list_index) | |
| 1464 ++app_list_index; | |
| 1465 } else { | |
| 1466 int target_index = FindInsertionPoint(is_app_list); | |
| 1467 MoveChromeOrApplistToFinalPosition(is_chrome, is_app_list, target_index, | |
| 1468 &chrome_index, &app_list_index); | |
| 1469 } | 1366 } |
| 1470 } | 1367 } |
| 1471 } | 1368 } |
| 1472 | 1369 |
| 1473 void ChromeLauncherControllerImpl::SetShelfAutoHideBehaviorFromPrefs() { | 1370 void ChromeLauncherControllerImpl::SetShelfAutoHideBehaviorFromPrefs() { |
| 1474 for (auto* window : ash::Shell::GetAllRootWindows()) { | 1371 for (auto* window : ash::Shell::GetAllRootWindows()) { |
| 1475 ash::Shelf* shelf = ash::Shelf::ForWindow(window); | 1372 ash::Shelf* shelf = ash::Shelf::ForWindow(window); |
| 1476 if (shelf) { | 1373 if (shelf) { |
| 1477 shelf->SetAutoHideBehavior(ash::GetShelfAutoHideBehaviorPref( | 1374 shelf->SetAutoHideBehavior(ash::launcher::GetShelfAutoHideBehaviorPref( |
| 1478 profile_->GetPrefs(), GetDisplayIDForShelf(shelf))); | 1375 profile_->GetPrefs(), GetDisplayIDForShelf(shelf))); |
| 1479 } | 1376 } |
| 1480 } | 1377 } |
| 1481 } | 1378 } |
| 1482 | 1379 |
| 1483 void ChromeLauncherControllerImpl::SetShelfAlignmentFromPrefs() { | 1380 void ChromeLauncherControllerImpl::SetShelfAlignmentFromPrefs() { |
| 1484 if (!ash::ShelfWidget::ShelfAlignmentAllowed()) | 1381 if (!ash::ShelfWidget::ShelfAlignmentAllowed()) |
| 1485 return; | 1382 return; |
| 1486 | 1383 |
| 1487 for (auto* window : ash::Shell::GetAllRootWindows()) { | 1384 for (auto* window : ash::Shell::GetAllRootWindows()) { |
| 1488 ash::Shelf* shelf = ash::Shelf::ForWindow(window); | 1385 ash::Shelf* shelf = ash::Shelf::ForWindow(window); |
| 1489 if (shelf) { | 1386 if (shelf) { |
| 1490 shelf->SetAlignment(ash::GetShelfAlignmentPref( | 1387 shelf->SetAlignment(ash::launcher::GetShelfAlignmentPref( |
| 1491 profile_->GetPrefs(), GetDisplayIDForShelf(shelf))); | 1388 profile_->GetPrefs(), GetDisplayIDForShelf(shelf))); |
| 1492 } | 1389 } |
| 1493 } | 1390 } |
| 1494 } | 1391 } |
| 1495 | 1392 |
| 1496 void ChromeLauncherControllerImpl::SetShelfBehaviorsFromPrefs() { | 1393 void ChromeLauncherControllerImpl::SetShelfBehaviorsFromPrefs() { |
| 1497 SetShelfAutoHideBehaviorFromPrefs(); | 1394 SetShelfAutoHideBehaviorFromPrefs(); |
| 1498 SetShelfAlignmentFromPrefs(); | 1395 SetShelfAlignmentFromPrefs(); |
| 1499 } | 1396 } |
| 1500 | 1397 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1584 static_cast<AppShortcutLauncherItemController*>(controller); | 1481 static_cast<AppShortcutLauncherItemController*>(controller); |
| 1585 return app_controller->GetRunningApplications(); | 1482 return app_controller->GetRunningApplications(); |
| 1586 } | 1483 } |
| 1587 | 1484 |
| 1588 ash::ShelfID ChromeLauncherControllerImpl::CreateBrowserShortcutLauncherItem() { | 1485 ash::ShelfID ChromeLauncherControllerImpl::CreateBrowserShortcutLauncherItem() { |
| 1589 ash::ShelfItem browser_shortcut; | 1486 ash::ShelfItem browser_shortcut; |
| 1590 browser_shortcut.type = ash::TYPE_BROWSER_SHORTCUT; | 1487 browser_shortcut.type = ash::TYPE_BROWSER_SHORTCUT; |
| 1591 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 1488 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| 1592 browser_shortcut.image = *rb.GetImageSkiaNamed(IDR_PRODUCT_LOGO_32); | 1489 browser_shortcut.image = *rb.GetImageSkiaNamed(IDR_PRODUCT_LOGO_32); |
| 1593 ash::ShelfID id = model_->next_id(); | 1490 ash::ShelfID id = model_->next_id(); |
| 1594 size_t index = GetChromeIconIndexForCreation(); | 1491 model_->AddAt(0, browser_shortcut); |
| 1595 model_->AddAt(index, browser_shortcut); | |
| 1596 id_to_item_controller_map_[id] = | 1492 id_to_item_controller_map_[id] = |
| 1597 new BrowserShortcutLauncherItemController(this, model_); | 1493 new BrowserShortcutLauncherItemController(this, model_); |
| 1598 id_to_item_controller_map_[id]->set_shelf_id(id); | 1494 id_to_item_controller_map_[id]->set_shelf_id(id); |
| 1599 // ShelfItemDelegateManager owns BrowserShortcutLauncherItemController. | 1495 // ShelfItemDelegateManager owns BrowserShortcutLauncherItemController. |
| 1600 SetShelfItemDelegate(id, id_to_item_controller_map_[id]); | 1496 SetShelfItemDelegate(id, id_to_item_controller_map_[id]); |
| 1601 return id; | 1497 return id; |
| 1602 } | 1498 } |
| 1603 | 1499 |
| 1604 bool ChromeLauncherControllerImpl::IsIncognito( | 1500 bool ChromeLauncherControllerImpl::IsIncognito( |
| 1605 const content::WebContents* web_contents) const { | 1501 const content::WebContents* web_contents) const { |
| 1606 const Profile* profile = | 1502 const Profile* profile = |
| 1607 Profile::FromBrowserContext(web_contents->GetBrowserContext()); | 1503 Profile::FromBrowserContext(web_contents->GetBrowserContext()); |
| 1608 return profile->IsOffTheRecord() && !profile->IsGuestSession() && | 1504 return profile->IsOffTheRecord() && !profile->IsGuestSession() && |
| 1609 !profile->IsSystemProfile(); | 1505 !profile->IsSystemProfile(); |
| 1610 } | 1506 } |
| 1611 | 1507 |
| 1612 void ChromeLauncherControllerImpl::PersistChromeItemIndex(int index) { | 1508 int ChromeLauncherControllerImpl::FindInsertionPoint() { |
| 1613 profile_->GetPrefs()->SetInteger(prefs::kShelfChromeIconIndex, index); | 1509 DCHECK_GT(model_->item_count(), 0); |
| 1614 } | |
| 1615 | |
| 1616 void ChromeLauncherControllerImpl::MoveChromeOrApplistToFinalPosition( | |
| 1617 bool is_chrome, | |
| 1618 bool is_app_list, | |
| 1619 int target_index, | |
| 1620 int* chrome_index, | |
| 1621 int* app_list_index) { | |
| 1622 if (is_chrome && *chrome_index != -1) { | |
| 1623 model_->Move(*chrome_index, target_index); | |
| 1624 if (*app_list_index != -1 && *chrome_index < *app_list_index && | |
| 1625 target_index > *app_list_index) | |
| 1626 --(*app_list_index); | |
| 1627 *chrome_index = -1; | |
| 1628 } else if (is_app_list && *app_list_index != -1) { | |
| 1629 model_->Move(*app_list_index, target_index); | |
| 1630 if (*chrome_index != -1 && *app_list_index < *chrome_index && | |
| 1631 target_index > *chrome_index) | |
| 1632 --(*chrome_index); | |
| 1633 *app_list_index = -1; | |
| 1634 } | |
| 1635 } | |
| 1636 | |
| 1637 int ChromeLauncherControllerImpl::FindInsertionPoint(bool is_app_list) { | |
| 1638 // Keeping this change small to backport to M33&32 (see crbug.com/329597). | |
| 1639 // TODO(skuhne): With the removal of the legacy shelf layout we should remove | |
| 1640 // the ability to move the app list item since this was never used. We should | |
| 1641 // instead ask the ShelfModel::ValidateInsertionIndex or similir for an index. | |
| 1642 if (is_app_list) | |
| 1643 return 0; | |
| 1644 | |
| 1645 for (int i = model_->item_count() - 1; i > 0; --i) { | 1510 for (int i = model_->item_count() - 1; i > 0; --i) { |
| 1646 ash::ShelfItemType type = model_->items()[i].type; | 1511 ash::ShelfItemType type = model_->items()[i].type; |
| 1512 DCHECK_NE(ash::TYPE_APP_LIST, type); |
| 1647 if (type == ash::TYPE_APP_SHORTCUT || | 1513 if (type == ash::TYPE_APP_SHORTCUT || |
| 1648 (is_app_list && type == ash::TYPE_APP_LIST) || | |
| 1649 type == ash::TYPE_BROWSER_SHORTCUT) { | 1514 type == ash::TYPE_BROWSER_SHORTCUT) { |
| 1650 return i; | 1515 return i; |
| 1651 } | 1516 } |
| 1652 } | 1517 } |
| 1653 return 0; | 1518 return 0; |
| 1654 } | 1519 } |
| 1655 | 1520 |
| 1656 int ChromeLauncherControllerImpl::GetChromeIconIndexForCreation() { | |
| 1657 // We get the list of pinned apps as they currently would get pinned. | |
| 1658 // Within this list the chrome icon will be the correct location. | |
| 1659 std::vector<std::string> pinned_apps = ash::GetPinnedAppsFromPrefs( | |
| 1660 profile_->GetPrefs(), launcher_controller_helper_.get()); | |
| 1661 | |
| 1662 std::vector<std::string>::iterator it = | |
| 1663 std::find(pinned_apps.begin(), pinned_apps.end(), | |
| 1664 std::string(extension_misc::kChromeAppId)); | |
| 1665 DCHECK(it != pinned_apps.end()); | |
| 1666 int index = it - pinned_apps.begin(); | |
| 1667 | |
| 1668 // We should do here a comparison between the is state and the "want to be" | |
| 1669 // state since some apps might be able to pin but are not yet. Instead - for | |
| 1670 // the time being we clamp against the amount of known items and wait for the | |
| 1671 // next |UpdateAppLaunchersFromPref()| call to correct it - it will come since | |
| 1672 // the pinning will be done then. | |
| 1673 return std::min(model_->item_count(), index); | |
| 1674 } | |
| 1675 | |
| 1676 void ChromeLauncherControllerImpl::CloseWindowedAppsFromRemovedExtension( | 1521 void ChromeLauncherControllerImpl::CloseWindowedAppsFromRemovedExtension( |
| 1677 const std::string& app_id, | 1522 const std::string& app_id, |
| 1678 const Profile* profile) { | 1523 const Profile* profile) { |
| 1679 // This function cannot rely on the controller's enumeration functionality | 1524 // This function cannot rely on the controller's enumeration functionality |
| 1680 // since the extension has already be unloaded. | 1525 // since the extension has already be unloaded. |
| 1681 const BrowserList* browser_list = BrowserList::GetInstance(); | 1526 const BrowserList* browser_list = BrowserList::GetInstance(); |
| 1682 std::vector<Browser*> browser_to_close; | 1527 std::vector<Browser*> browser_to_close; |
| 1683 for (BrowserList::const_reverse_iterator it = | 1528 for (BrowserList::const_reverse_iterator it = |
| 1684 browser_list->begin_last_active(); | 1529 browser_list->begin_last_active(); |
| 1685 it != browser_list->end_last_active(); ++it) { | 1530 it != browser_list->end_last_active(); ++it) { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1730 if (arc::ArcAuthService::IsAllowedForProfile(profile_)) { | 1575 if (arc::ArcAuthService::IsAllowedForProfile(profile_)) { |
| 1731 DCHECK(arc_deferred_launcher_.get()); | 1576 DCHECK(arc_deferred_launcher_.get()); |
| 1732 std::unique_ptr<AppIconLoader> arc_app_icon_loader( | 1577 std::unique_ptr<AppIconLoader> arc_app_icon_loader( |
| 1733 new ArcAppIconLoader(profile_, extension_misc::EXTENSION_ICON_SMALL, | 1578 new ArcAppIconLoader(profile_, extension_misc::EXTENSION_ICON_SMALL, |
| 1734 arc_deferred_launcher_.get(), this)); | 1579 arc_deferred_launcher_.get(), this)); |
| 1735 app_icon_loaders_.push_back(std::move(arc_app_icon_loader)); | 1580 app_icon_loaders_.push_back(std::move(arc_app_icon_loader)); |
| 1736 } | 1581 } |
| 1737 | 1582 |
| 1738 pref_change_registrar_.Init(profile_->GetPrefs()); | 1583 pref_change_registrar_.Init(profile_->GetPrefs()); |
| 1739 pref_change_registrar_.Add( | 1584 pref_change_registrar_.Add( |
| 1740 prefs::kPinnedLauncherApps, | |
| 1741 base::Bind(&ChromeLauncherControllerImpl::UpdateAppLaunchersFromPref, | |
| 1742 base::Unretained(this))); | |
| 1743 pref_change_registrar_.Add( | |
| 1744 prefs::kPolicyPinnedLauncherApps, | 1585 prefs::kPolicyPinnedLauncherApps, |
| 1745 base::Bind(&ChromeLauncherControllerImpl::UpdateAppLaunchersFromPref, | 1586 base::Bind(&ChromeLauncherControllerImpl::UpdateAppLaunchersFromPref, |
| 1746 base::Unretained(this))); | 1587 base::Unretained(this))); |
| 1747 pref_change_registrar_.Add( | 1588 pref_change_registrar_.Add( |
| 1748 prefs::kShelfAlignmentLocal, | 1589 prefs::kShelfAlignmentLocal, |
| 1749 base::Bind(&ChromeLauncherControllerImpl::SetShelfAlignmentFromPrefs, | 1590 base::Bind(&ChromeLauncherControllerImpl::SetShelfAlignmentFromPrefs, |
| 1750 base::Unretained(this))); | 1591 base::Unretained(this))); |
| 1751 pref_change_registrar_.Add( | 1592 pref_change_registrar_.Add( |
| 1752 prefs::kShelfAutoHideBehaviorLocal, | 1593 prefs::kShelfAutoHideBehaviorLocal, |
| 1753 base::Bind( | 1594 base::Bind( |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1765 | 1606 |
| 1766 std::unique_ptr<LauncherAppUpdater> extension_app_updater( | 1607 std::unique_ptr<LauncherAppUpdater> extension_app_updater( |
| 1767 new LauncherExtensionAppUpdater(this, profile_)); | 1608 new LauncherExtensionAppUpdater(this, profile_)); |
| 1768 app_updaters_.push_back(std::move(extension_app_updater)); | 1609 app_updaters_.push_back(std::move(extension_app_updater)); |
| 1769 | 1610 |
| 1770 if (arc::ArcAuthService::IsAllowedForProfile(profile_)) { | 1611 if (arc::ArcAuthService::IsAllowedForProfile(profile_)) { |
| 1771 std::unique_ptr<LauncherAppUpdater> arc_app_updater( | 1612 std::unique_ptr<LauncherAppUpdater> arc_app_updater( |
| 1772 new LauncherArcAppUpdater(this, profile_)); | 1613 new LauncherArcAppUpdater(this, profile_)); |
| 1773 app_updaters_.push_back(std::move(arc_app_updater)); | 1614 app_updaters_.push_back(std::move(arc_app_updater)); |
| 1774 } | 1615 } |
| 1616 |
| 1617 app_list::AppListSyncableService* app_service = |
| 1618 app_list::AppListSyncableServiceFactory::GetForProfile(profile_); |
| 1619 if (app_service) |
| 1620 app_service->AddObserverAndStart(this); |
| 1775 } | 1621 } |
| 1776 | 1622 |
| 1777 void ChromeLauncherControllerImpl::ReleaseProfile() { | 1623 void ChromeLauncherControllerImpl::ReleaseProfile() { |
| 1778 if (app_sync_ui_state_) | 1624 if (app_sync_ui_state_) |
| 1779 app_sync_ui_state_->RemoveObserver(this); | 1625 app_sync_ui_state_->RemoveObserver(this); |
| 1780 | 1626 |
| 1781 app_updaters_.clear(); | 1627 app_updaters_.clear(); |
| 1782 | 1628 |
| 1783 prefs_observer_.reset(); | 1629 prefs_observer_.reset(); |
| 1784 | 1630 |
| 1785 pref_change_registrar_.RemoveAll(); | 1631 pref_change_registrar_.RemoveAll(); |
| 1632 |
| 1633 app_list::AppListSyncableService* app_service = |
| 1634 app_list::AppListSyncableServiceFactory::GetForProfile(profile_); |
| 1635 if (app_service) |
| 1636 app_service->RemoveObserver(this); |
| 1786 } | 1637 } |
| 1787 | 1638 |
| 1788 AppIconLoader* ChromeLauncherControllerImpl::GetAppIconLoaderForApp( | 1639 AppIconLoader* ChromeLauncherControllerImpl::GetAppIconLoaderForApp( |
| 1789 const std::string& app_id) { | 1640 const std::string& app_id) { |
| 1790 for (const auto& app_icon_loader : app_icon_loaders_) { | 1641 for (const auto& app_icon_loader : app_icon_loaders_) { |
| 1791 if (app_icon_loader->CanLoadImageForApp(app_id)) | 1642 if (app_icon_loader->CanLoadImageForApp(app_id)) |
| 1792 return app_icon_loader.get(); | 1643 return app_icon_loader.get(); |
| 1793 } | 1644 } |
| 1794 | 1645 |
| 1795 return nullptr; | 1646 return nullptr; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1807 if (iter == id_to_item_controller_map_.end() || item_delegate == iter->second) | 1658 if (iter == id_to_item_controller_map_.end() || item_delegate == iter->second) |
| 1808 return; | 1659 return; |
| 1809 LOG(ERROR) << "Unexpected change of shelf item id: " << id; | 1660 LOG(ERROR) << "Unexpected change of shelf item id: " << id; |
| 1810 id_to_item_controller_map_.erase(iter); | 1661 id_to_item_controller_map_.erase(iter); |
| 1811 } | 1662 } |
| 1812 | 1663 |
| 1813 /////////////////////////////////////////////////////////////////////////////// | 1664 /////////////////////////////////////////////////////////////////////////////// |
| 1814 // ash::ShelfModelObserver: | 1665 // ash::ShelfModelObserver: |
| 1815 | 1666 |
| 1816 void ChromeLauncherControllerImpl::ShelfItemAdded(int index) { | 1667 void ChromeLauncherControllerImpl::ShelfItemAdded(int index) { |
| 1817 // The app list launcher can get added to the shelf after we applied the | |
| 1818 // preferences. In that case the item might be at the wrong spot. As such we | |
| 1819 // call the function again. | |
| 1820 if (model_->items()[index].type == ash::TYPE_APP_LIST) | |
| 1821 UpdateAppLaunchersFromPref(); | |
| 1822 } | 1668 } |
| 1823 | 1669 |
| 1824 void ChromeLauncherControllerImpl::ShelfItemRemoved(int index, | 1670 void ChromeLauncherControllerImpl::ShelfItemRemoved(int index, |
| 1825 ash::ShelfID id) { | 1671 ash::ShelfID id) { |
| 1826 // TODO(skuhne): This fixes crbug.com/429870, but it does not answer why we | 1672 // TODO(skuhne): This fixes crbug.com/429870, but it does not answer why we |
| 1827 // get into this state in the first place. | 1673 // get into this state in the first place. |
| 1828 IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id); | 1674 IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id); |
| 1829 if (iter == id_to_item_controller_map_.end()) | 1675 if (iter == id_to_item_controller_map_.end()) |
| 1830 return; | 1676 return; |
| 1831 | 1677 |
| 1832 LOG(ERROR) << "Unexpected change of shelf item id: " << id; | 1678 LOG(ERROR) << "Unexpected change of shelf item id: " << id; |
| 1833 | 1679 |
| 1834 id_to_item_controller_map_.erase(iter); | 1680 id_to_item_controller_map_.erase(iter); |
| 1835 } | 1681 } |
| 1836 | 1682 |
| 1837 void ChromeLauncherControllerImpl::ShelfItemMoved(int start_index, | 1683 void ChromeLauncherControllerImpl::ShelfItemMoved(int start_index, |
| 1838 int target_index) { | 1684 int target_index) { |
| 1839 const ash::ShelfItem& item = model_->items()[target_index]; | 1685 const ash::ShelfItem& item = model_->items()[target_index]; |
| 1840 // We remember the moved item position if it is either pinnable or | 1686 // We remember the moved item position if it is either pinnable or |
| 1841 // it is the app list with the alternate shelf layout. | 1687 // it is the app list with the alternate shelf layout. |
| 1842 if ((HasShelfIDToAppIDMapping(item.id) && IsPinned(item.id)) || | 1688 DCHECK_NE(ash::TYPE_APP_LIST, item.type); |
| 1843 item.type == ash::TYPE_APP_LIST) | 1689 if (HasShelfIDToAppIDMapping(item.id) && IsPinned(item.id)) |
| 1844 PersistPinnedState(); | 1690 SyncPinPosition(item.id); |
| 1845 } | 1691 } |
| 1846 | 1692 |
| 1847 void ChromeLauncherControllerImpl::ShelfItemChanged( | 1693 void ChromeLauncherControllerImpl::ShelfItemChanged( |
| 1848 int index, | 1694 int index, |
| 1849 const ash::ShelfItem& old_item) {} | 1695 const ash::ShelfItem& old_item) {} |
| 1850 | 1696 |
| 1851 /////////////////////////////////////////////////////////////////////////////// | 1697 /////////////////////////////////////////////////////////////////////////////// |
| 1852 // ash::WindowTreeHostManager::Observer: | 1698 // ash::WindowTreeHostManager::Observer: |
| 1853 | 1699 |
| 1854 void ChromeLauncherControllerImpl::OnDisplayConfigurationChanged() { | 1700 void ChromeLauncherControllerImpl::OnDisplayConfigurationChanged() { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1882 continue; | 1728 continue; |
| 1883 int index = model_->ItemIndexByID(i->first); | 1729 int index = model_->ItemIndexByID(i->first); |
| 1884 if (index == -1) | 1730 if (index == -1) |
| 1885 continue; | 1731 continue; |
| 1886 ash::ShelfItem item = model_->items()[index]; | 1732 ash::ShelfItem item = model_->items()[index]; |
| 1887 item.image = image; | 1733 item.image = image; |
| 1888 model_->Set(index, item); | 1734 model_->Set(index, item); |
| 1889 // It's possible we're waiting on more than one item, so don't break. | 1735 // It's possible we're waiting on more than one item, so don't break. |
| 1890 } | 1736 } |
| 1891 } | 1737 } |
| OLD | NEW |