| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" | 5 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| 11 #include "ash/ash_switches.h" | 11 #include "ash/ash_switches.h" |
| 12 #include "ash/common/shelf/shelf_item_delegate_manager.h" | 12 #include "ash/common/shelf/shelf_item_delegate_manager.h" |
| 13 #include "ash/common/shelf/shelf_model.h" | 13 #include "ash/common/shelf/shelf_model.h" |
| 14 #include "ash/desktop_background/desktop_background_controller.h" | 14 #include "ash/desktop_background/desktop_background_controller.h" |
| 15 #include "ash/multi_profile_uma.h" | 15 #include "ash/multi_profile_uma.h" |
| 16 #include "ash/root_window_controller.h" | 16 #include "ash/root_window_controller.h" |
| 17 #include "ash/shelf/shelf.h" | 17 #include "ash/shelf/shelf.h" |
| 18 #include "ash/shell.h" | 18 #include "ash/shell.h" |
| 19 #include "ash/system/tray/system_tray_delegate.h" | 19 #include "ash/system/tray/system_tray_delegate.h" |
| 20 #include "ash/wm/window_util.h" | 20 #include "ash/wm/window_util.h" |
| 21 #include "base/command_line.h" | 21 #include "base/command_line.h" |
| 22 #include "base/macros.h" | 22 #include "base/macros.h" |
| 23 #include "base/strings/pattern.h" | 23 #include "base/strings/pattern.h" |
| 24 #include "base/strings/string_util.h" | 24 #include "base/strings/string_util.h" |
| 25 #include "base/strings/utf_string_conversions.h" | 25 #include "base/strings/utf_string_conversions.h" |
| 26 #include "base/values.h" | 26 #include "base/values.h" |
| 27 #include "build/build_config.h" | 27 #include "build/build_config.h" |
| 28 #include "chrome/browser/browser_process.h" | 28 #include "chrome/browser/browser_process.h" |
| 29 #include "chrome/browser/chrome_notification_types.h" | 29 #include "chrome/browser/chrome_notification_types.h" |
| 30 #include "chrome/browser/chromeos/arc/arc_support_host.h" | |
| 31 #include "chrome/browser/defaults.h" | 30 #include "chrome/browser/defaults.h" |
| 32 #include "chrome/browser/extensions/extension_app_icon_loader.h" | 31 #include "chrome/browser/extensions/extension_app_icon_loader.h" |
| 33 #include "chrome/browser/extensions/extension_util.h" | 32 #include "chrome/browser/extensions/extension_util.h" |
| 34 #include "chrome/browser/extensions/launch_util.h" | 33 #include "chrome/browser/extensions/launch_util.h" |
| 35 #include "chrome/browser/prefs/incognito_mode_prefs.h" | 34 #include "chrome/browser/prefs/incognito_mode_prefs.h" |
| 36 #include "chrome/browser/prefs/pref_service_syncable_util.h" | 35 #include "chrome/browser/prefs/pref_service_syncable_util.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" |
| 39 #include "chrome/browser/ui/app_list/arc/arc_app_icon_loader.h" | 38 #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" | 39 #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 const char* local_path, | 127 const char* local_path, |
| 129 const char* synced_path) { | 128 const char* synced_path) { |
| 130 if (!pref_service->FindPreference(local_path)->HasUserSetting() && | 129 if (!pref_service->FindPreference(local_path)->HasUserSetting() && |
| 131 pref_service->IsSyncing()) { | 130 pref_service->IsSyncing()) { |
| 132 // First time the user is using this machine, propagate from remote to | 131 // First time the user is using this machine, propagate from remote to |
| 133 // local. | 132 // local. |
| 134 pref_service->SetString(local_path, pref_service->GetString(synced_path)); | 133 pref_service->SetString(local_path, pref_service->GetString(synced_path)); |
| 135 } | 134 } |
| 136 } | 135 } |
| 137 | 136 |
| 138 /* | |
| 139 * Return whether an app is pinned only by user. | |
| 140 * This function doesn't expect an app_id neither pinned by user nor by | |
| 141 * policy, the app_id in the arguments list MUST be pinned by either of | |
| 142 * those. Invalid input may lead to unexpected result. | |
| 143 * If this app is pinned by policy, but not by user, false is returned. | |
| 144 * If this app is pinned by both policy and user, false is returned. | |
| 145 * If this app is pinned not by policy, but by user, true is returned. | |
| 146 */ | |
| 147 bool IsAppForUserPinned(const std::string& app_id, | |
| 148 const base::ListValue* pinned_apps_pref, | |
| 149 const base::ListValue* policy_pinned_apps_pref) { | |
| 150 for (size_t index = 0; index < pinned_apps_pref->GetSize(); ++index) { | |
| 151 const base::DictionaryValue* app; | |
| 152 if (pinned_apps_pref->GetDictionary(index, &app)) { | |
| 153 std::string current_app_id; | |
| 154 bool pinned_by_policy = false; | |
| 155 if (app->GetString(ash::kPinnedAppsPrefAppIDPath, ¤t_app_id)) { | |
| 156 if (app_id == current_app_id) { | |
| 157 if (app->GetBoolean(ash::kPinnedAppsPrefPinnedByPolicy, | |
| 158 &pinned_by_policy) && | |
| 159 pinned_by_policy) { | |
| 160 // Pinned by policy in the past or present. | |
| 161 // Need to check policy_pinned_apps to determine | |
| 162 break; | |
| 163 } else { | |
| 164 // User Preference Already Pinned | |
| 165 return true; | |
| 166 } | |
| 167 } | |
| 168 } | |
| 169 } | |
| 170 } | |
| 171 for (size_t index = 0; index < policy_pinned_apps_pref->GetSize(); ++index) { | |
| 172 const base::DictionaryValue* app; | |
| 173 if (policy_pinned_apps_pref->GetDictionary(index, &app)) { | |
| 174 std::string app_id_; | |
| 175 if (app->GetString(ash::kPinnedAppsPrefAppIDPath, &app_id_)) { | |
| 176 // Only pinned by policy, which is not part of user-pinned | |
| 177 if (app_id == app_id_) | |
| 178 return false; | |
| 179 } | |
| 180 } | |
| 181 } | |
| 182 // Default, user added new pins | |
| 183 return true; | |
| 184 } | |
| 185 | |
| 186 const char* const kPinProhibitedExtensionIds[] = { | |
| 187 ArcSupportHost::kHostAppId, arc::kPlayStoreAppId, | |
| 188 }; | |
| 189 | |
| 190 const size_t kPinProhibitedExtensionIdsLength = | |
| 191 arraysize(kPinProhibitedExtensionIds); | |
| 192 | |
| 193 } // namespace | 137 } // namespace |
| 194 | 138 |
| 195 // A class to get events from ChromeOS when a user gets changed or added. | 139 // A class to get events from ChromeOS when a user gets changed or added. |
| 196 class ChromeLauncherControllerUserSwitchObserver | 140 class ChromeLauncherControllerUserSwitchObserver |
| 197 : public user_manager::UserManager::UserSessionStateObserver { | 141 : public user_manager::UserManager::UserSessionStateObserver { |
| 198 public: | 142 public: |
| 199 ChromeLauncherControllerUserSwitchObserver( | 143 ChromeLauncherControllerUserSwitchObserver( |
| 200 ChromeLauncherController* controller) | 144 ChromeLauncherController* controller) |
| 201 : controller_(controller) { | 145 : controller_(controller) { |
| 202 DCHECK(user_manager::UserManager::IsInitialized()); | 146 DCHECK(user_manager::UserManager::IsInitialized()); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 257 | 201 |
| 258 void ChromeLauncherControllerUserSwitchObserver::AddUser(Profile* profile) { | 202 void ChromeLauncherControllerUserSwitchObserver::AddUser(Profile* profile) { |
| 259 if (chrome::MultiUserWindowManager::GetMultiProfileMode() == | 203 if (chrome::MultiUserWindowManager::GetMultiProfileMode() == |
| 260 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED) | 204 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED) |
| 261 chrome::MultiUserWindowManager::GetInstance()->AddUser(profile); | 205 chrome::MultiUserWindowManager::GetInstance()->AddUser(profile); |
| 262 controller_->AdditionalUserAddedToSession(profile->GetOriginalProfile()); | 206 controller_->AdditionalUserAddedToSession(profile->GetOriginalProfile()); |
| 263 } | 207 } |
| 264 | 208 |
| 265 ChromeLauncherController::ChromeLauncherController(Profile* profile, | 209 ChromeLauncherController::ChromeLauncherController(Profile* profile, |
| 266 ash::ShelfModel* model) | 210 ash::ShelfModel* model) |
| 267 : model_(model), | 211 : model_(model), profile_(profile) { |
| 268 item_delegate_manager_(NULL), | |
| 269 profile_(profile), | |
| 270 app_sync_ui_state_(NULL), | |
| 271 ignore_persist_pinned_state_change_(false) { | |
| 272 if (!profile_) { | 212 if (!profile_) { |
| 273 // If no profile was passed, we take the currently active profile and use it | 213 // If no profile was passed, we take the currently active profile and use it |
| 274 // as the owner of the current desktop. | 214 // as the owner of the current desktop. |
| 275 // Use the original profile as on chromeos we may get a temporary off the | 215 // Use the original profile as on chromeos we may get a temporary off the |
| 276 // record profile, unless in guest session (where off the record profile is | 216 // record profile, unless in guest session (where off the record profile is |
| 277 // the right one). | 217 // the right one). |
| 278 profile_ = ProfileManager::GetActiveUserProfile(); | 218 profile_ = ProfileManager::GetActiveUserProfile(); |
| 279 if (!profile_->IsGuestSession() && !profile_->IsSystemProfile()) | 219 if (!profile_->IsGuestSession() && !profile_->IsSystemProfile()) |
| 280 profile_ = profile_->GetOriginalProfile(); | 220 profile_ = profile_->GetOriginalProfile(); |
| 281 | 221 |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 456 iter->second->set_shelf_id(id); | 396 iter->second->set_shelf_id(id); |
| 457 // Existing controller is destroyed and replaced by registering again. | 397 // Existing controller is destroyed and replaced by registering again. |
| 458 SetShelfItemDelegate(id, iter->second); | 398 SetShelfItemDelegate(id, iter->second); |
| 459 } else { | 399 } else { |
| 460 LauncherItemClosed(id); | 400 LauncherItemClosed(id); |
| 461 } | 401 } |
| 462 } | 402 } |
| 463 | 403 |
| 464 AppListControllerDelegate::Pinnable ChromeLauncherController::GetPinnable( | 404 AppListControllerDelegate::Pinnable ChromeLauncherController::GetPinnable( |
| 465 const std::string& app_id) { | 405 const std::string& app_id) { |
| 466 for (size_t i = 0; i < kPinProhibitedExtensionIdsLength; ++i) { | |
| 467 if (kPinProhibitedExtensionIds[i] == app_id) | |
| 468 return AppListControllerDelegate::NO_PIN; | |
| 469 } | |
| 470 | |
| 471 const base::ListValue* pref = | 406 const base::ListValue* pref = |
| 472 profile_->GetPrefs()->GetList(prefs::kPolicyPinnedLauncherApps); | 407 profile_->GetPrefs()->GetList(prefs::kPolicyPinnedLauncherApps); |
| 473 if (!pref) | 408 if (!pref) |
| 474 return AppListControllerDelegate::PIN_EDITABLE; | 409 return AppListControllerDelegate::PIN_EDITABLE; |
| 475 | 410 |
| 476 // Pinned ARC apps policy defines the package name of the apps, that must | 411 // Pinned ARC apps policy defines the package name of the apps, that must |
| 477 // be pinned. All the launch activities of any package in policy are pinned. | 412 // be pinned. All the launch activities of any package in policy are pinned. |
| 478 // In turn the input parameter to this function is app_id, which | 413 // In turn the input parameter to this function is app_id, which |
| 479 // is 32 chars hash. In case of ARC app this is a hash of | 414 // is 32 chars hash. In case of ARC app this is a hash of |
| 480 // (package name + activity). This means that we must identify the package | 415 // (package name + activity). This means that we must identify the package |
| (...skipping 29 matching lines...) Expand all Loading... |
| 510 ash::ShelfItem item = model_->items()[index]; | 445 ash::ShelfItem item = model_->items()[index]; |
| 511 | 446 |
| 512 if (item.type == ash::TYPE_PLATFORM_APP || | 447 if (item.type == ash::TYPE_PLATFORM_APP || |
| 513 item.type == ash::TYPE_WINDOWED_APP) { | 448 item.type == ash::TYPE_WINDOWED_APP) { |
| 514 item.type = ash::TYPE_APP_SHORTCUT; | 449 item.type = ash::TYPE_APP_SHORTCUT; |
| 515 model_->Set(index, item); | 450 model_->Set(index, item); |
| 516 } else if (item.type != ash::TYPE_APP_SHORTCUT) { | 451 } else if (item.type != ash::TYPE_APP_SHORTCUT) { |
| 517 return; | 452 return; |
| 518 } | 453 } |
| 519 | 454 |
| 520 if (GetLauncherItemController(id)->CanPin()) | 455 SyncPinPosition(id); |
| 521 PersistPinnedState(); | |
| 522 } | 456 } |
| 523 | 457 |
| 524 void ChromeLauncherController::Unpin(ash::ShelfID id) { | 458 void ChromeLauncherController::Unpin(ash::ShelfID id) { |
| 525 LauncherItemController* controller = GetLauncherItemController(id); | 459 LauncherItemController* controller = GetLauncherItemController(id); |
| 526 CHECK(controller); | 460 CHECK(controller); |
| 527 const bool can_pin = controller->CanPin(); | 461 |
| 462 ash::RemovePinPosition(profile_, GetAppIDForShelfID(id)); |
| 528 | 463 |
| 529 if (controller->type() == LauncherItemController::TYPE_APP || | 464 if (controller->type() == LauncherItemController::TYPE_APP || |
| 530 controller->locked()) { | 465 controller->locked()) { |
| 531 UnpinRunningAppInternal(model_->ItemIndexByID(id)); | 466 UnpinRunningAppInternal(model_->ItemIndexByID(id)); |
| 532 } else { | 467 } else { |
| 533 LauncherItemClosed(id); | 468 LauncherItemClosed(id); |
| 534 } | 469 } |
| 535 if (can_pin) | |
| 536 PersistPinnedState(); | |
| 537 } | 470 } |
| 538 | 471 |
| 539 bool ChromeLauncherController::IsPinned(ash::ShelfID id) { | 472 bool ChromeLauncherController::IsPinned(ash::ShelfID id) { |
| 540 int index = model_->ItemIndexByID(id); | 473 int index = model_->ItemIndexByID(id); |
| 541 if (index < 0) | 474 if (index < 0) |
| 542 return false; | 475 return false; |
| 543 ash::ShelfItemType type = model_->items()[index].type; | 476 ash::ShelfItemType type = model_->items()[index].type; |
| 544 return (type == ash::TYPE_APP_SHORTCUT || type == ash::TYPE_BROWSER_SHORTCUT); | 477 return (type == ash::TYPE_APP_SHORTCUT || type == ash::TYPE_BROWSER_SHORTCUT); |
| 545 } | 478 } |
| 546 | 479 |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 778 void ChromeLauncherController::CreateNewWindow() { | 711 void ChromeLauncherController::CreateNewWindow() { |
| 779 // Use the currently active user. | 712 // Use the currently active user. |
| 780 chrome::NewEmptyWindow(profile_); | 713 chrome::NewEmptyWindow(profile_); |
| 781 } | 714 } |
| 782 | 715 |
| 783 void ChromeLauncherController::CreateNewIncognitoWindow() { | 716 void ChromeLauncherController::CreateNewIncognitoWindow() { |
| 784 // Use the currently active user. | 717 // Use the currently active user. |
| 785 chrome::NewEmptyWindow(profile_->GetOffTheRecordProfile()); | 718 chrome::NewEmptyWindow(profile_->GetOffTheRecordProfile()); |
| 786 } | 719 } |
| 787 | 720 |
| 788 void ChromeLauncherController::PersistPinnedState() { | |
| 789 if (ignore_persist_pinned_state_change_) | |
| 790 return; | |
| 791 // It is a coding error to call PersistPinnedState() if the pinned apps are | |
| 792 // not user-editable. The code should check earlier and not perform any | |
| 793 // modification actions that trigger persisting the state. | |
| 794 // Mutating kPinnedLauncherApps is going to notify us and trigger us to | |
| 795 // process the change. We don't want that to happen so remove ourselves as a | |
| 796 // listener. | |
| 797 pref_change_registrar_.Remove(prefs::kPinnedLauncherApps); | |
| 798 { | |
| 799 std::unique_ptr<const base::ListValue> pinned_apps_pref = | |
| 800 profile_->GetPrefs() | |
| 801 ->GetList(prefs::kPinnedLauncherApps) | |
| 802 ->CreateDeepCopy(); | |
| 803 | |
| 804 const base::ListValue* policy_pinned_apps_pref = | |
| 805 profile_->GetPrefs()->GetList(prefs::kPolicyPinnedLauncherApps); | |
| 806 | |
| 807 ListPrefUpdate updater(profile_->GetPrefs(), prefs::kPinnedLauncherApps); | |
| 808 updater->Clear(); | |
| 809 for (size_t i = 0; i < model_->items().size(); ++i) { | |
| 810 if (model_->items()[i].type == ash::TYPE_APP_SHORTCUT) { | |
| 811 ash::ShelfID id = model_->items()[i].id; | |
| 812 LauncherItemController* controller = GetLauncherItemController(id); | |
| 813 // Don't persist pinning state for apps that are handled internally and | |
| 814 // have pinnable state AppListControllerDelegate::NO_PIN. | |
| 815 if (controller && IsPinned(id) && | |
| 816 GetPinnable(controller->app_id()) != | |
| 817 AppListControllerDelegate::NO_PIN) { | |
| 818 base::DictionaryValue* app_value = ash::CreateAppDict( | |
| 819 controller->app_id()); | |
| 820 if (app_value) { | |
| 821 if (!IsAppForUserPinned(controller->app_id(), | |
| 822 pinned_apps_pref.get(), | |
| 823 policy_pinned_apps_pref)) | |
| 824 app_value->SetBoolean(ash::kPinnedAppsPrefPinnedByPolicy, true); | |
| 825 updater->Append(app_value); | |
| 826 } | |
| 827 } | |
| 828 } else if (model_->items()[i].type == ash::TYPE_BROWSER_SHORTCUT) { | |
| 829 PersistChromeItemIndex(i); | |
| 830 } else if (model_->items()[i].type == ash::TYPE_APP_LIST) { | |
| 831 base::DictionaryValue* app_value = | |
| 832 ash::CreateAppDict(ash::kPinnedAppsPlaceholder); | |
| 833 if (app_value) | |
| 834 updater->Append(app_value); | |
| 835 } | |
| 836 } | |
| 837 } | |
| 838 pref_change_registrar_.Add( | |
| 839 prefs::kPinnedLauncherApps, | |
| 840 base::Bind(&ChromeLauncherController::UpdateAppLaunchersFromPref, | |
| 841 base::Unretained(this))); | |
| 842 } | |
| 843 | |
| 844 Profile* ChromeLauncherController::profile() { | 721 Profile* ChromeLauncherController::profile() { |
| 845 return profile_; | 722 return profile_; |
| 846 } | 723 } |
| 847 | 724 |
| 848 void ChromeLauncherController::UpdateAppState(content::WebContents* contents, | 725 void ChromeLauncherController::UpdateAppState(content::WebContents* contents, |
| 849 AppState app_state) { | 726 AppState app_state) { |
| 850 std::string app_id = launcher_controller_helper_->GetAppID(contents); | 727 std::string app_id = launcher_controller_helper_->GetAppID(contents); |
| 851 | 728 |
| 852 // Check if the gMail app is loaded and it matches the given content. | 729 // Check if the gMail app is loaded and it matches the given content. |
| 853 // This special treatment is needed to address crbug.com/234268. | 730 // This special treatment is needed to address crbug.com/234268. |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 983 GetDisplayIDForShelf(shelf), | 860 GetDisplayIDForShelf(shelf), |
| 984 shelf->auto_hide_behavior()); | 861 shelf->auto_hide_behavior()); |
| 985 } | 862 } |
| 986 | 863 |
| 987 void ChromeLauncherController::OnShelfAutoHideStateChanged(ash::Shelf* shelf) {} | 864 void ChromeLauncherController::OnShelfAutoHideStateChanged(ash::Shelf* shelf) {} |
| 988 | 865 |
| 989 void ChromeLauncherController::OnShelfVisibilityStateChanged( | 866 void ChromeLauncherController::OnShelfVisibilityStateChanged( |
| 990 ash::Shelf* shelf) {} | 867 ash::Shelf* shelf) {} |
| 991 | 868 |
| 992 void ChromeLauncherController::ShelfItemAdded(int index) { | 869 void ChromeLauncherController::ShelfItemAdded(int index) { |
| 993 // The app list launcher can get added to the shelf after we applied the | |
| 994 // preferences. In that case the item might be at the wrong spot. As such we | |
| 995 // call the function again. | |
| 996 if (model_->items()[index].type == ash::TYPE_APP_LIST) | |
| 997 UpdateAppLaunchersFromPref(); | |
| 998 } | 870 } |
| 999 | 871 |
| 1000 void ChromeLauncherController::ShelfItemRemoved(int index, ash::ShelfID id) { | 872 void ChromeLauncherController::ShelfItemRemoved(int index, ash::ShelfID id) { |
| 1001 // TODO(skuhne): This fixes crbug.com/429870, but it does not answer why we | 873 // TODO(skuhne): This fixes crbug.com/429870, but it does not answer why we |
| 1002 // get into this state in the first place. | 874 // get into this state in the first place. |
| 1003 IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id); | 875 IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id); |
| 1004 if (iter == id_to_item_controller_map_.end()) | 876 if (iter == id_to_item_controller_map_.end()) |
| 1005 return; | 877 return; |
| 1006 | 878 |
| 1007 LOG(ERROR) << "Unexpected change of shelf item id: " << id; | 879 LOG(ERROR) << "Unexpected change of shelf item id: " << id; |
| 1008 | 880 |
| 1009 id_to_item_controller_map_.erase(iter); | 881 id_to_item_controller_map_.erase(iter); |
| 1010 } | 882 } |
| 1011 | 883 |
| 1012 void ChromeLauncherController::ShelfItemMoved(int start_index, | 884 void ChromeLauncherController::ShelfItemMoved(int start_index, |
| 1013 int target_index) { | 885 int target_index) { |
| 1014 const ash::ShelfItem& item = model_->items()[target_index]; | 886 const ash::ShelfItem& item = model_->items()[target_index]; |
| 1015 // We remember the moved item position if it is either pinnable or | 887 // We remember the moved item position if it is either pinnable or |
| 1016 // it is the app list with the alternate shelf layout. | 888 // it is the app list with the alternate shelf layout. |
| 1017 if ((HasShelfIDToAppIDMapping(item.id) && IsPinned(item.id)) || | 889 DCHECK_NE(ash::TYPE_APP_LIST, item.type); |
| 1018 item.type == ash::TYPE_APP_LIST) | 890 if (HasShelfIDToAppIDMapping(item.id) && IsPinned(item.id)) |
| 1019 PersistPinnedState(); | 891 SyncPinPosition(item.id); |
| 1020 } | 892 } |
| 1021 | 893 |
| 1022 void ChromeLauncherController::ShelfItemChanged( | 894 void ChromeLauncherController::ShelfItemChanged( |
| 1023 int index, | 895 int index, |
| 1024 const ash::ShelfItem& old_item) {} | 896 const ash::ShelfItem& old_item) {} |
| 1025 | 897 |
| 1026 void ChromeLauncherController::ActiveUserChanged( | 898 void ChromeLauncherController::ActiveUserChanged( |
| 1027 const std::string& user_email) { | 899 const std::string& user_email) { |
| 1028 // Store the order of running applications for the user which gets inactive. | 900 // Store the order of running applications for the user which gets inactive. |
| 1029 RememberUnpinnedRunningApplicationOrder(); | 901 RememberUnpinnedRunningApplicationOrder(); |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1380 if (IsAppPinned(app_id)) | 1252 if (IsAppPinned(app_id)) |
| 1381 return; | 1253 return; |
| 1382 | 1254 |
| 1383 ash::ShelfID shelf_id = GetShelfIDForAppID(app_id); | 1255 ash::ShelfID shelf_id = GetShelfIDForAppID(app_id); |
| 1384 if (shelf_id) { | 1256 if (shelf_id) { |
| 1385 // App item exists, pin it | 1257 // App item exists, pin it |
| 1386 Pin(shelf_id); | 1258 Pin(shelf_id); |
| 1387 } else { | 1259 } else { |
| 1388 // Otherwise, create a shortcut item for it. | 1260 // Otherwise, create a shortcut item for it. |
| 1389 shelf_id = CreateAppShortcutLauncherItem(app_id, model_->item_count()); | 1261 shelf_id = CreateAppShortcutLauncherItem(app_id, model_->item_count()); |
| 1390 if (GetPinnable(app_id) == AppListControllerDelegate::PIN_EDITABLE) | 1262 SyncPinPosition(shelf_id); |
| 1391 PersistPinnedState(); | |
| 1392 } | 1263 } |
| 1393 } | 1264 } |
| 1394 | 1265 |
| 1395 void ChromeLauncherController::DoUnpinAppWithID(const std::string& app_id) { | 1266 void ChromeLauncherController::DoUnpinAppWithID(const std::string& app_id) { |
| 1396 ash::ShelfID shelf_id = GetShelfIDForAppID(app_id); | 1267 ash::ShelfID shelf_id = GetShelfIDForAppID(app_id); |
| 1397 if (shelf_id && IsPinned(shelf_id)) | 1268 if (shelf_id && IsPinned(shelf_id)) |
| 1398 Unpin(shelf_id); | 1269 Unpin(shelf_id); |
| 1399 } | 1270 } |
| 1400 | 1271 |
| 1401 int ChromeLauncherController::PinRunningAppInternal(int index, | 1272 int ChromeLauncherController::PinRunningAppInternal(int index, |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1422 DCHECK_EQ(item.type, ash::TYPE_APP_SHORTCUT); | 1293 DCHECK_EQ(item.type, ash::TYPE_APP_SHORTCUT); |
| 1423 item.type = ash::TYPE_WINDOWED_APP; | 1294 item.type = ash::TYPE_WINDOWED_APP; |
| 1424 // A platform app and a windowed app are sharing TYPE_APP_SHORTCUT. As such | 1295 // A platform app and a windowed app are sharing TYPE_APP_SHORTCUT. As such |
| 1425 // we have to check here what this was before it got a shortcut. | 1296 // we have to check here what this was before it got a shortcut. |
| 1426 LauncherItemController* controller = GetLauncherItemController(item.id); | 1297 LauncherItemController* controller = GetLauncherItemController(item.id); |
| 1427 if (controller && controller->type() == LauncherItemController::TYPE_APP) | 1298 if (controller && controller->type() == LauncherItemController::TYPE_APP) |
| 1428 item.type = ash::TYPE_PLATFORM_APP; | 1299 item.type = ash::TYPE_PLATFORM_APP; |
| 1429 model_->Set(index, item); | 1300 model_->Set(index, item); |
| 1430 } | 1301 } |
| 1431 | 1302 |
| 1303 void ChromeLauncherController::SyncPinPosition(ash::ShelfID shelf_id) { |
| 1304 DCHECK(shelf_id); |
| 1305 if (ignore_persist_pinned_state_change_) |
| 1306 return; |
| 1307 |
| 1308 const int max_index = model_->item_count(); |
| 1309 const int index = model_->ItemIndexByID(shelf_id); |
| 1310 DCHECK_GT(index, 0); |
| 1311 |
| 1312 const std::string& app_id = GetAppIDForShelfID(shelf_id); |
| 1313 DCHECK(!app_id.empty()); |
| 1314 |
| 1315 std::string app_id_before; |
| 1316 std::string app_id_after; |
| 1317 |
| 1318 for (int i = index - 1; i > 0; --i) { |
| 1319 const ash::ShelfID shelf_id_before = model_->items()[i].id; |
| 1320 if (IsPinned(shelf_id_before)) { |
| 1321 app_id_before = GetAppIDForShelfID(shelf_id_before); |
| 1322 DCHECK(!app_id_before.empty()); |
| 1323 break; |
| 1324 } |
| 1325 } |
| 1326 |
| 1327 for (int i = index + 1; i < max_index; ++i) { |
| 1328 const ash::ShelfID shelf_id_after = model_->items()[i].id; |
| 1329 if (IsPinned(shelf_id_after)) { |
| 1330 app_id_after = GetAppIDForShelfID(shelf_id_after); |
| 1331 DCHECK(!app_id_after.empty()); |
| 1332 break; |
| 1333 } |
| 1334 } |
| 1335 |
| 1336 ash::SetPinPosition(profile_, app_id, app_id_before, app_id_after); |
| 1337 } |
| 1338 |
| 1339 void ChromeLauncherController::OnSyncModelUpdated() { |
| 1340 UpdateAppLaunchersFromPref(); |
| 1341 } |
| 1342 |
| 1432 void ChromeLauncherController::UpdateAppLaunchersFromPref() { | 1343 void ChromeLauncherController::UpdateAppLaunchersFromPref() { |
| 1433 // There are various functions which will trigger a |PersistPinnedState| call | 1344 // There are various functions which will trigger a |SyncPinPosition| call |
| 1434 // like a direct call to |DoPinAppWithID|, or an indirect call to the menu | 1345 // like a direct call to |DoPinAppWithID|, or an indirect call to the |
| 1435 // model which will use weights to re-arrange the icons to new positions. | 1346 // menu model which will use weights to re-arrange the icons to new positions. |
| 1436 // Since this function is meant to synchronize the "is state" with the | 1347 // Since this function is meant to synchronize the "is state" with the |
| 1437 // "sync state", it makes no sense to store any changes by this function back | 1348 // "sync state", it makes no sense to store any changes by this function back |
| 1438 // into the pref state. Therefore we tell |persistPinnedState| to ignore any | 1349 // into the pref state. Therefore we tell |persistPinnedState| to ignore any |
| 1439 // invocations while we are running. | 1350 // invocations while we are running. |
| 1440 base::AutoReset<bool> auto_reset(&ignore_persist_pinned_state_change_, true); | 1351 base::AutoReset<bool> auto_reset(&ignore_persist_pinned_state_change_, true); |
| 1352 |
| 1441 std::vector<std::string> pinned_apps = ash::GetPinnedAppsFromPrefs( | 1353 std::vector<std::string> pinned_apps = ash::GetPinnedAppsFromPrefs( |
| 1442 profile_->GetPrefs(), launcher_controller_helper_.get()); | 1354 profile_->GetPrefs(), launcher_controller_helper_.get()); |
| 1443 | 1355 |
| 1444 int index = 0; | 1356 int index = 0; |
| 1445 int max_index = model_->item_count(); | 1357 int max_index = model_->item_count(); |
| 1358 int seen_chrome_index = -1; |
| 1446 | 1359 |
| 1447 // When one of the two special items cannot be moved (and we do not know where | 1360 // At least chrome browser shortcut should exist. |
| 1448 // yet), we remember the current location in one of these variables. | 1361 DCHECK_GT(max_index, 0); |
| 1449 int chrome_index = -1; | 1362 |
| 1450 int app_list_index = -1; | 1363 // Skip app list items if it exists. |
| 1364 if (model_->items()[0].type == ash::TYPE_APP_LIST) |
| 1365 ++index; |
| 1451 | 1366 |
| 1452 // Walk the model and |pinned_apps| from the pref lockstep, adding and | 1367 // Walk the model and |pinned_apps| from the pref lockstep, adding and |
| 1453 // removing items as necessary. NB: This code uses plain old indexing instead | 1368 // removing items as necessary. NB: This code uses plain old indexing instead |
| 1454 // of iterators because of model mutations as part of the loop. | 1369 // of iterators because of model mutations as part of the loop. |
| 1455 std::vector<std::string>::const_iterator pref_app_id(pinned_apps.begin()); | 1370 std::vector<std::string>::const_iterator pref_app_id(pinned_apps.begin()); |
| 1456 for (; index < max_index && pref_app_id != pinned_apps.end(); ++index) { | 1371 for (; index < max_index && pref_app_id != pinned_apps.end(); ++index) { |
| 1457 // Check if we have an item which we need to handle. | 1372 // Check if we have an item which we need to handle. |
| 1458 if (*pref_app_id == extension_misc::kChromeAppId || | 1373 if (IsAppPinned(*pref_app_id)) { |
| 1459 *pref_app_id == ash::kPinnedAppsPlaceholder || | 1374 if (seen_chrome_index >= 0 && |
| 1460 IsAppPinned(*pref_app_id)) { | 1375 *pref_app_id == extension_misc::kChromeAppId) { |
| 1376 // Current item is Chrome browser and we saw it before. |
| 1377 model_->Move(seen_chrome_index, index); |
| 1378 ++pref_app_id; |
| 1379 --index; |
| 1380 continue; |
| 1381 } |
| 1461 for (; index < max_index; ++index) { | 1382 for (; index < max_index; ++index) { |
| 1462 const ash::ShelfItem& item(model_->items()[index]); | 1383 const ash::ShelfItem& item(model_->items()[index]); |
| 1463 bool is_app_list = item.type == ash::TYPE_APP_LIST; | 1384 if (item.type != ash::TYPE_APP_SHORTCUT && |
| 1464 bool is_chrome = item.type == ash::TYPE_BROWSER_SHORTCUT; | 1385 item.type != ash::TYPE_BROWSER_SHORTCUT) |
| 1465 if (item.type != ash::TYPE_APP_SHORTCUT && !is_app_list && !is_chrome) | |
| 1466 continue; | 1386 continue; |
| 1467 LauncherItemController* controller = GetLauncherItemController(item.id); | 1387 LauncherItemController* controller = GetLauncherItemController(item.id); |
| 1468 if ((ash::kPinnedAppsPlaceholder == *pref_app_id && is_app_list) || | 1388 if (controller && controller->app_id() == *pref_app_id) { |
| 1469 (extension_misc::kChromeAppId == *pref_app_id && is_chrome) || | |
| 1470 (controller && controller->app_id() == *pref_app_id)) { | |
| 1471 // Check if an item needs to be moved here. | |
| 1472 MoveChromeOrApplistToFinalPosition( | |
| 1473 is_chrome, is_app_list, index, &chrome_index, &app_list_index); | |
| 1474 ++pref_app_id; | 1389 ++pref_app_id; |
| 1475 break; | 1390 break; |
| 1391 } else if (item.type == ash::TYPE_BROWSER_SHORTCUT) { |
| 1392 // We cannot close browser shortcut. Remember its position. |
| 1393 seen_chrome_index = index; |
| 1476 } else { | 1394 } else { |
| 1477 if (is_chrome || is_app_list) { | 1395 // Check if this is a platform or a windowed app. |
| 1478 // We cannot delete any of these shortcuts. As such we remember | 1396 if (item.type == ash::TYPE_APP_SHORTCUT && controller && |
| 1479 // their positions and move them later where they belong. | 1397 (controller->locked() || |
| 1480 if (is_chrome) | 1398 controller->type() == LauncherItemController::TYPE_APP)) { |
| 1481 chrome_index = index; | 1399 // Note: This will not change the amount of items (|max_index|). |
| 1482 else | 1400 // Even changes to the actual |index| due to item weighting |
| 1483 app_list_index = index; | 1401 // changes should be fine. |
| 1484 // And skip the item - or exit the loop if end is reached (note that | 1402 UnpinRunningAppInternal(index); |
| 1485 // in that case we will reduce the index again by one and this only | |
| 1486 // compensates for it). | |
| 1487 if (index >= max_index - 1) | |
| 1488 break; | |
| 1489 ++index; | |
| 1490 } else { | 1403 } else { |
| 1491 // Check if this is a platform or a windowed app. | 1404 if (controller) |
| 1492 if (item.type == ash::TYPE_APP_SHORTCUT && | 1405 LauncherItemClosed(item.id); |
| 1493 controller && | 1406 --max_index; |
| 1494 (controller->locked() || | |
| 1495 controller->type() == LauncherItemController::TYPE_APP)) { | |
| 1496 // Note: This will not change the amount of items (|max_index|). | |
| 1497 // Even changes to the actual |index| due to item weighting | |
| 1498 // changes should be fine. | |
| 1499 UnpinRunningAppInternal(index); | |
| 1500 } else { | |
| 1501 if (controller) | |
| 1502 LauncherItemClosed(item.id); | |
| 1503 --max_index; | |
| 1504 } | |
| 1505 } | 1407 } |
| 1506 --index; | 1408 --index; |
| 1507 } | 1409 } |
| 1508 } | 1410 } |
| 1509 // If the item wasn't found, that means id_to_item_controller_map_ | 1411 // If the item wasn't found, that means id_to_item_controller_map_ |
| 1510 // is out of sync. | 1412 // is out of sync. |
| 1511 DCHECK(index <= max_index); | 1413 DCHECK(index <= max_index); |
| 1512 } else { | 1414 } else { |
| 1513 // Check if the item was already running but not yet pinned. | 1415 // Check if the item was already running but not yet pinned. |
| 1514 ash::ShelfID shelf_id = GetShelfIDForAppID(*pref_app_id); | 1416 ash::ShelfID shelf_id = GetShelfIDForAppID(*pref_app_id); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1532 LauncherItemController* controller = GetLauncherItemController(item.id); | 1434 LauncherItemController* controller = GetLauncherItemController(item.id); |
| 1533 if (controller) { | 1435 if (controller) { |
| 1534 if (controller->locked() || | 1436 if (controller->locked() || |
| 1535 controller->type() == LauncherItemController::TYPE_APP) { | 1437 controller->type() == LauncherItemController::TYPE_APP) { |
| 1536 UnpinRunningAppInternal(index); | 1438 UnpinRunningAppInternal(index); |
| 1537 } else { | 1439 } else { |
| 1538 LauncherItemClosed(item.id); | 1440 LauncherItemClosed(item.id); |
| 1539 } | 1441 } |
| 1540 } | 1442 } |
| 1541 } else { | 1443 } else { |
| 1542 if (item.type == ash::TYPE_BROWSER_SHORTCUT) | |
| 1543 chrome_index = index; | |
| 1544 else if (item.type == ash::TYPE_APP_LIST) | |
| 1545 app_list_index = index; | |
| 1546 ++index; | 1444 ++index; |
| 1547 } | 1445 } |
| 1548 } | 1446 } |
| 1549 | 1447 |
| 1550 // Append unprocessed items from the pref to the end of the model. | 1448 // Append unprocessed items from the pref to the end of the model. |
| 1551 for (; pref_app_id != pinned_apps.end(); ++pref_app_id) { | 1449 for (; pref_app_id != pinned_apps.end(); ++pref_app_id) { |
| 1552 // All items but the chrome and / or app list shortcut needs to be added. | 1450 if (*pref_app_id == extension_misc::kChromeAppId) { |
| 1553 bool is_chrome = *pref_app_id == extension_misc::kChromeAppId; | 1451 int target_index = FindInsertionPoint(); |
| 1554 bool is_app_list = *pref_app_id == ash::kPinnedAppsPlaceholder; | 1452 DCHECK(seen_chrome_index >= 0 && seen_chrome_index < target_index); |
| 1555 // Coming here we know the next item which can be finalized, either the | 1453 model_->Move(seen_chrome_index, target_index); |
| 1556 // chrome item or the app launcher. The final position is the end of the | 1454 } else { |
| 1557 // list. The menu model will make sure that the item is grouped according | |
| 1558 // to its weight (which we do not know here). | |
| 1559 if (!is_chrome && !is_app_list) { | |
| 1560 DoPinAppWithID(*pref_app_id); | 1455 DoPinAppWithID(*pref_app_id); |
| 1561 int target_index = FindInsertionPoint(false); | 1456 int target_index = FindInsertionPoint(); |
| 1562 ash::ShelfID id = GetShelfIDForAppID(*pref_app_id); | 1457 ash::ShelfID id = GetShelfIDForAppID(*pref_app_id); |
| 1563 int source_index = model_->ItemIndexByID(id); | 1458 int source_index = model_->ItemIndexByID(id); |
| 1564 if (source_index != target_index) | 1459 if (source_index != target_index) |
| 1565 model_->Move(source_index, target_index); | 1460 model_->Move(source_index, target_index); |
| 1566 | |
| 1567 // Needed for the old layout - the weight might force it to be lower in | |
| 1568 // rank. | |
| 1569 if (app_list_index != -1 && target_index <= app_list_index) | |
| 1570 ++app_list_index; | |
| 1571 } else { | |
| 1572 int target_index = FindInsertionPoint(is_app_list); | |
| 1573 MoveChromeOrApplistToFinalPosition( | |
| 1574 is_chrome, is_app_list, target_index, &chrome_index, &app_list_index); | |
| 1575 } | 1461 } |
| 1576 } | 1462 } |
| 1577 } | 1463 } |
| 1578 | 1464 |
| 1579 void ChromeLauncherController::SetShelfAutoHideBehaviorFromPrefs() { | 1465 void ChromeLauncherController::SetShelfAutoHideBehaviorFromPrefs() { |
| 1580 for (auto* window : ash::Shell::GetAllRootWindows()) { | 1466 for (auto* window : ash::Shell::GetAllRootWindows()) { |
| 1581 ash::Shelf* shelf = ash::Shelf::ForWindow(window); | 1467 ash::Shelf* shelf = ash::Shelf::ForWindow(window); |
| 1582 if (shelf) { | 1468 if (shelf) { |
| 1583 shelf->SetAutoHideBehavior(ash::GetShelfAutoHideBehaviorPref( | 1469 shelf->SetAutoHideBehavior(ash::GetShelfAutoHideBehaviorPref( |
| 1584 profile_->GetPrefs(), GetDisplayIDForShelf(shelf))); | 1470 profile_->GetPrefs(), GetDisplayIDForShelf(shelf))); |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1704 << "There should be always be a BrowserShortcutLauncherItemController."; | 1590 << "There should be always be a BrowserShortcutLauncherItemController."; |
| 1705 return nullptr; | 1591 return nullptr; |
| 1706 } | 1592 } |
| 1707 | 1593 |
| 1708 ash::ShelfID ChromeLauncherController::CreateBrowserShortcutLauncherItem() { | 1594 ash::ShelfID ChromeLauncherController::CreateBrowserShortcutLauncherItem() { |
| 1709 ash::ShelfItem browser_shortcut; | 1595 ash::ShelfItem browser_shortcut; |
| 1710 browser_shortcut.type = ash::TYPE_BROWSER_SHORTCUT; | 1596 browser_shortcut.type = ash::TYPE_BROWSER_SHORTCUT; |
| 1711 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 1597 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| 1712 browser_shortcut.image = *rb.GetImageSkiaNamed(IDR_PRODUCT_LOGO_32); | 1598 browser_shortcut.image = *rb.GetImageSkiaNamed(IDR_PRODUCT_LOGO_32); |
| 1713 ash::ShelfID id = model_->next_id(); | 1599 ash::ShelfID id = model_->next_id(); |
| 1714 size_t index = GetChromeIconIndexForCreation(); | 1600 model_->AddAt(0, browser_shortcut); |
| 1715 model_->AddAt(index, browser_shortcut); | |
| 1716 id_to_item_controller_map_[id] = | 1601 id_to_item_controller_map_[id] = |
| 1717 new BrowserShortcutLauncherItemController(this, model_); | 1602 new BrowserShortcutLauncherItemController(this, model_); |
| 1718 id_to_item_controller_map_[id]->set_shelf_id(id); | 1603 id_to_item_controller_map_[id]->set_shelf_id(id); |
| 1719 // ShelfItemDelegateManager owns BrowserShortcutLauncherItemController. | 1604 // ShelfItemDelegateManager owns BrowserShortcutLauncherItemController. |
| 1720 SetShelfItemDelegate(id, id_to_item_controller_map_[id]); | 1605 SetShelfItemDelegate(id, id_to_item_controller_map_[id]); |
| 1721 return id; | 1606 return id; |
| 1722 } | 1607 } |
| 1723 | 1608 |
| 1724 void ChromeLauncherController::PersistChromeItemIndex(int index) { | 1609 int ChromeLauncherController::FindInsertionPoint() { |
| 1725 profile_->GetPrefs()->SetInteger(prefs::kShelfChromeIconIndex, index); | 1610 DCHECK_GT(model_->item_count(), 0); |
| 1726 } | |
| 1727 | |
| 1728 void ChromeLauncherController::MoveChromeOrApplistToFinalPosition( | |
| 1729 bool is_chrome, | |
| 1730 bool is_app_list, | |
| 1731 int target_index, | |
| 1732 int* chrome_index, | |
| 1733 int* app_list_index) { | |
| 1734 if (is_chrome && *chrome_index != -1) { | |
| 1735 model_->Move(*chrome_index, target_index); | |
| 1736 if (*app_list_index != -1 && | |
| 1737 *chrome_index < *app_list_index && | |
| 1738 target_index > *app_list_index) | |
| 1739 --(*app_list_index); | |
| 1740 *chrome_index = -1; | |
| 1741 } else if (is_app_list && *app_list_index != -1) { | |
| 1742 model_->Move(*app_list_index, target_index); | |
| 1743 if (*chrome_index != -1 && | |
| 1744 *app_list_index < *chrome_index && | |
| 1745 target_index > *chrome_index) | |
| 1746 --(*chrome_index); | |
| 1747 *app_list_index = -1; | |
| 1748 } | |
| 1749 } | |
| 1750 | |
| 1751 int ChromeLauncherController::FindInsertionPoint(bool is_app_list) { | |
| 1752 // Keeping this change small to backport to M33&32 (see crbug.com/329597). | |
| 1753 // TODO(skuhne): With the removal of the legacy shelf layout we should remove | |
| 1754 // the ability to move the app list item since this was never used. We should | |
| 1755 // instead ask the ShelfModel::ValidateInsertionIndex or similir for an index. | |
| 1756 if (is_app_list) | |
| 1757 return 0; | |
| 1758 | 1611 |
| 1759 for (int i = model_->item_count() - 1; i > 0; --i) { | 1612 for (int i = model_->item_count() - 1; i > 0; --i) { |
| 1760 ash::ShelfItemType type = model_->items()[i].type; | 1613 ash::ShelfItemType type = model_->items()[i].type; |
| 1614 DCHECK_NE(ash::TYPE_APP_LIST, type); |
| 1761 if (type == ash::TYPE_APP_SHORTCUT || | 1615 if (type == ash::TYPE_APP_SHORTCUT || |
| 1762 (is_app_list && type == ash::TYPE_APP_LIST) || | |
| 1763 type == ash::TYPE_BROWSER_SHORTCUT) { | 1616 type == ash::TYPE_BROWSER_SHORTCUT) { |
| 1764 return i; | 1617 return i; |
| 1765 } | 1618 } |
| 1766 } | 1619 } |
| 1767 return 0; | 1620 return 0; |
| 1768 } | 1621 } |
| 1769 | 1622 |
| 1770 int ChromeLauncherController::GetChromeIconIndexForCreation() { | |
| 1771 // We get the list of pinned apps as they currently would get pinned. | |
| 1772 // Within this list the chrome icon will be the correct location. | |
| 1773 std::vector<std::string> pinned_apps = ash::GetPinnedAppsFromPrefs( | |
| 1774 profile_->GetPrefs(), launcher_controller_helper_.get()); | |
| 1775 | |
| 1776 std::vector<std::string>::iterator it = | |
| 1777 std::find(pinned_apps.begin(), | |
| 1778 pinned_apps.end(), | |
| 1779 std::string(extension_misc::kChromeAppId)); | |
| 1780 DCHECK(it != pinned_apps.end()); | |
| 1781 int index = it - pinned_apps.begin(); | |
| 1782 | |
| 1783 // We should do here a comparison between the is state and the "want to be" | |
| 1784 // state since some apps might be able to pin but are not yet. Instead - for | |
| 1785 // the time being we clamp against the amount of known items and wait for the | |
| 1786 // next |UpdateAppLaunchersFromPref()| call to correct it - it will come since | |
| 1787 // the pinning will be done then. | |
| 1788 return std::min(model_->item_count(), index); | |
| 1789 } | |
| 1790 | |
| 1791 bool ChromeLauncherController::IsIncognito( | 1623 bool ChromeLauncherController::IsIncognito( |
| 1792 const content::WebContents* web_contents) const { | 1624 const content::WebContents* web_contents) const { |
| 1793 const Profile* profile = | 1625 const Profile* profile = |
| 1794 Profile::FromBrowserContext(web_contents->GetBrowserContext()); | 1626 Profile::FromBrowserContext(web_contents->GetBrowserContext()); |
| 1795 return profile->IsOffTheRecord() && !profile->IsGuestSession() && | 1627 return profile->IsOffTheRecord() && !profile->IsGuestSession() && |
| 1796 !profile->IsSystemProfile(); | 1628 !profile->IsSystemProfile(); |
| 1797 } | 1629 } |
| 1798 | 1630 |
| 1799 void ChromeLauncherController::CloseWindowedAppsFromRemovedExtension( | 1631 void ChromeLauncherController::CloseWindowedAppsFromRemovedExtension( |
| 1800 const std::string& app_id, | 1632 const std::string& app_id, |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1853 if (arc::ArcAuthService::IsAllowedForProfile(profile_)) { | 1685 if (arc::ArcAuthService::IsAllowedForProfile(profile_)) { |
| 1854 DCHECK(arc_deferred_launcher()); | 1686 DCHECK(arc_deferred_launcher()); |
| 1855 std::unique_ptr<AppIconLoader> arc_app_icon_loader( | 1687 std::unique_ptr<AppIconLoader> arc_app_icon_loader( |
| 1856 new ArcAppIconLoader(profile_, extension_misc::EXTENSION_ICON_SMALL, | 1688 new ArcAppIconLoader(profile_, extension_misc::EXTENSION_ICON_SMALL, |
| 1857 arc_deferred_launcher(), this)); | 1689 arc_deferred_launcher(), this)); |
| 1858 app_icon_loaders_.push_back(std::move(arc_app_icon_loader)); | 1690 app_icon_loaders_.push_back(std::move(arc_app_icon_loader)); |
| 1859 } | 1691 } |
| 1860 | 1692 |
| 1861 pref_change_registrar_.Init(profile_->GetPrefs()); | 1693 pref_change_registrar_.Init(profile_->GetPrefs()); |
| 1862 pref_change_registrar_.Add( | 1694 pref_change_registrar_.Add( |
| 1863 prefs::kPinnedLauncherApps, | |
| 1864 base::Bind(&ChromeLauncherController::UpdateAppLaunchersFromPref, | |
| 1865 base::Unretained(this))); | |
| 1866 pref_change_registrar_.Add( | |
| 1867 prefs::kPolicyPinnedLauncherApps, | 1695 prefs::kPolicyPinnedLauncherApps, |
| 1868 base::Bind(&ChromeLauncherController::UpdateAppLaunchersFromPref, | 1696 base::Bind(&ChromeLauncherController::UpdateAppLaunchersFromPref, |
| 1869 base::Unretained(this))); | 1697 base::Unretained(this))); |
| 1870 pref_change_registrar_.Add( | 1698 pref_change_registrar_.Add( |
| 1871 prefs::kShelfAlignmentLocal, | 1699 prefs::kShelfAlignmentLocal, |
| 1872 base::Bind(&ChromeLauncherController::SetShelfAlignmentFromPrefs, | 1700 base::Bind(&ChromeLauncherController::SetShelfAlignmentFromPrefs, |
| 1873 base::Unretained(this))); | 1701 base::Unretained(this))); |
| 1874 pref_change_registrar_.Add( | 1702 pref_change_registrar_.Add( |
| 1875 prefs::kShelfAutoHideBehaviorLocal, | 1703 prefs::kShelfAutoHideBehaviorLocal, |
| 1876 base::Bind(&ChromeLauncherController:: | 1704 base::Bind(&ChromeLauncherController:: |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1887 | 1715 |
| 1888 std::unique_ptr<LauncherAppUpdater> extension_app_updater( | 1716 std::unique_ptr<LauncherAppUpdater> extension_app_updater( |
| 1889 new LauncherExtensionAppUpdater(this, profile_)); | 1717 new LauncherExtensionAppUpdater(this, profile_)); |
| 1890 app_updaters_.push_back(std::move(extension_app_updater)); | 1718 app_updaters_.push_back(std::move(extension_app_updater)); |
| 1891 | 1719 |
| 1892 if (arc::ArcAuthService::IsAllowedForProfile(profile_)) { | 1720 if (arc::ArcAuthService::IsAllowedForProfile(profile_)) { |
| 1893 std::unique_ptr<LauncherAppUpdater> arc_app_updater( | 1721 std::unique_ptr<LauncherAppUpdater> arc_app_updater( |
| 1894 new LauncherArcAppUpdater(this, profile_)); | 1722 new LauncherArcAppUpdater(this, profile_)); |
| 1895 app_updaters_.push_back(std::move(arc_app_updater)); | 1723 app_updaters_.push_back(std::move(arc_app_updater)); |
| 1896 } | 1724 } |
| 1725 |
| 1726 app_list::AppListSyncableService* app_service = |
| 1727 app_list::AppListSyncableService::Get(profile_); |
| 1728 if (app_service) |
| 1729 app_service->AddObserverAndStart(this); |
| 1897 } | 1730 } |
| 1898 | 1731 |
| 1899 void ChromeLauncherController::ReleaseProfile() { | 1732 void ChromeLauncherController::ReleaseProfile() { |
| 1900 if (app_sync_ui_state_) | 1733 if (app_sync_ui_state_) |
| 1901 app_sync_ui_state_->RemoveObserver(this); | 1734 app_sync_ui_state_->RemoveObserver(this); |
| 1902 | 1735 |
| 1903 app_updaters_.clear(); | 1736 app_updaters_.clear(); |
| 1904 | 1737 |
| 1905 PrefServiceSyncableFromProfile(profile_)->RemoveObserver(this); | 1738 PrefServiceSyncableFromProfile(profile_)->RemoveObserver(this); |
| 1906 | 1739 |
| 1907 pref_change_registrar_.RemoveAll(); | 1740 pref_change_registrar_.RemoveAll(); |
| 1741 |
| 1742 app_list::AppListSyncableService* app_service = |
| 1743 app_list::AppListSyncableService::Get(profile_); |
| 1744 if (app_service) |
| 1745 app_service->RemoveObserver(this); |
| 1908 } | 1746 } |
| 1909 | 1747 |
| 1910 AppIconLoader* ChromeLauncherController::GetAppIconLoaderForApp( | 1748 AppIconLoader* ChromeLauncherController::GetAppIconLoaderForApp( |
| 1911 const std::string& app_id) { | 1749 const std::string& app_id) { |
| 1912 for (const auto& app_icon_loader : app_icon_loaders_) { | 1750 for (const auto& app_icon_loader : app_icon_loaders_) { |
| 1913 if (app_icon_loader->CanLoadImageForApp(app_id)) | 1751 if (app_icon_loader->CanLoadImageForApp(app_id)) |
| 1914 return app_icon_loader.get(); | 1752 return app_icon_loader.get(); |
| 1915 } | 1753 } |
| 1916 | 1754 |
| 1917 return nullptr; | 1755 return nullptr; |
| 1918 } | 1756 } |
| OLD | NEW |