Revert "Remove Unused parts of LauncherPrefs causing cyclical dependency."

This reverts commit 21ab3b979b78d15d71f979f6290844b0dd1795ee.

Reason for revert: Culprit for b/326611479. Will be verifying through ABTD for confirmation and before submitting the revert.

Change-Id: Ib71791d159b3ac65ca332f58500341a1a0fe36e1
diff --git a/src/com/android/launcher3/LauncherPrefs.kt b/src/com/android/launcher3/LauncherPrefs.kt
index d7e6387..b0a644b 100644
--- a/src/com/android/launcher3/LauncherPrefs.kt
+++ b/src/com/android/launcher3/LauncherPrefs.kt
@@ -19,6 +19,7 @@
 import android.content.Context.MODE_PRIVATE
 import android.content.SharedPreferences
 import android.content.SharedPreferences.OnSharedPreferenceChangeListener
+import android.util.Log
 import android.view.ViewConfiguration
 import androidx.annotation.VisibleForTesting
 import com.android.launcher3.BuildConfig.WIDGET_ON_FIRST_SCREEN
@@ -37,6 +38,8 @@
  * Use same context for shared preferences, so that we use a single cached instance
  *
  * TODO(b/262721340): Replace all direct SharedPreference refs with LauncherPrefs / Item methods.
+ * TODO(b/274501660): Fix ReorderWidgets#simpleReorder test before enabling
+ *   isBootAwareStartupDataEnabled
  */
 class LauncherPrefs(private val encryptedContext: Context) {
     private val deviceProtectedStorageContext =
@@ -49,8 +52,22 @@
     private val Item.encryptedPrefs
         get() = encryptedContext.getSharedPreferences(sharedPrefFile, MODE_PRIVATE)
 
+    // This call to `SharedPreferences` needs to be explicit rather than using `get` since doing so
+    // would result in a circular dependency between `isStartupDataMigrated` and `choosePreferences`
+    val isStartupDataMigrated: Boolean
+        get() =
+            bootAwarePrefs.getBoolean(
+                IS_STARTUP_DATA_MIGRATED.sharedPrefKey,
+                IS_STARTUP_DATA_MIGRATED.defaultValue
+            )
+
     private fun chooseSharedPreferences(item: Item): SharedPreferences =
-        if (item.encryptionType == EncryptionType.DEVICE_PROTECTED) bootAwarePrefs
+        if (
+            (moveStartupDataToDeviceProtectedStorageIsEnabled &&
+                item.encryptionType == EncryptionType.MOVE_TO_DEVICE_PROTECTED &&
+                isStartupDataMigrated) || item.encryptionType == EncryptionType.DEVICE_PROTECTED
+        )
+            bootAwarePrefs
         else item.encryptedPrefs
 
     /** Wrapper around `getInner` for a `ContextualItem` */
@@ -130,7 +147,11 @@
                 .toMutableMap()
 
         val bootAwareUpdates =
-            updates.filter { it.first.encryptionType == EncryptionType.DEVICE_PROTECTED }
+            updates.filter {
+                (it.first.encryptionType == EncryptionType.MOVE_TO_DEVICE_PROTECTED &&
+                    moveStartupDataToDeviceProtectedStorageIsEnabled) ||
+                    it.first.encryptionType == EncryptionType.DEVICE_PROTECTED
+            }
         if (bootAwareUpdates.isNotEmpty()) {
             updatesPerPrefFile[bootAwarePrefs] = bootAwareUpdates
         }
@@ -231,7 +252,12 @@
                 .groupBy { it.encryptedPrefs }
                 .toMutableMap()
 
-        val bootAwareUpdates = items.filter { it.encryptionType == EncryptionType.DEVICE_PROTECTED }
+        val bootAwareUpdates =
+            items.filter {
+                (it.encryptionType == EncryptionType.MOVE_TO_DEVICE_PROTECTED &&
+                    moveStartupDataToDeviceProtectedStorageIsEnabled) ||
+                    it.encryptionType == EncryptionType.DEVICE_PROTECTED
+            }
         if (bootAwareUpdates.isNotEmpty()) {
             itemsPerFile[bootAwarePrefs] = bootAwareUpdates
         }
@@ -243,7 +269,24 @@
         }
     }
 
