Merge "Fixes user switcher dialog animations."
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 53ee440..cefcf06 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -193,7 +193,7 @@
     <permission android:name="com.android.systemui.permission.FLAGS"
                 android:protectionLevel="signature" />
 
-    <permission android:name="android.permission.ACCESS_KEYGUARD_QUICK_AFFORDANCES"
+    <permission android:name="android.permission.CUSTOMIZE_SYSTEM_UI"
         android:protectionLevel="signature|privileged" />
 
     <!-- Adding Quick Settings tiles -->
@@ -1020,10 +1020,10 @@
         </activity>
 
         <provider
-            android:authorities="com.android.systemui.keyguard.quickaffordance"
-            android:name="com.android.systemui.keyguard.KeyguardQuickAffordanceProvider"
+            android:authorities="com.android.systemui.customization"
+            android:name="com.android.systemui.keyguard.CustomizationProvider"
             android:exported="true"
-            android:permission="android.permission.ACCESS_KEYGUARD_QUICK_AFFORDANCES"
+            android:permission="android.permission.CUSTOMIZE_SYSTEM_UI"
             />
     </application>
 </manifest>
diff --git a/packages/SystemUI/compose/features/tests/AndroidManifest.xml b/packages/SystemUI/compose/features/tests/AndroidManifest.xml
index 2fa475d..2f41ea9 100644
--- a/packages/SystemUI/compose/features/tests/AndroidManifest.xml
+++ b/packages/SystemUI/compose/features/tests/AndroidManifest.xml
@@ -35,7 +35,7 @@
             android:enabled="false"
             tools:replace="android:authorities"
             tools:node="remove" />
-        <provider android:name="com.android.systemui.keyguard.KeyguardQuickAffordanceProvider"
+        <provider android:name="com.android.systemui.keyguard.CustomizationProvider"
             android:authorities="com.android.systemui.test.keyguard.quickaffordance.disabled"
             android:enabled="false"
             tools:replace="android:authorities"
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/data/content/KeyguardQuickAffordanceProviderClient.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderClient.kt
similarity index 75%
rename from packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/data/content/KeyguardQuickAffordanceProviderClient.kt
rename to packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderClient.kt
index 3213b2e..5bb3707 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/data/content/KeyguardQuickAffordanceProviderClient.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderClient.kt
@@ -15,7 +15,7 @@
  *
  */
 
-package com.android.systemui.shared.quickaffordance.data.content
+package com.android.systemui.shared.customization.data.content
 
 import android.annotation.SuppressLint
 import android.content.ContentValues
@@ -25,7 +25,7 @@
 import android.graphics.drawable.Drawable
 import android.net.Uri
 import androidx.annotation.DrawableRes
-import com.android.systemui.shared.quickaffordance.data.content.KeyguardQuickAffordanceProviderContract as Contract
+import com.android.systemui.shared.customization.data.content.CustomizationProviderContract as Contract
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.channels.awaitClose
 import kotlinx.coroutines.flow.Flow
@@ -35,7 +35,7 @@
 import kotlinx.coroutines.withContext
 
 /** Client for using a content provider implementing the [Contract]. */
