| 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 |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 const char* local_path, | 128 const char* local_path, |
| 129 const char* synced_path) { | 129 const char* synced_path) { |
| 130 if (!pref_service->FindPreference(local_path)->HasUserSetting() && | 130 if (!pref_service->FindPreference(local_path)->HasUserSetting() && |
| 131 pref_service->IsSyncing()) { | 131 pref_service->IsSyncing()) { |
| 132 // First time the user is using this machine, propagate from remote to | 132 // First time the user is using this machine, propagate from remote to |
| 133 // local. | 133 // local. |
| 134 pref_service->SetString(local_path, pref_service->GetString(synced_path)); | 134 pref_service->SetString(local_path, pref_service->GetString(synced_path)); |
| 135 } | 135 } |
| 136 } | 136 } |
| 137 | 137 |
| 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[] = { | 138 const char* const kPinProhibitedExtensionIds[] = { |
| 187 ArcSupportHost::kHostAppId, arc::kPlayStoreAppId, | 139 ArcSupportHost::kHostAppId, arc::kPlayStoreAppId, |
| 188 }; | 140 }; |
| 189 | 141 |
| 190 const size_t kPinProhibitedExtensionIdsLength = | 142 const size_t kPinProhibitedExtensionIdsLength = |
| 191 arraysize(kPinProhibitedExtensionIds); | 143 arraysize(kPinProhibitedExtensionIds); |
| 192 | 144 |
| 193 } // namespace | 145 } // namespace |
| 194 | 146 |
| 195 // A class to get events from ChromeOS when a user gets changed or added. | 147 // A class to get events from ChromeOS when a user gets changed or added. |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 257 | 209 |
| 258 void ChromeLauncherControllerUserSwitchObserver::AddUser(Profile* profile) { | 210 void ChromeLauncherControllerUserSwitchObserver::AddUser(Profile* profile) { |
| 259 if (chrome::MultiUserWindowManager::GetMultiProfileMode() == | 211 if (chrome::MultiUserWindowManager::GetMultiProfileMode() == |
| 260 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED) | 212 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED) |
| 261 chrome::MultiUserWindowManager::GetInstance()->AddUser(profile); | 213 chrome::MultiUserWindowManager::GetInstance()->AddUser(profile); |
| 262 controller_->AdditionalUserAddedToSession(profile->GetOriginalProfile()); | 214 controller_->AdditionalUserAddedToSession(profile->GetOriginalProfile()); |
| 263 } | 215 } |
| 264 | 216 |
| 265 ChromeLauncherController::ChromeLauncherController(Profile* profile, | 217 ChromeLauncherController::ChromeLauncherController(Profile* profile, |
| 266 ash::ShelfModel* model) | 218 ash::ShelfModel* model) |
| 267 : model_(model), | 219 : 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_) { | 220 if (!profile_) { |
| 273 // If no profile was passed, we take the currently active profile and use it | 221 // If no profile was passed, we take the currently active profile and use it |
| 274 // as the owner of the current desktop. | 222 // as the owner of the current desktop. |
| 275 // Use the original profile as on chromeos we may get a temporary off the | 223 // 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 | 224 // record profile, unless in guest session (where off the record profile is |
| 277 // the right one). | 225 // the right one). |
| 278 profile_ = ProfileManager::GetActiveUserProfile(); | 226 profile_ = ProfileManager::GetActiveUserProfile(); |
| 279 if (!profile_->IsGuestSession() && !profile_->IsSystemProfile()) | 227 if (!profile_->IsGuestSession() && !profile_->IsSystemProfile()) |
| 280 profile_ = profile_->GetOriginalProfile(); | 228 profile_ = profile_->GetOriginalProfile(); |
| 281 | 229 |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 510 ash::ShelfItem item = model_->items()[index]; | 458 ash::ShelfItem item = model_->items()[index]; |
| 511 | 459 |
| 512 if (item.type == ash::TYPE_PLATFORM_APP || | 460 if (item.type == ash::TYPE_PLATFORM_APP || |
| 513 item.type == ash::TYPE_WINDOWED_APP) { | 461 item.type == ash::TYPE_WINDOWED_APP) { |
| 514 item.type = ash::TYPE_APP_SHORTCUT; | 462 item.type = ash::TYPE_APP_SHORTCUT; |
| 515 model_->Set(index, item); | 463 model_->Set(index, item); |
| 516 } else if (item.type != ash::TYPE_APP_SHORTCUT) { | 464 } else if (item.type != ash::TYPE_APP_SHORTCUT) { |
| 517 return; | 465 return; |
| 518 } | 466 } |
| 519 | 467 |
| 520 if (GetLauncherItemController(id)->CanPin()) | 468 UpdatePinnedPosition(id); |
| 521 PersistPinnedState(); | |
| 522 } | 469 } |
| 523 | 470 |
| 524 void ChromeLauncherController::Unpin(ash::ShelfID id) { | 471 void ChromeLauncherController::Unpin(ash::ShelfID id) { |
| 525 LauncherItemController* controller = GetLauncherItemController(id); | 472 LauncherItemController* controller = GetLauncherItemController(id); |
| 526 CHECK(controller); | 473 CHECK(controller); |
| 527 const bool can_pin = controller->CanPin(); | 474 |
| 475 ash::RemovePinPosition(profile_, GetAppIDForShelfID(id)); |
| 528 | 476 |
| 529 if (controller->type() == LauncherItemController::TYPE_APP || | 477 if (controller->type() == LauncherItemController::TYPE_APP || |
| 530 controller->locked()) { | 478 controller->locked()) { |
| 531 UnpinRunningAppInternal(model_->ItemIndexByID(id)); | 479 UnpinRunningAppInternal(model_->ItemIndexByID(id)); |
| 532 } else { | 480 } else { |
| 533 LauncherItemClosed(id); | 481 LauncherItemClosed(id); |
| 534 } | 482 } |
| 535 if (can_pin) | |
| 536 PersistPinnedState(); | |
| 537 } | 483 } |
| 538 | 484 |
| 539 bool ChromeLauncherController::IsPinned(ash::ShelfID id) { | 485 bool ChromeLauncherController::IsPinned(ash::ShelfID id) { |
| 540 int index = model_->ItemIndexByID(id); | 486 int index = model_->ItemIndexByID(id); |
| 541 if (index < 0) | 487 if (index < 0) |
| 542 return false; | 488 return false; |
| 543 ash::ShelfItemType type = model_->items()[index].type; | 489 ash::ShelfItemType type = model_->items()[index].type; |
| 544 return (type == ash::TYPE_APP_SHORTCUT || type == ash::TYPE_BROWSER_SHORTCUT); | 490 return (type == ash::TYPE_APP_SHORTCUT || type == ash::TYPE_BROWSER_SHORTCUT); |
| 545 } | 491 } |
| 546 | 492 |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 778 void ChromeLauncherController::CreateNewWindow() { | 724 void ChromeLauncherController::CreateNewWindow() { |
| 779 // Use the currently active user. | 725 // Use the currently active user. |
| 780 chrome::NewEmptyWindow(profile_); | 726 chrome::NewEmptyWindow(profile_); |
| 781 } | 727 } |
| 782 | 728 |
| 783 void ChromeLauncherController::CreateNewIncognitoWindow() { | 729 void ChromeLauncherController::CreateNewIncognitoWindow() { |
| 784 // Use the currently active user. | 730 // Use the currently active user. |
| 785 chrome::NewEmptyWindow(profile_->GetOffTheRecordProfile()); | 731 chrome::NewEmptyWindow(profile_->GetOffTheRecordProfile()); |
| 786 } | 732 } |
| 787 | 733 |
| 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() { | 734 Profile* ChromeLauncherController::profile() { |
| 845 return profile_; | 735 return profile_; |
| 846 } | 736 } |
| 847 | 737 |
| 848 void ChromeLauncherController::UpdateAppState(content::WebContents* contents, | 738 void ChromeLauncherController::UpdateAppState(content::WebContents* contents, |
| 849 AppState app_state) { | 739 AppState app_state) { |
| 850 std::string app_id = launcher_controller_helper_->GetAppID(contents); | 740 std::string app_id = launcher_controller_helper_->GetAppID(contents); |
| 851 | 741 |
| 852 // Check if the gMail app is loaded and it matches the given content. | 742 // Check if the gMail app is loaded and it matches the given content. |
| 853 // This special treatment is needed to address crbug.com/234268. | 743 // 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), | 873 GetDisplayIDForShelf(shelf), |
| 984 shelf->auto_hide_behavior()); | 874 shelf->auto_hide_behavior()); |
| 985 } | 875 } |
| 986 | 876 |
| 987 void ChromeLauncherController::OnShelfAutoHideStateChanged(ash::Shelf* shelf) {} | 877 void ChromeLauncherController::OnShelfAutoHideStateChanged(ash::Shelf* shelf) {} |
| 988 | 878 |
| 989 void ChromeLauncherController::OnShelfVisibilityStateChanged( | 879 void ChromeLauncherController::OnShelfVisibilityStateChanged( |
| 990 ash::Shelf* shelf) {} | 880 ash::Shelf* shelf) {} |
| 991 | 881 |
| 992 void ChromeLauncherController::ShelfItemAdded(int index) { | 882 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 } | 883 } |
| 999 | 884 |
| 1000 void ChromeLauncherController::ShelfItemRemoved(int index, ash::ShelfID id) { | 885 void ChromeLauncherController::ShelfItemRemoved(int index, ash::ShelfID id) { |
| 1001 // TODO(skuhne): This fixes crbug.com/429870, but it does not answer why we | 886 // TODO(skuhne): This fixes crbug.com/429870, but it does not answer why we |
| 1002 // get into this state in the first place. | 887 // get into this state in the first place. |
| 1003 IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id); | 888 IDToItemControllerMap::iterator iter = id_to_item_controller_map_.find(id); |
| 1004 if (iter == id_to_item_controller_map_.end()) | 889 if (iter == id_to_item_controller_map_.end()) |
| 1005 return; | 890 return; |
| 1006 | 891 |
| 1007 LOG(ERROR) << "Unexpected change of shelf item id: " << id; | 892 LOG(ERROR) << "Unexpected change of shelf item id: " << id; |
| 1008 | 893 |
| 1009 id_to_item_controller_map_.erase(iter); | 894 id_to_item_controller_map_.erase(iter); |
| 1010 } | 895 } |
| 1011 | 896 |
| 1012 void ChromeLauncherController::ShelfItemMoved(int start_index, | 897 void ChromeLauncherController::ShelfItemMoved(int start_index, |
| 1013 int target_index) { | 898 int target_index) { |
| 1014 const ash::ShelfItem& item = model_->items()[target_index]; | 899 const ash::ShelfItem& item = model_->items()[target_index]; |
| 1015 // We remember the moved item position if it is either pinnable or | 900 // We remember the moved item position if it is either pinnable or |
| 1016 // it is the app list with the alternate shelf layout. | 901 // it is the app list with the alternate shelf layout. |
| 1017 if ((HasShelfIDToAppIDMapping(item.id) && IsPinned(item.id)) || | 902 DCHECK_NE(ash::TYPE_APP_LIST, item.type); |
| 1018 item.type == ash::TYPE_APP_LIST) | 903 if (HasShelfIDToAppIDMapping(item.id) && IsPinned(item.id)) |
| 1019 PersistPinnedState(); | 904 UpdatePinnedPosition(item.id); |
| 1020 } | 905 } |
| 1021 | 906 |
| 1022 void ChromeLauncherController::ShelfItemChanged( | 907 void ChromeLauncherController::ShelfItemChanged( |
| 1023 int index, | 908 int index, |
| 1024 const ash::ShelfItem& old_item) {} | 909 const ash::ShelfItem& old_item) {} |
| 1025 | 910 |
| 1026 void ChromeLauncherController::ActiveUserChanged( | 911 void ChromeLauncherController::ActiveUserChanged( |
| 1027 const std::string& user_email) { | 912 const std::string& user_email) { |
| 1028 // Store the order of running applications for the user which gets inactive. | 913 // Store the order of running applications for the user which gets inactive. |
| 1029 RememberUnpinnedRunningApplicationOrder(); | 914 RememberUnpinnedRunningApplicationOrder(); |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1380 if (IsAppPinned(app_id)) | 1265 if (IsAppPinned(app_id)) |
| 1381 return; | 1266 return; |
| 1382 | 1267 |
| 1383 ash::ShelfID shelf_id = GetShelfIDForAppID(app_id); | 1268 ash::ShelfID shelf_id = GetShelfIDForAppID(app_id); |
| 1384 if (shelf_id) { | 1269 if (shelf_id) { |
| 1385 // App item exists, pin it | 1270 // App item exists, pin it |
| 1386 Pin(shelf_id); | 1271 Pin(shelf_id); |
| 1387 } else { | 1272 } else { |
| 1388 // Otherwise, create a shortcut item for it. | 1273 // Otherwise, create a shortcut item for it. |
| 1389 shelf_id = CreateAppShortcutLauncherItem(app_id, model_->item_count()); | 1274 shelf_id = CreateAppShortcutLauncherItem(app_id, model_->item_count()); |
| 1390 if (GetPinnable(app_id) == AppListControllerDelegate::PIN_EDITABLE) | 1275 UpdatePinnedPosition(shelf_id); |
| 1391 PersistPinnedState(); | |
| 1392 } | 1276 } |
| 1393 } | 1277 } |
| 1394 | 1278 |
| 1395 void ChromeLauncherController::DoUnpinAppWithID(const std::string& app_id) { | 1279 void ChromeLauncherController::DoUnpinAppWithID(const std::string& app_id) { |
| 1396 ash::ShelfID shelf_id = GetShelfIDForAppID(app_id); | 1280 ash::ShelfID shelf_id = GetShelfIDForAppID(app_id); |
| 1397 if (shelf_id && IsPinned(shelf_id)) | 1281 if (shelf_id && IsPinned(shelf_id)) |
| 1398 Unpin(shelf_id); | 1282 Unpin(shelf_id); |
| 1399 } | 1283 } |
| 1400 | 1284 |
| 1401 int ChromeLauncherController::PinRunningAppInternal(int index, | 1285 int ChromeLauncherController::PinRunningAppInternal(int index, |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1422 DCHECK_EQ(item.type, ash::TYPE_APP_SHORTCUT); | 1306 DCHECK_EQ(item.type, ash::TYPE_APP_SHORTCUT); |
| 1423 item.type = ash::TYPE_WINDOWED_APP; | 1307 item.type = ash::TYPE_WINDOWED_APP; |
| 1424 // A platform app and a windowed app are sharing TYPE_APP_SHORTCUT. As such | 1308 // 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. | 1309 // we have to check here what this was before it got a shortcut. |
| 1426 LauncherItemController* controller = GetLauncherItemController(item.id); | 1310 LauncherItemController* controller = GetLauncherItemController(item.id); |
| 1427 if (controller && controller->type() == LauncherItemController::TYPE_APP) | 1311 if (controller && controller->type() == LauncherItemController::TYPE_APP) |
| 1428 item.type = ash::TYPE_PLATFORM_APP; | 1312 item.type = ash::TYPE_PLATFORM_APP; |
| 1429 model_->Set(index, item); | 1313 model_->Set(index, item); |
| 1430 } | 1314 } |
| 1431 | 1315 |
| 1316 void ChromeLauncherController::UpdatePinnedPosition(ash::ShelfID shelf_id) { |
| 1317 DCHECK(shelf_id); |
| 1318 if (ignore_persist_pinned_state_change_) |
| 1319 return; |
| 1320 |
| 1321 const int max_index = model_->item_count(); |
| 1322 const int index = model_->ItemIndexByID(shelf_id); |
| 1323 DCHECK_GT(index, 0); |
| 1324 |
| 1325 const std::string& app_id = GetAppIDForShelfID(shelf_id); |
| 1326 DCHECK(!app_id.empty()); |
| 1327 |
| 1328 std::string app_id_before; |
| 1329 std::string app_id_after; |
| 1330 |
| 1331 for (int i = index - 1; i > 0; --i) { |
| 1332 const ash::ShelfID shelf_id_before = model_->items()[i].id; |
| 1333 if (IsPinned(shelf_id_before)) { |
| 1334 app_id_before = GetAppIDForShelfID(shelf_id_before); |
| 1335 DCHECK(!app_id_before.empty()); |
| 1336 break; |
| 1337 } |
| 1338 } |
| 1339 |
| 1340 for (int i = index + 1; i < max_index; ++i) { |
| 1341 const ash::ShelfID shelf_id_after = model_->items()[i].id; |
| 1342 if (IsPinned(shelf_id_after)) { |
| 1343 app_id_after = GetAppIDForShelfID(shelf_id_after); |
| 1344 DCHECK(!app_id_after.empty()); |
| 1345 break; |
| 1346 } |
| 1347 } |
| 1348 |
| 1349 ash::SetPinPosition(profile_, app_id, app_id_before, app_id_after); |
| 1350 } |
| 1351 |
| 1352 void ChromeLauncherController::OnSyncModelUpdated() { |
| 1353 UpdateAppLaunchersFromPref(); |
| 1354 } |
| 1355 |
| 1432 void ChromeLauncherController::UpdateAppLaunchersFromPref() { | 1356 void ChromeLauncherController::UpdateAppLaunchersFromPref() { |
| 1433 // There are various functions which will trigger a |PersistPinnedState| call | 1357 // There are various functions which will trigger a |UpdatePinnedPosition| |
| 1434 // like a direct call to |DoPinAppWithID|, or an indirect call to the menu | 1358 // call 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. | 1359 // 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 | 1360 // 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 | 1361 // "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 | 1362 // into the pref state. Therefore we tell |persistPinnedState| to ignore any |
| 1439 // invocations while we are running. | 1363 // invocations while we are running. |
| 1440 base::AutoReset<bool> auto_reset(&ignore_persist_pinned_state_change_, true); | 1364 base::AutoReset<bool> auto_reset(&ignore_persist_pinned_state_change_, true); |
| 1365 |
| 1441 std::vector<std::string> pinned_apps = ash::GetPinnedAppsFromPrefs( | 1366 std::vector<std::string> pinned_apps = ash::GetPinnedAppsFromPrefs( |
| 1442 profile_->GetPrefs(), launcher_controller_helper_.get()); | 1367 profile_->GetPrefs(), launcher_controller_helper_.get()); |
| 1443 | 1368 |
| 1444 int index = 0; | 1369 int index = 1; |
| 1445 int max_index = model_->item_count(); | 1370 int max_index = model_->item_count(); |
| 1371 int seen_chrome_index = -1; |
| 1446 | 1372 |
| 1447 // When one of the two special items cannot be moved (and we do not know where | 1373 // At least chrome browser shortcut should exist. |
| 1448 // yet), we remember the current location in one of these variables. | 1374 DCHECK_GT(max_index, 0); |
| 1449 int chrome_index = -1; | 1375 DCHECK_EQ(ash::TYPE_APP_LIST, model_->items()[0].type); |
| 1450 int app_list_index = -1; | |
| 1451 | 1376 |
| 1452 // Walk the model and |pinned_apps| from the pref lockstep, adding and | 1377 // 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 | 1378 // removing items as necessary. NB: This code uses plain old indexing instead |
| 1454 // of iterators because of model mutations as part of the loop. | 1379 // of iterators because of model mutations as part of the loop. |
| 1455 std::vector<std::string>::const_iterator pref_app_id(pinned_apps.begin()); | 1380 std::vector<std::string>::const_iterator pref_app_id(pinned_apps.begin()); |
| 1456 for (; index < max_index && pref_app_id != pinned_apps.end(); ++index) { | 1381 for (; index < max_index && pref_app_id != pinned_apps.end(); ++index) { |
| 1457 // Check if we have an item which we need to handle. | 1382 // Check if we have an item which we need to handle. |
| 1458 if (*pref_app_id == extension_misc::kChromeAppId || | 1383 if (IsAppPinned(*pref_app_id)) { |
| 1459 *pref_app_id == ash::kPinnedAppsPlaceholder || | 1384 if (seen_chrome_index >= 0 && |
| 1460 IsAppPinned(*pref_app_id)) { | 1385 *pref_app_id == extension_misc::kChromeAppId) { |
| 1386 // Current item is Chrome browser and we saw it before. |
| 1387 model_->Move(seen_chrome_index, index); |
| 1388 ++pref_app_id; |
| 1389 --index; |
| 1390 continue; |
| 1391 } |
| 1461 for (; index < max_index; ++index) { | 1392 for (; index < max_index; ++index) { |
| 1462 const ash::ShelfItem& item(model_->items()[index]); | 1393 const ash::ShelfItem& item(model_->items()[index]); |
| 1463 bool is_app_list = item.type == ash::TYPE_APP_LIST; | 1394 if (item.type != ash::TYPE_APP_SHORTCUT && |
| 1464 bool is_chrome = item.type == ash::TYPE_BROWSER_SHORTCUT; | 1395 item.type != ash::TYPE_BROWSER_SHORTCUT) |
| 1465 if (item.type != ash::TYPE_APP_SHORTCUT && !is_app_list && !is_chrome) | |
| 1466 continue; | 1396 continue; |
| 1467 LauncherItemController* controller = GetLauncherItemController(item.id); | 1397 LauncherItemController* controller = GetLauncherItemController(item.id); |
| 1468 if ((ash::kPinnedAppsPlaceholder == *pref_app_id && is_app_list) || | 1398 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; | 1399 ++pref_app_id; |
| 1475 break; | 1400 break; |
| 1401 } else if (item.type == ash::TYPE_BROWSER_SHORTCUT) { |
| 1402 // We cannot close browser shortcut. Remember its position. |
| 1403 seen_chrome_index = index; |
| 1476 } else { | 1404 } else { |
| 1477 if (is_chrome || is_app_list) { | 1405 // Check if this is a platform or a windowed app. |
| 1478 // We cannot delete any of these shortcuts. As such we remember | 1406 if (item.type == ash::TYPE_APP_SHORTCUT && controller && |
| 1479 // their positions and move them later where they belong. | 1407 (controller->locked() || |
| 1480 if (is_chrome) | 1408 controller->type() == LauncherItemController::TYPE_APP)) { |
| 1481 chrome_index = index; | 1409 // Note: This will not change the amount of items (|max_index|). |
| 1482 else | 1410 // Even changes to the actual |index| due to item weighting |
| 1483 app_list_index = index; | 1411 // changes should be fine. |
| 1484 // And skip the item - or exit the loop if end is reached (note that | 1412 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 { | 1413 } else { |
| 1491 // Check if this is a platform or a windowed app. | 1414 if (controller) |
| 1492 if (item.type == ash::TYPE_APP_SHORTCUT && | 1415 LauncherItemClosed(item.id); |
| 1493 controller && | 1416 --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 } | 1417 } |
| 1506 --index; | 1418 --index; |
| 1507 } | 1419 } |
| 1508 } | 1420 } |
| 1509 // If the item wasn't found, that means id_to_item_controller_map_ | 1421 // If the item wasn't found, that means id_to_item_controller_map_ |
| 1510 // is out of sync. | 1422 // is out of sync. |
| 1511 DCHECK(index <= max_index); | 1423 DCHECK(index <= max_index); |
| 1512 } else { | 1424 } else { |
| 1513 // Check if the item was already running but not yet pinned. | 1425 // Check if the item was already running but not yet pinned. |
| 1514 ash::ShelfID shelf_id = GetShelfIDForAppID(*pref_app_id); | 1426 ash::ShelfID shelf_id = GetShelfIDForAppID(*pref_app_id); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1532 LauncherItemController* controller = GetLauncherItemController(item.id); | 1444 LauncherItemController* controller = GetLauncherItemController(item.id); |
| 1533 if (controller) { | 1445 if (controller) { |
| 1534 if (controller->locked() || | 1446 if (controller->locked() || |
| 1535 controller->type() == LauncherItemController::TYPE_APP) { | 1447 controller->type() == LauncherItemController::TYPE_APP) { |
| 1536 UnpinRunningAppInternal(index); | 1448 UnpinRunningAppInternal(index); |
| 1537 } else { | 1449 } else { |
| 1538 LauncherItemClosed(item.id); | 1450 LauncherItemClosed(item.id); |
| 1539 } | 1451 } |
| 1540 } | 1452 } |
| 1541 } else { | 1453 } 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; | 1454 ++index; |
| 1547 } | 1455 } |
| 1548 } | 1456 } |
| 1549 | 1457 |
| 1550 // Append unprocessed items from the pref to the end of the model. | 1458 // Append unprocessed items from the pref to the end of the model. |
| 1551 for (; pref_app_id != pinned_apps.end(); ++pref_app_id) { | 1459 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. | 1460 if (*pref_app_id == extension_misc::kChromeAppId) { |
| 1553 bool is_chrome = *pref_app_id == extension_misc::kChromeAppId; | 1461 int target_index = FindInsertionPoint(); |
| 1554 bool is_app_list = *pref_app_id == ash::kPinnedAppsPlaceholder; | 1462 DCHECK(seen_chrome_index >= 0 && seen_chrome_index < target_index); |
| 1555 // Coming here we know the next item which can be finalized, either the | 1463 model_->Move(seen_chrome_index, target_index); |
| 1556 // chrome item or the app launcher. The final position is the end of the | 1464 } 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); | 1465 DoPinAppWithID(*pref_app_id); |
| 1561 int target_index = FindInsertionPoint(false); | 1466 int target_index = FindInsertionPoint(); |
| 1562 ash::ShelfID id = GetShelfIDForAppID(*pref_app_id); | 1467 ash::ShelfID id = GetShelfIDForAppID(*pref_app_id); |
| 1563 int source_index = model_->ItemIndexByID(id); | 1468 int source_index = model_->ItemIndexByID(id); |
| 1564 if (source_index != target_index) | 1469 if (source_index != target_index) |
| 1565 model_->Move(source_index, target_index); | 1470 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 } | 1471 } |
| 1576 } | 1472 } |
| 1577 } | 1473 } |
| 1578 | 1474 |
| 1579 void ChromeLauncherController::SetShelfAutoHideBehaviorFromPrefs() { | 1475 void ChromeLauncherController::SetShelfAutoHideBehaviorFromPrefs() { |
| 1580 for (auto* window : ash::Shell::GetAllRootWindows()) { | 1476 for (auto* window : ash::Shell::GetAllRootWindows()) { |
| 1581 ash::Shelf* shelf = ash::Shelf::ForWindow(window); | 1477 ash::Shelf* shelf = ash::Shelf::ForWindow(window); |
| 1582 if (shelf) { | 1478 if (shelf) { |
| 1583 shelf->SetAutoHideBehavior(ash::GetShelfAutoHideBehaviorPref( | 1479 shelf->SetAutoHideBehavior(ash::GetShelfAutoHideBehaviorPref( |
| 1584 profile_->GetPrefs(), GetDisplayIDForShelf(shelf))); | 1480 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."; | 1600 << "There should be always be a BrowserShortcutLauncherItemController."; |
| 1705 return nullptr; | 1601 return nullptr; |
| 1706 } | 1602 } |
| 1707 | 1603 |
| 1708 ash::ShelfID ChromeLauncherController::CreateBrowserShortcutLauncherItem() { | 1604 ash::ShelfID ChromeLauncherController::CreateBrowserShortcutLauncherItem() { |
| 1709 ash::ShelfItem browser_shortcut; | 1605 ash::ShelfItem browser_shortcut; |
| 1710 browser_shortcut.type = ash::TYPE_BROWSER_SHORTCUT; | 1606 browser_shortcut.type = ash::TYPE_BROWSER_SHORTCUT; |
| 1711 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 1607 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| 1712 browser_shortcut.image = *rb.GetImageSkiaNamed(IDR_PRODUCT_LOGO_32); | 1608 browser_shortcut.image = *rb.GetImageSkiaNamed(IDR_PRODUCT_LOGO_32); |
| 1713 ash::ShelfID id = model_->next_id(); | 1609 ash::ShelfID id = model_->next_id(); |
| 1714 size_t index = GetChromeIconIndexForCreation(); | 1610 model_->AddAt(0, browser_shortcut); |
| 1715 model_->AddAt(index, browser_shortcut); | |
| 1716 id_to_item_controller_map_[id] = | 1611 id_to_item_controller_map_[id] = |
| 1717 new BrowserShortcutLauncherItemController(this, model_); | 1612 new BrowserShortcutLauncherItemController(this, model_); |
| 1718 id_to_item_controller_map_[id]->set_shelf_id(id); | 1613 id_to_item_controller_map_[id]->set_shelf_id(id); |
| 1719 // ShelfItemDelegateManager owns BrowserShortcutLauncherItemController. | 1614 // ShelfItemDelegateManager owns BrowserShortcutLauncherItemController. |
| 1720 SetShelfItemDelegate(id, id_to_item_controller_map_[id]); | 1615 SetShelfItemDelegate(id, id_to_item_controller_map_[id]); |
| 1721 return id; | 1616 return id; |
| 1722 } | 1617 } |
| 1723 | 1618 |
| 1724 void ChromeLauncherController::PersistChromeItemIndex(int index) { | 1619 int ChromeLauncherController::FindInsertionPoint() { |
| 1725 profile_->GetPrefs()->SetInteger(prefs::kShelfChromeIconIndex, index); | 1620 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 | 1621 |
| 1759 for (int i = model_->item_count() - 1; i > 0; --i) { | 1622 for (int i = model_->item_count() - 1; i > 0; --i) { |
| 1760 ash::ShelfItemType type = model_->items()[i].type; | 1623 ash::ShelfItemType type = model_->items()[i].type; |
| 1624 DCHECK_NE(ash::TYPE_APP_LIST, type); |
| 1761 if (type == ash::TYPE_APP_SHORTCUT || | 1625 if (type == ash::TYPE_APP_SHORTCUT || |
| 1762 (is_app_list && type == ash::TYPE_APP_LIST) || | |
| 1763 type == ash::TYPE_BROWSER_SHORTCUT) { | 1626 type == ash::TYPE_BROWSER_SHORTCUT) { |
| 1764 return i; | 1627 return i; |
| 1765 } | 1628 } |
| 1766 } | 1629 } |
| 1767 return 0; | 1630 return 0; |
| 1768 } | 1631 } |
| 1769 | 1632 |
| 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( | 1633 bool ChromeLauncherController::IsIncognito( |
| 1792 const content::WebContents* web_contents) const { | 1634 const content::WebContents* web_contents) const { |
| 1793 const Profile* profile = | 1635 const Profile* profile = |
| 1794 Profile::FromBrowserContext(web_contents->GetBrowserContext()); | 1636 Profile::FromBrowserContext(web_contents->GetBrowserContext()); |
| 1795 return profile->IsOffTheRecord() && !profile->IsGuestSession() && | 1637 return profile->IsOffTheRecord() && !profile->IsGuestSession() && |
| 1796 !profile->IsSystemProfile(); | 1638 !profile->IsSystemProfile(); |
| 1797 } | 1639 } |
| 1798 | 1640 |
| 1799 void ChromeLauncherController::CloseWindowedAppsFromRemovedExtension( | 1641 void ChromeLauncherController::CloseWindowedAppsFromRemovedExtension( |
| 1800 const std::string& app_id, | 1642 const std::string& app_id, |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1853 if (arc::ArcAuthService::IsAllowedForProfile(profile_)) { | 1695 if (arc::ArcAuthService::IsAllowedForProfile(profile_)) { |
| 1854 DCHECK(arc_deferred_launcher()); | 1696 DCHECK(arc_deferred_launcher()); |
| 1855 std::unique_ptr<AppIconLoader> arc_app_icon_loader( | 1697 std::unique_ptr<AppIconLoader> arc_app_icon_loader( |
| 1856 new ArcAppIconLoader(profile_, extension_misc::EXTENSION_ICON_SMALL, | 1698 new ArcAppIconLoader(profile_, extension_misc::EXTENSION_ICON_SMALL, |
| 1857 arc_deferred_launcher(), this)); | 1699 arc_deferred_launcher(), this)); |
| 1858 app_icon_loaders_.push_back(std::move(arc_app_icon_loader)); | 1700 app_icon_loaders_.push_back(std::move(arc_app_icon_loader)); |
| 1859 } | 1701 } |
| 1860 | 1702 |
| 1861 pref_change_registrar_.Init(profile_->GetPrefs()); | 1703 pref_change_registrar_.Init(profile_->GetPrefs()); |
| 1862 pref_change_registrar_.Add( | 1704 pref_change_registrar_.Add( |
| 1863 prefs::kPinnedLauncherApps, | |
| 1864 base::Bind(&ChromeLauncherController::UpdateAppLaunchersFromPref, | |
| 1865 base::Unretained(this))); | |
| 1866 pref_change_registrar_.Add( | |
| 1867 prefs::kPolicyPinnedLauncherApps, | 1705 prefs::kPolicyPinnedLauncherApps, |
| 1868 base::Bind(&ChromeLauncherController::UpdateAppLaunchersFromPref, | 1706 base::Bind(&ChromeLauncherController::UpdateAppLaunchersFromPref, |
| 1869 base::Unretained(this))); | 1707 base::Unretained(this))); |
| 1870 pref_change_registrar_.Add( | 1708 pref_change_registrar_.Add( |
| 1871 prefs::kShelfAlignmentLocal, | 1709 prefs::kShelfAlignmentLocal, |
| 1872 base::Bind(&ChromeLauncherController::SetShelfAlignmentFromPrefs, | 1710 base::Bind(&ChromeLauncherController::SetShelfAlignmentFromPrefs, |
| 1873 base::Unretained(this))); | 1711 base::Unretained(this))); |
| 1874 pref_change_registrar_.Add( | 1712 pref_change_registrar_.Add( |
| 1875 prefs::kShelfAutoHideBehaviorLocal, | 1713 prefs::kShelfAutoHideBehaviorLocal, |
| 1876 base::Bind(&ChromeLauncherController:: | 1714 base::Bind(&ChromeLauncherController:: |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1887 | 1725 |
| 1888 std::unique_ptr<LauncherAppUpdater> extension_app_updater( | 1726 std::unique_ptr<LauncherAppUpdater> extension_app_updater( |
| 1889 new LauncherExtensionAppUpdater(this, profile_)); | 1727 new LauncherExtensionAppUpdater(this, profile_)); |
| 1890 app_updaters_.push_back(std::move(extension_app_updater)); | 1728 app_updaters_.push_back(std::move(extension_app_updater)); |
| 1891 | 1729 |
| 1892 if (arc::ArcAuthService::IsAllowedForProfile(profile_)) { | 1730 if (arc::ArcAuthService::IsAllowedForProfile(profile_)) { |
| 1893 std::unique_ptr<LauncherAppUpdater> arc_app_updater( | 1731 std::unique_ptr<LauncherAppUpdater> arc_app_updater( |
| 1894 new LauncherArcAppUpdater(this, profile_)); | 1732 new LauncherArcAppUpdater(this, profile_)); |
| 1895 app_updaters_.push_back(std::move(arc_app_updater)); | 1733 app_updaters_.push_back(std::move(arc_app_updater)); |
| 1896 } | 1734 } |
| 1735 |
| 1736 app_list::AppListSyncableService* app_service = |
| 1737 app_list::AppListSyncableService::Get(profile_); |
| 1738 if (app_service) |
| 1739 app_service->AddObserverAndStart(this); |
| 1897 } | 1740 } |
| 1898 | 1741 |
| 1899 void ChromeLauncherController::ReleaseProfile() { | 1742 void ChromeLauncherController::ReleaseProfile() { |
| 1900 if (app_sync_ui_state_) | 1743 if (app_sync_ui_state_) |
| 1901 app_sync_ui_state_->RemoveObserver(this); | 1744 app_sync_ui_state_->RemoveObserver(this); |
| 1902 | 1745 |
| 1903 app_updaters_.clear(); | 1746 app_updaters_.clear(); |
| 1904 | 1747 |
| 1905 PrefServiceSyncableFromProfile(profile_)->RemoveObserver(this); | 1748 PrefServiceSyncableFromProfile(profile_)->RemoveObserver(this); |
| 1906 | 1749 |
| 1907 pref_change_registrar_.RemoveAll(); | 1750 pref_change_registrar_.RemoveAll(); |
| 1751 |
| 1752 app_list::AppListSyncableService* app_service = |
| 1753 app_list::AppListSyncableService::Get(profile_); |
| 1754 if (app_service) |
| 1755 app_service->RemoveObserver(this); |
| 1908 } | 1756 } |
| 1909 | 1757 |
| 1910 AppIconLoader* ChromeLauncherController::GetAppIconLoaderForApp( | 1758 AppIconLoader* ChromeLauncherController::GetAppIconLoaderForApp( |
| 1911 const std::string& app_id) { | 1759 const std::string& app_id) { |
| 1912 for (const auto& app_icon_loader : app_icon_loaders_) { | 1760 for (const auto& app_icon_loader : app_icon_loaders_) { |
| 1913 if (app_icon_loader->CanLoadImageForApp(app_id)) | 1761 if (app_icon_loader->CanLoadImageForApp(app_id)) |
| 1914 return app_icon_loader.get(); | 1762 return app_icon_loader.get(); |
| 1915 } | 1763 } |
| 1916 | 1764 |
| 1917 return nullptr; | 1765 return nullptr; |
| 1918 } | 1766 } |
| OLD | NEW |