+    fun migrateStartupDataToDeviceProtectedStorage() {
+        if (!moveStartupDataToDeviceProtectedStorageIsEnabled) return
+
+        Log.d(
+            TAG,
+            "Migrating data to unencrypted shared preferences to enable preloading " +
+                "while the user is locked the next time the device reboots."
+        )
+
+        with(bootAwarePrefs.edit()) {
+            ITEMS_TO_MOVE_TO_DEVICE_PROTECTED_STORAGE.forEach { putValue(it, get(it)) }
+            putBoolean(IS_STARTUP_DATA_MIGRATED.sharedPrefKey, true)
+            apply()
+        }
+    }
+
     companion object {
+        private const val TAG = "LauncherPrefs"
         @VisibleForTesting const val BOOT_AWARE_PREFS_KEY = "boot_aware_prefs"
 
         @JvmField var INSTANCE = MainThreadInitializedObject { LauncherPrefs(it) }
@@ -253,50 +296,80 @@
         const val TASKBAR_PINNING_KEY = "TASKBAR_PINNING_KEY"
         const val SHOULD_SHOW_SMARTSPACE_KEY = "SHOULD_SHOW_SMARTSPACE_KEY"
         @JvmField
-        val ICON_STATE = nonRestorableItem("pref_icon_shape_path", "", EncryptionType.ENCRYPTED)
+        val ICON_STATE =
+            nonRestorableItem("pref_icon_shape_path", "", EncryptionType.MOVE_TO_DEVICE_PROTECTED)
         @JvmField
         val ALL_APPS_OVERVIEW_THRESHOLD =
-            nonRestorableItem("pref_all_apps_overview_threshold", 180, EncryptionType.ENCRYPTED)
+            nonRestorableItem(
+                "pref_all_apps_overview_threshold",
+                180,
+                EncryptionType.MOVE_TO_DEVICE_PROTECTED
+            )
         @JvmField
         val LONG_PRESS_NAV_HANDLE_SLOP_PERCENTAGE =
-            nonRestorableItem("LPNH_SLOP_PERCENTAGE", 100, EncryptionType.ENCRYPTED)
+            nonRestorableItem("LPNH_SLOP_PERCENTAGE", 100, EncryptionType.MOVE_TO_DEVICE_PROTECTED)
         @JvmField
         val LONG_PRESS_NAV_HANDLE_TIMEOUT_MS =
             nonRestorableItem(
                 "LPNH_TIMEOUT_MS",
                 ViewConfiguration.getLongPressTimeout(),
-                EncryptionType.ENCRYPTED
+                EncryptionType.MOVE_TO_DEVICE_PROTECTED
             )
         @JvmField
         val LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_START_SCALE_PERCENT =
-            nonRestorableItem("LPNH_HAPTIC_HINT_START_SCALE_PERCENT", 0, EncryptionType.ENCRYPTED)
+            nonRestorableItem(
+                "LPNH_HAPTIC_HINT_START_SCALE_PERCENT",
+                0,
+                EncryptionType.MOVE_TO_DEVICE_PROTECTED
+            )
         @JvmField
         val LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_END_SCALE_PERCENT =
-            nonRestorableItem("LPNH_HAPTIC_HINT_END_SCALE_PERCENT", 100, EncryptionType.ENCRYPTED)
+            nonRestorableItem(
+                "LPNH_HAPTIC_HINT_END_SCALE_PERCENT",
+                100,
+                EncryptionType.MOVE_TO_DEVICE_PROTECTED
+            )
         @JvmField
         val LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_SCALE_EXPONENT =
-            nonRestorableItem("LPNH_HAPTIC_HINT_SCALE_EXPONENT", 1, EncryptionType.ENCRYPTED)
+            nonRestorableItem(
+                "LPNH_HAPTIC_HINT_SCALE_EXPONENT",
+                1,
+                EncryptionType.MOVE_TO_DEVICE_PROTECTED
+            )
         @JvmField
         val LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_ITERATIONS =
-            nonRestorableItem("LPNH_HAPTIC_HINT_ITERATIONS", 50, EncryptionType.ENCRYPTED)
+            nonRestorableItem(
+                "LPNH_HAPTIC_HINT_ITERATIONS",
+                50,
+                EncryptionType.MOVE_TO_DEVICE_PROTECTED
+            )
         @JvmField
         val LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_DELAY =
-            nonRestorableItem("LPNH_HAPTIC_HINT_DELAY", 0, EncryptionType.ENCRYPTED)
+            nonRestorableItem("LPNH_HAPTIC_HINT_DELAY", 0, EncryptionType.MOVE_TO_DEVICE_PROTECTED)
         @JvmField
         val PRIVATE_SPACE_APPS =
-            nonRestorableItem("pref_private_space_apps", 0, EncryptionType.ENCRYPTED)
+            nonRestorableItem("pref_private_space_apps", 0, EncryptionType.MOVE_TO_DEVICE_PROTECTED)
+        @JvmField val ENABLE_TWOLINE_ALLAPPS_TOGGLE =
+                backedUpItem("pref_enable_two_line_toggle", false)
         @JvmField
-        val ENABLE_TWOLINE_ALLAPPS_TOGGLE = backedUpItem("pref_enable_two_line_toggle", false)
-        @JvmField
-        val THEMED_ICONS = backedUpItem(Themes.KEY_THEMED_ICONS, false, EncryptionType.ENCRYPTED)
+        val THEMED_ICONS =
+            backedUpItem(Themes.KEY_THEMED_ICONS, false, EncryptionType.MOVE_TO_DEVICE_PROTECTED)
         @JvmField val PROMISE_ICON_IDS = backedUpItem(InstallSessionHelper.PROMISE_ICON_IDS, "")
         @JvmField val WORK_EDU_STEP = backedUpItem("showed_work_profile_edu", 0)
         @JvmField
         val WORKSPACE_SIZE =
-            backedUpItem(DeviceGridState.KEY_WORKSPACE_SIZE, "", EncryptionType.ENCRYPTED)
+            backedUpItem(
+                DeviceGridState.KEY_WORKSPACE_SIZE,
+                "",
+                EncryptionType.MOVE_TO_DEVICE_PROTECTED
+            )
         @JvmField
         val HOTSEAT_COUNT =
-            backedUpItem(DeviceGridState.KEY_HOTSEAT_COUNT, -1, EncryptionType.ENCRYPTED)
+            backedUpItem(
+                DeviceGridState.KEY_HOTSEAT_COUNT,
+                -1,
+                EncryptionType.MOVE_TO_DEVICE_PROTECTED
+            )
         @JvmField
         val TASKBAR_PINNING =
             backedUpItem(TASKBAR_PINNING_KEY, false, EncryptionType.DEVICE_PROTECTED)
@@ -306,10 +379,11 @@
             backedUpItem(
                 DeviceGridState.KEY_DEVICE_TYPE,
                 InvariantDeviceProfile.TYPE_PHONE,
-                EncryptionType.ENCRYPTED
+                EncryptionType.MOVE_TO_DEVICE_PROTECTED
             )
         @JvmField
-        val DB_FILE = backedUpItem(DeviceGridState.KEY_DB_FILE, "", EncryptionType.ENCRYPTED)
+        val DB_FILE =
+            backedUpItem(DeviceGridState.KEY_DB_FILE, "", EncryptionType.MOVE_TO_DEVICE_PROTECTED)
         @JvmField
         val SHOULD_SHOW_SMARTSPACE =
             backedUpItem(
@@ -322,11 +396,15 @@
             backedUpItem(
                 RestoreDbTask.RESTORED_DEVICE_TYPE,
                 InvariantDeviceProfile.TYPE_PHONE,
-                EncryptionType.ENCRYPTED
+                EncryptionType.MOVE_TO_DEVICE_PROTECTED
             )
         @JvmField
         val IS_FIRST_LOAD_AFTER_RESTORE =
-            nonRestorableItem(FIRST_LOAD_AFTER_RESTORE_KEY, false, EncryptionType.ENCRYPTED)
+            nonRestorableItem(
+                FIRST_LOAD_AFTER_RESTORE_KEY,
+                false,
+                EncryptionType.MOVE_TO_DEVICE_PROTECTED
+            )
         @JvmField val APP_WIDGET_IDS = backedUpItem(RestoreDbTask.APPWIDGET_IDS, "")
         @JvmField val OLD_APP_WIDGET_IDS = backedUpItem(RestoreDbTask.APPWIDGET_OLD_IDS, "")
         @JvmField
@@ -335,7 +413,7 @@
                 "idp_grid_name",
                 isBackedUp = true,
                 defaultValue = null,
-                encryptionType = EncryptionType.ENCRYPTED,
+                encryptionType = EncryptionType.MOVE_TO_DEVICE_PROTECTED,
                 type = String::class.java
             )
         @JvmField
@@ -343,6 +421,14 @@
             backedUpItem(RotationHelper.ALLOW_ROTATION_PREFERENCE_KEY, Boolean::class.java) {
                 RotationHelper.getAllowRotationDefaultValue(DisplayController.INSTANCE.get(it).info)
             }
+        @JvmField
+        val IS_STARTUP_DATA_MIGRATED =
+            ConstantItem(
+                "is_startup_data_boot_aware",
+                isBackedUp = false,
+                defaultValue = false,
+                encryptionType = EncryptionType.DEVICE_PROTECTED
+            )
 
         // Preferences for widget configurations
         @JvmField
@@ -407,6 +493,12 @@
     }
 }
 