-interface KeyguardQuickAffordanceProviderClient {
+interface CustomizationProviderClient {
 
     /**
      * Selects an affordance with the given ID for a slot on the lock screen with the given ID.
@@ -190,10 +190,10 @@
     )
 }
 
-class KeyguardQuickAffordanceProviderClientImpl(
+class CustomizationProviderClientImpl(
     private val context: Context,
     private val backgroundDispatcher: CoroutineDispatcher,
-) : KeyguardQuickAffordanceProviderClient {
+) : CustomizationProviderClient {
 
     override suspend fun insertSelection(
         slotId: String,
@@ -201,20 +201,23 @@
     ) {
         withContext(backgroundDispatcher) {
             context.contentResolver.insert(
-                Contract.SelectionTable.URI,
+                Contract.LockScreenQuickAffordances.SelectionTable.URI,
                 ContentValues().apply {
-                    put(Contract.SelectionTable.Columns.SLOT_ID, slotId)
-                    put(Contract.SelectionTable.Columns.AFFORDANCE_ID, affordanceId)
+                    put(Contract.LockScreenQuickAffordances.SelectionTable.Columns.SLOT_ID, slotId)
+                    put(
+                        Contract.LockScreenQuickAffordances.SelectionTable.Columns.AFFORDANCE_ID,
+                        affordanceId
+                    )
                 }
             )
         }
     }
 
-    override suspend fun querySlots(): List<KeyguardQuickAffordanceProviderClient.Slot> {
+    override suspend fun querySlots(): List<CustomizationProviderClient.Slot> {
         return withContext(backgroundDispatcher) {
             context.contentResolver
                 .query(
-                    Contract.SlotTable.URI,
+                    Contract.LockScreenQuickAffordances.SlotTable.URI,
                     null,
                     null,
                     null,
@@ -222,16 +225,21 @@
                 )
                 ?.use { cursor ->
                     buildList {
-                        val idColumnIndex = cursor.getColumnIndex(Contract.SlotTable.Columns.ID)
+                        val idColumnIndex =
+                            cursor.getColumnIndex(
+                                Contract.LockScreenQuickAffordances.SlotTable.Columns.ID
+                            )
                         val capacityColumnIndex =
-                            cursor.getColumnIndex(Contract.SlotTable.Columns.CAPACITY)
+                            cursor.getColumnIndex(
+                                Contract.LockScreenQuickAffordances.SlotTable.Columns.CAPACITY
+                            )
                         if (idColumnIndex == -1 || capacityColumnIndex == -1) {
                             return@buildList
                         }
 
                         while (cursor.moveToNext()) {
                             add(
-                                KeyguardQuickAffordanceProviderClient.Slot(
+                                CustomizationProviderClient.Slot(
                                     id = cursor.getString(idColumnIndex),
                                     capacity = cursor.getInt(capacityColumnIndex),
                                 )
@@ -243,7 +251,7 @@
             ?: emptyList()
     }
 
-    override suspend fun queryFlags(): List<KeyguardQuickAffordanceProviderClient.Flag> {
+    override suspend fun queryFlags(): List<CustomizationProviderClient.Flag> {
         return withContext(backgroundDispatcher) {
             context.contentResolver
                 .query(
@@ -265,7 +273,7 @@
 
                         while (cursor.moveToNext()) {
                             add(
-                                KeyguardQuickAffordanceProviderClient.Flag(
+                                CustomizationProviderClient.Flag(
                                     name = cursor.getString(nameColumnIndex),
                                     value = cursor.getInt(valueColumnIndex) == 1,
                                 )
@@ -277,20 +285,19 @@
             ?: emptyList()
     }
 
-    override fun observeSlots(): Flow<List<KeyguardQuickAffordanceProviderClient.Slot>> {
-        return observeUri(Contract.SlotTable.URI).map { querySlots() }
+    override fun observeSlots(): Flow<List<CustomizationProviderClient.Slot>> {
+        return observeUri(Contract.LockScreenQuickAffordances.SlotTable.URI).map { querySlots() }
     }
 
-    override fun observeFlags(): Flow<List<KeyguardQuickAffordanceProviderClient.Flag>> {
+    override fun observeFlags(): Flow<List<CustomizationProviderClient.Flag>> {
         return observeUri(Contract.FlagsTable.URI).map { queryFlags() }
     }
 
-    override suspend fun queryAffordances():
-        List<KeyguardQuickAffordanceProviderClient.Affordance> {
+    override suspend fun queryAffordances(): List<CustomizationProviderClient.Affordance> {
         return withContext(backgroundDispatcher) {
             context.contentResolver
                 .query(
-                    Contract.AffordanceTable.URI,
+                    Contract.LockScreenQuickAffordances.AffordanceTable.URI,
                     null,
                     null,
                     null,
@@ -299,24 +306,36 @@
                 ?.use { cursor ->
                     buildList {
                         val idColumnIndex =
-                            cursor.getColumnIndex(Contract.AffordanceTable.Columns.ID)
+                            cursor.getColumnIndex(
+                                Contract.LockScreenQuickAffordances.AffordanceTable.Columns.ID
+                            )
                         val nameColumnIndex =
-                            cursor.getColumnIndex(Contract.AffordanceTable.Columns.NAME)
+                            cursor.getColumnIndex(
+                                Contract.LockScreenQuickAffordances.AffordanceTable.Columns.NAME
+                            )
                         val iconColumnIndex =
-                            cursor.getColumnIndex(Contract.AffordanceTable.Columns.ICON)
+                            cursor.getColumnIndex(
+                                Contract.LockScreenQuickAffordances.AffordanceTable.Columns.ICON
+                            )
                         val isEnabledColumnIndex =
-                            cursor.getColumnIndex(Contract.AffordanceTable.Columns.IS_ENABLED)
+                            cursor.getColumnIndex(
+                                Contract.LockScreenQuickAffordances.AffordanceTable.Columns
+                                    .IS_ENABLED
+                            )
                         val enablementInstructionsColumnIndex =
                             cursor.getColumnIndex(
-                                Contract.AffordanceTable.Columns.ENABLEMENT_INSTRUCTIONS
+                                Contract.LockScreenQuickAffordances.AffordanceTable.Columns
+                                    .ENABLEMENT_INSTRUCTIONS
                             )
                         val enablementActionTextColumnIndex =
                             cursor.getColumnIndex(
-                                Contract.AffordanceTable.Columns.ENABLEMENT_ACTION_TEXT
+                                Contract.LockScreenQuickAffordances.AffordanceTable.Columns
+                                    .ENABLEMENT_ACTION_TEXT
                             )
                         val enablementComponentNameColumnIndex =
                             cursor.getColumnIndex(
-                                Contract.AffordanceTable.Columns.ENABLEMENT_COMPONENT_NAME
+                                Contract.LockScreenQuickAffordances.AffordanceTable.Columns
+                                    .ENABLEMENT_COMPONENT_NAME
                             )
                         if (
                             idColumnIndex == -1 ||
@@ -332,7 +351,7 @@
 
                         while (cursor.moveToNext()) {
                             add(
-                                KeyguardQuickAffordanceProviderClient.Affordance(
+                                CustomizationProviderClient.Affordance(
                                     id = cursor.getString(idColumnIndex),
                                     name = cursor.getString(nameColumnIndex),
                                     iconResourceId = cursor.getInt(iconColumnIndex),
@@ -341,7 +360,7 @@
                                         cursor
                                             .getString(enablementInstructionsColumnIndex)
                                             ?.split(
-                                                Contract.AffordanceTable
+                                                Contract.LockScreenQuickAffordances.AffordanceTable
                                                     .ENABLEMENT_INSTRUCTIONS_DELIMITER
                                             ),
                                     enablementActionText =
@@ -357,16 +376,17 @@
             ?: emptyList()
     }
 
-    override fun observeAffordances():
-        Flow<List<KeyguardQuickAffordanceProviderClient.Affordance>> {
-        return observeUri(Contract.AffordanceTable.URI).map { queryAffordances() }
+    override fun observeAffordances(): Flow<List<CustomizationProviderClient.Affordance>> {
+        return observeUri(Contract.LockScreenQuickAffordances.AffordanceTable.URI).map {
+            queryAffordances()
+        }
     }
 
-    override suspend fun querySelections(): List<KeyguardQuickAffordanceProviderClient.Selection> {
+    override suspend fun querySelections(): List<CustomizationProviderClient.Selection> {
         return withContext(backgroundDispatcher) {
             context.contentResolver
                 .query(
-                    Contract.SelectionTable.URI,
+                    Contract.LockScreenQuickAffordances.SelectionTable.URI,
                     null,
                     null,
                     null,
@@ -375,11 +395,19 @@
                 ?.use { cursor ->
                     buildList {
                         val slotIdColumnIndex =
-                            cursor.getColumnIndex(Contract.SelectionTable.Columns.SLOT_ID)
+                            cursor.getColumnIndex(
+                                Contract.LockScreenQuickAffordances.SelectionTable.Columns.SLOT_ID
+                            )
                         val affordanceIdColumnIndex =
-                            cursor.getColumnIndex(Contract.SelectionTable.Columns.AFFORDANCE_ID)
+                            cursor.getColumnIndex(
+                                Contract.LockScreenQuickAffordances.SelectionTable.Columns
+                                    .AFFORDANCE_ID
+                            )
                         val affordanceNameColumnIndex =
-                            cursor.getColumnIndex(Contract.SelectionTable.Columns.AFFORDANCE_NAME)
+                            cursor.getColumnIndex(
+                                Contract.LockScreenQuickAffordances.SelectionTable.Columns
+                                    .AFFORDANCE_NAME
+                            )
                         if (
                             slotIdColumnIndex == -1 ||
                                 affordanceIdColumnIndex == -1 ||
@@ -390,7 +418,7 @@
 
                         while (cursor.moveToNext()) {
                             add(
-                                KeyguardQuickAffordanceProviderClient.Selection(
+                                CustomizationProviderClient.Selection(
                                     slotId = cursor.getString(slotIdColumnIndex),
                                     affordanceId = cursor.getString(affordanceIdColumnIndex),
                                     affordanceName = cursor.getString(affordanceNameColumnIndex),
@@ -403,8 +431,10 @@
             ?: emptyList()
     }
 
-    override fun observeSelections(): Flow<List<KeyguardQuickAffordanceProviderClient.Selection>> {
-        return observeUri(Contract.SelectionTable.URI).map { querySelections() }
+    override fun observeSelections(): Flow<List<CustomizationProviderClient.Selection>> {
+        return observeUri(Contract.LockScreenQuickAffordances.SelectionTable.URI).map {
+            querySelections()
+        }
     }
 
     override suspend fun deleteSelection(
@@ -413,9 +443,10 @@
     ) {
         withContext(backgroundDispatcher) {
             context.contentResolver.delete(
-                Contract.SelectionTable.URI,
-                "${Contract.SelectionTable.Columns.SLOT_ID} = ? AND" +
-                    " ${Contract.SelectionTable.Columns.AFFORDANCE_ID} = ?",
+                Contract.LockScreenQuickAffordances.SelectionTable.URI,
+                "${Contract.LockScreenQuickAffordances.SelectionTable.Columns.SLOT_ID} = ? AND" +
+                    " ${Contract.LockScreenQuickAffordances.SelectionTable.Columns.AFFORDANCE_ID}" +
+                    " = ?",
                 arrayOf(
                     slotId,
                     affordanceId,
@@ -429,8 +460,8 @@
     ) {
         withContext(backgroundDispatcher) {
             context.contentResolver.delete(
-                Contract.SelectionTable.URI,
-                Contract.SelectionTable.Columns.SLOT_ID,
+                Contract.LockScreenQuickAffordances.SelectionTable.URI,
+                Contract.LockScreenQuickAffordances.SelectionTable.Columns.SLOT_ID,
                 arrayOf(
                     slotId,
                 ),
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderContract.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderContract.kt
new file mode 100644
index 0000000..1e2e7d2
--- /dev/null
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderContract.kt
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.systemui.shared.customization.data.content
+
+import android.content.ContentResolver
+import android.net.Uri
+
+/** Contract definitions for querying content about keyguard quick affordances. */
+object CustomizationProviderContract {
+
+    const val AUTHORITY = "com.android.systemui.customization"
+    const val PERMISSION = "android.permission.CUSTOMIZE_SYSTEM_UI"
+
+    private val BASE_URI: Uri =
+        Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(AUTHORITY).build()
+
+    /** Namespace for lock screen shortcut (quick affordance) tables. */
+    object LockScreenQuickAffordances {
+
+        const val NAMESPACE = "lockscreen_quickaffordance"
+
+        private val LOCK_SCREEN_QUICK_AFFORDANCE_BASE_URI: Uri =
+            BASE_URI.buildUpon().path(NAMESPACE).build()
+
+        fun qualifiedTablePath(tableName: String): String {
+            return "$NAMESPACE/$tableName"
+        }
+
+        /**
+         * Table for slots.
+         *
+         * Slots are positions where affordances can be placed on the lock screen. Affordances that
+         * are placed on slots are said to be "selected". The system supports the idea of multiple
+         * affordances per slot, though the implementation may limit the number of affordances on
+         * each slot.
+         *
+         * Supported operations:
+         * - Query - to know which slots are available, query the [SlotTable.URI] [Uri]. The result
+         * set will contain rows with the [SlotTable.Columns] columns.
+         */
+        object SlotTable {
+            const val TABLE_NAME = "slots"
+            val URI: Uri =
+                LOCK_SCREEN_QUICK_AFFORDANCE_BASE_URI.buildUpon().appendPath(TABLE_NAME).build()
+
+            object Columns {
+                /** String. Unique ID for this slot. */
+                const val ID = "id"
+                /** Integer. The maximum number of affordances that can be placed in the slot. */
+                const val CAPACITY = "capacity"
+            }
+        }
+
+        /**
+         * Table for affordances.
+         *
+         * Affordances are actions/buttons that the user can execute. They are placed on slots on
+         * the lock screen.
+         *
+         * Supported operations:
+         * - Query - to know about all the affordances that are available on the device, regardless
+         * of which ones are currently selected, query the [AffordanceTable.URI] [Uri]. The result
+         * set will contain rows, each with the columns specified in [AffordanceTable.Columns].
+         */
+        object AffordanceTable {
+            const val TABLE_NAME = "affordances"
+            val URI: Uri =
+                LOCK_SCREEN_QUICK_AFFORDANCE_BASE_URI.buildUpon().appendPath(TABLE_NAME).build()
+            const val ENABLEMENT_INSTRUCTIONS_DELIMITER = "]["
+            const val COMPONENT_NAME_SEPARATOR = "/"
+
+            object Columns {
+                /** String. Unique ID for this affordance. */
+                const val ID = "id"
+                /** String. User-visible name for this affordance. */
+                const val NAME = "name"
+                /**
+                 * Integer. Resource ID for the drawable to load for this affordance. This is a
+                 * resource ID from the system UI package.
+                 */
+                const val ICON = "icon"
+                /** Integer. `1` if the affordance is enabled or `0` if it disabled. */
+                const val IS_ENABLED = "is_enabled"
+                /**
+                 * String. List of strings, delimited by [ENABLEMENT_INSTRUCTIONS_DELIMITER] to be
+                 * shown to the user if the affordance is disabled and the user selects the
+                 * affordance.
+                 */
+                const val ENABLEMENT_INSTRUCTIONS = "enablement_instructions"
+                /**
+                 * String. Optional label for a button that, when clicked, opens a destination
+                 * activity where the user can re-enable the disabled affordance.
+                 */
+                const val ENABLEMENT_ACTION_TEXT = "enablement_action_text"
+                /**
+                 * String. Optional package name and activity action string, delimited by
+                 * [COMPONENT_NAME_SEPARATOR] to use with an `Intent` to start an activity that
+                 * opens a destination where the user can re-enable the disabled affordance.
+                 */
+                const val ENABLEMENT_COMPONENT_NAME = "enablement_action_intent"
+            }
+        }
+
+        /**
+         * Table for selections.
+         *
+         * Selections are pairs of slot and affordance IDs.
+         *
+         * Supported operations:
+         * - Insert - to insert an affordance and place it in a slot, insert values for the columns
+         * into the [SelectionTable.URI] [Uri]. The maximum capacity rule is enforced by the system.
+         * Selecting a new affordance for a slot that is already full will automatically remove the
+         * oldest affordance from the slot.
+         * - Query - to know which affordances are set on which slots, query the
+         * [SelectionTable.URI] [Uri]. The result set will contain rows, each of which with the
+         * columns from [SelectionTable.Columns].
+         * - Delete - to unselect an affordance, removing it from a slot, delete from the
+         * [SelectionTable.URI] [Uri], passing in values for each column.
+         */
+        object SelectionTable {
+            const val TABLE_NAME = "selections"
+            val URI: Uri =
+                LOCK_SCREEN_QUICK_AFFORDANCE_BASE_URI.buildUpon().appendPath(TABLE_NAME).build()
+
+            object Columns {
+                /** String. Unique ID for the slot. */
+                const val SLOT_ID = "slot_id"
+                /** String. Unique ID for the selected affordance. */
+                const val AFFORDANCE_ID = "affordance_id"
+                /** String. Human-readable name for the affordance. */
+                const val AFFORDANCE_NAME = "affordance_name"
+            }
+        }
+    }
+
+    /**
+     * Table for flags.
+     *
+     * Flags are key-value pairs.
+     *
+     * Supported operations:
+     * - Query - to know the values of flags, query the [FlagsTable.URI] [Uri]. The result set will
+     * contain rows, each of which with the columns from [FlagsTable.Columns].
+     */
+    object FlagsTable {
+        const val TABLE_NAME = "flags"
+        val URI: Uri = BASE_URI.buildUpon().path(TABLE_NAME).build()
+
+        /** Flag denoting whether the Wallpaper Picker should use the new, revamped UI. */
+        const val FLAG_NAME_REVAMPED_WALLPAPER_UI = "revamped_wallpaper_ui"
+
+        /**
+         * Flag denoting whether the customizable lock screen quick affordances feature is enabled.
+         */
+        const val FLAG_NAME_CUSTOM_LOCK_SCREEN_QUICK_AFFORDANCES_ENABLED =
+            "is_custom_lock_screen_quick_affordances_feature_enabled"
+
+        /** Flag denoting whether the customizable clocks feature is enabled. */
+        const val FLAG_NAME_CUSTOM_CLOCKS_ENABLED = "is_custom_clocks_feature_enabled"
+
+        object Columns {
+            /** String. Unique ID for the flag. */
+            const val NAME = "name"
+            /** Int. Value of the flag. `1` means `true` and `0` means `false`. */
+            const val VALUE = "value"
+        }
+    }
+}
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/data/content/FakeKeyguardQuickAffordanceProviderClient.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/FakeCustomizationProviderClient.kt
similarity index 71%
rename from packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/data/content/FakeKeyguardQuickAffordanceProviderClient.kt
rename to packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/FakeCustomizationProviderClient.kt
index ec5e703..f5a955d 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/data/content/FakeKeyguardQuickAffordanceProviderClient.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/FakeCustomizationProviderClient.kt
@@ -15,7 +15,7 @@
  *
  */
 
-package com.android.systemui.shared.quickaffordance.data.content
+package com.android.systemui.shared.customization.data.content
 
 import android.graphics.drawable.BitmapDrawable
 import android.graphics.drawable.Drawable
@@ -25,46 +25,46 @@
 import kotlinx.coroutines.flow.asStateFlow
 import kotlinx.coroutines.flow.combine
 
-class FakeKeyguardQuickAffordanceProviderClient(
-    slots: List<KeyguardQuickAffordanceProviderClient.Slot> =
+class FakeCustomizationProviderClient(
+    slots: List<CustomizationProviderClient.Slot> =
         listOf(
-            KeyguardQuickAffordanceProviderClient.Slot(
+            CustomizationProviderClient.Slot(
                 id = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START,
                 capacity = 1,
             ),
-            KeyguardQuickAffordanceProviderClient.Slot(
+            CustomizationProviderClient.Slot(
                 id = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END,
                 capacity = 1,
             ),
         ),
-    affordances: List<KeyguardQuickAffordanceProviderClient.Affordance> =
+    affordances: List<CustomizationProviderClient.Affordance> =
         listOf(
-            KeyguardQuickAffordanceProviderClient.Affordance(
+            CustomizationProviderClient.Affordance(
                 id = AFFORDANCE_1,
                 name = AFFORDANCE_1,
                 iconResourceId = 1,
             ),
-            KeyguardQuickAffordanceProviderClient.Affordance(
+            CustomizationProviderClient.Affordance(
                 id = AFFORDANCE_2,
                 name = AFFORDANCE_2,
                 iconResourceId = 2,
             ),
-            KeyguardQuickAffordanceProviderClient.Affordance(
+            CustomizationProviderClient.Affordance(
                 id = AFFORDANCE_3,
                 name = AFFORDANCE_3,
                 iconResourceId = 3,
             ),
         ),
-    flags: List<KeyguardQuickAffordanceProviderClient.Flag> =
+    flags: List<CustomizationProviderClient.Flag> =
         listOf(
-            KeyguardQuickAffordanceProviderClient.Flag(
+            CustomizationProviderClient.Flag(
                 name =
-                    KeyguardQuickAffordanceProviderContract.FlagsTable
+                    CustomizationProviderContract.FlagsTable
                         .FLAG_NAME_CUSTOM_LOCK_SCREEN_QUICK_AFFORDANCES_ENABLED,
                 value = true,
             )
         ),
-) : KeyguardQuickAffordanceProviderClient {
+) : CustomizationProviderClient {
 
     private val slots = MutableStateFlow(slots)
     private val affordances = MutableStateFlow(affordances)
@@ -85,37 +85,35 @@
         selections.value = selections.value.toMutableMap().apply { this[slotId] = affordances }
     }
 
-    override suspend fun querySlots(): List<KeyguardQuickAffordanceProviderClient.Slot> {
+    override suspend fun querySlots(): List<CustomizationProviderClient.Slot> {
         return slots.value
     }
 
-    override suspend fun queryFlags(): List<KeyguardQuickAffordanceProviderClient.Flag> {
+    override suspend fun queryFlags(): List<CustomizationProviderClient.Flag> {
         return flags.value
     }
 
-    override fun observeSlots(): Flow<List<KeyguardQuickAffordanceProviderClient.Slot>> {
+    override fun observeSlots(): Flow<List<CustomizationProviderClient.Slot>> {
         return slots.asStateFlow()
     }
 
-    override fun observeFlags(): Flow<List<KeyguardQuickAffordanceProviderClient.Flag>> {
+    override fun observeFlags(): Flow<List<CustomizationProviderClient.Flag>> {
         return flags.asStateFlow()
     }
 
-    override suspend fun queryAffordances():
-        List<KeyguardQuickAffordanceProviderClient.Affordance> {
+    override suspend fun queryAffordances(): List<CustomizationProviderClient.Affordance> {
         return affordances.value
     }
 
-    override fun observeAffordances():
-        Flow<List<KeyguardQuickAffordanceProviderClient.Affordance>> {
+    override fun observeAffordances(): Flow<List<CustomizationProviderClient.Affordance>> {
         return affordances.asStateFlow()
     }
 
-    override suspend fun querySelections(): List<KeyguardQuickAffordanceProviderClient.Selection> {
+    override suspend fun querySelections(): List<CustomizationProviderClient.Selection> {
         return toSelectionList(selections.value, affordances.value)
     }
 
-    override fun observeSelections(): Flow<List<KeyguardQuickAffordanceProviderClient.Selection>> {
+    override fun observeSelections(): Flow<List<CustomizationProviderClient.Selection>> {
         return combine(selections, affordances) { selections, affordances ->
             toSelectionList(selections, affordances)
         }
@@ -148,7 +146,7 @@
         flags.value =
             flags.value.toMutableList().apply {
                 removeIf { it.name == name }
-                add(KeyguardQuickAffordanceProviderClient.Flag(name = name, value = value))
+                add(CustomizationProviderClient.Flag(name = name, value = value))
             }
     }
 
@@ -157,29 +155,26 @@
             slots.value.toMutableList().apply {
                 val index = indexOfFirst { it.id == slotId }
                 check(index != -1) { "Slot with ID \"$slotId\" doesn't exist!" }
-                set(
-                    index,
-                    KeyguardQuickAffordanceProviderClient.Slot(id = slotId, capacity = capacity)
-                )
+                set(index, CustomizationProviderClient.Slot(id = slotId, capacity = capacity))
             }
     }
 
-    fun addAffordance(affordance: KeyguardQuickAffordanceProviderClient.Affordance): Int {
+    fun addAffordance(affordance: CustomizationProviderClient.Affordance): Int {
         affordances.value = affordances.value + listOf(affordance)
         return affordances.value.size - 1
     }
 
     private fun toSelectionList(
         selections: Map<String, List<String>>,
-        affordances: List<KeyguardQuickAffordanceProviderClient.Affordance>,
-    ): List<KeyguardQuickAffordanceProviderClient.Selection> {
+        affordances: List<CustomizationProviderClient.Affordance>,
+    ): List<CustomizationProviderClient.Selection> {
         return selections
             .map { (slotId, affordanceIds) ->
                 affordanceIds.map { affordanceId ->
                     val affordanceName =
                         affordances.find { it.id == affordanceId }?.name
                             ?: error("No affordance with ID of \"$affordanceId\"!")
-                    KeyguardQuickAffordanceProviderClient.Selection(
+                    CustomizationProviderClient.Selection(
                         slotId = slotId,
                         affordanceId = affordanceId,
                         affordanceName = affordanceName,
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/data/content/KeyguardQuickAffordanceProviderContract.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/data/content/KeyguardQuickAffordanceProviderContract.kt
deleted file mode 100644
index e197752..0000000
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/data/content/KeyguardQuickAffordanceProviderContract.kt
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package com.android.systemui.shared.quickaffordance.data.content
-
-import android.content.ContentResolver
-import android.net.Uri
-
-/** Contract definitions for querying content about keyguard quick affordances. */
-object KeyguardQuickAffordanceProviderContract {
-
-    const val AUTHORITY = "com.android.systemui.keyguard.quickaffordance"
-    const val PERMISSION = "android.permission.ACCESS_KEYGUARD_QUICK_AFFORDANCES"
-
-    private val BASE_URI: Uri =
-        Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(AUTHORITY).build()
-
-    /**
-     * Table for slots.
-     *
-     * Slots are positions where affordances can be placed on the lock screen. Affordances that are
-     * placed on slots are said to be "selected". The system supports the idea of multiple
-     * affordances per slot, though the implementation may limit the number of affordances on each
-     * slot.
-     *
-     * Supported operations:
-     * - Query - to know which slots are available, query the [SlotTable.URI] [Uri]. The result set
-     * will contain rows with the [SlotTable.Columns] columns.
-     */
-    object SlotTable {
-        const val TABLE_NAME = "slots"
-        val URI: Uri = BASE_URI.buildUpon().path(TABLE_NAME).build()
-
-        object Columns {
-            /** String. Unique ID for this slot. */
-            const val ID = "id"
-            /** Integer. The maximum number of affordances that can be placed in the slot. */
-            const val CAPACITY = "capacity"
-        }
-    }
-
-    /**
-     * Table for affordances.
-     *
-     * Affordances are actions/buttons that the user can execute. They are placed on slots on the
-     * lock screen.
-     *
-     * Supported operations:
-     * - Query - to know about all the affordances that are available on the device, regardless of
-     * which ones are currently selected, query the [AffordanceTable.URI] [Uri]. The result set will
-     * contain rows, each with the columns specified in [AffordanceTable.Columns].
-     */
-    object AffordanceTable {
-        const val TABLE_NAME = "affordances"
-        val URI: Uri = BASE_URI.buildUpon().path(TABLE_NAME).build()
-        const val ENABLEMENT_INSTRUCTIONS_DELIMITER = "]["
-        const val COMPONENT_NAME_SEPARATOR = "/"
-
-        object Columns {
-            /** String. Unique ID for this affordance. */
-            const val ID = "id"
-            /** String. User-visible name for this affordance. */
-            const val NAME = "name"
-            /**
-             * Integer. Resource ID for the drawable to load for this affordance. This is a resource
-             * ID from the system UI package.
-             */
-            const val ICON = "icon"
-            /** Integer. `1` if the affordance is enabled or `0` if it disabled. */
-            const val IS_ENABLED = "is_enabled"
-            /**
-             * String. List of strings, delimited by [ENABLEMENT_INSTRUCTIONS_DELIMITER] to be shown
-             * to the user if the affordance is disabled and the user selects the affordance. The
-             * first one is a title while the rest are the steps needed to re-enable the affordance.
-             */
-            const val ENABLEMENT_INSTRUCTIONS = "enablement_instructions"
-            /**
-             * String. Optional label for a button that, when clicked, opens a destination activity
-             * where the user can re-enable the disabled affordance.
-             */
-            const val ENABLEMENT_ACTION_TEXT = "enablement_action_text"
-            /**
-             * String. Optional package name and activity action string, delimited by
-             * [COMPONENT_NAME_SEPARATOR] to use with an `Intent` to start an activity that opens a
-             * destination where the user can re-enable the disabled affordance.
-             */
-            const val ENABLEMENT_COMPONENT_NAME = "enablement_action_intent"
-        }
-    }
-
-    /**
-     * Table for selections.
-     *
-     * Selections are pairs of slot and affordance IDs.
-     *
-     * Supported operations:
-     * - Insert - to insert an affordance and place it in a slot, insert values for the columns into
-     * the [SelectionTable.URI] [Uri]. The maximum capacity rule is enforced by the system.
-     * Selecting a new affordance for a slot that is already full will automatically remove the
-     * oldest affordance from the slot.
-     * - Query - to know which affordances are set on which slots, query the [SelectionTable.URI]
-     * [Uri]. The result set will contain rows, each of which with the columns from
-     * [SelectionTable.Columns].
-     * - Delete - to unselect an affordance, removing it from a slot, delete from the
-     * [SelectionTable.URI] [Uri], passing in values for each column.
-     */
-    object SelectionTable {
-        const val TABLE_NAME = "selections"
-        val URI: Uri = BASE_URI.buildUpon().path(TABLE_NAME).build()
-
-        object Columns {
-            /** String. Unique ID for the slot. */
-            const val SLOT_ID = "slot_id"
-            /** String. Unique ID for the selected affordance. */
-            const val AFFORDANCE_ID = "affordance_id"
-            /** String. Human-readable name for the affordance. */
-            const val AFFORDANCE_NAME = "affordance_name"
-        }
-    }
-
-    /**
-     * Table for flags.
-     *
-     * Flags are key-value pairs.
-     *
-     * Supported operations:
-     * - Query - to know the values of flags, query the [FlagsTable.URI] [Uri]. The result set will
-     * contain rows, each of which with the columns from [FlagsTable.Columns].
-     */
-    object FlagsTable {
-        const val TABLE_NAME = "flags"
-        val URI: Uri = BASE_URI.buildUpon().path(TABLE_NAME).build()
-
-        /** Flag denoting whether the Wallpaper Picker should use the new, revamped UI. */
-        const val FLAG_NAME_REVAMPED_WALLPAPER_UI = "revamped_wallpaper_ui"
-
-        /**
-         * Flag denoting whether the customizable lock screen quick affordances feature is enabled.
-         */
-        const val FLAG_NAME_CUSTOM_LOCK_SCREEN_QUICK_AFFORDANCES_ENABLED =
-            "is_custom_lock_screen_quick_affordances_feature_enabled"
-
-        /** Flag denoting whether the customizable clocks feature is enabled. */
-        const val FLAG_NAME_CUSTOM_CLOCKS_ENABLED = "is_custom_clocks_feature_enabled"
-
-        object Columns {
-            /** String. Unique ID for the flag. */
-            const val NAME = "name"
-            /** Int. Value of the flag. `1` means `true` and `0` means `false`. */
-            const val VALUE = "value"
-        }
-    }
-}
diff --git a/packages/SystemUI/docs/device-entry/quickaffordance.md b/packages/SystemUI/docs/device-entry/quickaffordance.md
index 01d4f00..ccb35fa 100644
--- a/packages/SystemUI/docs/device-entry/quickaffordance.md
+++ b/packages/SystemUI/docs/device-entry/quickaffordance.md
@@ -31,7 +31,7 @@
 ### Accessing Quick Affordance Data
 Quick Affordances structured data are exposed to other applications through the `KeyguardQuickAffordanceProvider` content provider which is owned by the System UI process.
 
-To access this content provider, applications must have the `android.permission.ACCESS_KEYGUARD_QUICK_AFFORDANCES` permission which is a signature and privileged permission, limiting access to system apps or apps signed by the same signature as System UI. The `KeyguardQuickAffordanceProviderContract` file defines the content provider schema for consumers.
+To access this content provider, applications must have the `android.permission.CUSTOMIZE_SYSTEM_UI` permission which is a signature and privileged permission, limiting access to system apps or apps signed by the same signature as System UI. The `KeyguardQuickAffordanceProviderContract` file defines the content provider schema for consumers.
 
 Generally speaking, there are three important tables served by the content provider: `slots`, `affordances`, and `selections`. There is also a `flags` table, but that's not important and may be ignored.
 
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 2eb58b9..07e8bad 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2826,12 +2826,6 @@
     <string name="keyguard_affordance_enablement_dialog_action_template">Open <xliff:g id="appName" example="Wallet">%1$s</xliff:g></string>
 
     <!--
-    Template for a message shown right before a list of instructions that tell the user what to do
-    in order to enable a shortcut to a specific app. [CHAR LIMIT=NONE]
-    -->
-    <string name="keyguard_affordance_enablement_dialog_message">To add the <xliff:g id="appName" example="Wallet">%1$s</xliff:g> app as a shortcut, make sure</string>
-
-    <!--
     Requirement for the wallet app to be available for the user to use. This is shown as part of a
     bulleted list of requirements. When all requirements are met, the app can be accessed through a
     shortcut button on the lock screen. [CHAR LIMIT=NONE].
@@ -2867,10 +2861,10 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2">&#8226; At least one device is available</string>
 
     <!--
-    Error message shown when a button should be pressed and held to activate it, usually shown when
-    the user attempted to tap the button or held it for too short a time. [CHAR LIMIT=32].
+    Error message shown when a shortcut must be pressed and held to activate it, usually shown when
+    the user tried to tap the shortcut or held it for too short a time. [CHAR LIMIT=32].
     -->
-    <string name="keyguard_affordance_press_too_short">Touch &amp; hold to open</string>
+    <string name="keyguard_affordance_press_too_short">Touch &amp; hold shortcut</string>
 
     <!-- Text for education page of cancel button to hide the page. [CHAR_LIMIT=NONE] -->
     <string name="rear_display_bottom_sheet_cancel">Cancel</string>
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSysUIComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSysUIComponent.java
index b30e0c2..a431a59 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSysUIComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSysUIComponent.java
@@ -16,7 +16,7 @@
 
 package com.android.systemui.dagger;
 
-import com.android.systemui.keyguard.KeyguardQuickAffordanceProvider;
+import com.android.systemui.keyguard.CustomizationProvider;
 import com.android.systemui.statusbar.NotificationInsetsModule;
 import com.android.systemui.statusbar.QsFrameTranslateModule;
 
@@ -49,5 +49,5 @@
     /**
      * Member injection into the supplied argument.
      */
-    void inject(KeyguardQuickAffordanceProvider keyguardQuickAffordanceProvider);
+    void inject(CustomizationProvider customizationProvider);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardQuickAffordanceProvider.kt b/packages/SystemUI/src/com/android/systemui/keyguard/CustomizationProvider.kt
similarity index 73%
rename from packages/SystemUI/src/com/android/systemui/keyguard/KeyguardQuickAffordanceProvider.kt
rename to packages/SystemUI/src/com/android/systemui/keyguard/CustomizationProvider.kt
index cbcede0..eaf1081 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardQuickAffordanceProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/CustomizationProvider.kt
@@ -33,11 +33,11 @@
 import com.android.systemui.SystemUIAppComponentFactoryBase.ContextAvailableCallback
 import com.android.systemui.keyguard.domain.interactor.KeyguardQuickAffordanceInteractor
 import com.android.systemui.keyguard.ui.preview.KeyguardRemotePreviewManager
-import com.android.systemui.shared.quickaffordance.data.content.KeyguardQuickAffordanceProviderContract as Contract
+import com.android.systemui.shared.customization.data.content.CustomizationProviderContract as Contract
 import javax.inject.Inject
 import kotlinx.coroutines.runBlocking
 
-class KeyguardQuickAffordanceProvider :
+class CustomizationProvider :
     ContentProvider(), SystemUIAppComponentFactoryBase.ContextInitializer {
 
     @Inject lateinit var interactor: KeyguardQuickAffordanceInteractor
@@ -49,17 +49,23 @@
         UriMatcher(UriMatcher.NO_MATCH).apply {
             addURI(
                 Contract.AUTHORITY,
-                Contract.SlotTable.TABLE_NAME,
+                Contract.LockScreenQuickAffordances.qualifiedTablePath(
+                    Contract.LockScreenQuickAffordances.SlotTable.TABLE_NAME,
+                ),
                 MATCH_CODE_ALL_SLOTS,
             )
             addURI(
                 Contract.AUTHORITY,
-                Contract.AffordanceTable.TABLE_NAME,
+                Contract.LockScreenQuickAffordances.qualifiedTablePath(
+                    Contract.LockScreenQuickAffordances.AffordanceTable.TABLE_NAME,
+                ),
                 MATCH_CODE_ALL_AFFORDANCES,
             )
             addURI(
                 Contract.AUTHORITY,
-                Contract.SelectionTable.TABLE_NAME,
+                Contract.LockScreenQuickAffordances.qualifiedTablePath(
+                    Contract.LockScreenQuickAffordances.SelectionTable.TABLE_NAME,
+                ),
                 MATCH_CODE_ALL_SELECTIONS,
             )
             addURI(
@@ -94,9 +100,18 @@
 
         val tableName =
             when (uriMatcher.match(uri)) {
-                MATCH_CODE_ALL_SLOTS -> Contract.SlotTable.TABLE_NAME
-                MATCH_CODE_ALL_AFFORDANCES -> Contract.AffordanceTable.TABLE_NAME
-                MATCH_CODE_ALL_SELECTIONS -> Contract.SelectionTable.TABLE_NAME
+                MATCH_CODE_ALL_SLOTS ->
+                    Contract.LockScreenQuickAffordances.qualifiedTablePath(
+                        Contract.LockScreenQuickAffordances.SlotTable.TABLE_NAME,
+                    )
+                MATCH_CODE_ALL_AFFORDANCES ->
+                    Contract.LockScreenQuickAffordances.qualifiedTablePath(
+                        Contract.LockScreenQuickAffordances.AffordanceTable.TABLE_NAME,
+                    )
+                MATCH_CODE_ALL_SELECTIONS ->
+                    Contract.LockScreenQuickAffordances.qualifiedTablePath(
+                        Contract.LockScreenQuickAffordances.SelectionTable.TABLE_NAME,
+                    )
                 MATCH_CODE_ALL_FLAGS -> Contract.FlagsTable.TABLE_NAME
                 else -> null
             }
@@ -174,22 +189,34 @@
             throw IllegalArgumentException("Cannot insert selection, no values passed in!")
         }
 
-        if (!values.containsKey(Contract.SelectionTable.Columns.SLOT_ID)) {
+        if (
+            !values.containsKey(Contract.LockScreenQuickAffordances.SelectionTable.Columns.SLOT_ID)
+        ) {
             throw IllegalArgumentException(
                 "Cannot insert selection, " +
-                    "\"${Contract.SelectionTable.Columns.SLOT_ID}\" not specified!"
+                    "\"${Contract.LockScreenQuickAffordances.SelectionTable.Columns.SLOT_ID}\"" +
+                    " not specified!"
             )
         }
 
-        if (!values.containsKey(Contract.SelectionTable.Columns.AFFORDANCE_ID)) {
+        if (
+            !values.containsKey(
+                Contract.LockScreenQuickAffordances.SelectionTable.Columns.AFFORDANCE_ID
+            )
+        ) {
             throw IllegalArgumentException(
                 "Cannot insert selection, " +
-                    "\"${Contract.SelectionTable.Columns.AFFORDANCE_ID}\" not specified!"
+                    "\"${Contract.LockScreenQuickAffordances
+                        .SelectionTable.Columns.AFFORDANCE_ID}\" not specified!"
             )
         }
 
-        val slotId = values.getAsString(Contract.SelectionTable.Columns.SLOT_ID)
-        val affordanceId = values.getAsString(Contract.SelectionTable.Columns.AFFORDANCE_ID)
+        val slotId =
+            values.getAsString(Contract.LockScreenQuickAffordances.SelectionTable.Columns.SLOT_ID)
+        val affordanceId =
+            values.getAsString(
+                Contract.LockScreenQuickAffordances.SelectionTable.Columns.AFFORDANCE_ID
+            )
 
         if (slotId.isNullOrEmpty()) {
             throw IllegalArgumentException("Cannot insert selection, slot ID was empty!")
@@ -207,8 +234,10 @@
 
         return if (success) {
             Log.d(TAG, "Successfully selected $affordanceId for slot $slotId")
-            context?.contentResolver?.notifyChange(Contract.SelectionTable.URI, null)
-            Contract.SelectionTable.URI
+            context
+                ?.contentResolver
+                ?.notifyChange(Contract.LockScreenQuickAffordances.SelectionTable.URI, null)
+            Contract.LockScreenQuickAffordances.SelectionTable.URI
         } else {
             Log.d(TAG, "Failed to select $affordanceId for slot $slotId")
             null
@@ -218,9 +247,9 @@
     private suspend fun querySelections(): Cursor {
         return MatrixCursor(
                 arrayOf(
-                    Contract.SelectionTable.Columns.SLOT_ID,
-                    Contract.SelectionTable.Columns.AFFORDANCE_ID,
-                    Contract.SelectionTable.Columns.AFFORDANCE_NAME,
+                    Contract.LockScreenQuickAffordances.SelectionTable.Columns.SLOT_ID,
+                    Contract.LockScreenQuickAffordances.SelectionTable.Columns.AFFORDANCE_ID,
+                    Contract.LockScreenQuickAffordances.SelectionTable.Columns.AFFORDANCE_NAME,
                 )
             )
             .apply {
@@ -243,13 +272,16 @@
     private suspend fun queryAffordances(): Cursor {
         return MatrixCursor(
                 arrayOf(
-                    Contract.AffordanceTable.Columns.ID,
-                    Contract.AffordanceTable.Columns.NAME,
-                    Contract.AffordanceTable.Columns.ICON,
-                    Contract.AffordanceTable.Columns.IS_ENABLED,
-                    Contract.AffordanceTable.Columns.ENABLEMENT_INSTRUCTIONS,
-                    Contract.AffordanceTable.Columns.ENABLEMENT_ACTION_TEXT,
-                    Contract.AffordanceTable.Columns.ENABLEMENT_COMPONENT_NAME,
+                    Contract.LockScreenQuickAffordances.AffordanceTable.Columns.ID,
+                    Contract.LockScreenQuickAffordances.AffordanceTable.Columns.NAME,
+                    Contract.LockScreenQuickAffordances.AffordanceTable.Columns.ICON,
+                    Contract.LockScreenQuickAffordances.AffordanceTable.Columns.IS_ENABLED,
+                    Contract.LockScreenQuickAffordances.AffordanceTable.Columns
+                        .ENABLEMENT_INSTRUCTIONS,
+                    Contract.LockScreenQuickAffordances.AffordanceTable.Columns
+                        .ENABLEMENT_ACTION_TEXT,
+                    Contract.LockScreenQuickAffordances.AffordanceTable.Columns
+                        .ENABLEMENT_COMPONENT_NAME,
                 )
             )
             .apply {
@@ -261,7 +293,8 @@
                             representation.iconResourceId,
                             if (representation.isEnabled) 1 else 0,
                             representation.instructions?.joinToString(
-                                Contract.AffordanceTable.ENABLEMENT_INSTRUCTIONS_DELIMITER
+                                Contract.LockScreenQuickAffordances.AffordanceTable
+                                    .ENABLEMENT_INSTRUCTIONS_DELIMITER
                             ),
                             representation.actionText,
                             representation.actionComponentName,
@@ -274,8 +307,8 @@
     private fun querySlots(): Cursor {
         return MatrixCursor(
                 arrayOf(
-                    Contract.SlotTable.Columns.ID,
-                    Contract.SlotTable.Columns.CAPACITY,
+                    Contract.LockScreenQuickAffordances.SlotTable.Columns.ID,
+                    Contract.LockScreenQuickAffordances.SlotTable.Columns.CAPACITY,
                 )
             )
             .apply {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfig.kt
index 394426d..09e5ec0 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfig.kt
@@ -81,10 +81,6 @@
                 instructions =
                     listOf(
                         context.getString(
-                            R.string.keyguard_affordance_enablement_dialog_message,
-                            pickerName,
-                        ),
-                        context.getString(
                             R.string.keyguard_affordance_enablement_dialog_home_instruction_1
                         ),
                         context.getString(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt
index 02ebcd3..20588e9 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt
@@ -22,7 +22,7 @@
 import com.android.systemui.animation.Expandable
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.keyguard.shared.quickaffordance.ActivationState
-import com.android.systemui.shared.quickaffordance.data.content.KeyguardQuickAffordanceProviderContract as Contract
+import com.android.systemui.shared.customization.data.content.CustomizationProviderContract as Contract
 import kotlinx.coroutines.flow.Flow
 
 /** Defines interface that can act as data source for a single quick affordance model. */
@@ -90,8 +90,9 @@
              * the user to be able to set up the quick affordance and make it enabled.
              *
              * This is either just an action for the `Intent` or a package name and action,
-             * separated by [Contract.AffordanceTable.COMPONENT_NAME_SEPARATOR] for convenience, you
-             * can use the [componentName] function.
+             * separated by
+             * [Contract.LockScreenQuickAffordances.AffordanceTable.COMPONENT_NAME_SEPARATOR] for
+             * convenience, you can use the [componentName] function.
              */
             val actionComponentName: String? = null,
         ) : PickerScreenState() {
@@ -145,8 +146,8 @@
 
         /**
          * Returning this as a result from the [onTriggered] method means that the implementation
-         * has _not_ taken care of the action and the system should show a Dialog using the
-         * given [AlertDialog] and [Expandable].
+         * has _not_ taken care of the action and the system should show a Dialog using the given
+         * [AlertDialog] and [Expandable].
          */
         data class ShowDialog(
             val dialog: AlertDialog,
@@ -162,7 +163,8 @@
             return when {
                 action.isNullOrEmpty() -> null
                 !packageName.isNullOrEmpty() ->
-                    "$packageName${Contract.AffordanceTable.COMPONENT_NAME_SEPARATOR}$action"
+                    "$packageName${Contract.LockScreenQuickAffordances.AffordanceTable
+                        .COMPONENT_NAME_SEPARATOR}$action"
                 else -> action
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceProviderClientFactory.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceProviderClientFactory.kt
index 727a813..60ef116 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceProviderClientFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceProviderClientFactory.kt
@@ -19,13 +19,13 @@
 
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.settings.UserTracker
-import com.android.systemui.shared.quickaffordance.data.content.KeyguardQuickAffordanceProviderClient
-import com.android.systemui.shared.quickaffordance.data.content.KeyguardQuickAffordanceProviderClientImpl
+import com.android.systemui.shared.customization.data.content.CustomizationProviderClient
+import com.android.systemui.shared.customization.data.content.CustomizationProviderClientImpl
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineDispatcher
 
 interface KeyguardQuickAffordanceProviderClientFactory {
-    fun create(): KeyguardQuickAffordanceProviderClient
+    fun create(): CustomizationProviderClient
 }
 
 class KeyguardQuickAffordanceProviderClientFactoryImpl
@@ -34,8 +34,8 @@
     private val userTracker: UserTracker,
     @Background private val backgroundDispatcher: CoroutineDispatcher,
 ) : KeyguardQuickAffordanceProviderClientFactory {
-    override fun create(): KeyguardQuickAffordanceProviderClient {
-        return KeyguardQuickAffordanceProviderClientImpl(
+    override fun create(): CustomizationProviderClient {
+        return CustomizationProviderClientImpl(
             context = userTracker.userContext,
             backgroundDispatcher = backgroundDispatcher,
         )
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManager.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManager.kt
index 8ffef25..e9bd889 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManager.kt
@@ -24,7 +24,7 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.settings.UserTracker
-import com.android.systemui.shared.quickaffordance.data.content.KeyguardQuickAffordanceProviderClient
+import com.android.systemui.shared.customization.data.content.CustomizationProviderClient
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -69,7 +69,7 @@
         awaitClose { userTracker.removeCallback(callback) }
     }
 
-    private val clientOrNull: StateFlow<KeyguardQuickAffordanceProviderClient?> =
+    private val clientOrNull: StateFlow<CustomizationProviderClient?> =
         userId
             .distinctUntilChanged()
             .map { selectedUserId ->
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfig.kt
index a96ce77..4f7990f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfig.kt
@@ -84,10 +84,6 @@
                     instructions =
                         listOf(
                             context.getString(
-                                R.string.keyguard_affordance_enablement_dialog_message,
-                                pickerName,
-                            ),
-                            context.getString(
                                 R.string
                                     .keyguard_affordance_enablement_dialog_qr_scanner_instruction
                             ),
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt
index beb20ce..1928f40 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt
@@ -118,10 +118,6 @@
                     instructions =
                         listOf(
                             context.getString(
-                                R.string.keyguard_affordance_enablement_dialog_message,
-                                pickerName,
-                            ),
-                            context.getString(
                                 R.string.keyguard_affordance_enablement_dialog_wallet_instruction_1
                             ),
                             context.getString(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt
index 9772cb9..c219380 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt
@@ -36,7 +36,7 @@
 import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancePosition
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.settings.UserTracker
-import com.android.systemui.shared.quickaffordance.data.content.KeyguardQuickAffordanceProviderContract as Contract
+import com.android.systemui.shared.customization.data.content.CustomizationProviderContract as Contract
 import com.android.systemui.statusbar.phone.SystemUIDialog
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import dagger.Lazy
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt
index b19795c..0e4058b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt
@@ -392,6 +392,7 @@
                                     }
                                     view.performClick()
                                     view.setOnClickListener(null)
+                                    cancel()
                                 }
                         true
                     } else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt
index 6757605..31ac7a1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt
@@ -61,6 +61,9 @@
     /** True if the RAT icon should always be displayed and false otherwise. */
     val alwaysShowDataRatIcon: StateFlow<Boolean>
 
+    /** True if the CDMA level should be preferred over the primary level. */
+    val alwaysUseCdmaLevel: StateFlow<Boolean>
+
     /** Observable for RAT type (network type) indicator */
     val networkTypeIconGroup: StateFlow<MobileIconGroup>
 
@@ -97,6 +100,7 @@
     @Application scope: CoroutineScope,
     defaultSubscriptionHasDataEnabled: StateFlow<Boolean>,
     override val alwaysShowDataRatIcon: StateFlow<Boolean>,
+    override val alwaysUseCdmaLevel: StateFlow<Boolean>,
     defaultMobileIconMapping: StateFlow<Map<String, MobileIconGroup>>,
     defaultMobileIconGroup: StateFlow<MobileIconGroup>,
     override val isDefaultConnectionFailed: StateFlow<Boolean>,
@@ -157,13 +161,12 @@
             .stateIn(scope, SharingStarted.WhileSubscribed(), false)
 
     override val level: StateFlow<Int> =
-        connectionInfo
-            .mapLatest { connection ->
-                // TODO: incorporate [MobileMappings.Config.alwaysShowCdmaRssi]
-                if (connection.isGsm) {
-                    connection.primaryLevel
-                } else {
-                    connection.cdmaLevel
+        combine(connectionInfo, alwaysUseCdmaLevel) { connection, alwaysUseCdmaLevel ->
+                when {
+                    // GSM connections should never use the CDMA level
+                    connection.isGsm -> connection.primaryLevel
+                    alwaysUseCdmaLevel -> connection.cdmaLevel
+                    else -> connection.primaryLevel
                 }
             }
             .stateIn(scope, SharingStarted.WhileSubscribed(), 0)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt
index 21f6d8e..83da1dd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt
@@ -55,8 +55,13 @@
     val filteredSubscriptions: Flow<List<SubscriptionModel>>
     /** True if the active mobile data subscription has data enabled */
     val activeDataConnectionHasDataEnabled: StateFlow<Boolean>
+
     /** True if the RAT icon should always be displayed and false otherwise. */
     val alwaysShowDataRatIcon: StateFlow<Boolean>
+
+    /** True if the CDMA level should be preferred over the primary level. */
+    val alwaysUseCdmaLevel: StateFlow<Boolean>
+
     /** The icon mapping from network type to [MobileIconGroup] for the default subscription */
     val defaultMobileIconMapping: StateFlow<Map<String, MobileIconGroup>>
     /** Fallback [MobileIconGroup] in the case where there is no icon in the mapping */
@@ -165,6 +170,11 @@
             .mapLatest { it.alwaysShowDataRatIcon }
             .stateIn(scope, SharingStarted.WhileSubscribed(), false)
 
+    override val alwaysUseCdmaLevel: StateFlow<Boolean> =
+        mobileConnectionsRepo.defaultDataSubRatConfig
+            .mapLatest { it.alwaysShowCdmaRssi }
+            .stateIn(scope, SharingStarted.WhileSubscribed(), false)
+
     /** If there is no mapping in [defaultMobileIconMapping], then use this default icon group */
     override val defaultMobileIconGroup: StateFlow<MobileIconGroup> =
         mobileConnectionsRepo.defaultMobileIconGroup.stateIn(
@@ -196,6 +206,7 @@
             scope,
             activeDataConnectionHasDataEnabled,
             alwaysShowDataRatIcon,
+            alwaysUseCdmaLevel,
             defaultMobileIconMapping,
             defaultMobileIconGroup,
             isDefaultConnectionFailed,
diff --git a/packages/SystemUI/tests/AndroidManifest.xml b/packages/SystemUI/tests/AndroidManifest.xml
index 2d257b9..2c1e681 100644
--- a/packages/SystemUI/tests/AndroidManifest.xml
+++ b/packages/SystemUI/tests/AndroidManifest.xml
@@ -146,7 +146,7 @@
             tools:replace="android:authorities"
             tools:node="remove" />
 
-        <provider android:name="com.android.systemui.keyguard.KeyguardQuickAffordanceProvider"
+        <provider android:name="com.android.systemui.keyguard.CustomizationProvider"
             android:authorities="com.android.systemui.test.keyguard.quickaffordance.disabled"
             android:enabled="false"
             tools:replace="android:authorities"
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardQuickAffordanceProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
similarity index 82%
rename from packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardQuickAffordanceProviderTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
index 5e4a43f..4659766 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardQuickAffordanceProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
@@ -49,8 +49,8 @@
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.settings.UserFileManager
 import com.android.systemui.settings.UserTracker
+import com.android.systemui.shared.customization.data.content.CustomizationProviderContract as Contract
 import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
-import com.android.systemui.shared.quickaffordance.data.content.KeyguardQuickAffordanceProviderContract as Contract
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.util.FakeSharedPreferences
 import com.android.systemui.util.mockito.any
@@ -75,7 +75,7 @@
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
-class KeyguardQuickAffordanceProviderTest : SysuiTestCase() {
+class CustomizationProviderTest : SysuiTestCase() {
 
     @Mock private lateinit var lockPatternUtils: LockPatternUtils
     @Mock private lateinit var keyguardStateController: KeyguardStateController
@@ -87,7 +87,7 @@
     @Mock private lateinit var previewSurfacePackage: SurfaceControlViewHost.SurfacePackage
     @Mock private lateinit var launchAnimator: DialogLaunchAnimator
 
-    private lateinit var underTest: KeyguardQuickAffordanceProvider
+    private lateinit var underTest: CustomizationProvider
 
     private lateinit var testScope: TestScope
 
@@ -98,7 +98,7 @@
         whenever(previewRendererFactory.create(any())).thenReturn(previewRenderer)
         whenever(backgroundHandler.looper).thenReturn(TestableLooper.get(this).looper)
 
-        underTest = KeyguardQuickAffordanceProvider()
+        underTest = CustomizationProvider()
         val testDispatcher = StandardTestDispatcher()
         testScope = TestScope(testDispatcher)
         val localUserSelectionManager =
@@ -205,19 +205,34 @@
 
     @Test
     fun getType() {
-        assertThat(underTest.getType(Contract.AffordanceTable.URI))
+        assertThat(underTest.getType(Contract.LockScreenQuickAffordances.AffordanceTable.URI))
             .isEqualTo(
                 "vnd.android.cursor.dir/vnd." +
-                    "${Contract.AUTHORITY}.${Contract.AffordanceTable.TABLE_NAME}"
+                    "${Contract.AUTHORITY}." +
+                    Contract.LockScreenQuickAffordances.qualifiedTablePath(
+                        Contract.LockScreenQuickAffordances.AffordanceTable.TABLE_NAME
+                    )
             )
-        assertThat(underTest.getType(Contract.SlotTable.URI))
+        assertThat(underTest.getType(Contract.LockScreenQuickAffordances.SlotTable.URI))
             .isEqualTo(
-                "vnd.android.cursor.dir/vnd.${Contract.AUTHORITY}.${Contract.SlotTable.TABLE_NAME}"
+                "vnd.android.cursor.dir/vnd.${Contract.AUTHORITY}." +
+                    Contract.LockScreenQuickAffordances.qualifiedTablePath(
+                        Contract.LockScreenQuickAffordances.SlotTable.TABLE_NAME
+                    )
             )
-        assertThat(underTest.getType(Contract.SelectionTable.URI))
+        assertThat(underTest.getType(Contract.LockScreenQuickAffordances.SelectionTable.URI))
             .isEqualTo(
                 "vnd.android.cursor.dir/vnd." +
-                    "${Contract.AUTHORITY}.${Contract.SelectionTable.TABLE_NAME}"
+                    "${Contract.AUTHORITY}." +
+                    Contract.LockScreenQuickAffordances.qualifiedTablePath(
+                        Contract.LockScreenQuickAffordances.SelectionTable.TABLE_NAME
+                    )
+            )
+        assertThat(underTest.getType(Contract.FlagsTable.URI))
+            .isEqualTo(
+                "vnd.android.cursor.dir/vnd." +
+                    "${Contract.AUTHORITY}." +
+                    Contract.FlagsTable.TABLE_NAME
             )
     }
 
@@ -296,9 +311,10 @@
             )
 
             context.contentResolver.delete(
-                Contract.SelectionTable.URI,
-                "${Contract.SelectionTable.Columns.SLOT_ID} = ? AND" +
-                    " ${Contract.SelectionTable.Columns.AFFORDANCE_ID} = ?",
+                Contract.LockScreenQuickAffordances.SelectionTable.URI,
+                "${Contract.LockScreenQuickAffordances.SelectionTable.Columns.SLOT_ID} = ? AND" +
+                    " ${Contract.LockScreenQuickAffordances.SelectionTable.Columns.AFFORDANCE_ID}" +
+                    " = ?",
                 arrayOf(
                     KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END,
                     AFFORDANCE_2,
@@ -330,8 +346,8 @@
             )
 
             context.contentResolver.delete(
-                Contract.SelectionTable.URI,
-                Contract.SelectionTable.Columns.SLOT_ID,
+                Contract.LockScreenQuickAffordances.SelectionTable.URI,
+                Contract.LockScreenQuickAffordances.SelectionTable.Columns.SLOT_ID,
                 arrayOf(
                     KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END,
                 ),
@@ -371,10 +387,13 @@
         affordanceId: String,
     ) {
         context.contentResolver.insert(
-            Contract.SelectionTable.URI,
+            Contract.LockScreenQuickAffordances.SelectionTable.URI,
             ContentValues().apply {
-                put(Contract.SelectionTable.Columns.SLOT_ID, slotId)
-                put(Contract.SelectionTable.Columns.AFFORDANCE_ID, affordanceId)
+                put(Contract.LockScreenQuickAffordances.SelectionTable.Columns.SLOT_ID, slotId)
+                put(
+                    Contract.LockScreenQuickAffordances.SelectionTable.Columns.AFFORDANCE_ID,
+                    affordanceId
+                )
             }
         )
     }
@@ -382,7 +401,7 @@
     private fun querySelections(): List<Selection> {
         return context.contentResolver
             .query(
-                Contract.SelectionTable.URI,
+                Contract.LockScreenQuickAffordances.SelectionTable.URI,
                 null,
                 null,
                 null,
@@ -391,11 +410,18 @@
             ?.use { cursor ->
                 buildList {
                     val slotIdColumnIndex =
-                        cursor.getColumnIndex(Contract.SelectionTable.Columns.SLOT_ID)
+                        cursor.getColumnIndex(
+                            Contract.LockScreenQuickAffordances.SelectionTable.Columns.SLOT_ID
+                        )
                     val affordanceIdColumnIndex =
-                        cursor.getColumnIndex(Contract.SelectionTable.Columns.AFFORDANCE_ID)
+                        cursor.getColumnIndex(
+                            Contract.LockScreenQuickAffordances.SelectionTable.Columns.AFFORDANCE_ID
+                        )
                     val affordanceNameColumnIndex =
-                        cursor.getColumnIndex(Contract.SelectionTable.Columns.AFFORDANCE_NAME)
+                        cursor.getColumnIndex(
+                            Contract.LockScreenQuickAffordances.SelectionTable.Columns
+                                .AFFORDANCE_NAME
+                        )
                     if (
                         slotIdColumnIndex == -1 ||
                             affordanceIdColumnIndex == -1 ||
@@ -421,7 +447,7 @@
     private fun querySlots(): List<Slot> {
         return context.contentResolver
             .query(
-                Contract.SlotTable.URI,
+                Contract.LockScreenQuickAffordances.SlotTable.URI,
                 null,
                 null,
                 null,
@@ -429,9 +455,14 @@
             )
             ?.use { cursor ->
                 buildList {
-                    val idColumnIndex = cursor.getColumnIndex(Contract.SlotTable.Columns.ID)
+                    val idColumnIndex =
+                        cursor.getColumnIndex(
+                            Contract.LockScreenQuickAffordances.SlotTable.Columns.ID
+                        )
                     val capacityColumnIndex =
-                        cursor.getColumnIndex(Contract.SlotTable.Columns.CAPACITY)
+                        cursor.getColumnIndex(
+                            Contract.LockScreenQuickAffordances.SlotTable.Columns.CAPACITY
+                        )
                     if (idColumnIndex == -1 || capacityColumnIndex == -1) {
                         return@buildList
                     }
@@ -452,7 +483,7 @@
     private fun queryAffordances(): List<Affordance> {
         return context.contentResolver
             .query(
-                Contract.AffordanceTable.URI,
+                Contract.LockScreenQuickAffordances.AffordanceTable.URI,
                 null,
                 null,
                 null,
@@ -460,11 +491,18 @@
             )
             ?.use { cursor ->
                 buildList {
-                    val idColumnIndex = cursor.getColumnIndex(Contract.AffordanceTable.Columns.ID)
+                    val idColumnIndex =
+                        cursor.getColumnIndex(
+                            Contract.LockScreenQuickAffordances.AffordanceTable.Columns.ID
+                        )
                     val nameColumnIndex =
-                        cursor.getColumnIndex(Contract.AffordanceTable.Columns.NAME)
+                        cursor.getColumnIndex(
+                            Contract.LockScreenQuickAffordances.AffordanceTable.Columns.NAME
+                        )
                     val iconColumnIndex =
-                        cursor.getColumnIndex(Contract.AffordanceTable.Columns.ICON)
+                        cursor.getColumnIndex(
+                            Contract.LockScreenQuickAffordances.AffordanceTable.Columns.ICON
+                        )
                     if (idColumnIndex == -1 || nameColumnIndex == -1 || iconColumnIndex == -1) {
                         return@buildList
                     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManagerTest.kt
index d7e9cf1..b21cec9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManagerTest.kt
@@ -22,8 +22,8 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.settings.FakeUserTracker
+import com.android.systemui.shared.customization.data.content.FakeCustomizationProviderClient
 import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
-import com.android.systemui.shared.quickaffordance.data.content.FakeKeyguardQuickAffordanceProviderClient
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -54,16 +54,16 @@
     private lateinit var testScope: TestScope
     private lateinit var testDispatcher: TestDispatcher
     private lateinit var userTracker: FakeUserTracker
-    private lateinit var client1: FakeKeyguardQuickAffordanceProviderClient
-    private lateinit var client2: FakeKeyguardQuickAffordanceProviderClient
+    private lateinit var client1: FakeCustomizationProviderClient
+    private lateinit var client2: FakeCustomizationProviderClient
 
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
         whenever(userHandle.identifier).thenReturn(UserHandle.USER_SYSTEM)
         whenever(userHandle.isSystem).thenReturn(true)
-        client1 = FakeKeyguardQuickAffordanceProviderClient()
-        client2 = FakeKeyguardQuickAffordanceProviderClient()
+        client1 = FakeCustomizationProviderClient()
+        client2 = FakeCustomizationProviderClient()
 
         userTracker = FakeUserTracker()
         userTracker.set(
@@ -122,11 +122,11 @@
 
             client1.insertSelection(
                 slotId = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START,
-                affordanceId = FakeKeyguardQuickAffordanceProviderClient.AFFORDANCE_1,
+                affordanceId = FakeCustomizationProviderClient.AFFORDANCE_1,
             )
             client2.insertSelection(
                 slotId = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END,
-                affordanceId = FakeKeyguardQuickAffordanceProviderClient.AFFORDANCE_2,
+                affordanceId = FakeCustomizationProviderClient.AFFORDANCE_2,
             )
 
             userTracker.set(
@@ -139,7 +139,7 @@
                     mapOf(
                         KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START to
                             listOf(
-                                FakeKeyguardQuickAffordanceProviderClient.AFFORDANCE_1,
+                                FakeCustomizationProviderClient.AFFORDANCE_1,
                             ),
                     )
                 )
@@ -154,7 +154,7 @@
                     mapOf(
                         KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END to
                             listOf(
-                                FakeKeyguardQuickAffordanceProviderClient.AFFORDANCE_2,
+                                FakeCustomizationProviderClient.AFFORDANCE_2,
                             ),
                     )
                 )
@@ -174,7 +174,7 @@
 
             client1.insertSelection(
                 slotId = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START,
-                affordanceId = FakeKeyguardQuickAffordanceProviderClient.AFFORDANCE_1,
+                affordanceId = FakeCustomizationProviderClient.AFFORDANCE_1,
             )
             userTracker.set(
                 userInfos = userTracker.userProfiles,
@@ -197,7 +197,7 @@
 
             underTest.setSelections(
                 slotId = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START,
-                affordanceIds = listOf(FakeKeyguardQuickAffordanceProviderClient.AFFORDANCE_1),
+                affordanceIds = listOf(FakeCustomizationProviderClient.AFFORDANCE_1),
             )
             runCurrent()
 
@@ -206,7 +206,7 @@
                     mapOf(
                         KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START to
                             listOf(
-                                FakeKeyguardQuickAffordanceProviderClient.AFFORDANCE_1,
+                                FakeCustomizationProviderClient.AFFORDANCE_1,
                             ),
                     )
                 )
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
index c187a3f..b071a02 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
@@ -32,8 +32,8 @@
 import com.android.systemui.keyguard.shared.model.KeyguardSlotPickerRepresentation
 import com.android.systemui.settings.FakeUserTracker
 import com.android.systemui.settings.UserFileManager
+import com.android.systemui.shared.customization.data.content.FakeCustomizationProviderClient
 import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
-import com.android.systemui.shared.quickaffordance.data.content.FakeKeyguardQuickAffordanceProviderClient
 import com.android.systemui.util.FakeSharedPreferences
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
@@ -63,19 +63,13 @@
     private lateinit var config1: FakeKeyguardQuickAffordanceConfig
     private lateinit var config2: FakeKeyguardQuickAffordanceConfig
     private lateinit var userTracker: FakeUserTracker
-    private lateinit var client1: FakeKeyguardQuickAffordanceProviderClient
-    private lateinit var client2: FakeKeyguardQuickAffordanceProviderClient
+    private lateinit var client1: FakeCustomizationProviderClient
+    private lateinit var client2: FakeCustomizationProviderClient
 
     @Before
     fun setUp() {
-        config1 =
-            FakeKeyguardQuickAffordanceConfig(
-                FakeKeyguardQuickAffordanceProviderClient.AFFORDANCE_1
-            )
-        config2 =
-            FakeKeyguardQuickAffordanceConfig(
-                FakeKeyguardQuickAffordanceProviderClient.AFFORDANCE_2
-            )
+        config1 = FakeKeyguardQuickAffordanceConfig(FakeCustomizationProviderClient.AFFORDANCE_1)
+        config2 = FakeKeyguardQuickAffordanceConfig(FakeCustomizationProviderClient.AFFORDANCE_2)
         val scope = CoroutineScope(IMMEDIATE)
         userTracker = FakeUserTracker()
         val localUserSelectionManager =
@@ -95,8 +89,8 @@
                 userTracker = userTracker,
                 broadcastDispatcher = fakeBroadcastDispatcher,
             )
-        client1 = FakeKeyguardQuickAffordanceProviderClient()
-        client2 = FakeKeyguardQuickAffordanceProviderClient()
+        client1 = FakeCustomizationProviderClient()
+        client2 = FakeCustomizationProviderClient()
         val remoteUserSelectionManager =
             KeyguardQuickAffordanceRemoteUserSelectionManager(
                 scope = scope,
@@ -256,7 +250,7 @@
             )
             client2.insertSelection(
                 slotId = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START,
-                affordanceId = FakeKeyguardQuickAffordanceProviderClient.AFFORDANCE_2,
+                affordanceId = FakeCustomizationProviderClient.AFFORDANCE_2,
             )
             val observed = mutableListOf<Map<String, List<KeyguardQuickAffordanceConfig>>>()
             val job = underTest.selections.onEach { observed.add(it) }.launchIn(this)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt
index 5889ec8..ff72715 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt
@@ -29,6 +29,8 @@
 ) : MobileIconInteractor {
     override val alwaysShowDataRatIcon = MutableStateFlow(false)
 
+    override val alwaysUseCdmaLevel = MutableStateFlow(false)
+
     override val activity =
         MutableStateFlow(
             DataActivityModel(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt
index 19e5516..1c00646 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt
@@ -58,6 +58,8 @@
 
     override val alwaysShowDataRatIcon = MutableStateFlow(false)
 
+    override val alwaysUseCdmaLevel = MutableStateFlow(false)
+
     private val _defaultMobileIconMapping = MutableStateFlow(TEST_MAPPING)
     override val defaultMobileIconMapping = _defaultMobileIconMapping
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt
index cb2ee99..5abe335 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt
@@ -61,6 +61,7 @@
                 scope,
                 mobileIconsInteractor.activeDataConnectionHasDataEnabled,
                 mobileIconsInteractor.alwaysShowDataRatIcon,
+                mobileIconsInteractor.alwaysUseCdmaLevel,
                 mobileIconsInteractor.defaultMobileIconMapping,
                 mobileIconsInteractor.defaultMobileIconGroup,
                 mobileIconsInteractor.isDefaultConnectionFailed,
@@ -103,7 +104,27 @@
         }
 
     @Test
-    fun cdma_level_default_unknown() =
+    fun gsm_alwaysShowCdmaTrue_stillUsesGsmLevel() =
+        runBlocking(IMMEDIATE) {
+            connectionRepository.setConnectionInfo(
+                MobileConnectionModel(
+                    isGsm = true,
+                    primaryLevel = GSM_LEVEL,
+                    cdmaLevel = CDMA_LEVEL,
+                ),
+            )
+            mobileIconsInteractor.alwaysUseCdmaLevel.value = true
+
+            var latest: Int? = null
+            val job = underTest.level.onEach { latest = it }.launchIn(this)
+
+            assertThat(latest).isEqualTo(GSM_LEVEL)
+
+            job.cancel()
+        }
+
+    @Test
+    fun notGsm_level_default_unknown() =
         runBlocking(IMMEDIATE) {
             connectionRepository.setConnectionInfo(
                 MobileConnectionModel(isGsm = false),
@@ -117,7 +138,7 @@
         }
 
     @Test
-    fun cdma_usesCdmaLevel() =
+    fun notGsm_alwaysShowCdmaTrue_usesCdmaLevel() =
         runBlocking(IMMEDIATE) {
             connectionRepository.setConnectionInfo(
                 MobileConnectionModel(
@@ -126,6 +147,7 @@
                     cdmaLevel = CDMA_LEVEL
                 ),
             )
+            mobileIconsInteractor.alwaysUseCdmaLevel.value = true
 
             var latest: Int? = null
             val job = underTest.level.onEach { latest = it }.launchIn(this)
@@ -136,6 +158,26 @@
         }
 
     @Test
+    fun notGsm_alwaysShowCdmaFalse_usesPrimaryLevel() =
+        runBlocking(IMMEDIATE) {
+            connectionRepository.setConnectionInfo(
+                MobileConnectionModel(
+                    isGsm = false,
+                    primaryLevel = GSM_LEVEL,
+                    cdmaLevel = CDMA_LEVEL,
+                ),
+            )
+            mobileIconsInteractor.alwaysUseCdmaLevel.value = false
+
+            var latest: Int? = null
+            val job = underTest.level.onEach { latest = it }.launchIn(this)
+
+            assertThat(latest).isEqualTo(GSM_LEVEL)
+
+            job.cancel()
+        }
+
+    @Test
     fun iconGroup_three_g() =
         runBlocking(IMMEDIATE) {
             connectionRepository.setConnectionInfo(
@@ -240,6 +282,21 @@
         }
 
     @Test
+    fun alwaysUseCdmaLevel_matchesParent() =
+        runBlocking(IMMEDIATE) {
+            var latest: Boolean? = null
+            val job = underTest.alwaysUseCdmaLevel.onEach { latest = it }.launchIn(this)
+
+            mobileIconsInteractor.alwaysUseCdmaLevel.value = true
+            assertThat(latest).isTrue()
+
+            mobileIconsInteractor.alwaysUseCdmaLevel.value = false
+            assertThat(latest).isFalse()
+
+            job.cancel()
+        }
+
+    @Test
     fun test_isDefaultDataEnabled_matchesParent() =
         runBlocking(IMMEDIATE) {
             var latest: Boolean? = null
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt
index 2fa3467..b82a584 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt
@@ -291,6 +291,38 @@
             job.cancel()
         }
 
+    @Test
+    fun alwaysUseCdmaLevel_configHasTrue() =
+        runBlocking(IMMEDIATE) {
+            var latest: Boolean? = null
+            val job = underTest.alwaysUseCdmaLevel.onEach { latest = it }.launchIn(this)
+
+            val config = MobileMappings.Config()
+            config.alwaysShowCdmaRssi = true
+            connectionsRepository.defaultDataSubRatConfig.value = config
+            yield()
+
+            assertThat(latest).isTrue()
+
+            job.cancel()
+        }
+
+    @Test
+    fun alwaysUseCdmaLevel_configHasFalse() =
+        runBlocking(IMMEDIATE) {
+            var latest: Boolean? = null
+            val job = underTest.alwaysUseCdmaLevel.onEach { latest = it }.launchIn(this)
+
+            val config = MobileMappings.Config()
+            config.alwaysShowCdmaRssi = false
+            connectionsRepository.defaultDataSubRatConfig.value = config
+            yield()
+
+            assertThat(latest).isFalse()
+
+            job.cancel()
+        }
+
     companion object {
         private val IMMEDIATE = Dispatchers.Main.immediate
         private val tableLogBuffer =
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceProviderClientFactory.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceProviderClientFactory.kt
index d85dd2e..16a1298 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceProviderClientFactory.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceProviderClientFactory.kt
@@ -18,17 +18,17 @@
 package com.android.systemui.keyguard.data.quickaffordance
 
 import com.android.systemui.settings.UserTracker
-import com.android.systemui.shared.quickaffordance.data.content.FakeKeyguardQuickAffordanceProviderClient
-import com.android.systemui.shared.quickaffordance.data.content.KeyguardQuickAffordanceProviderClient
+import com.android.systemui.shared.customization.data.content.CustomizationProviderClient
+import com.android.systemui.shared.customization.data.content.FakeCustomizationProviderClient
 
 class FakeKeyguardQuickAffordanceProviderClientFactory(
     private val userTracker: UserTracker,
-    private val callback: (Int) -> KeyguardQuickAffordanceProviderClient = {
-        FakeKeyguardQuickAffordanceProviderClient()
+    private val callback: (Int) -> CustomizationProviderClient = {
+        FakeCustomizationProviderClient()
     },
 ) : KeyguardQuickAffordanceProviderClientFactory {
 
-    override fun create(): KeyguardQuickAffordanceProviderClient {
+    override fun create(): CustomizationProviderClient {
         return callback(userTracker.userId)
     }
 }
diff --git a/services/core/java/com/android/server/am/BroadcastRecord.java b/services/core/java/com/android/server/am/BroadcastRecord.java
index 0fec082..1d4d425 100644
--- a/services/core/java/com/android/server/am/BroadcastRecord.java
+++ b/services/core/java/com/android/server/am/BroadcastRecord.java
@@ -655,8 +655,7 @@
         // TODO: migrate alarm-prioritization flag to BroadcastConstants
         return (isForeground()
                 || interactive
-                || alarm)
-                && receivers.size() == 1;
+                || alarm);
     }
 
     @NonNull String getHostingRecordTriggerType() {
diff --git a/services/core/java/com/android/server/attention/AttentionManagerService.java b/services/core/java/com/android/server/attention/AttentionManagerService.java
index d4ef638..658e38b 100644
--- a/services/core/java/com/android/server/attention/AttentionManagerService.java
+++ b/services/core/java/com/android/server/attention/AttentionManagerService.java
@@ -668,8 +668,8 @@
             mIProximityUpdateCallback = new IProximityUpdateCallback.Stub() {
                 @Override
                 public void onProximityUpdate(double distance) {
+                    mCallbackInternal.onProximityUpdate(distance);
                     synchronized (mLock) {
-                        mCallbackInternal.onProximityUpdate(distance);
                         freeIfInactiveLocked();
                     }
                 }
diff --git a/services/core/java/com/android/server/security/OWNERS b/services/core/java/com/android/server/security/OWNERS
index 5c2d5ba..5bcc98b6 100644
--- a/services/core/java/com/android/server/security/OWNERS
+++ b/services/core/java/com/android/server/security/OWNERS
@@ -1,4 +1,4 @@
 # Bug component: 36824
 
 per-file *AttestationVerification* = file:/core/java/android/security/attestationverification/OWNERS
-per-file FileIntegrityService.java = victorhsieh@google.com
+per-file FileIntegrity*.java = victorhsieh@google.com