Fixes i18n issue with shortcut names.
Some lock screen shortcut names were not updating to their translated names when the user changed system language, remaining with the old language in Settings and in Wallpaper Picker. This CL fixes that issue. The cause for the issue was how some pickerName properties were implemented using a getter and some were constants, without a getter. The constant ones were not being translated. The approach in the CL is to actually move from a property to a method call. This way, there is no choice but to recalculate the name of the affordance every time; closing the door on the reintroduction of this issue when a new config implementation is added with the developer skipping the getter. Fix: 280077350 Fix: 280829365 Fix: 278858630 Test: changed languages and verified that the shortcut names are updated to the new language in both "Wallpaper & style" and in Display > Lock screen Change-Id: I2d3e3a621b6f24c42c1600ce4af17617dd52560a
This commit is contained in:
@@ -52,8 +52,7 @@ constructor(
|
||||
override val key: String
|
||||
get() = BuiltInKeyguardQuickAffordanceKeys.CAMERA
|
||||
|
||||
override val pickerName: String
|
||||
get() = context.getString(R.string.accessibility_camera_button)
|
||||
override fun pickerName(): String = context.getString(R.string.accessibility_camera_button)
|
||||
|
||||
override val pickerIconResourceId: Int
|
||||
get() = R.drawable.ic_camera
|
||||
|
||||
@@ -99,7 +99,7 @@ constructor(
|
||||
|
||||
override val key: String = BuiltInKeyguardQuickAffordanceKeys.DO_NOT_DISTURB
|
||||
|
||||
override val pickerName: String = context.getString(R.string.quick_settings_dnd_label)
|
||||
override fun pickerName(): String = context.getString(R.string.quick_settings_dnd_label)
|
||||
|
||||
override val pickerIconResourceId: Int = R.drawable.ic_do_not_disturb
|
||||
|
||||
|
||||
@@ -75,8 +75,7 @@ constructor(
|
||||
override val key: String
|
||||
get() = BuiltInKeyguardQuickAffordanceKeys.FLASHLIGHT
|
||||
|
||||
override val pickerName: String
|
||||
get() = context.getString(R.string.quick_settings_flashlight_label)
|
||||
override fun pickerName(): String = context.getString(R.string.quick_settings_flashlight_label)
|
||||
|
||||
override val pickerIconResourceId: Int
|
||||
get() = R.drawable.ic_flashlight_off
|
||||
|
||||
@@ -54,7 +54,7 @@ constructor(
|
||||
|
||||
override val key: String = BuiltInKeyguardQuickAffordanceKeys.HOME_CONTROLS
|
||||
|
||||
override val pickerName: String by lazy { context.getString(component.getTileTitleId()) }
|
||||
override fun pickerName(): String = context.getString(component.getTileTitleId())
|
||||
|
||||
override val pickerIconResourceId: Int by lazy { component.getTileImageId() }
|
||||
|
||||
|
||||
@@ -31,8 +31,6 @@ interface KeyguardQuickAffordanceConfig {
|
||||
/** Unique identifier for this quick affordance. It must be globally unique. */
|
||||
val key: String
|
||||
|
||||
val pickerName: String
|
||||
|
||||
val pickerIconResourceId: Int
|
||||
|
||||
/**
|
||||
@@ -42,6 +40,12 @@ interface KeyguardQuickAffordanceConfig {
|
||||
*/
|
||||
val lockScreenState: Flow<LockScreenState>
|
||||
|
||||
/**
|
||||
* Returns a user-visible [String] that should be shown as the name for the option in the
|
||||
* wallpaper picker / settings app to select this quick affordance.
|
||||
*/
|
||||
fun pickerName(): String
|
||||
|
||||
/**
|
||||
* Returns the [PickerScreenState] representing the affordance in the settings or selector
|
||||
* experience.
|
||||
|
||||
@@ -34,6 +34,7 @@ import com.android.systemui.keyguard.shared.quickaffordance.ActivationState
|
||||
import com.android.systemui.settings.UserFileManager
|
||||
import com.android.systemui.settings.UserTracker
|
||||
import com.android.systemui.util.RingerModeTracker
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
@@ -45,30 +46,32 @@ import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.onStart
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import javax.inject.Inject
|
||||
|
||||
@SysUISingleton
|
||||
class MuteQuickAffordanceConfig @Inject constructor(
|
||||
context: Context,
|
||||
private val userTracker: UserTracker,
|
||||
private val userFileManager: UserFileManager,
|
||||
private val ringerModeTracker: RingerModeTracker,
|
||||
private val audioManager: AudioManager,
|
||||
@Application private val coroutineScope: CoroutineScope,
|
||||
@Main private val mainDispatcher: CoroutineDispatcher,
|
||||
@Background private val backgroundDispatcher: CoroutineDispatcher,
|
||||
class MuteQuickAffordanceConfig
|
||||
@Inject
|
||||
constructor(
|
||||
private val context: Context,
|
||||
private val userTracker: UserTracker,
|
||||
private val userFileManager: UserFileManager,
|
||||
private val ringerModeTracker: RingerModeTracker,
|
||||
private val audioManager: AudioManager,
|
||||
@Application private val coroutineScope: CoroutineScope,
|
||||
@Main private val mainDispatcher: CoroutineDispatcher,
|
||||
@Background private val backgroundDispatcher: CoroutineDispatcher,
|
||||
) : KeyguardQuickAffordanceConfig {
|
||||
|
||||
private var previousNonSilentMode: Int = DEFAULT_LAST_NON_SILENT_VALUE
|
||||
|
||||
override val key: String = BuiltInKeyguardQuickAffordanceKeys.MUTE
|
||||
|
||||
override val pickerName: String = context.getString(R.string.volume_ringer_status_silent)
|
||||
override fun pickerName(): String = context.getString(R.string.volume_ringer_status_silent)
|
||||
|
||||
override val pickerIconResourceId: Int = R.drawable.ic_notifications_silence
|
||||
|
||||
override val lockScreenState: Flow<KeyguardQuickAffordanceConfig.LockScreenState> =
|
||||
ringerModeTracker.ringerModeInternal.asFlow()
|
||||
ringerModeTracker.ringerModeInternal
|
||||
.asFlow()
|
||||
.onStart { getLastNonSilentRingerMode() }
|
||||
.distinctUntilChanged()
|
||||
.onEach { mode ->
|
||||
@@ -78,17 +81,14 @@ class MuteQuickAffordanceConfig @Inject constructor(
|
||||
}
|
||||
}
|
||||
.map { mode ->
|
||||
val (activationState, contentDescriptionRes) = when {
|
||||
audioManager.isVolumeFixed ->
|
||||
ActivationState.NotSupported to
|
||||
R.string.volume_ringer_hint_mute
|
||||
mode == AudioManager.RINGER_MODE_SILENT ->
|
||||
ActivationState.Active to
|
||||
R.string.volume_ringer_hint_mute
|
||||
else ->
|
||||
ActivationState.Inactive to
|
||||
R.string.volume_ringer_hint_unmute
|
||||
}
|
||||
val (activationState, contentDescriptionRes) =
|
||||
when {
|
||||
audioManager.isVolumeFixed ->
|
||||
ActivationState.NotSupported to R.string.volume_ringer_hint_mute
|
||||
mode == AudioManager.RINGER_MODE_SILENT ->
|
||||
ActivationState.Active to R.string.volume_ringer_hint_mute
|
||||
else -> ActivationState.Inactive to R.string.volume_ringer_hint_unmute
|
||||
}
|
||||
|
||||
KeyguardQuickAffordanceConfig.LockScreenState.Visible(
|
||||
Icon.Resource(
|
||||
@@ -130,32 +130,35 @@ class MuteQuickAffordanceConfig @Inject constructor(
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the last non-silent ringer mode from shared-preferences if it exists. This is
|
||||
* cached by [MuteQuickAffordanceCoreStartable] while this affordance is selected
|
||||
* Gets the last non-silent ringer mode from shared-preferences if it exists. This is cached by
|
||||
* [MuteQuickAffordanceCoreStartable] while this affordance is selected
|
||||
*/
|
||||
private suspend fun getLastNonSilentRingerMode(): Int =
|
||||
withContext(backgroundDispatcher) {
|
||||
userFileManager.getSharedPreferences(
|
||||
userFileManager
|
||||
.getSharedPreferences(
|
||||
MUTE_QUICK_AFFORDANCE_PREFS_FILE_NAME,
|
||||
Context.MODE_PRIVATE,
|
||||
userTracker.userId
|
||||
).getInt(
|
||||
)
|
||||
.getInt(
|
||||
LAST_NON_SILENT_RINGER_MODE_KEY,
|
||||
ringerModeTracker.ringerModeInternal.value ?: DEFAULT_LAST_NON_SILENT_VALUE
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private fun <T> LiveData<T>.asFlow(): Flow<T?> =
|
||||
conflatedCallbackFlow {
|
||||
val observer = Observer { value: T -> trySend(value) }
|
||||
observeForever(observer)
|
||||
send(value)
|
||||
awaitClose { removeObserver(observer) }
|
||||
}.flowOn(mainDispatcher)
|
||||
val observer = Observer { value: T -> trySend(value) }
|
||||
observeForever(observer)
|
||||
send(value)
|
||||
awaitClose { removeObserver(observer) }
|
||||
}
|
||||
.flowOn(mainDispatcher)
|
||||
|
||||
companion object {
|
||||
const val LAST_NON_SILENT_RINGER_MODE_KEY = "key_last_non_silent_ringer_mode"
|
||||
const val MUTE_QUICK_AFFORDANCE_PREFS_FILE_NAME = "quick_affordance_mute_ringer_mode_cache"
|
||||
private const val DEFAULT_LAST_NON_SILENT_VALUE = AudioManager.RINGER_MODE_NORMAL
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ constructor(
|
||||
|
||||
override val key: String = BuiltInKeyguardQuickAffordanceKeys.QR_CODE_SCANNER
|
||||
|
||||
override val pickerName = context.getString(R.string.qr_code_scanner_title)
|
||||
override fun pickerName(): String = context.getString(R.string.qr_code_scanner_title)
|
||||
|
||||
override val pickerIconResourceId = R.drawable.ic_qr_code_scanner
|
||||
|
||||
@@ -53,6 +53,7 @@ constructor(
|
||||
override fun onQRCodeScannerActivityChanged() {
|
||||
trySendWithFailureLogging(state(), TAG)
|
||||
}
|
||||
|
||||
override fun onQRCodeScannerPreferenceChanged() {
|
||||
trySendWithFailureLogging(state(), TAG)
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ constructor(
|
||||
|
||||
override val key: String = BuiltInKeyguardQuickAffordanceKeys.QUICK_ACCESS_WALLET
|
||||
|
||||
override val pickerName: String = context.getString(R.string.accessibility_wallet_button)
|
||||
override fun pickerName(): String = context.getString(R.string.accessibility_wallet_button)
|
||||
|
||||
override val pickerIconResourceId = R.drawable.ic_wallet_lockscreen
|
||||
|
||||
|
||||
@@ -62,8 +62,7 @@ constructor(
|
||||
override val key: String
|
||||
get() = BuiltInKeyguardQuickAffordanceKeys.VIDEO_CAMERA
|
||||
|
||||
override val pickerName: String
|
||||
get() = context.getString(R.string.video_camera)
|
||||
override fun pickerName(): String = context.getString(R.string.video_camera)
|
||||
|
||||
override val pickerIconResourceId: Int
|
||||
get() = R.drawable.ic_videocam
|
||||
|
||||
@@ -170,7 +170,7 @@ constructor(
|
||||
pickerState as? KeyguardQuickAffordanceConfig.PickerScreenState.Disabled
|
||||
KeyguardQuickAffordancePickerRepresentation(
|
||||
id = config.key,
|
||||
name = config.pickerName,
|
||||
name = config.pickerName(),
|
||||
iconResourceId = config.pickerIconResourceId,
|
||||
isEnabled =
|
||||
pickerState is KeyguardQuickAffordanceConfig.PickerScreenState.Default,
|
||||
@@ -234,7 +234,9 @@ constructor(
|
||||
pw.println(" $slotId$selectionText (capacity = $capacity)")
|
||||
}
|
||||
pw.println("Available affordances on device:")
|
||||
configs.forEach { config -> pw.println(" ${config.key} (\"${config.pickerName}\")") }
|
||||
configs.forEach { config ->
|
||||
pw.println(" ${config.key} (\"${config.pickerName()}\")")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ constructor(
|
||||
|
||||
private val pickerNameResourceId = R.string.note_task_button_label
|
||||
|
||||
override val pickerName: String = context.getString(pickerNameResourceId)
|
||||
override fun pickerName(): String = context.getString(pickerNameResourceId)
|
||||
|
||||
override val pickerIconResourceId = R.drawable.ic_note_task_shortcut_keyguard
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ import kotlinx.coroutines.yield
|
||||
@RoboPilotTest
|
||||
class FakeKeyguardQuickAffordanceConfig(
|
||||
override val key: String,
|
||||
override val pickerName: String = key,
|
||||
private val pickerName: String = key,
|
||||
override val pickerIconResourceId: Int = 0,
|
||||
) : KeyguardQuickAffordanceConfig {
|
||||
|
||||
@@ -41,6 +41,8 @@ class FakeKeyguardQuickAffordanceConfig(
|
||||
override val lockScreenState: Flow<KeyguardQuickAffordanceConfig.LockScreenState> =
|
||||
_lockScreenState
|
||||
|
||||
override fun pickerName(): String = pickerName
|
||||
|
||||
override fun onTriggered(
|
||||
expandable: Expandable?,
|
||||
): OnTriggeredResult {
|
||||
|
||||
@@ -189,12 +189,12 @@ class KeyguardQuickAffordanceRepositoryTest : SysuiTestCase() {
|
||||
listOf(
|
||||
KeyguardQuickAffordancePickerRepresentation(
|
||||
id = config1.key,
|
||||
name = config1.pickerName,
|
||||
name = config1.pickerName(),
|
||||
iconResourceId = config1.pickerIconResourceId,
|
||||
),
|
||||
KeyguardQuickAffordancePickerRepresentation(
|
||||
id = config2.key,
|
||||
name = config2.pickerName,
|
||||
name = config2.pickerName(),
|
||||
iconResourceId = config2.pickerIconResourceId,
|
||||
),
|
||||
)
|
||||
|
||||
@@ -435,7 +435,7 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
|
||||
listOf(
|
||||
KeyguardQuickAffordancePickerRepresentation(
|
||||
id = homeControls.key,
|
||||
name = homeControls.pickerName,
|
||||
name = homeControls.pickerName(),
|
||||
iconResourceId = homeControls.pickerIconResourceId,
|
||||
),
|
||||
),
|
||||
@@ -469,7 +469,7 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
|
||||
listOf(
|
||||
KeyguardQuickAffordancePickerRepresentation(
|
||||
id = quickAccessWallet.key,
|
||||
name = quickAccessWallet.pickerName,
|
||||
name = quickAccessWallet.pickerName(),
|
||||
iconResourceId = quickAccessWallet.pickerIconResourceId,
|
||||
),
|
||||
),
|
||||
@@ -506,7 +506,7 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
|
||||
listOf(
|
||||
KeyguardQuickAffordancePickerRepresentation(
|
||||
id = quickAccessWallet.key,
|
||||
name = quickAccessWallet.pickerName,
|
||||
name = quickAccessWallet.pickerName(),
|
||||
iconResourceId = quickAccessWallet.pickerIconResourceId,
|
||||
),
|
||||
),
|
||||
@@ -514,7 +514,7 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
|
||||
listOf(
|
||||
KeyguardQuickAffordancePickerRepresentation(
|
||||
id = qrCodeScanner.key,
|
||||
name = qrCodeScanner.pickerName,
|
||||
name = qrCodeScanner.pickerName(),
|
||||
iconResourceId = qrCodeScanner.pickerIconResourceId,
|
||||
),
|
||||
),
|
||||
@@ -570,7 +570,7 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
|
||||
listOf(
|
||||
KeyguardQuickAffordancePickerRepresentation(
|
||||
id = quickAccessWallet.key,
|
||||
name = quickAccessWallet.pickerName,
|
||||
name = quickAccessWallet.pickerName(),
|
||||
iconResourceId = quickAccessWallet.pickerIconResourceId,
|
||||
),
|
||||
),
|
||||
@@ -665,7 +665,7 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
|
||||
listOf(
|
||||
KeyguardQuickAffordancePickerRepresentation(
|
||||
id = quickAccessWallet.key,
|
||||
name = quickAccessWallet.pickerName,
|
||||
name = quickAccessWallet.pickerName(),
|
||||
iconResourceId = quickAccessWallet.pickerIconResourceId,
|
||||
),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user