+// It is a var because the unit tests are setting this to true so they can run.
+var moveStartupDataToDeviceProtectedStorageIsEnabled: Boolean =
+    com.android.launcher3.config.FeatureFlags.MOVE_STARTUP_DATA_TO_DEVICE_PROTECTED_STORAGE.get()
+
+private val ITEMS_TO_MOVE_TO_DEVICE_PROTECTED_STORAGE: MutableSet<ConstantItem<*>> = mutableSetOf()
+
 abstract class Item {
     abstract val sharedPrefKey: String
     abstract val isBackedUp: Boolean
@@ -426,6 +518,14 @@
     // The default value can be null. If so, the type needs to be explicitly stated, or else NPE
     override val type: Class<out T> = defaultValue!!::class.java
 ) : Item() {
+    init {
+        if (
+            encryptionType == EncryptionType.MOVE_TO_DEVICE_PROTECTED &&
+                moveStartupDataToDeviceProtectedStorageIsEnabled
+        ) {
+            ITEMS_TO_MOVE_TO_DEVICE_PROTECTED_STORAGE.add(this)
+        }
+    }
 
     fun get(c: Context): T = LauncherPrefs.get(c).get(this)
 }
@@ -452,4 +552,5 @@
 enum class EncryptionType {
     ENCRYPTED,
     DEVICE_PROTECTED,
+    MOVE_TO_DEVICE_PROTECTED
 }