Merge "Renames customization content provider (1/7)." into tm-qpr-dev
This commit is contained in:
@@ -193,7 +193,7 @@
|
|||||||
<permission android:name="com.android.systemui.permission.FLAGS"
|
<permission android:name="com.android.systemui.permission.FLAGS"
|
||||||
android:protectionLevel="signature" />
|
android:protectionLevel="signature" />
|
||||||
|
|
||||||
<permission android:name="android.permission.ACCESS_KEYGUARD_QUICK_AFFORDANCES"
|
<permission android:name="android.permission.CUSTOMIZE_SYSTEM_UI"
|
||||||
android:protectionLevel="signature|privileged" />
|
android:protectionLevel="signature|privileged" />
|
||||||
|
|
||||||
<!-- Adding Quick Settings tiles -->
|
<!-- Adding Quick Settings tiles -->
|
||||||
@@ -1003,10 +1003,10 @@
|
|||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
<provider
|
<provider
|
||||||
android:authorities="com.android.systemui.keyguard.quickaffordance"
|
android:authorities="com.android.systemui.customization"
|
||||||
android:name="com.android.systemui.keyguard.KeyguardQuickAffordanceProvider"
|
android:name="com.android.systemui.keyguard.CustomizationProvider"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:permission="android.permission.ACCESS_KEYGUARD_QUICK_AFFORDANCES"
|
android:permission="android.permission.CUSTOMIZE_SYSTEM_UI"
|
||||||
/>
|
/>
|
||||||
</application>
|
</application>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
android:enabled="false"
|
android:enabled="false"
|
||||||
tools:replace="android:authorities"
|
tools:replace="android:authorities"
|
||||||
tools:node="remove" />
|
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:authorities="com.android.systemui.test.keyguard.quickaffordance.disabled"
|
||||||
android:enabled="false"
|
android:enabled="false"
|
||||||
tools:replace="android:authorities"
|
tools:replace="android:authorities"
|
||||||
|
|||||||
@@ -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.annotation.SuppressLint
|
||||||
import android.content.ContentValues
|
import android.content.ContentValues
|
||||||
@@ -25,7 +25,7 @@ import android.graphics.Color
|
|||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import androidx.annotation.DrawableRes
|
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.CoroutineDispatcher
|
||||||
import kotlinx.coroutines.channels.awaitClose
|
import kotlinx.coroutines.channels.awaitClose
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
@@ -35,7 +35,7 @@ import kotlinx.coroutines.flow.onStart
|
|||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
/** Client for using a content provider implementing the [Contract]. */
|
/** 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.
|
* Selects an affordance with the given ID for a slot on the lock screen with the given ID.
|
||||||
@@ -190,10 +190,10 @@ interface KeyguardQuickAffordanceProviderClient {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
class KeyguardQuickAffordanceProviderClientImpl(
|
class CustomizationProviderClientImpl(
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
private val backgroundDispatcher: CoroutineDispatcher,
|
private val backgroundDispatcher: CoroutineDispatcher,
|
||||||
) : KeyguardQuickAffordanceProviderClient {
|
) : CustomizationProviderClient {
|
||||||
|
|
||||||
override suspend fun insertSelection(
|
override suspend fun insertSelection(
|
||||||
slotId: String,
|
slotId: String,
|
||||||
@@ -201,20 +201,23 @@ class KeyguardQuickAffordanceProviderClientImpl(
|
|||||||
) {
|
) {
|
||||||
withContext(backgroundDispatcher) {
|
withContext(backgroundDispatcher) {
|
||||||
context.contentResolver.insert(
|
context.contentResolver.insert(
|
||||||
Contract.SelectionTable.URI,
|
Contract.LockScreenQuickAffordances.SelectionTable.URI,
|
||||||
ContentValues().apply {
|
ContentValues().apply {
|
||||||
put(Contract.SelectionTable.Columns.SLOT_ID, slotId)
|
put(Contract.LockScreenQuickAffordances.SelectionTable.Columns.SLOT_ID, slotId)
|
||||||
put(Contract.SelectionTable.Columns.AFFORDANCE_ID, affordanceId)
|
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) {
|
return withContext(backgroundDispatcher) {
|
||||||
context.contentResolver
|
context.contentResolver
|
||||||
.query(
|
.query(
|
||||||
Contract.SlotTable.URI,
|
Contract.LockScreenQuickAffordances.SlotTable.URI,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
@@ -222,16 +225,21 @@ class KeyguardQuickAffordanceProviderClientImpl(
|
|||||||
)
|
)
|
||||||
?.use { cursor ->
|
?.use { cursor ->
|
||||||
buildList {
|
buildList {
|
||||||
val idColumnIndex = cursor.getColumnIndex(Contract.SlotTable.Columns.ID)
|
val idColumnIndex =
|
||||||
|
cursor.getColumnIndex(
|
||||||
|
Contract.LockScreenQuickAffordances.SlotTable.Columns.ID
|
||||||
|
)
|
||||||
val capacityColumnIndex =
|
val capacityColumnIndex =
|
||||||
cursor.getColumnIndex(Contract.SlotTable.Columns.CAPACITY)
|
cursor.getColumnIndex(
|
||||||
|
Contract.LockScreenQuickAffordances.SlotTable.Columns.CAPACITY
|
||||||
|
)
|
||||||
if (idColumnIndex == -1 || capacityColumnIndex == -1) {
|
if (idColumnIndex == -1 || capacityColumnIndex == -1) {
|
||||||
return@buildList
|
return@buildList
|
||||||
}
|
}
|
||||||
|
|
||||||
while (cursor.moveToNext()) {
|
while (cursor.moveToNext()) {
|
||||||
add(
|
add(
|
||||||
KeyguardQuickAffordanceProviderClient.Slot(
|
CustomizationProviderClient.Slot(
|
||||||
id = cursor.getString(idColumnIndex),
|
id = cursor.getString(idColumnIndex),
|
||||||
capacity = cursor.getInt(capacityColumnIndex),
|
capacity = cursor.getInt(capacityColumnIndex),
|
||||||
)
|
)
|
||||||
@@ -243,7 +251,7 @@ class KeyguardQuickAffordanceProviderClientImpl(
|
|||||||
?: emptyList()
|
?: emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun queryFlags(): List<KeyguardQuickAffordanceProviderClient.Flag> {
|
override suspend fun queryFlags(): List<CustomizationProviderClient.Flag> {
|
||||||
return withContext(backgroundDispatcher) {
|
return withContext(backgroundDispatcher) {
|
||||||
context.contentResolver
|
context.contentResolver
|
||||||
.query(
|
.query(
|
||||||
@@ -265,7 +273,7 @@ class KeyguardQuickAffordanceProviderClientImpl(
|
|||||||
|
|
||||||
while (cursor.moveToNext()) {
|
while (cursor.moveToNext()) {
|
||||||
add(
|
add(
|
||||||
KeyguardQuickAffordanceProviderClient.Flag(
|
CustomizationProviderClient.Flag(
|
||||||
name = cursor.getString(nameColumnIndex),
|
name = cursor.getString(nameColumnIndex),
|
||||||
value = cursor.getInt(valueColumnIndex) == 1,
|
value = cursor.getInt(valueColumnIndex) == 1,
|
||||||
)
|
)
|
||||||
@@ -277,20 +285,19 @@ class KeyguardQuickAffordanceProviderClientImpl(
|
|||||||
?: emptyList()
|
?: emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun observeSlots(): Flow<List<KeyguardQuickAffordanceProviderClient.Slot>> {
|
override fun observeSlots(): Flow<List<CustomizationProviderClient.Slot>> {
|
||||||
return observeUri(Contract.SlotTable.URI).map { querySlots() }
|
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() }
|
return observeUri(Contract.FlagsTable.URI).map { queryFlags() }
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun queryAffordances():
|
override suspend fun queryAffordances(): List<CustomizationProviderClient.Affordance> {
|
||||||
List<KeyguardQuickAffordanceProviderClient.Affordance> {
|
|
||||||
return withContext(backgroundDispatcher) {
|
return withContext(backgroundDispatcher) {
|
||||||
context.contentResolver
|
context.contentResolver
|
||||||
.query(
|
.query(
|
||||||
Contract.AffordanceTable.URI,
|
Contract.LockScreenQuickAffordances.AffordanceTable.URI,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
@@ -299,24 +306,36 @@ class KeyguardQuickAffordanceProviderClientImpl(
|
|||||||
?.use { cursor ->
|
?.use { cursor ->
|
||||||
buildList {
|
buildList {
|
||||||
val idColumnIndex =
|
val idColumnIndex =
|
||||||
cursor.getColumnIndex(Contract.AffordanceTable.Columns.ID)
|
cursor.getColumnIndex(
|
||||||
|
Contract.LockScreenQuickAffordances.AffordanceTable.Columns.ID
|
||||||
|
)
|
||||||
val nameColumnIndex =
|
val nameColumnIndex =
|
||||||
cursor.getColumnIndex(Contract.AffordanceTable.Columns.NAME)
|
cursor.getColumnIndex(
|
||||||
|
Contract.LockScreenQuickAffordances.AffordanceTable.Columns.NAME
|
||||||
|
)
|
||||||
val iconColumnIndex =
|
val iconColumnIndex =
|
||||||
cursor.getColumnIndex(Contract.AffordanceTable.Columns.ICON)
|
cursor.getColumnIndex(
|
||||||
|
Contract.LockScreenQuickAffordances.AffordanceTable.Columns.ICON
|
||||||
|
)
|
||||||
val isEnabledColumnIndex =
|
val isEnabledColumnIndex =
|
||||||
cursor.getColumnIndex(Contract.AffordanceTable.Columns.IS_ENABLED)
|
cursor.getColumnIndex(
|
||||||
|
Contract.LockScreenQuickAffordances.AffordanceTable.Columns
|
||||||
|
.IS_ENABLED
|
||||||
|
)
|
||||||
val enablementInstructionsColumnIndex =
|
val enablementInstructionsColumnIndex =
|
||||||
cursor.getColumnIndex(
|
cursor.getColumnIndex(
|
||||||
Contract.AffordanceTable.Columns.ENABLEMENT_INSTRUCTIONS
|
Contract.LockScreenQuickAffordances.AffordanceTable.Columns
|
||||||
|
.ENABLEMENT_INSTRUCTIONS
|
||||||
)
|
)
|
||||||
val enablementActionTextColumnIndex =
|
val enablementActionTextColumnIndex =
|
||||||
cursor.getColumnIndex(
|
cursor.getColumnIndex(
|
||||||
Contract.AffordanceTable.Columns.ENABLEMENT_ACTION_TEXT
|
Contract.LockScreenQuickAffordances.AffordanceTable.Columns
|
||||||
|
.ENABLEMENT_ACTION_TEXT
|
||||||
)
|
)
|
||||||
val enablementComponentNameColumnIndex =
|
val enablementComponentNameColumnIndex =
|
||||||
cursor.getColumnIndex(
|
cursor.getColumnIndex(
|
||||||
Contract.AffordanceTable.Columns.ENABLEMENT_COMPONENT_NAME
|
Contract.LockScreenQuickAffordances.AffordanceTable.Columns
|
||||||
|
.ENABLEMENT_COMPONENT_NAME
|
||||||
)
|
)
|
||||||
if (
|
if (
|
||||||
idColumnIndex == -1 ||
|
idColumnIndex == -1 ||
|
||||||
@@ -332,7 +351,7 @@ class KeyguardQuickAffordanceProviderClientImpl(
|
|||||||
|
|
||||||
while (cursor.moveToNext()) {
|
while (cursor.moveToNext()) {
|
||||||
add(
|
add(
|
||||||
KeyguardQuickAffordanceProviderClient.Affordance(
|
CustomizationProviderClient.Affordance(
|
||||||
id = cursor.getString(idColumnIndex),
|
id = cursor.getString(idColumnIndex),
|
||||||
name = cursor.getString(nameColumnIndex),
|
name = cursor.getString(nameColumnIndex),
|
||||||
iconResourceId = cursor.getInt(iconColumnIndex),
|
iconResourceId = cursor.getInt(iconColumnIndex),
|
||||||
@@ -341,7 +360,7 @@ class KeyguardQuickAffordanceProviderClientImpl(
|
|||||||
cursor
|
cursor
|
||||||
.getString(enablementInstructionsColumnIndex)
|
.getString(enablementInstructionsColumnIndex)
|
||||||
?.split(
|
?.split(
|
||||||
Contract.AffordanceTable
|
Contract.LockScreenQuickAffordances.AffordanceTable
|
||||||
.ENABLEMENT_INSTRUCTIONS_DELIMITER
|
.ENABLEMENT_INSTRUCTIONS_DELIMITER
|
||||||
),
|
),
|
||||||
enablementActionText =
|
enablementActionText =
|
||||||
@@ -357,16 +376,17 @@ class KeyguardQuickAffordanceProviderClientImpl(
|
|||||||
?: emptyList()
|
?: emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun observeAffordances():
|
override fun observeAffordances(): Flow<List<CustomizationProviderClient.Affordance>> {
|
||||||
Flow<List<KeyguardQuickAffordanceProviderClient.Affordance>> {
|
return observeUri(Contract.LockScreenQuickAffordances.AffordanceTable.URI).map {
|
||||||
return observeUri(Contract.AffordanceTable.URI).map { queryAffordances() }
|
queryAffordances()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun querySelections(): List<KeyguardQuickAffordanceProviderClient.Selection> {
|
override suspend fun querySelections(): List<CustomizationProviderClient.Selection> {
|
||||||
return withContext(backgroundDispatcher) {
|
return withContext(backgroundDispatcher) {
|
||||||
context.contentResolver
|
context.contentResolver
|
||||||
.query(
|
.query(
|
||||||
Contract.SelectionTable.URI,
|
Contract.LockScreenQuickAffordances.SelectionTable.URI,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
@@ -375,11 +395,19 @@ class KeyguardQuickAffordanceProviderClientImpl(
|
|||||||
?.use { cursor ->
|
?.use { cursor ->
|
||||||
buildList {
|
buildList {
|
||||||
val slotIdColumnIndex =
|
val slotIdColumnIndex =
|
||||||
cursor.getColumnIndex(Contract.SelectionTable.Columns.SLOT_ID)
|
cursor.getColumnIndex(
|
||||||
|
Contract.LockScreenQuickAffordances.SelectionTable.Columns.SLOT_ID
|
||||||
|
)
|
||||||
val affordanceIdColumnIndex =
|
val affordanceIdColumnIndex =
|
||||||
cursor.getColumnIndex(Contract.SelectionTable.Columns.AFFORDANCE_ID)
|
cursor.getColumnIndex(
|
||||||
|
Contract.LockScreenQuickAffordances.SelectionTable.Columns
|
||||||
|
.AFFORDANCE_ID
|
||||||
|
)
|
||||||
val affordanceNameColumnIndex =
|
val affordanceNameColumnIndex =
|
||||||
cursor.getColumnIndex(Contract.SelectionTable.Columns.AFFORDANCE_NAME)
|
cursor.getColumnIndex(
|
||||||
|
Contract.LockScreenQuickAffordances.SelectionTable.Columns
|
||||||
|
.AFFORDANCE_NAME
|
||||||
|
)
|
||||||
if (
|
if (
|
||||||
slotIdColumnIndex == -1 ||
|
slotIdColumnIndex == -1 ||
|
||||||
affordanceIdColumnIndex == -1 ||
|
affordanceIdColumnIndex == -1 ||
|
||||||
@@ -390,7 +418,7 @@ class KeyguardQuickAffordanceProviderClientImpl(
|
|||||||
|
|
||||||
while (cursor.moveToNext()) {
|
while (cursor.moveToNext()) {
|
||||||
add(
|
add(
|
||||||
KeyguardQuickAffordanceProviderClient.Selection(
|
CustomizationProviderClient.Selection(
|
||||||
slotId = cursor.getString(slotIdColumnIndex),
|
slotId = cursor.getString(slotIdColumnIndex),
|
||||||
affordanceId = cursor.getString(affordanceIdColumnIndex),
|
affordanceId = cursor.getString(affordanceIdColumnIndex),
|
||||||
affordanceName = cursor.getString(affordanceNameColumnIndex),
|
affordanceName = cursor.getString(affordanceNameColumnIndex),
|
||||||
@@ -403,8 +431,10 @@ class KeyguardQuickAffordanceProviderClientImpl(
|
|||||||
?: emptyList()
|
?: emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun observeSelections(): Flow<List<KeyguardQuickAffordanceProviderClient.Selection>> {
|
override fun observeSelections(): Flow<List<CustomizationProviderClient.Selection>> {
|
||||||
return observeUri(Contract.SelectionTable.URI).map { querySelections() }
|
return observeUri(Contract.LockScreenQuickAffordances.SelectionTable.URI).map {
|
||||||
|
querySelections()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun deleteSelection(
|
override suspend fun deleteSelection(
|
||||||
@@ -413,9 +443,10 @@ class KeyguardQuickAffordanceProviderClientImpl(
|
|||||||
) {
|
) {
|
||||||
withContext(backgroundDispatcher) {
|
withContext(backgroundDispatcher) {
|
||||||
context.contentResolver.delete(
|
context.contentResolver.delete(
|
||||||
Contract.SelectionTable.URI,
|
Contract.LockScreenQuickAffordances.SelectionTable.URI,
|
||||||
"${Contract.SelectionTable.Columns.SLOT_ID} = ? AND" +
|
"${Contract.LockScreenQuickAffordances.SelectionTable.Columns.SLOT_ID} = ? AND" +
|
||||||
" ${Contract.SelectionTable.Columns.AFFORDANCE_ID} = ?",
|
" ${Contract.LockScreenQuickAffordances.SelectionTable.Columns.AFFORDANCE_ID}" +
|
||||||
|
" = ?",
|
||||||
arrayOf(
|
arrayOf(
|
||||||
slotId,
|
slotId,
|
||||||
affordanceId,
|
affordanceId,
|
||||||
@@ -429,8 +460,8 @@ class KeyguardQuickAffordanceProviderClientImpl(
|
|||||||
) {
|
) {
|
||||||
withContext(backgroundDispatcher) {
|
withContext(backgroundDispatcher) {
|
||||||
context.contentResolver.delete(
|
context.contentResolver.delete(
|
||||||
Contract.SelectionTable.URI,
|
Contract.LockScreenQuickAffordances.SelectionTable.URI,
|
||||||
Contract.SelectionTable.Columns.SLOT_ID,
|
Contract.LockScreenQuickAffordances.SelectionTable.Columns.SLOT_ID,
|
||||||
arrayOf(
|
arrayOf(
|
||||||
slotId,
|
slotId,
|
||||||
),
|
),
|
||||||
@@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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.BitmapDrawable
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
@@ -25,46 +25,46 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
|||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.flow.combine
|
import kotlinx.coroutines.flow.combine
|
||||||
|
|
||||||
class FakeKeyguardQuickAffordanceProviderClient(
|
class FakeCustomizationProviderClient(
|
||||||
slots: List<KeyguardQuickAffordanceProviderClient.Slot> =
|
slots: List<CustomizationProviderClient.Slot> =
|
||||||
listOf(
|
listOf(
|
||||||
KeyguardQuickAffordanceProviderClient.Slot(
|
CustomizationProviderClient.Slot(
|
||||||
id = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START,
|
id = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START,
|
||||||
capacity = 1,
|
capacity = 1,
|
||||||
),
|
),
|
||||||
KeyguardQuickAffordanceProviderClient.Slot(
|
CustomizationProviderClient.Slot(
|
||||||
id = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END,
|
id = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END,
|
||||||
capacity = 1,
|
capacity = 1,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
affordances: List<KeyguardQuickAffordanceProviderClient.Affordance> =
|
affordances: List<CustomizationProviderClient.Affordance> =
|
||||||
listOf(
|
listOf(
|
||||||
KeyguardQuickAffordanceProviderClient.Affordance(
|
CustomizationProviderClient.Affordance(
|
||||||
id = AFFORDANCE_1,
|
id = AFFORDANCE_1,
|
||||||
name = AFFORDANCE_1,
|
name = AFFORDANCE_1,
|
||||||
iconResourceId = 1,
|
iconResourceId = 1,
|
||||||
),
|
),
|
||||||
KeyguardQuickAffordanceProviderClient.Affordance(
|
CustomizationProviderClient.Affordance(
|
||||||
id = AFFORDANCE_2,
|
id = AFFORDANCE_2,
|
||||||
name = AFFORDANCE_2,
|
name = AFFORDANCE_2,
|
||||||
iconResourceId = 2,
|
iconResourceId = 2,
|
||||||
),
|
),
|
||||||
KeyguardQuickAffordanceProviderClient.Affordance(
|
CustomizationProviderClient.Affordance(
|
||||||
id = AFFORDANCE_3,
|
id = AFFORDANCE_3,
|
||||||
name = AFFORDANCE_3,
|
name = AFFORDANCE_3,
|
||||||
iconResourceId = 3,
|
iconResourceId = 3,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
flags: List<KeyguardQuickAffordanceProviderClient.Flag> =
|
flags: List<CustomizationProviderClient.Flag> =
|
||||||
listOf(
|
listOf(
|
||||||
KeyguardQuickAffordanceProviderClient.Flag(
|
CustomizationProviderClient.Flag(
|
||||||
name =
|
name =
|
||||||
KeyguardQuickAffordanceProviderContract.FlagsTable
|
CustomizationProviderContract.FlagsTable
|
||||||
.FLAG_NAME_CUSTOM_LOCK_SCREEN_QUICK_AFFORDANCES_ENABLED,
|
.FLAG_NAME_CUSTOM_LOCK_SCREEN_QUICK_AFFORDANCES_ENABLED,
|
||||||
value = true,
|
value = true,
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
) : KeyguardQuickAffordanceProviderClient {
|
) : CustomizationProviderClient {
|
||||||
|
|
||||||
private val slots = MutableStateFlow(slots)
|
private val slots = MutableStateFlow(slots)
|
||||||
private val affordances = MutableStateFlow(affordances)
|
private val affordances = MutableStateFlow(affordances)
|
||||||
@@ -85,37 +85,35 @@ class FakeKeyguardQuickAffordanceProviderClient(
|
|||||||
selections.value = selections.value.toMutableMap().apply { this[slotId] = affordances }
|
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
|
return slots.value
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun queryFlags(): List<KeyguardQuickAffordanceProviderClient.Flag> {
|
override suspend fun queryFlags(): List<CustomizationProviderClient.Flag> {
|
||||||
return flags.value
|
return flags.value
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun observeSlots(): Flow<List<KeyguardQuickAffordanceProviderClient.Slot>> {
|
override fun observeSlots(): Flow<List<CustomizationProviderClient.Slot>> {
|
||||||
return slots.asStateFlow()
|
return slots.asStateFlow()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun observeFlags(): Flow<List<KeyguardQuickAffordanceProviderClient.Flag>> {
|
override fun observeFlags(): Flow<List<CustomizationProviderClient.Flag>> {
|
||||||
return flags.asStateFlow()
|
return flags.asStateFlow()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun queryAffordances():
|
override suspend fun queryAffordances(): List<CustomizationProviderClient.Affordance> {
|
||||||
List<KeyguardQuickAffordanceProviderClient.Affordance> {
|
|
||||||
return affordances.value
|
return affordances.value
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun observeAffordances():
|
override fun observeAffordances(): Flow<List<CustomizationProviderClient.Affordance>> {
|
||||||
Flow<List<KeyguardQuickAffordanceProviderClient.Affordance>> {
|
|
||||||
return affordances.asStateFlow()
|
return affordances.asStateFlow()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun querySelections(): List<KeyguardQuickAffordanceProviderClient.Selection> {
|
override suspend fun querySelections(): List<CustomizationProviderClient.Selection> {
|
||||||
return toSelectionList(selections.value, affordances.value)
|
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 ->
|
return combine(selections, affordances) { selections, affordances ->
|
||||||
toSelectionList(selections, affordances)
|
toSelectionList(selections, affordances)
|
||||||
}
|
}
|
||||||
@@ -148,7 +146,7 @@ class FakeKeyguardQuickAffordanceProviderClient(
|
|||||||
flags.value =
|
flags.value =
|
||||||
flags.value.toMutableList().apply {
|
flags.value.toMutableList().apply {
|
||||||
removeIf { it.name == name }
|
removeIf { it.name == name }
|
||||||
add(KeyguardQuickAffordanceProviderClient.Flag(name = name, value = value))
|
add(CustomizationProviderClient.Flag(name = name, value = value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,29 +155,26 @@ class FakeKeyguardQuickAffordanceProviderClient(
|
|||||||
slots.value.toMutableList().apply {
|
slots.value.toMutableList().apply {
|
||||||
val index = indexOfFirst { it.id == slotId }
|
val index = indexOfFirst { it.id == slotId }
|
||||||
check(index != -1) { "Slot with ID \"$slotId\" doesn't exist!" }
|
check(index != -1) { "Slot with ID \"$slotId\" doesn't exist!" }
|
||||||
set(
|
set(index, CustomizationProviderClient.Slot(id = slotId, capacity = capacity))
|
||||||
index,
|
|
||||||
KeyguardQuickAffordanceProviderClient.Slot(id = slotId, capacity = capacity)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addAffordance(affordance: KeyguardQuickAffordanceProviderClient.Affordance): Int {
|
fun addAffordance(affordance: CustomizationProviderClient.Affordance): Int {
|
||||||
affordances.value = affordances.value + listOf(affordance)
|
affordances.value = affordances.value + listOf(affordance)
|
||||||
return affordances.value.size - 1
|
return affordances.value.size - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun toSelectionList(
|
private fun toSelectionList(
|
||||||
selections: Map<String, List<String>>,
|
selections: Map<String, List<String>>,
|
||||||
affordances: List<KeyguardQuickAffordanceProviderClient.Affordance>,
|
affordances: List<CustomizationProviderClient.Affordance>,
|
||||||
): List<KeyguardQuickAffordanceProviderClient.Selection> {
|
): List<CustomizationProviderClient.Selection> {
|
||||||
return selections
|
return selections
|
||||||
.map { (slotId, affordanceIds) ->
|
.map { (slotId, affordanceIds) ->
|
||||||
affordanceIds.map { affordanceId ->
|
affordanceIds.map { affordanceId ->
|
||||||
val affordanceName =
|
val affordanceName =
|
||||||
affordances.find { it.id == affordanceId }?.name
|
affordances.find { it.id == affordanceId }?.name
|
||||||
?: error("No affordance with ID of \"$affordanceId\"!")
|
?: error("No affordance with ID of \"$affordanceId\"!")
|
||||||
KeyguardQuickAffordanceProviderClient.Selection(
|
CustomizationProviderClient.Selection(
|
||||||
slotId = slotId,
|
slotId = slotId,
|
||||||
affordanceId = affordanceId,
|
affordanceId = affordanceId,
|
||||||
affordanceName = affordanceName,
|
affordanceName = affordanceName,
|
||||||
@@ -1,166 +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.
|
|
||||||
*/
|
|
||||||
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"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -31,7 +31,7 @@ This section describes how to implement a potential picker, selector, or configu
|
|||||||
### Accessing Quick Affordance Data
|
### 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.
|
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.
|
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.
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package com.android.systemui.dagger;
|
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.NotificationInsetsModule;
|
||||||
import com.android.systemui.statusbar.QsFrameTranslateModule;
|
import com.android.systemui.statusbar.QsFrameTranslateModule;
|
||||||
|
|
||||||
@@ -49,5 +49,5 @@ public interface ReferenceSysUIComponent extends SysUIComponent {
|
|||||||
/**
|
/**
|
||||||
* Member injection into the supplied argument.
|
* Member injection into the supplied argument.
|
||||||
*/
|
*/
|
||||||
void inject(KeyguardQuickAffordanceProvider keyguardQuickAffordanceProvider);
|
void inject(CustomizationProvider customizationProvider);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,11 +33,11 @@ import com.android.systemui.SystemUIAppComponentFactoryBase
|
|||||||
import com.android.systemui.SystemUIAppComponentFactoryBase.ContextAvailableCallback
|
import com.android.systemui.SystemUIAppComponentFactoryBase.ContextAvailableCallback
|
||||||
import com.android.systemui.keyguard.domain.interactor.KeyguardQuickAffordanceInteractor
|
import com.android.systemui.keyguard.domain.interactor.KeyguardQuickAffordanceInteractor
|
||||||
import com.android.systemui.keyguard.ui.preview.KeyguardRemotePreviewManager
|
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 javax.inject.Inject
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
|
|
||||||
class KeyguardQuickAffordanceProvider :
|
class CustomizationProvider :
|
||||||
ContentProvider(), SystemUIAppComponentFactoryBase.ContextInitializer {
|
ContentProvider(), SystemUIAppComponentFactoryBase.ContextInitializer {
|
||||||
|
|
||||||
@Inject lateinit var interactor: KeyguardQuickAffordanceInteractor
|
@Inject lateinit var interactor: KeyguardQuickAffordanceInteractor
|
||||||
@@ -49,17 +49,23 @@ class KeyguardQuickAffordanceProvider :
|
|||||||
UriMatcher(UriMatcher.NO_MATCH).apply {
|
UriMatcher(UriMatcher.NO_MATCH).apply {
|
||||||
addURI(
|
addURI(
|
||||||
Contract.AUTHORITY,
|
Contract.AUTHORITY,
|
||||||
Contract.SlotTable.TABLE_NAME,
|
Contract.LockScreenQuickAffordances.qualifiedTablePath(
|
||||||
|
Contract.LockScreenQuickAffordances.SlotTable.TABLE_NAME,
|
||||||
|
),
|
||||||
MATCH_CODE_ALL_SLOTS,
|
MATCH_CODE_ALL_SLOTS,
|
||||||
)
|
)
|
||||||
addURI(
|
addURI(
|
||||||
Contract.AUTHORITY,
|
Contract.AUTHORITY,
|
||||||
Contract.AffordanceTable.TABLE_NAME,
|
Contract.LockScreenQuickAffordances.qualifiedTablePath(
|
||||||
|
Contract.LockScreenQuickAffordances.AffordanceTable.TABLE_NAME,
|
||||||
|
),
|
||||||
MATCH_CODE_ALL_AFFORDANCES,
|
MATCH_CODE_ALL_AFFORDANCES,
|
||||||
)
|
)
|
||||||
addURI(
|
addURI(
|
||||||
Contract.AUTHORITY,
|
Contract.AUTHORITY,
|
||||||
Contract.SelectionTable.TABLE_NAME,
|
Contract.LockScreenQuickAffordances.qualifiedTablePath(
|
||||||
|
Contract.LockScreenQuickAffordances.SelectionTable.TABLE_NAME,
|
||||||
|
),
|
||||||
MATCH_CODE_ALL_SELECTIONS,
|
MATCH_CODE_ALL_SELECTIONS,
|
||||||
)
|
)
|
||||||
addURI(
|
addURI(
|
||||||
@@ -94,9 +100,18 @@ class KeyguardQuickAffordanceProvider :
|
|||||||
|
|
||||||
val tableName =
|
val tableName =
|
||||||
when (uriMatcher.match(uri)) {
|
when (uriMatcher.match(uri)) {
|
||||||
MATCH_CODE_ALL_SLOTS -> Contract.SlotTable.TABLE_NAME
|
MATCH_CODE_ALL_SLOTS ->
|
||||||
MATCH_CODE_ALL_AFFORDANCES -> Contract.AffordanceTable.TABLE_NAME
|
Contract.LockScreenQuickAffordances.qualifiedTablePath(
|
||||||
MATCH_CODE_ALL_SELECTIONS -> Contract.SelectionTable.TABLE_NAME
|
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
|
MATCH_CODE_ALL_FLAGS -> Contract.FlagsTable.TABLE_NAME
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
@@ -174,22 +189,34 @@ class KeyguardQuickAffordanceProvider :
|
|||||||
throw IllegalArgumentException("Cannot insert selection, no values passed in!")
|
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(
|
throw IllegalArgumentException(
|
||||||
"Cannot insert selection, " +
|
"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(
|
throw IllegalArgumentException(
|
||||||
"Cannot insert selection, " +
|
"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 slotId =
|
||||||
val affordanceId = values.getAsString(Contract.SelectionTable.Columns.AFFORDANCE_ID)
|
values.getAsString(Contract.LockScreenQuickAffordances.SelectionTable.Columns.SLOT_ID)
|
||||||
|
val affordanceId =
|
||||||
|
values.getAsString(
|
||||||
|
Contract.LockScreenQuickAffordances.SelectionTable.Columns.AFFORDANCE_ID
|
||||||
|
)
|
||||||
|
|
||||||
if (slotId.isNullOrEmpty()) {
|
if (slotId.isNullOrEmpty()) {
|
||||||
throw IllegalArgumentException("Cannot insert selection, slot ID was empty!")
|
throw IllegalArgumentException("Cannot insert selection, slot ID was empty!")
|
||||||
@@ -207,8 +234,10 @@ class KeyguardQuickAffordanceProvider :
|
|||||||
|
|
||||||
return if (success) {
|
return if (success) {
|
||||||
Log.d(TAG, "Successfully selected $affordanceId for slot $slotId")
|
Log.d(TAG, "Successfully selected $affordanceId for slot $slotId")
|
||||||
context?.contentResolver?.notifyChange(Contract.SelectionTable.URI, null)
|
context
|
||||||
Contract.SelectionTable.URI
|
?.contentResolver
|
||||||
|
?.notifyChange(Contract.LockScreenQuickAffordances.SelectionTable.URI, null)
|
||||||
|
Contract.LockScreenQuickAffordances.SelectionTable.URI
|
||||||
} else {
|
} else {
|
||||||
Log.d(TAG, "Failed to select $affordanceId for slot $slotId")
|
Log.d(TAG, "Failed to select $affordanceId for slot $slotId")
|
||||||
null
|
null
|
||||||
@@ -218,9 +247,9 @@ class KeyguardQuickAffordanceProvider :
|
|||||||
private suspend fun querySelections(): Cursor {
|
private suspend fun querySelections(): Cursor {
|
||||||
return MatrixCursor(
|
return MatrixCursor(
|
||||||
arrayOf(
|
arrayOf(
|
||||||
Contract.SelectionTable.Columns.SLOT_ID,
|
Contract.LockScreenQuickAffordances.SelectionTable.Columns.SLOT_ID,
|
||||||
Contract.SelectionTable.Columns.AFFORDANCE_ID,
|
Contract.LockScreenQuickAffordances.SelectionTable.Columns.AFFORDANCE_ID,
|
||||||
Contract.SelectionTable.Columns.AFFORDANCE_NAME,
|
Contract.LockScreenQuickAffordances.SelectionTable.Columns.AFFORDANCE_NAME,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.apply {
|
.apply {
|
||||||
@@ -243,13 +272,16 @@ class KeyguardQuickAffordanceProvider :
|
|||||||
private suspend fun queryAffordances(): Cursor {
|
private suspend fun queryAffordances(): Cursor {
|
||||||
return MatrixCursor(
|
return MatrixCursor(
|
||||||
arrayOf(
|
arrayOf(
|
||||||
Contract.AffordanceTable.Columns.ID,
|
Contract.LockScreenQuickAffordances.AffordanceTable.Columns.ID,
|
||||||
Contract.AffordanceTable.Columns.NAME,
|
Contract.LockScreenQuickAffordances.AffordanceTable.Columns.NAME,
|
||||||
Contract.AffordanceTable.Columns.ICON,
|
Contract.LockScreenQuickAffordances.AffordanceTable.Columns.ICON,
|
||||||
Contract.AffordanceTable.Columns.IS_ENABLED,
|
Contract.LockScreenQuickAffordances.AffordanceTable.Columns.IS_ENABLED,
|
||||||
Contract.AffordanceTable.Columns.ENABLEMENT_INSTRUCTIONS,
|
Contract.LockScreenQuickAffordances.AffordanceTable.Columns
|
||||||
Contract.AffordanceTable.Columns.ENABLEMENT_ACTION_TEXT,
|
.ENABLEMENT_INSTRUCTIONS,
|
||||||
Contract.AffordanceTable.Columns.ENABLEMENT_COMPONENT_NAME,
|
Contract.LockScreenQuickAffordances.AffordanceTable.Columns
|
||||||
|
.ENABLEMENT_ACTION_TEXT,
|
||||||
|
Contract.LockScreenQuickAffordances.AffordanceTable.Columns
|
||||||
|
.ENABLEMENT_COMPONENT_NAME,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.apply {
|
.apply {
|
||||||
@@ -261,7 +293,8 @@ class KeyguardQuickAffordanceProvider :
|
|||||||
representation.iconResourceId,
|
representation.iconResourceId,
|
||||||
if (representation.isEnabled) 1 else 0,
|
if (representation.isEnabled) 1 else 0,
|
||||||
representation.instructions?.joinToString(
|
representation.instructions?.joinToString(
|
||||||
Contract.AffordanceTable.ENABLEMENT_INSTRUCTIONS_DELIMITER
|
Contract.LockScreenQuickAffordances.AffordanceTable
|
||||||
|
.ENABLEMENT_INSTRUCTIONS_DELIMITER
|
||||||
),
|
),
|
||||||
representation.actionText,
|
representation.actionText,
|
||||||
representation.actionComponentName,
|
representation.actionComponentName,
|
||||||
@@ -274,8 +307,8 @@ class KeyguardQuickAffordanceProvider :
|
|||||||
private fun querySlots(): Cursor {
|
private fun querySlots(): Cursor {
|
||||||
return MatrixCursor(
|
return MatrixCursor(
|
||||||
arrayOf(
|
arrayOf(
|
||||||
Contract.SlotTable.Columns.ID,
|
Contract.LockScreenQuickAffordances.SlotTable.Columns.ID,
|
||||||
Contract.SlotTable.Columns.CAPACITY,
|
Contract.LockScreenQuickAffordances.SlotTable.Columns.CAPACITY,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.apply {
|
.apply {
|
||||||
@@ -22,7 +22,7 @@ import android.content.Intent
|
|||||||
import com.android.systemui.animation.Expandable
|
import com.android.systemui.animation.Expandable
|
||||||
import com.android.systemui.common.shared.model.Icon
|
import com.android.systemui.common.shared.model.Icon
|
||||||
import com.android.systemui.keyguard.shared.quickaffordance.ActivationState
|
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
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
/** Defines interface that can act as data source for a single quick affordance model. */
|
/** Defines interface that can act as data source for a single quick affordance model. */
|
||||||
@@ -90,8 +90,9 @@ interface KeyguardQuickAffordanceConfig {
|
|||||||
* the user to be able to set up the quick affordance and make it enabled.
|
* 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,
|
* 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
|
* separated by
|
||||||
* can use the [componentName] function.
|
* [Contract.LockScreenQuickAffordances.AffordanceTable.COMPONENT_NAME_SEPARATOR] for
|
||||||
|
* convenience, you can use the [componentName] function.
|
||||||
*/
|
*/
|
||||||
val actionComponentName: String? = null,
|
val actionComponentName: String? = null,
|
||||||
) : PickerScreenState() {
|
) : PickerScreenState() {
|
||||||
@@ -145,8 +146,8 @@ interface KeyguardQuickAffordanceConfig {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returning this as a result from the [onTriggered] method means that the implementation
|
* 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
|
* has _not_ taken care of the action and the system should show a Dialog using the given
|
||||||
* given [AlertDialog] and [Expandable].
|
* [AlertDialog] and [Expandable].
|
||||||
*/
|
*/
|
||||||
data class ShowDialog(
|
data class ShowDialog(
|
||||||
val dialog: AlertDialog,
|
val dialog: AlertDialog,
|
||||||
@@ -162,7 +163,8 @@ interface KeyguardQuickAffordanceConfig {
|
|||||||
return when {
|
return when {
|
||||||
action.isNullOrEmpty() -> null
|
action.isNullOrEmpty() -> null
|
||||||
!packageName.isNullOrEmpty() ->
|
!packageName.isNullOrEmpty() ->
|
||||||
"$packageName${Contract.AffordanceTable.COMPONENT_NAME_SEPARATOR}$action"
|
"$packageName${Contract.LockScreenQuickAffordances.AffordanceTable
|
||||||
|
.COMPONENT_NAME_SEPARATOR}$action"
|
||||||
else -> action
|
else -> action
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,13 +19,13 @@ package com.android.systemui.keyguard.data.quickaffordance
|
|||||||
|
|
||||||
import com.android.systemui.dagger.qualifiers.Background
|
import com.android.systemui.dagger.qualifiers.Background
|
||||||
import com.android.systemui.settings.UserTracker
|
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 com.android.systemui.shared.quickaffordance.data.content.KeyguardQuickAffordanceProviderClientImpl
|
import com.android.systemui.shared.customization.data.content.CustomizationProviderClientImpl
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlinx.coroutines.CoroutineDispatcher
|
import kotlinx.coroutines.CoroutineDispatcher
|
||||||
|
|
||||||
interface KeyguardQuickAffordanceProviderClientFactory {
|
interface KeyguardQuickAffordanceProviderClientFactory {
|
||||||
fun create(): KeyguardQuickAffordanceProviderClient
|
fun create(): CustomizationProviderClient
|
||||||
}
|
}
|
||||||
|
|
||||||
class KeyguardQuickAffordanceProviderClientFactoryImpl
|
class KeyguardQuickAffordanceProviderClientFactoryImpl
|
||||||
@@ -34,8 +34,8 @@ constructor(
|
|||||||
private val userTracker: UserTracker,
|
private val userTracker: UserTracker,
|
||||||
@Background private val backgroundDispatcher: CoroutineDispatcher,
|
@Background private val backgroundDispatcher: CoroutineDispatcher,
|
||||||
) : KeyguardQuickAffordanceProviderClientFactory {
|
) : KeyguardQuickAffordanceProviderClientFactory {
|
||||||
override fun create(): KeyguardQuickAffordanceProviderClient {
|
override fun create(): CustomizationProviderClient {
|
||||||
return KeyguardQuickAffordanceProviderClientImpl(
|
return CustomizationProviderClientImpl(
|
||||||
context = userTracker.userContext,
|
context = userTracker.userContext,
|
||||||
backgroundDispatcher = backgroundDispatcher,
|
backgroundDispatcher = backgroundDispatcher,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCall
|
|||||||
import com.android.systemui.dagger.SysUISingleton
|
import com.android.systemui.dagger.SysUISingleton
|
||||||
import com.android.systemui.dagger.qualifiers.Application
|
import com.android.systemui.dagger.qualifiers.Application
|
||||||
import com.android.systemui.settings.UserTracker
|
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 javax.inject.Inject
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
@@ -69,7 +69,7 @@ constructor(
|
|||||||
awaitClose { userTracker.removeCallback(callback) }
|
awaitClose { userTracker.removeCallback(callback) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private val clientOrNull: StateFlow<KeyguardQuickAffordanceProviderClient?> =
|
private val clientOrNull: StateFlow<CustomizationProviderClient?> =
|
||||||
userId
|
userId
|
||||||
.distinctUntilChanged()
|
.distinctUntilChanged()
|
||||||
.map { selectedUserId ->
|
.map { selectedUserId ->
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ import com.android.systemui.keyguard.shared.model.KeyguardSlotPickerRepresentati
|
|||||||
import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancePosition
|
import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancePosition
|
||||||
import com.android.systemui.plugins.ActivityStarter
|
import com.android.systemui.plugins.ActivityStarter
|
||||||
import com.android.systemui.settings.UserTracker
|
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.phone.SystemUIDialog
|
||||||
import com.android.systemui.statusbar.policy.KeyguardStateController
|
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||||
import dagger.Lazy
|
import dagger.Lazy
|
||||||
|
|||||||
@@ -146,7 +146,7 @@
|
|||||||
tools:replace="android:authorities"
|
tools:replace="android:authorities"
|
||||||
tools:node="remove" />
|
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:authorities="com.android.systemui.test.keyguard.quickaffordance.disabled"
|
||||||
android:enabled="false"
|
android:enabled="false"
|
||||||
tools:replace="android:authorities"
|
tools:replace="android:authorities"
|
||||||
|
|||||||
@@ -49,8 +49,8 @@ import com.android.systemui.keyguard.ui.preview.KeyguardRemotePreviewManager
|
|||||||
import com.android.systemui.plugins.ActivityStarter
|
import com.android.systemui.plugins.ActivityStarter
|
||||||
import com.android.systemui.settings.UserFileManager
|
import com.android.systemui.settings.UserFileManager
|
||||||
import com.android.systemui.settings.UserTracker
|
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.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.statusbar.policy.KeyguardStateController
|
||||||
import com.android.systemui.util.FakeSharedPreferences
|
import com.android.systemui.util.FakeSharedPreferences
|
||||||
import com.android.systemui.util.mockito.any
|
import com.android.systemui.util.mockito.any
|
||||||
@@ -75,7 +75,7 @@ import org.mockito.MockitoAnnotations
|
|||||||
@SmallTest
|
@SmallTest
|
||||||
@RunWith(AndroidTestingRunner::class)
|
@RunWith(AndroidTestingRunner::class)
|
||||||
@TestableLooper.RunWithLooper(setAsMainLooper = true)
|
@TestableLooper.RunWithLooper(setAsMainLooper = true)
|
||||||
class KeyguardQuickAffordanceProviderTest : SysuiTestCase() {
|
class CustomizationProviderTest : SysuiTestCase() {
|
||||||
|
|
||||||
@Mock private lateinit var lockPatternUtils: LockPatternUtils
|
@Mock private lateinit var lockPatternUtils: LockPatternUtils
|
||||||
@Mock private lateinit var keyguardStateController: KeyguardStateController
|
@Mock private lateinit var keyguardStateController: KeyguardStateController
|
||||||
@@ -87,7 +87,7 @@ class KeyguardQuickAffordanceProviderTest : SysuiTestCase() {
|
|||||||
@Mock private lateinit var previewSurfacePackage: SurfaceControlViewHost.SurfacePackage
|
@Mock private lateinit var previewSurfacePackage: SurfaceControlViewHost.SurfacePackage
|
||||||
@Mock private lateinit var launchAnimator: DialogLaunchAnimator
|
@Mock private lateinit var launchAnimator: DialogLaunchAnimator
|
||||||
|
|
||||||
private lateinit var underTest: KeyguardQuickAffordanceProvider
|
private lateinit var underTest: CustomizationProvider
|
||||||
|
|
||||||
private lateinit var testScope: TestScope
|
private lateinit var testScope: TestScope
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ class KeyguardQuickAffordanceProviderTest : SysuiTestCase() {
|
|||||||
whenever(previewRendererFactory.create(any())).thenReturn(previewRenderer)
|
whenever(previewRendererFactory.create(any())).thenReturn(previewRenderer)
|
||||||
whenever(backgroundHandler.looper).thenReturn(TestableLooper.get(this).looper)
|
whenever(backgroundHandler.looper).thenReturn(TestableLooper.get(this).looper)
|
||||||
|
|
||||||
underTest = KeyguardQuickAffordanceProvider()
|
underTest = CustomizationProvider()
|
||||||
val testDispatcher = StandardTestDispatcher()
|
val testDispatcher = StandardTestDispatcher()
|
||||||
testScope = TestScope(testDispatcher)
|
testScope = TestScope(testDispatcher)
|
||||||
val localUserSelectionManager =
|
val localUserSelectionManager =
|
||||||
@@ -205,19 +205,34 @@ class KeyguardQuickAffordanceProviderTest : SysuiTestCase() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun getType() {
|
fun getType() {
|
||||||
assertThat(underTest.getType(Contract.AffordanceTable.URI))
|
assertThat(underTest.getType(Contract.LockScreenQuickAffordances.AffordanceTable.URI))
|
||||||
.isEqualTo(
|
.isEqualTo(
|
||||||
"vnd.android.cursor.dir/vnd." +
|
"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(
|
.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(
|
.isEqualTo(
|
||||||
"vnd.android.cursor.dir/vnd." +
|
"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 @@ class KeyguardQuickAffordanceProviderTest : SysuiTestCase() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
context.contentResolver.delete(
|
context.contentResolver.delete(
|
||||||
Contract.SelectionTable.URI,
|
Contract.LockScreenQuickAffordances.SelectionTable.URI,
|
||||||
"${Contract.SelectionTable.Columns.SLOT_ID} = ? AND" +
|
"${Contract.LockScreenQuickAffordances.SelectionTable.Columns.SLOT_ID} = ? AND" +
|
||||||
" ${Contract.SelectionTable.Columns.AFFORDANCE_ID} = ?",
|
" ${Contract.LockScreenQuickAffordances.SelectionTable.Columns.AFFORDANCE_ID}" +
|
||||||
|
" = ?",
|
||||||
arrayOf(
|
arrayOf(
|
||||||
KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END,
|
KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END,
|
||||||
AFFORDANCE_2,
|
AFFORDANCE_2,
|
||||||
@@ -330,8 +346,8 @@ class KeyguardQuickAffordanceProviderTest : SysuiTestCase() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
context.contentResolver.delete(
|
context.contentResolver.delete(
|
||||||
Contract.SelectionTable.URI,
|
Contract.LockScreenQuickAffordances.SelectionTable.URI,
|
||||||
Contract.SelectionTable.Columns.SLOT_ID,
|
Contract.LockScreenQuickAffordances.SelectionTable.Columns.SLOT_ID,
|
||||||
arrayOf(
|
arrayOf(
|
||||||
KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END,
|
KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END,
|
||||||
),
|
),
|
||||||
@@ -371,10 +387,13 @@ class KeyguardQuickAffordanceProviderTest : SysuiTestCase() {
|
|||||||
affordanceId: String,
|
affordanceId: String,
|
||||||
) {
|
) {
|
||||||
context.contentResolver.insert(
|
context.contentResolver.insert(
|
||||||
Contract.SelectionTable.URI,
|
Contract.LockScreenQuickAffordances.SelectionTable.URI,
|
||||||
ContentValues().apply {
|
ContentValues().apply {
|
||||||
put(Contract.SelectionTable.Columns.SLOT_ID, slotId)
|
put(Contract.LockScreenQuickAffordances.SelectionTable.Columns.SLOT_ID, slotId)
|
||||||
put(Contract.SelectionTable.Columns.AFFORDANCE_ID, affordanceId)
|
put(
|
||||||
|
Contract.LockScreenQuickAffordances.SelectionTable.Columns.AFFORDANCE_ID,
|
||||||
|
affordanceId
|
||||||
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -382,7 +401,7 @@ class KeyguardQuickAffordanceProviderTest : SysuiTestCase() {
|
|||||||
private fun querySelections(): List<Selection> {
|
private fun querySelections(): List<Selection> {
|
||||||
return context.contentResolver
|
return context.contentResolver
|
||||||
.query(
|
.query(
|
||||||
Contract.SelectionTable.URI,
|
Contract.LockScreenQuickAffordances.SelectionTable.URI,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
@@ -391,11 +410,18 @@ class KeyguardQuickAffordanceProviderTest : SysuiTestCase() {
|
|||||||
?.use { cursor ->
|
?.use { cursor ->
|
||||||
buildList {
|
buildList {
|
||||||
val slotIdColumnIndex =
|
val slotIdColumnIndex =
|
||||||
cursor.getColumnIndex(Contract.SelectionTable.Columns.SLOT_ID)
|
cursor.getColumnIndex(
|
||||||
|
Contract.LockScreenQuickAffordances.SelectionTable.Columns.SLOT_ID
|
||||||
|
)
|
||||||
val affordanceIdColumnIndex =
|
val affordanceIdColumnIndex =
|
||||||
cursor.getColumnIndex(Contract.SelectionTable.Columns.AFFORDANCE_ID)
|
cursor.getColumnIndex(
|
||||||
|
Contract.LockScreenQuickAffordances.SelectionTable.Columns.AFFORDANCE_ID
|
||||||
|
)
|
||||||
val affordanceNameColumnIndex =
|
val affordanceNameColumnIndex =
|
||||||
cursor.getColumnIndex(Contract.SelectionTable.Columns.AFFORDANCE_NAME)
|
cursor.getColumnIndex(
|
||||||
|
Contract.LockScreenQuickAffordances.SelectionTable.Columns
|
||||||
|
.AFFORDANCE_NAME
|
||||||
|
)
|
||||||
if (
|
if (
|
||||||
slotIdColumnIndex == -1 ||
|
slotIdColumnIndex == -1 ||
|
||||||
affordanceIdColumnIndex == -1 ||
|
affordanceIdColumnIndex == -1 ||
|
||||||
@@ -421,7 +447,7 @@ class KeyguardQuickAffordanceProviderTest : SysuiTestCase() {
|
|||||||
private fun querySlots(): List<Slot> {
|
private fun querySlots(): List<Slot> {
|
||||||
return context.contentResolver
|
return context.contentResolver
|
||||||
.query(
|
.query(
|
||||||
Contract.SlotTable.URI,
|
Contract.LockScreenQuickAffordances.SlotTable.URI,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
@@ -429,9 +455,14 @@ class KeyguardQuickAffordanceProviderTest : SysuiTestCase() {
|
|||||||
)
|
)
|
||||||
?.use { cursor ->
|
?.use { cursor ->
|
||||||
buildList {
|
buildList {
|
||||||
val idColumnIndex = cursor.getColumnIndex(Contract.SlotTable.Columns.ID)
|
val idColumnIndex =
|
||||||
|
cursor.getColumnIndex(
|
||||||
|
Contract.LockScreenQuickAffordances.SlotTable.Columns.ID
|
||||||
|
)
|
||||||
val capacityColumnIndex =
|
val capacityColumnIndex =
|
||||||
cursor.getColumnIndex(Contract.SlotTable.Columns.CAPACITY)
|
cursor.getColumnIndex(
|
||||||
|
Contract.LockScreenQuickAffordances.SlotTable.Columns.CAPACITY
|
||||||
|
)
|
||||||
if (idColumnIndex == -1 || capacityColumnIndex == -1) {
|
if (idColumnIndex == -1 || capacityColumnIndex == -1) {
|
||||||
return@buildList
|
return@buildList
|
||||||
}
|
}
|
||||||
@@ -452,7 +483,7 @@ class KeyguardQuickAffordanceProviderTest : SysuiTestCase() {
|
|||||||
private fun queryAffordances(): List<Affordance> {
|
private fun queryAffordances(): List<Affordance> {
|
||||||
return context.contentResolver
|
return context.contentResolver
|
||||||
.query(
|
.query(
|
||||||
Contract.AffordanceTable.URI,
|
Contract.LockScreenQuickAffordances.AffordanceTable.URI,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
@@ -460,11 +491,18 @@ class KeyguardQuickAffordanceProviderTest : SysuiTestCase() {
|
|||||||
)
|
)
|
||||||
?.use { cursor ->
|
?.use { cursor ->
|
||||||
buildList {
|
buildList {
|
||||||
val idColumnIndex = cursor.getColumnIndex(Contract.AffordanceTable.Columns.ID)
|
val idColumnIndex =
|
||||||
|
cursor.getColumnIndex(
|
||||||
|
Contract.LockScreenQuickAffordances.AffordanceTable.Columns.ID
|
||||||
|
)
|
||||||
val nameColumnIndex =
|
val nameColumnIndex =
|
||||||
cursor.getColumnIndex(Contract.AffordanceTable.Columns.NAME)
|
cursor.getColumnIndex(
|
||||||
|
Contract.LockScreenQuickAffordances.AffordanceTable.Columns.NAME
|
||||||
|
)
|
||||||
val iconColumnIndex =
|
val iconColumnIndex =
|
||||||
cursor.getColumnIndex(Contract.AffordanceTable.Columns.ICON)
|
cursor.getColumnIndex(
|
||||||
|
Contract.LockScreenQuickAffordances.AffordanceTable.Columns.ICON
|
||||||
|
)
|
||||||
if (idColumnIndex == -1 || nameColumnIndex == -1 || iconColumnIndex == -1) {
|
if (idColumnIndex == -1 || nameColumnIndex == -1 || iconColumnIndex == -1) {
|
||||||
return@buildList
|
return@buildList
|
||||||
}
|
}
|
||||||
@@ -22,8 +22,8 @@ import android.os.UserHandle
|
|||||||
import androidx.test.filters.SmallTest
|
import androidx.test.filters.SmallTest
|
||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
import com.android.systemui.settings.FakeUserTracker
|
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.keyguard.shared.model.KeyguardQuickAffordanceSlots
|
||||||
import com.android.systemui.shared.quickaffordance.data.content.FakeKeyguardQuickAffordanceProviderClient
|
|
||||||
import com.android.systemui.util.mockito.whenever
|
import com.android.systemui.util.mockito.whenever
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
@@ -54,16 +54,16 @@ class KeyguardQuickAffordanceRemoteUserSelectionManagerTest : SysuiTestCase() {
|
|||||||
private lateinit var testScope: TestScope
|
private lateinit var testScope: TestScope
|
||||||
private lateinit var testDispatcher: TestDispatcher
|
private lateinit var testDispatcher: TestDispatcher
|
||||||
private lateinit var userTracker: FakeUserTracker
|
private lateinit var userTracker: FakeUserTracker
|
||||||
private lateinit var client1: FakeKeyguardQuickAffordanceProviderClient
|
private lateinit var client1: FakeCustomizationProviderClient
|
||||||
private lateinit var client2: FakeKeyguardQuickAffordanceProviderClient
|
private lateinit var client2: FakeCustomizationProviderClient
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
MockitoAnnotations.initMocks(this)
|
MockitoAnnotations.initMocks(this)
|
||||||
whenever(userHandle.identifier).thenReturn(UserHandle.USER_SYSTEM)
|
whenever(userHandle.identifier).thenReturn(UserHandle.USER_SYSTEM)
|
||||||
whenever(userHandle.isSystem).thenReturn(true)
|
whenever(userHandle.isSystem).thenReturn(true)
|
||||||
client1 = FakeKeyguardQuickAffordanceProviderClient()
|
client1 = FakeCustomizationProviderClient()
|
||||||
client2 = FakeKeyguardQuickAffordanceProviderClient()
|
client2 = FakeCustomizationProviderClient()
|
||||||
|
|
||||||
userTracker = FakeUserTracker()
|
userTracker = FakeUserTracker()
|
||||||
userTracker.set(
|
userTracker.set(
|
||||||
@@ -122,11 +122,11 @@ class KeyguardQuickAffordanceRemoteUserSelectionManagerTest : SysuiTestCase() {
|
|||||||
|
|
||||||
client1.insertSelection(
|
client1.insertSelection(
|
||||||
slotId = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START,
|
slotId = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START,
|
||||||
affordanceId = FakeKeyguardQuickAffordanceProviderClient.AFFORDANCE_1,
|
affordanceId = FakeCustomizationProviderClient.AFFORDANCE_1,
|
||||||
)
|
)
|
||||||
client2.insertSelection(
|
client2.insertSelection(
|
||||||
slotId = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END,
|
slotId = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END,
|
||||||
affordanceId = FakeKeyguardQuickAffordanceProviderClient.AFFORDANCE_2,
|
affordanceId = FakeCustomizationProviderClient.AFFORDANCE_2,
|
||||||
)
|
)
|
||||||
|
|
||||||
userTracker.set(
|
userTracker.set(
|
||||||
@@ -139,7 +139,7 @@ class KeyguardQuickAffordanceRemoteUserSelectionManagerTest : SysuiTestCase() {
|
|||||||
mapOf(
|
mapOf(
|
||||||
KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START to
|
KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START to
|
||||||
listOf(
|
listOf(
|
||||||
FakeKeyguardQuickAffordanceProviderClient.AFFORDANCE_1,
|
FakeCustomizationProviderClient.AFFORDANCE_1,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -154,7 +154,7 @@ class KeyguardQuickAffordanceRemoteUserSelectionManagerTest : SysuiTestCase() {
|
|||||||
mapOf(
|
mapOf(
|
||||||
KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END to
|
KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END to
|
||||||
listOf(
|
listOf(
|
||||||
FakeKeyguardQuickAffordanceProviderClient.AFFORDANCE_2,
|
FakeCustomizationProviderClient.AFFORDANCE_2,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -174,7 +174,7 @@ class KeyguardQuickAffordanceRemoteUserSelectionManagerTest : SysuiTestCase() {
|
|||||||
|
|
||||||
client1.insertSelection(
|
client1.insertSelection(
|
||||||
slotId = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START,
|
slotId = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START,
|
||||||
affordanceId = FakeKeyguardQuickAffordanceProviderClient.AFFORDANCE_1,
|
affordanceId = FakeCustomizationProviderClient.AFFORDANCE_1,
|
||||||
)
|
)
|
||||||
userTracker.set(
|
userTracker.set(
|
||||||
userInfos = userTracker.userProfiles,
|
userInfos = userTracker.userProfiles,
|
||||||
@@ -197,7 +197,7 @@ class KeyguardQuickAffordanceRemoteUserSelectionManagerTest : SysuiTestCase() {
|
|||||||
|
|
||||||
underTest.setSelections(
|
underTest.setSelections(
|
||||||
slotId = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START,
|
slotId = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START,
|
||||||
affordanceIds = listOf(FakeKeyguardQuickAffordanceProviderClient.AFFORDANCE_1),
|
affordanceIds = listOf(FakeCustomizationProviderClient.AFFORDANCE_1),
|
||||||
)
|
)
|
||||||
runCurrent()
|
runCurrent()
|
||||||
|
|
||||||
@@ -206,7 +206,7 @@ class KeyguardQuickAffordanceRemoteUserSelectionManagerTest : SysuiTestCase() {
|
|||||||
mapOf(
|
mapOf(
|
||||||
KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START to
|
KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START to
|
||||||
listOf(
|
listOf(
|
||||||
FakeKeyguardQuickAffordanceProviderClient.AFFORDANCE_1,
|
FakeCustomizationProviderClient.AFFORDANCE_1,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -32,8 +32,8 @@ import com.android.systemui.keyguard.shared.model.KeyguardQuickAffordancePickerR
|
|||||||
import com.android.systemui.keyguard.shared.model.KeyguardSlotPickerRepresentation
|
import com.android.systemui.keyguard.shared.model.KeyguardSlotPickerRepresentation
|
||||||
import com.android.systemui.settings.FakeUserTracker
|
import com.android.systemui.settings.FakeUserTracker
|
||||||
import com.android.systemui.settings.UserFileManager
|
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.keyguard.shared.model.KeyguardQuickAffordanceSlots
|
||||||
import com.android.systemui.shared.quickaffordance.data.content.FakeKeyguardQuickAffordanceProviderClient
|
|
||||||
import com.android.systemui.util.FakeSharedPreferences
|
import com.android.systemui.util.FakeSharedPreferences
|
||||||
import com.android.systemui.util.mockito.mock
|
import com.android.systemui.util.mockito.mock
|
||||||
import com.android.systemui.util.mockito.whenever
|
import com.android.systemui.util.mockito.whenever
|
||||||
@@ -63,19 +63,13 @@ class KeyguardQuickAffordanceRepositoryTest : SysuiTestCase() {
|
|||||||
private lateinit var config1: FakeKeyguardQuickAffordanceConfig
|
private lateinit var config1: FakeKeyguardQuickAffordanceConfig
|
||||||
private lateinit var config2: FakeKeyguardQuickAffordanceConfig
|
private lateinit var config2: FakeKeyguardQuickAffordanceConfig
|
||||||
private lateinit var userTracker: FakeUserTracker
|
private lateinit var userTracker: FakeUserTracker
|
||||||
private lateinit var client1: FakeKeyguardQuickAffordanceProviderClient
|
private lateinit var client1: FakeCustomizationProviderClient
|
||||||
private lateinit var client2: FakeKeyguardQuickAffordanceProviderClient
|
private lateinit var client2: FakeCustomizationProviderClient
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
config1 =
|
config1 = FakeKeyguardQuickAffordanceConfig(FakeCustomizationProviderClient.AFFORDANCE_1)
|
||||||
FakeKeyguardQuickAffordanceConfig(
|
config2 = FakeKeyguardQuickAffordanceConfig(FakeCustomizationProviderClient.AFFORDANCE_2)
|
||||||
FakeKeyguardQuickAffordanceProviderClient.AFFORDANCE_1
|
|
||||||
)
|
|
||||||
config2 =
|
|
||||||
FakeKeyguardQuickAffordanceConfig(
|
|
||||||
FakeKeyguardQuickAffordanceProviderClient.AFFORDANCE_2
|
|
||||||
)
|
|
||||||
val scope = CoroutineScope(IMMEDIATE)
|
val scope = CoroutineScope(IMMEDIATE)
|
||||||
userTracker = FakeUserTracker()
|
userTracker = FakeUserTracker()
|
||||||
val localUserSelectionManager =
|
val localUserSelectionManager =
|
||||||
@@ -95,8 +89,8 @@ class KeyguardQuickAffordanceRepositoryTest : SysuiTestCase() {
|
|||||||
userTracker = userTracker,
|
userTracker = userTracker,
|
||||||
broadcastDispatcher = fakeBroadcastDispatcher,
|
broadcastDispatcher = fakeBroadcastDispatcher,
|
||||||
)
|
)
|
||||||
client1 = FakeKeyguardQuickAffordanceProviderClient()
|
client1 = FakeCustomizationProviderClient()
|
||||||
client2 = FakeKeyguardQuickAffordanceProviderClient()
|
client2 = FakeCustomizationProviderClient()
|
||||||
val remoteUserSelectionManager =
|
val remoteUserSelectionManager =
|
||||||
KeyguardQuickAffordanceRemoteUserSelectionManager(
|
KeyguardQuickAffordanceRemoteUserSelectionManager(
|
||||||
scope = scope,
|
scope = scope,
|
||||||
@@ -256,7 +250,7 @@ class KeyguardQuickAffordanceRepositoryTest : SysuiTestCase() {
|
|||||||
)
|
)
|
||||||
client2.insertSelection(
|
client2.insertSelection(
|
||||||
slotId = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START,
|
slotId = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START,
|
||||||
affordanceId = FakeKeyguardQuickAffordanceProviderClient.AFFORDANCE_2,
|
affordanceId = FakeCustomizationProviderClient.AFFORDANCE_2,
|
||||||
)
|
)
|
||||||
val observed = mutableListOf<Map<String, List<KeyguardQuickAffordanceConfig>>>()
|
val observed = mutableListOf<Map<String, List<KeyguardQuickAffordanceConfig>>>()
|
||||||
val job = underTest.selections.onEach { observed.add(it) }.launchIn(this)
|
val job = underTest.selections.onEach { observed.add(it) }.launchIn(this)
|
||||||
|
|||||||
@@ -18,17 +18,17 @@
|
|||||||
package com.android.systemui.keyguard.data.quickaffordance
|
package com.android.systemui.keyguard.data.quickaffordance
|
||||||
|
|
||||||
import com.android.systemui.settings.UserTracker
|
import com.android.systemui.settings.UserTracker
|
||||||
import com.android.systemui.shared.quickaffordance.data.content.FakeKeyguardQuickAffordanceProviderClient
|
import com.android.systemui.shared.customization.data.content.CustomizationProviderClient
|
||||||
import com.android.systemui.shared.quickaffordance.data.content.KeyguardQuickAffordanceProviderClient
|
import com.android.systemui.shared.customization.data.content.FakeCustomizationProviderClient
|
||||||
|
|
||||||
class FakeKeyguardQuickAffordanceProviderClientFactory(
|
class FakeKeyguardQuickAffordanceProviderClientFactory(
|
||||||
private val userTracker: UserTracker,
|
private val userTracker: UserTracker,
|
||||||
private val callback: (Int) -> KeyguardQuickAffordanceProviderClient = {
|
private val callback: (Int) -> CustomizationProviderClient = {
|
||||||
FakeKeyguardQuickAffordanceProviderClient()
|
FakeCustomizationProviderClient()
|
||||||
},
|
},
|
||||||
) : KeyguardQuickAffordanceProviderClientFactory {
|
) : KeyguardQuickAffordanceProviderClientFactory {
|
||||||
|
|
||||||
override fun create(): KeyguardQuickAffordanceProviderClient {
|
override fun create(): CustomizationProviderClient {
|
||||||
return callback(userTracker.userId)
|
return callback(userTracker.userId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user