Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/chrome_launcher_prefs.h" | 5 #include "chrome/browser/ui/ash/chrome_launcher_prefs.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <set> | 9 #include <set> |
| 10 | 10 |
| 11 #include "base/macros.h" | 11 #include "base/macros.h" |
| 12 #include "base/strings/string_number_conversions.h" | 12 #include "base/strings/string_number_conversions.h" |
| 13 #include "base/values.h" | 13 #include "base/values.h" |
| 14 #include "chrome/browser/app_mode/app_mode_utils.h" | 14 #include "chrome/browser/app_mode/app_mode_utils.h" |
| 15 #include "chrome/browser/chromeos/arc/arc_auth_service.h" | 15 #include "chrome/browser/chromeos/arc/arc_auth_service.h" |
| 16 #include "chrome/browser/chromeos/arc/arc_support_host.h" | 16 #include "chrome/browser/chromeos/arc/arc_support_host.h" |
| 17 #include "chrome/browser/prefs/pref_service_syncable_util.h" | 17 #include "chrome/browser/prefs/pref_service_syncable_util.h" |
| 18 #include "chrome/browser/profiles/profile.h" | |
| 18 #include "chrome/browser/ui/app_list/app_list_syncable_service.h" | 19 #include "chrome/browser/ui/app_list/app_list_syncable_service.h" |
| 19 #include "chrome/browser/ui/app_list/app_list_syncable_service_factory.h" | 20 #include "chrome/browser/ui/app_list/app_list_syncable_service_factory.h" |
| 20 #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" | 21 #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" |
| 21 #include "chrome/browser/ui/ash/launcher/launcher_controller_helper.h" | 22 #include "chrome/browser/ui/ash/launcher/launcher_controller_helper.h" |
| 22 #include "chrome/common/extensions/extension_constants.h" | 23 #include "chrome/common/extensions/extension_constants.h" |
| 23 #include "chrome/common/pref_names.h" | 24 #include "chrome/common/pref_names.h" |
| 24 #include "components/pref_registry/pref_registry_syncable.h" | 25 #include "components/pref_registry/pref_registry_syncable.h" |
| 25 #include "components/prefs/pref_service.h" | 26 #include "components/prefs/pref_service.h" |
| 26 #include "components/prefs/scoped_user_pref_update.h" | 27 #include "components/prefs/scoped_user_pref_update.h" |
| 27 #include "components/sync/model/string_ordinal.h" | 28 #include "components/sync/model/string_ordinal.h" |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 263 MaybeAddApp(app_id, helper); | 264 MaybeAddApp(app_id, helper); |
| 264 } | 265 } |
| 265 | 266 |
| 266 const std::vector<std::string>& app_list() const { return app_list_; } | 267 const std::vector<std::string>& app_list() const { return app_list_; } |
| 267 | 268 |
| 268 private: | 269 private: |
| 269 std::vector<std::string> app_list_; | 270 std::vector<std::string> app_list_; |
| 270 std::set<std::string> app_set_; | 271 std::set<std::string> app_set_; |
| 271 }; | 272 }; |
| 272 | 273 |
| 274 // If sync is running then return position from sync service, otherwise use | |
| 275 // local copy. | |
| 276 syncer::StringOrdinal GetPinPosition( | |
| 277 app_list::AppListSyncableService* app_service, | |
| 278 const std::string& app_id) { | |
| 279 DCHECK(app_service); | |
| 280 if (app_service->is_active()) | |
| 281 return app_service->GetPinPosition(app_id); | |
| 282 | |
| 283 const base::DictionaryValue* apps = | |
| 284 app_service->profile()->GetPrefs()->GetDictionary(prefs::kShelfPins); | |
| 285 DCHECK(apps); | |
| 286 std::string position_string; | |
| 287 if (!apps->GetString(app_id, &position_string)) | |
| 288 return syncer::StringOrdinal(); | |
| 289 | |
| 290 const syncer::StringOrdinal position(position_string); | |
| 291 if (!position.IsValid()) { | |
| 292 LOG(ERROR) << "Found wrong pin position " << position_string | |
| 293 << " in local copy for " << app_id; | |
| 294 return syncer::StringOrdinal(); | |
| 295 } | |
| 296 | |
| 297 return position; | |
| 298 } | |
| 299 | |
| 273 } // namespace | 300 } // namespace |
| 274 | 301 |
| 275 const char kPinnedAppsPrefAppIDPath[] = "id"; | 302 const char kPinnedAppsPrefAppIDPath[] = "id"; |
| 276 const char kPinnedAppsPrefPinnedByPolicy[] = "pinned_by_policy"; | 303 const char kPinnedAppsPrefPinnedByPolicy[] = "pinned_by_policy"; |
| 277 const char kPinnedAppsPlaceholder[] = "AppShelfIDPlaceholder--------"; | 304 const char kPinnedAppsPlaceholder[] = "AppShelfIDPlaceholder--------"; |
| 278 | 305 |
| 279 const char kShelfAutoHideBehaviorAlways[] = "Always"; | 306 const char kShelfAutoHideBehaviorAlways[] = "Always"; |
| 280 const char kShelfAutoHideBehaviorNever[] = "Never"; | 307 const char kShelfAutoHideBehaviorNever[] = "Never"; |
| 281 | 308 |
| 282 const char kShelfAlignmentBottom[] = "Bottom"; | 309 const char kShelfAlignmentBottom[] = "Bottom"; |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 300 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); | 327 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); |
| 301 registry->RegisterStringPref(prefs::kShelfAutoHideBehaviorLocal, | 328 registry->RegisterStringPref(prefs::kShelfAutoHideBehaviorLocal, |
| 302 std::string()); | 329 std::string()); |
| 303 registry->RegisterStringPref(prefs::kShelfAlignment, | 330 registry->RegisterStringPref(prefs::kShelfAlignment, |
| 304 kShelfAlignmentBottom, | 331 kShelfAlignmentBottom, |
| 305 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); | 332 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); |
| 306 registry->RegisterStringPref(prefs::kShelfAlignmentLocal, std::string()); | 333 registry->RegisterStringPref(prefs::kShelfAlignmentLocal, std::string()); |
| 307 registry->RegisterDictionaryPref(prefs::kShelfPreferences); | 334 registry->RegisterDictionaryPref(prefs::kShelfPreferences); |
| 308 registry->RegisterIntegerPref(prefs::kLogoutDialogDurationMs, 20000); | 335 registry->RegisterIntegerPref(prefs::kLogoutDialogDurationMs, 20000); |
| 309 registry->RegisterBooleanPref(prefs::kShowLogoutButtonInTray, false); | 336 registry->RegisterBooleanPref(prefs::kShowLogoutButtonInTray, false); |
| 337 registry->RegisterDictionaryPref(prefs::kShelfPins); | |
| 310 } | 338 } |
| 311 | 339 |
| 312 base::DictionaryValue* CreateAppDict(const std::string& app_id) { | 340 base::DictionaryValue* CreateAppDict(const std::string& app_id) { |
| 313 std::unique_ptr<base::DictionaryValue> app_value(new base::DictionaryValue); | 341 std::unique_ptr<base::DictionaryValue> app_value(new base::DictionaryValue); |
| 314 app_value->SetString(kPinnedAppsPrefAppIDPath, app_id); | 342 app_value->SetString(kPinnedAppsPrefAppIDPath, app_id); |
| 315 return app_value.release(); | 343 return app_value.release(); |
| 316 } | 344 } |
| 317 | 345 |
| 318 ShelfAutoHideBehavior GetShelfAutoHideBehaviorPref(PrefService* prefs, | 346 ShelfAutoHideBehavior GetShelfAutoHideBehaviorPref(PrefService* prefs, |
| 319 int64_t display_id) { | 347 int64_t display_id) { |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 536 const PrefService* prefs, | 564 const PrefService* prefs, |
| 537 LauncherControllerHelper* helper, | 565 LauncherControllerHelper* helper, |
| 538 const AppTracker& policy_apps) { | 566 const AppTracker& policy_apps) { |
| 539 std::vector<std::string> legacy_pins = | 567 std::vector<std::string> legacy_pins = |
| 540 GetPinnedAppsFromPrefsLegacy(prefs, helper); | 568 GetPinnedAppsFromPrefsLegacy(prefs, helper); |
| 541 DCHECK(!legacy_pins.empty()); | 569 DCHECK(!legacy_pins.empty()); |
| 542 | 570 |
| 543 app_list::AppListSyncableService* app_service = | 571 app_list::AppListSyncableService* app_service = |
| 544 app_list::AppListSyncableServiceFactory::GetForProfile(helper->profile()); | 572 app_list::AppListSyncableServiceFactory::GetForProfile(helper->profile()); |
| 545 | 573 |
| 574 // Update pin info in local copy in order to keep it up to date. | |
| 575 DictionaryPrefUpdate pref_update(helper->profile()->GetPrefs(), | |
| 576 prefs::kShelfPins); | |
| 577 | |
| 546 syncer::StringOrdinal last_position = | 578 syncer::StringOrdinal last_position = |
| 547 syncer::StringOrdinal::CreateInitialOrdinal(); | 579 syncer::StringOrdinal::CreateInitialOrdinal(); |
| 548 // Convert to sync item record. | 580 // Convert to sync item record. |
| 549 for (const auto& app_id : legacy_pins) { | 581 for (const auto& app_id : legacy_pins) { |
| 550 DCHECK_NE(kPinnedAppsPlaceholder, app_id); | 582 DCHECK_NE(kPinnedAppsPlaceholder, app_id); |
| 551 app_service->SetPinPosition(app_id, last_position); | 583 app_service->SetPinPosition(app_id, last_position); |
| 584 pref_update->SetString(app_id, last_position.ToInternalValue()); | |
| 552 last_position = last_position.CreateAfter(); | 585 last_position = last_position.CreateAfter(); |
| 553 } | 586 } |
| 554 | 587 |
| 555 // Now process default apps. | 588 // Now process default apps. |
| 556 for (size_t i = 0; i < arraysize(kDefaultPinnedApps); ++i) { | 589 for (size_t i = 0; i < arraysize(kDefaultPinnedApps); ++i) { |
| 557 const std::string& app_id = kDefaultPinnedApps[i]; | 590 const std::string& app_id = kDefaultPinnedApps[i]; |
| 558 // Check if it is already imported. | 591 // Check if it is already imported. |
| 559 if (app_service->GetPinPosition(app_id).IsValid()) | 592 if (GetPinPosition(app_service, app_id).IsValid()) |
| 560 continue; | 593 continue; |
| 561 // Check if it is present but not in legacy pin. | 594 // Check if it is present but not in legacy pin. |
| 562 if (helper->IsValidIDForCurrentUser(app_id)) | 595 if (helper->IsValidIDForCurrentUser(app_id)) |
| 563 continue; | 596 continue; |
| 564 app_service->SetPinPosition(app_id, last_position); | 597 app_service->SetPinPosition(app_id, last_position); |
| 598 pref_update->SetString(app_id, last_position.ToInternalValue()); | |
| 565 last_position = last_position.CreateAfter(); | 599 last_position = last_position.CreateAfter(); |
| 566 } | 600 } |
| 567 | 601 |
| 568 return legacy_pins; | 602 return legacy_pins; |
| 569 } | 603 } |
| 570 | 604 |
| 605 void SavePinnedAppsInLocalCopy(Profile* profile, | |
| 606 const std::vector<PinInfo>& pins) { | |
| 607 DictionaryPrefUpdate pref_update(profile->GetPrefs(), prefs::kShelfPins); | |
| 608 pref_update->Clear(); | |
| 609 for (const auto pin : pins) { | |
| 610 pref_update->SetString(pin.app_id, pin.item_ordinal.ToInternalValue()); | |
| 611 } | |
| 612 } | |
| 613 | |
| 571 std::vector<std::string> GetPinnedAppsFromPrefs( | 614 std::vector<std::string> GetPinnedAppsFromPrefs( |
| 572 const PrefService* prefs, | 615 const PrefService* prefs, |
| 573 LauncherControllerHelper* helper) { | 616 LauncherControllerHelper* helper) { |
| 574 app_list::AppListSyncableService* app_service = | 617 app_list::AppListSyncableService* app_service = |
| 575 app_list::AppListSyncableServiceFactory::GetForProfile(helper->profile()); | 618 app_list::AppListSyncableServiceFactory::GetForProfile(helper->profile()); |
| 576 // Some unit tests may not have it. | 619 // Some unit tests may not have it. |
| 577 if (!app_service) | 620 if (!app_service) |
| 578 return std::vector<std::string>(); | 621 return std::vector<std::string>(); |
| 579 | 622 |
| 580 std::vector<PinInfo> pin_infos; | 623 std::vector<PinInfo> pin_infos; |
| 581 | 624 |
| 582 AppTracker policy_apps; | 625 AppTracker policy_apps; |
| 583 GetAppsPinnedByPolicy(prefs, helper, &policy_apps); | 626 GetAppsPinnedByPolicy(prefs, helper, &policy_apps); |
| 584 | 627 |
| 628 const base::DictionaryValue* apps_in_local_copy = | |
| 629 helper->profile()->GetPrefs()->GetDictionary(prefs::kShelfPins); | |
| 630 DCHECK(apps_in_local_copy); | |
| 631 | |
| 585 // Empty pins indicates that sync based pin model is used for the first | 632 // Empty pins indicates that sync based pin model is used for the first |
| 586 // time. In normal workflow we have at least Chrome browser pin info. | 633 // time. In normal workflow we have at least Chrome browser pin info. |
| 587 bool first_run = true; | 634 // In case sync is not started, first run is detected by absence of local |
| 635 // pins copy. | |
| 636 bool first_run = apps_in_local_copy->empty(); | |
| 588 | 637 |
| 589 for (const auto& sync_peer : app_service->sync_items()) { | 638 if (app_service->is_active()) { |
| 590 if (!sync_peer.second->item_pin_ordinal.IsValid()) | 639 for (const auto& sync_peer : app_service->sync_items()) { |
| 591 continue; | 640 if (!sync_peer.second->item_pin_ordinal.IsValid()) |
| 641 continue; | |
| 592 | 642 |
| 593 first_run = false; | 643 first_run = false; |
| 594 // Don't include apps that currently do not exist on device. | 644 // Don't include apps that currently do not exist on device. |
| 595 if (sync_peer.first != extension_misc::kChromeAppId && | 645 if (sync_peer.first != extension_misc::kChromeAppId && |
| 596 !helper->IsValidIDForCurrentUser(sync_peer.first)) { | 646 !helper->IsValidIDForCurrentUser(sync_peer.first)) { |
| 597 continue; | 647 continue; |
| 648 } | |
| 649 | |
| 650 pin_infos.push_back( | |
| 651 PinInfo(sync_peer.first, sync_peer.second->item_pin_ordinal)); | |
| 598 } | 652 } |
| 653 } else { | |
| 654 // If sync is not active, use information from local copy. | |
| 655 for (base::DictionaryValue::Iterator app(*apps_in_local_copy); | |
| 656 !app.IsAtEnd(); app.Advance()) { | |
| 657 // Don't include apps that currently do not exist on device. | |
| 658 if (app.key() != extension_misc::kChromeAppId && | |
| 659 !helper->IsValidIDForCurrentUser(app.key())) { | |
| 660 continue; | |
| 661 } | |
| 599 | 662 |
| 600 pin_infos.push_back( | 663 std::string position_string; |
| 601 PinInfo(sync_peer.first, sync_peer.second->item_pin_ordinal)); | 664 app.value().GetAsString(&position_string); |
| 665 const syncer::StringOrdinal position(position_string); | |
| 666 if (!position.IsValid()) { | |
| 667 NOTREACHED(); | |
| 668 continue; | |
| 669 } | |
|
stevenjb
2016/10/14 20:27:25
This should just be:
DCHECK(position.IsValid());
khmel
2016/10/17 21:10:57
Yes, I agree with your point of view, thanks for e
| |
| 670 | |
| 671 pin_infos.push_back(PinInfo(app.key(), position)); | |
| 672 } | |
| 602 } | 673 } |
| 603 | 674 |
| 604 if (first_run) { | 675 if (first_run) { |
| 605 // We need to import legacy pins model and convert it to sync based | 676 // We need to import legacy pins model and convert it to sync based |
| 606 // model. | 677 // model. |
| 607 return ImportLegacyPinnedApps(prefs, helper, policy_apps); | 678 return ImportLegacyPinnedApps(prefs, helper, policy_apps); |
| 608 } | 679 } |
| 609 | 680 |
| 610 // Sort pins according their ordinals. | 681 // Sort pins according their ordinals. |
| 611 std::sort(pin_infos.begin(), pin_infos.end(), ComparePinInfo()); | 682 std::sort(pin_infos.begin(), pin_infos.end(), ComparePinInfo()); |
| 612 | 683 |
| 613 // Pinned by policy apps appear first, if they were not shown before. | 684 // Pinned by policy apps appear first, if they were not shown before. |
| 614 syncer::StringOrdinal front_position = GetFirstPinPosition(helper->profile()); | 685 syncer::StringOrdinal front_position = GetFirstPinPosition(helper->profile()); |
| 615 std::vector<std::string>::const_reverse_iterator it; | 686 std::vector<std::string>::const_reverse_iterator it; |
| 616 for (it = policy_apps.app_list().rbegin(); | 687 for (it = policy_apps.app_list().rbegin(); |
| 617 it != policy_apps.app_list().rend(); ++it) { | 688 it != policy_apps.app_list().rend(); ++it) { |
| 618 const std::string& app_id = *it; | 689 const std::string& app_id = *it; |
| 619 if (app_id == kPinnedAppsPlaceholder) | 690 if (app_id == kPinnedAppsPlaceholder) |
| 620 continue; | 691 continue; |
| 621 | 692 |
| 622 // Check if we already processed current app. | 693 // Check if we already processed current app. |
| 623 if (app_service->GetPinPosition(app_id).IsValid()) | 694 if (GetPinPosition(app_service, app_id).IsValid()) |
| 624 continue; | 695 continue; |
| 625 | 696 |
| 626 // Now move it to the front. | 697 // Now move it to the front. |
| 627 pin_infos.insert(pin_infos.begin(), PinInfo(app_id, front_position)); | 698 pin_infos.insert(pin_infos.begin(), PinInfo(app_id, front_position)); |
| 628 app_service->SetPinPosition(app_id, front_position); | 699 app_service->SetPinPosition(app_id, front_position); |
| 629 front_position = front_position.CreateBefore(); | 700 front_position = front_position.CreateBefore(); |
| 630 } | 701 } |
| 631 | 702 |
| 632 // Now insert Chrome browser app if needed. | 703 // Now insert Chrome browser app if needed. |
| 633 if (!app_service->GetPinPosition(extension_misc::kChromeAppId).IsValid()) { | 704 if (!GetPinPosition(app_service, extension_misc::kChromeAppId).IsValid()) { |
| 634 pin_infos.insert(pin_infos.begin(), | 705 pin_infos.insert(pin_infos.begin(), |
| 635 PinInfo(extension_misc::kChromeAppId, front_position)); | 706 PinInfo(extension_misc::kChromeAppId, front_position)); |
| 636 app_service->SetPinPosition(extension_misc::kChromeAppId, front_position); | 707 app_service->SetPinPosition(extension_misc::kChromeAppId, front_position); |
| 637 } | 708 } |
| 638 | 709 |
| 639 if (helper->IsValidIDForCurrentUser(ArcSupportHost::kHostAppId)) { | 710 if (helper->IsValidIDForCurrentUser(ArcSupportHost::kHostAppId)) { |
| 640 if (!app_service->GetSyncItem(ArcSupportHost::kHostAppId)) { | 711 // TODO(khmel) Find the better way to initial pin PlayStore item when sync |
| 712 // is off. | |
|
stevenjb
2016/10/14 20:27:24
'find a way' ? It looks like we currently don't ha
khmel
2016/10/17 21:10:57
With new approach this is not required.
| |
| 713 if (app_service->is_active() && | |
| 714 !app_service->GetSyncItem(ArcSupportHost::kHostAppId)) { | |
| 641 const syncer::StringOrdinal arc_host_position = | 715 const syncer::StringOrdinal arc_host_position = |
| 642 GetLastPinPosition(helper->profile()); | 716 GetLastPinPosition(helper->profile()); |
| 643 pin_infos.insert(pin_infos.begin(), | 717 pin_infos.insert(pin_infos.begin(), |
| 644 PinInfo(ArcSupportHost::kHostAppId, arc_host_position)); | 718 PinInfo(ArcSupportHost::kHostAppId, arc_host_position)); |
| 645 app_service->SetPinPosition(ArcSupportHost::kHostAppId, | 719 app_service->SetPinPosition(ArcSupportHost::kHostAppId, |
| 646 arc_host_position); | 720 arc_host_position); |
| 647 } | 721 } |
| 648 } | 722 } |
| 649 | 723 |
| 650 // Convert to string array. | 724 // Convert to string array. |
| 651 std::vector<std::string> pins(pin_infos.size()); | 725 std::vector<std::string> pins(pin_infos.size()); |
| 652 for (size_t i = 0; i < pin_infos.size(); ++i) | 726 for (size_t i = 0; i < pin_infos.size(); ++i) |
| 653 pins[i] = pin_infos[i].app_id; | 727 pins[i] = pin_infos[i].app_id; |
| 654 | 728 |
| 729 // Sync current pins with local copy if required. | |
| 730 if (app_service->is_active()) | |
| 731 SavePinnedAppsInLocalCopy(helper->profile(), pin_infos); | |
| 732 | |
| 655 return pins; | 733 return pins; |
| 656 } | 734 } |
| 657 | 735 |
| 658 void RemovePinPosition(Profile* profile, const std::string& app_id) { | 736 void RemovePinPosition(Profile* profile, const std::string& app_id) { |
| 659 DCHECK(profile); | 737 DCHECK(profile); |
| 660 DCHECK(!app_id.empty()); | 738 DCHECK(!app_id.empty()); |
| 739 | |
| 740 // Remove pin info from local copy in order to keep it up to date. | |
| 741 DictionaryPrefUpdate pref_update(profile->GetPrefs(), prefs::kShelfPins); | |
| 742 pref_update->Remove(app_id, nullptr); | |
| 743 | |
| 661 app_list::AppListSyncableService* app_service = | 744 app_list::AppListSyncableService* app_service = |
| 662 app_list::AppListSyncableServiceFactory::GetForProfile(profile); | 745 app_list::AppListSyncableServiceFactory::GetForProfile(profile); |
| 663 app_service->SetPinPosition(app_id, syncer::StringOrdinal()); | 746 app_service->SetPinPosition(app_id, syncer::StringOrdinal()); |
| 664 } | 747 } |
| 665 | 748 |
| 666 void SetPinPosition(Profile* profile, | 749 void SetPinPosition(Profile* profile, |
| 667 const std::string& app_id, | 750 const std::string& app_id, |
| 668 const std::string& app_id_before, | 751 const std::string& app_id_before, |
| 669 const std::vector<std::string>& app_ids_after) { | 752 const std::vector<std::string>& app_ids_after) { |
| 670 DCHECK(profile); | 753 DCHECK(profile); |
| 671 DCHECK(!app_id.empty()); | 754 DCHECK(!app_id.empty()); |
| 672 DCHECK_NE(app_id, app_id_before); | 755 DCHECK_NE(app_id, app_id_before); |
| 673 | 756 |
| 674 app_list::AppListSyncableService* app_service = | 757 app_list::AppListSyncableService* app_service = |
| 675 app_list::AppListSyncableServiceFactory::GetForProfile(profile); | 758 app_list::AppListSyncableServiceFactory::GetForProfile(profile); |
| 676 // Some unit tests may not have this service. | 759 // Some unit tests may not have this service. |
| 677 if (!app_service) | 760 if (!app_service) |
| 678 return; | 761 return; |
| 679 | 762 |
| 680 syncer::StringOrdinal position_before = | 763 syncer::StringOrdinal position_before = |
| 681 app_id_before.empty() ? syncer::StringOrdinal() | 764 app_id_before.empty() ? syncer::StringOrdinal() |
| 682 : app_service->GetPinPosition(app_id_before); | 765 : GetPinPosition(app_service, app_id_before); |
| 683 syncer::StringOrdinal position_after; | 766 syncer::StringOrdinal position_after; |
| 684 for (const auto& app_id_after : app_ids_after) { | 767 for (const auto& app_id_after : app_ids_after) { |
| 685 DCHECK_NE(app_id_after, app_id); | 768 DCHECK_NE(app_id_after, app_id); |
| 686 DCHECK_NE(app_id_after, app_id_before); | 769 DCHECK_NE(app_id_after, app_id_before); |
| 687 syncer::StringOrdinal position = app_service->GetPinPosition(app_id_after); | 770 syncer::StringOrdinal position = GetPinPosition(app_service, app_id_after); |
| 688 DCHECK(position.IsValid()); | 771 DCHECK(position.IsValid()); |
| 689 if (!position.IsValid()) { | 772 if (!position.IsValid()) { |
| 690 LOG(ERROR) << "Sync pin position was not found for " << app_id_after; | 773 LOG(ERROR) << "Sync pin position was not found for " << app_id_after; |
| 691 continue; | 774 continue; |
| 692 } | 775 } |
| 693 if (!position_before.IsValid() || !position.Equals(position_before)) { | 776 if (!position_before.IsValid() || !position.Equals(position_before)) { |
| 694 position_after = position; | 777 position_after = position; |
| 695 break; | 778 break; |
| 696 } | 779 } |
| 697 } | 780 } |
| 698 | 781 |
| 699 syncer::StringOrdinal pin_position; | 782 syncer::StringOrdinal pin_position; |
| 700 if (position_before.IsValid() && position_after.IsValid()) | 783 if (position_before.IsValid() && position_after.IsValid()) |
| 701 pin_position = position_before.CreateBetween(position_after); | 784 pin_position = position_before.CreateBetween(position_after); |
| 702 else if (position_before.IsValid()) | 785 else if (position_before.IsValid()) |
| 703 pin_position = position_before.CreateAfter(); | 786 pin_position = position_before.CreateAfter(); |
| 704 else if (position_after.IsValid()) | 787 else if (position_after.IsValid()) |
| 705 pin_position = position_after.CreateBefore(); | 788 pin_position = position_after.CreateBefore(); |
| 706 else | 789 else |
| 707 pin_position = syncer::StringOrdinal::CreateInitialOrdinal(); | 790 pin_position = syncer::StringOrdinal::CreateInitialOrdinal(); |
| 791 | |
| 792 // Update pin info in local copy in order to keep it up to date. | |
| 793 DictionaryPrefUpdate pref_update(profile->GetPrefs(), prefs::kShelfPins); | |
| 794 pref_update->SetString(app_id, pin_position.ToInternalValue()); | |
| 795 | |
| 708 app_service->SetPinPosition(app_id, pin_position); | 796 app_service->SetPinPosition(app_id, pin_position); |
| 709 } | 797 } |
| 710 | 798 |
| 711 } // namespace launcher | 799 } // namespace launcher |
| 712 } // namespace ash | 800 } // namespace ash |
| OLD | NEW |