Merge "Accessibility for privacy status animations" into sc-dev
This commit is contained in:
@@ -497,7 +497,12 @@ class PrivacyDotViewController @Inject constructor(
|
||||
}
|
||||
|
||||
if (state.designatedCorner != currentViewState.designatedCorner) {
|
||||
currentViewState.designatedCorner?.contentDescription = null
|
||||
state.designatedCorner?.contentDescription = state.contentDescription
|
||||
|
||||
updateDesignatedCorner(state.designatedCorner, state.shouldShowDot())
|
||||
} else if (state.contentDescription != currentViewState.contentDescription) {
|
||||
state.designatedCorner?.contentDescription = state.contentDescription
|
||||
}
|
||||
|
||||
val shouldShow = state.shouldShowDot()
|
||||
@@ -514,9 +519,13 @@ class PrivacyDotViewController @Inject constructor(
|
||||
|
||||
private val systemStatusAnimationCallback: SystemStatusAnimationCallback =
|
||||
object : SystemStatusAnimationCallback {
|
||||
override fun onSystemStatusAnimationTransitionToPersistentDot(): Animator? {
|
||||
override fun onSystemStatusAnimationTransitionToPersistentDot(
|
||||
contentDescr: String?
|
||||
): Animator? {
|
||||
synchronized(lock) {
|
||||
nextViewState = nextViewState.copy(systemPrivacyEventIsActive = true)
|
||||
nextViewState = nextViewState.copy(
|
||||
systemPrivacyEventIsActive = true,
|
||||
contentDescription = contentDescr)
|
||||
}
|
||||
|
||||
return null
|
||||
@@ -620,7 +629,9 @@ private data class ViewState(
|
||||
val rotation: Int = 0,
|
||||
val height: Int = 0,
|
||||
val cornerIndex: Int = -1,
|
||||
val designatedCorner: View? = null
|
||||
val designatedCorner: View? = null,
|
||||
|
||||
val contentDescription: String? = null
|
||||
) {
|
||||
fun shouldShowDot(): Boolean {
|
||||
return systemPrivacyEventIsActive && !shadeExpanded && !qsExpanded
|
||||
|
||||
@@ -34,6 +34,7 @@ interface StatusEvent {
|
||||
// Whether or not to show an animation for this event
|
||||
val showAnimation: Boolean
|
||||
val viewCreator: (context: Context) -> View
|
||||
var contentDescription: String?
|
||||
|
||||
// Update this event with values from another event.
|
||||
fun updateFromEvent(other: StatusEvent?) {
|
||||
@@ -50,6 +51,7 @@ class BatteryEvent : StatusEvent {
|
||||
override val priority = 50
|
||||
override val forceVisible = false
|
||||
override val showAnimation = true
|
||||
override var contentDescription: String? = ""
|
||||
|
||||
override val viewCreator: (context: Context) -> View = { context ->
|
||||
val iv = ImageView(context)
|
||||
@@ -62,7 +64,9 @@ class BatteryEvent : StatusEvent {
|
||||
return javaClass.simpleName
|
||||
}
|
||||
}
|
||||
|
||||
class PrivacyEvent(override val showAnimation: Boolean = true) : StatusEvent {
|
||||
override var contentDescription: String? = null
|
||||
override val priority = 100
|
||||
override val forceVisible = true
|
||||
var privacyItems: List<PrivacyItem> = listOf()
|
||||
@@ -72,6 +76,7 @@ class PrivacyEvent(override val showAnimation: Boolean = true) : StatusEvent {
|
||||
val v = LayoutInflater.from(context)
|
||||
.inflate(R.layout.ongoing_privacy_chip, null) as OngoingPrivacyChip
|
||||
v.privacyList = privacyItems
|
||||
v.contentDescription = contentDescription
|
||||
privacyChip = v
|
||||
v
|
||||
}
|
||||
@@ -81,7 +86,9 @@ class PrivacyEvent(override val showAnimation: Boolean = true) : StatusEvent {
|
||||
}
|
||||
|
||||
override fun shouldUpdateFromEvent(other: StatusEvent?): Boolean {
|
||||
return other is PrivacyEvent && other.privacyItems != privacyItems
|
||||
return other is PrivacyEvent &&
|
||||
(other.privacyItems != privacyItems ||
|
||||
other.contentDescription != contentDescription)
|
||||
}
|
||||
|
||||
override fun updateFromEvent(other: StatusEvent?) {
|
||||
@@ -90,6 +97,9 @@ class PrivacyEvent(override val showAnimation: Boolean = true) : StatusEvent {
|
||||
}
|
||||
|
||||
privacyItems = other.privacyItems
|
||||
contentDescription = other.contentDescription
|
||||
|
||||
privacyChip?.contentDescription = other.contentDescription
|
||||
privacyChip?.privacyList = other.privacyItems
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,8 +34,7 @@ import com.android.systemui.statusbar.phone.StatusBarWindowView
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* //TODO: this _probably_ doesn't control a window anymore
|
||||
* Controls the window for system event animations.
|
||||
* Controls the view for system event animations.
|
||||
*/
|
||||
class SystemEventChipAnimationController @Inject constructor(
|
||||
private val context: Context,
|
||||
|
||||
@@ -16,9 +16,12 @@
|
||||
|
||||
package com.android.systemui.statusbar.events
|
||||
|
||||
import android.content.Context
|
||||
import android.provider.DeviceConfig
|
||||
import android.provider.DeviceConfig.NAMESPACE_PRIVACY
|
||||
import com.android.systemui.R
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import com.android.systemui.privacy.PrivacyChipBuilder
|
||||
import com.android.systemui.privacy.PrivacyItem
|
||||
import com.android.systemui.privacy.PrivacyItemController
|
||||
import com.android.systemui.statusbar.policy.BatteryController
|
||||
@@ -33,7 +36,8 @@ import javax.inject.Inject
|
||||
class SystemEventCoordinator @Inject constructor(
|
||||
private val systemClock: SystemClock,
|
||||
private val batteryController: BatteryController,
|
||||
private val privacyController: PrivacyItemController
|
||||
private val privacyController: PrivacyItemController,
|
||||
private val context: Context
|
||||
) {
|
||||
private lateinit var scheduler: SystemStatusAnimationScheduler
|
||||
|
||||
@@ -66,6 +70,11 @@ class SystemEventCoordinator @Inject constructor(
|
||||
fun notifyPrivacyItemsChanged(showAnimation: Boolean = true) {
|
||||
val event = PrivacyEvent(showAnimation)
|
||||
event.privacyItems = privacyStateListener.currentPrivacyItems
|
||||
event.contentDescription = {
|
||||
val items = PrivacyChipBuilder(context, event.privacyItems).joinTypes()
|
||||
context.getString(
|
||||
R.string.ongoing_privacy_chip_content_multiple_apps, items)
|
||||
}()
|
||||
scheduler.onStatusEvent(event)
|
||||
}
|
||||
|
||||
|
||||
@@ -100,17 +100,20 @@ class SystemStatusAnimationScheduler @Inject constructor(
|
||||
|
||||
// Don't deal with threading for now (no need let's be honest)
|
||||
Assert.isMainThread()
|
||||
if (event.priority > scheduledEvent?.priority ?: -1 ||
|
||||
scheduledEvent?.shouldUpdateFromEvent(event) == true) {
|
||||
if ((event.priority > scheduledEvent?.priority ?: -1) &&
|
||||
animationState != ANIMATING_OUT &&
|
||||
(animationState != SHOWING_PERSISTENT_DOT && event.forceVisible)) {
|
||||
// events can only be scheduled if a higher priority or no other event is in progress
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "scheduling event $event")
|
||||
}
|
||||
if (event.showAnimation) {
|
||||
scheduleEvent(event)
|
||||
} else if (event.forceVisible) {
|
||||
hasPersistentDot = true
|
||||
notifyTransitionToPersistentDot()
|
||||
|
||||
scheduleEvent(event)
|
||||
} else if (scheduledEvent?.shouldUpdateFromEvent(event) == true) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "updating current event from: $event")
|
||||
}
|
||||
scheduledEvent?.updateFromEvent(event)
|
||||
} else {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "ignoring event $event")
|
||||
@@ -142,24 +145,18 @@ class SystemStatusAnimationScheduler @Inject constructor(
|
||||
* Clear the scheduled event (if any) and schedule a new one
|
||||
*/
|
||||
private fun scheduleEvent(event: StatusEvent) {
|
||||
if (animationState == ANIMATING_OUT ||
|
||||
(animationState == SHOWING_PERSISTENT_DOT && event.forceVisible)) {
|
||||
// do not schedule an event or change the current one
|
||||
return
|
||||
}
|
||||
scheduledEvent = event
|
||||
|
||||
// If we are showing the chip, possibly update the current event, rather than replacing
|
||||
if (scheduledEvent?.shouldUpdateFromEvent(event) == true) {
|
||||
scheduledEvent?.updateFromEvent(event)
|
||||
return
|
||||
} else {
|
||||
scheduledEvent = event
|
||||
}
|
||||
|
||||
if (scheduledEvent!!.forceVisible) {
|
||||
if (event.forceVisible) {
|
||||
hasPersistentDot = true
|
||||
}
|
||||
|
||||
// If animations are turned off, we'll transition directly to the dot
|
||||
if (!event.showAnimation && event.forceVisible) {
|
||||
notifyTransitionToPersistentDot()
|
||||
return
|
||||
}
|
||||
|
||||
// Schedule the animation to start after a debounce period
|
||||
cancelExecutionRunnable = executor.executeDelayed({
|
||||
cancelExecutionRunnable = null
|
||||
@@ -218,7 +215,7 @@ class SystemStatusAnimationScheduler @Inject constructor(
|
||||
|
||||
private fun notifyTransitionToPersistentDot(): Animator? {
|
||||
val anims: List<Animator> = listeners.mapNotNull {
|
||||
it.onSystemStatusAnimationTransitionToPersistentDot()
|
||||
it.onSystemStatusAnimationTransitionToPersistentDot(scheduledEvent?.contentDescription)
|
||||
}
|
||||
if (anims.isNotEmpty()) {
|
||||
val aSet = AnimatorSet()
|
||||
@@ -346,7 +343,10 @@ interface SystemStatusAnimationCallback {
|
||||
@JvmDefault fun onSystemChromeAnimationEnd() {}
|
||||
|
||||
// Best method name, change my mind
|
||||
@JvmDefault fun onSystemStatusAnimationTransitionToPersistentDot(): Animator? { return null }
|
||||
@JvmDefault
|
||||
fun onSystemStatusAnimationTransitionToPersistentDot(contentDescription: String?): Animator? {
|
||||
return null
|
||||
}
|
||||
@JvmDefault fun onHidePersistentDot(): Animator? { return null }
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user