| // Copyright 2012 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CHROME_BROWSER_UI_ASH_SHELF_CHROME_SHELF_PREFS_H_ |
| #define CHROME_BROWSER_UI_ASH_SHELF_CHROME_SHELF_PREFS_H_ |
| |
| #include <string> |
| #include <vector> |
| |
| #include "base/containers/span.h" |
| #include "base/gtest_prod_util.h" |
| #include "base/memory/raw_ptr.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/scoped_observation.h" |
| #include "chrome/browser/ash/app_list/app_list_syncable_service.h" |
| #include "components/services/app_service/public/cpp/package_id.h" |
| |
| class ShelfControllerHelper; |
| class PrefService; |
| class Profile; |
| |
| namespace ash { |
| struct ShelfID; |
| } // namespace ash |
| |
| namespace user_prefs { |
| class PrefRegistrySyncable; |
| } // namespace user_prefs |
| |
| // This class is responsible for briding between sync/pref-store and the ash |
| // shelf. |
| class ChromeShelfPrefs : public app_list::AppListSyncableService::Observer { |
| public: |
| explicit ChromeShelfPrefs(Profile* profile); |
| ChromeShelfPrefs(const ChromeShelfPrefs&) = delete; |
| ChromeShelfPrefs& operator=(const ChromeShelfPrefs&) = delete; |
| ~ChromeShelfPrefs() override; |
| |
| // Key for the dictionary entries in the prefs::kPinnedLauncherApps list |
| // specifying the extension ID of the app to be pinned by that entry. |
| static constexpr char kPinnedAppsPrefAppIDKey[] = "id"; |
| |
| // All prefs must be registered early in the process lifecycle. |
| static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); |
| |
| // Cleanup multiple values of 'preload' added to ShelfDefaultPinLayoutRolls. |
| static void CleanupPreloadPrefs(PrefService* profile_prefs); |
| |
| // Init a local pref from a synced pref, if the local pref has no user |
| // setting. This is used to init shelf alignment and auto-hide on the first |
| // user sync. The goal is to apply the last elected shelf alignment and |
| // auto-hide values when a user signs in to a new device for the first time. |
| // Otherwise, shelf properties are persisted per-display/device. The local |
| // prefs are initialized with synced (or default) values when when syncing |
| // begins, to avoid syncing shelf prefs across devices after the very start of |
| // the user's first session. |
| void InitLocalPref(PrefService* prefs, const char* local, const char* synced); |
| |
| // Gets the ordered list of pinned apps that exist on device from the app sync |
| // service. This returns apps that are known to the app service with one |
| // exceptions: app_constants::kChromeAppId (ash-chrome) can be returned and is |
| // not known to the app service. |
| std::vector<ash::ShelfID> GetPinnedAppsFromSync( |
| ShelfControllerHelper* helper); |
| |
| // Gets the ordered list of apps that have been pinned by policy. May contain |
| // duplicates. |
| static std::vector<std::string> GetAppsPinnedByPolicy(Profile* profile); |
| |
| // Removes information about pin position from sync model for the app. |
| // Note, |shelf_id| with non-empty launch_id is not supported. |
| void RemovePinPosition(const ash::ShelfID& shelf_id); |
| |
| // Updates information about pin position in sync model for the app |
| // |shelf_id|. |shelf_id_before| optionally specifies an app that exists right |
| // before the target app. |shelf_ids_after| optionally specifies sorted by |
| // position apps that exist right after the target app. Note, |shelf_id| with |
| // non-empty launch_id is not supported. |
| void SetPinPosition(const ash::ShelfID& shelf_id, |
| const ash::ShelfID& shelf_id_before, |
| base::span<const ash::ShelfID> shelf_ids_after); |
| |
| // Makes ShouldAddDefaultApps() return true if set to true. |
| static void SetShouldAddDefaultAppsForTest(bool value); |
| |
| // In multi-user login, it's possible for the profile to change during a |
| // session. This requires resetting all migrations. This method is also called |
| // shorty after initialization. |
| void AttachProfile(Profile* profile); |
| |
| // Get the `promise_package_id` value if one exists for the sync item with an |
| // item ID of `app_id`. |
| std::string GetPromisePackageIdForSyncItem(const std::string& app_id); |
| |
| private: |
| FRIEND_TEST_ALL_PREFIXES(ChromeShelfPrefsTest, AddChromePinNoExistingOrdinal); |
| FRIEND_TEST_ALL_PREFIXES(ChromeShelfPrefsTest, AddChromePinExistingOrdinal); |
| FRIEND_TEST_ALL_PREFIXES(ChromeShelfPrefsTest, AddDefaultApps); |
| FRIEND_TEST_ALL_PREFIXES(ChromeShelfPrefsTest, ProfileChanged); |
| FRIEND_TEST_ALL_PREFIXES(ChromeShelfPrefsTest, PinPreloadApps); |
| FRIEND_TEST_ALL_PREFIXES(ChromeShelfPrefsTest, PinPreloadRepeats); |
| FRIEND_TEST_ALL_PREFIXES(ChromeShelfPrefsTest, PinPreloadEmpty); |
| |
| // Sync is the source of truth. However, the data from sync can be |
| // nonsensical, either because the user nuked all sync data, corruption, or |
| // otherwise. The purpose of the consistency migrations are two fold: |
| // (1) To perform what should logically be 1-time migrations. |
| // (2) In case of data loss or corruption, to bring the user back to a |
| // safe/consistent state. |
| // By necessity, all consistency migrations must be idempotent. Otherwise the |
| // logic will trigger on every call to GetPinnedAppsFromSync(). |
| // |
| // This method returns whether the consistency migrations need to be run |
| // again. |
| bool ShouldPerformConsistencyMigrations() const; |
| |
| // Ensure the Files Chrome app pinned positions are appropriately migrated to |
| // the Files System Web App. |
| void MigrateFilesChromeAppToSWA(); |
| |
| // Ensure that Projector app pinned positions are appropriatley migrated after |
| // the change to its app-id. |
| void EnsureProjectorShelfPinConsistency(); |
| |
| // This is run each time ash launches and each time new data is obtained from |
| // sync. It ensures that ash-chrome is properly pinned or unpinned. |
| void EnsureChromePinned(); |
| |
| // Whether the default apps have already been added for this device form |
| // factor. |
| bool DidAddDefaultApps() const; |
| |
| // Whether it's safe to add the default apps. We will refrain from adding the |
| // default apps if there are policies that modify the pinned apps, or if app |
| // sync has not yet started. |
| bool ShouldAddDefaultApps() const; |
| |
| // This migration is run once per device form factor and the result is stored |
| // in prefs. It is never run again if that pref is present. It causes several |
| // default apps to be shown in the shelf. |
| void AddDefaultApps(); |
| |
| // Whether App Preload Service apps have already been added. |
| bool DidAddPreloadApps() const; |
| |
| // Pin preload apps received along with desired order via OnAppPreloadReady(). |
| void PinPreloadApps(); |
| |
| // app_list::AppListSyncableService::Observer: |
| void OnSyncModelUpdated() override; |
| |
| // Receives Pin preload apps when AppPreloadService is ready. |
| void OnGetPinPreloadApps(const std::vector<apps::PackageId>& pin_apps, |
| const std::vector<apps::PackageId>& pin_order); |
| |
| // Migrations are performed in several situations: |
| // (1) On first launch |
| // (2) Any time there's a sync update |
| // (3) On profile change. |
| // In order to prevent an endless cycle of sync updates, all migrations must |
| // be idempotent. |
| bool needs_consistency_migrations_ = true; |
| |
| // List of preload apps to pin once they are installed. |
| std::vector<apps::PackageId> pending_preload_apps_; |
| |
| // Desired order to pin preload apps, includes default apps (e.g. chrome) to |
| // show where preload apps should be pinned. |
| std::vector<apps::PackageId> preload_pin_order_; |
| |
| base::ScopedObservation<app_list::AppListSyncableService, |
| app_list::AppListSyncableService::Observer> |
| sync_service_observer_{this}; |
| |
| // The owner of this class is responsible for ensuring the validity of this |
| // pointer. |
| raw_ptr<Profile> profile_ = nullptr; |
| |
| base::WeakPtrFactory<ChromeShelfPrefs> weak_ptr_factory_{this}; |
| }; |
| |
| #endif // CHROME_BROWSER_UI_ASH_SHELF_CHROME_SHELF_PREFS_H_ |