summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Fabian Kozynski <kozynski@google.com> 2022-09-06 16:42:27 +0000
committer Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> 2022-09-06 16:42:27 +0000
commitff04c8b4d477b85fd6d32ea4e7dd95d3fb206693 (patch)
treebfa9ca1cf18f2229f7ee5c12cfa474b35c797f29
parent0d5367cd2c27afd9a55d0c9afc4bb599306b0d82 (diff)
parent54dd46a8142d5d00375d0f17c035d6b3c66c0c19 (diff)
Merge "Make disabled by policy tiles look UNAVAILABLE" into tm-qpr-dev am: 54dd46a814
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19802196 Change-Id: I41fd0ba7950495059e63cb199078bb9e63b8ab57 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--packages/SystemUI/res/values/strings.xml5
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java29
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt93
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSIconViewImplTest.java16
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt84
6 files changed, 178 insertions, 53 deletions
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index b33cea7fe22e..df6486abb083 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1644,8 +1644,9 @@
<!-- The tile in quick settings is unavailable. [CHAR LIMIT=32] -->
<string name="tile_unavailable">Unavailable</string>
- <!-- The tile in quick settings is disabled by a device administration policy [CHAR LIMIT=32] -->
- <string name="tile_disabled">Disabled</string>
+ <!-- Accessibility text for the click action on a tile that is disabled by policy. This will
+ be used following "Double-tap to..." [CHAR LIMIT=NONE] -->
+ <string name="accessibility_tile_disabled_by_policy_action_description">learn more</string>
<!-- SysUI Tuner: Button that leads to the navigation bar customization screen [CHAR LIMIT=60] -->
<string name="nav_bar">Navigation bar</string>
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java
index be6982ab2470..58426656e4bf 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java
@@ -165,7 +165,7 @@ public class QSIconViewImpl extends QSIconView {
iv.clearColorFilter();
}
if (state.state != mState) {
- int color = getColor(state.state);
+ int color = getColor(state);
mState = state.state;
if (mTint != 0 && allowAnimations && shouldAnimate(iv)) {
animateGrayScale(mTint, color, iv, () -> updateIcon(iv, state, allowAnimations));
@@ -183,7 +183,7 @@ public class QSIconViewImpl extends QSIconView {
}
}
- protected int getColor(int state) {
+ protected int getColor(QSTile.State state) {
return getIconColorForState(getContext(), state);
}
@@ -239,19 +239,18 @@ public class QSIconViewImpl extends QSIconView {
/**
* Color to tint the tile icon based on state
*/
- public static int getIconColorForState(Context context, int state) {
- switch (state) {
- case Tile.STATE_UNAVAILABLE:
- return Utils.applyAlpha(QSTileViewImpl.UNAVAILABLE_ALPHA,
- Utils.getColorAttrDefaultColor(context, android.R.attr.textColorPrimary));
- case Tile.STATE_INACTIVE:
- return Utils.getColorAttrDefaultColor(context, android.R.attr.textColorPrimary);
- case Tile.STATE_ACTIVE:
- return Utils.getColorAttrDefaultColor(context,
- com.android.internal.R.attr.textColorOnAccent);
- default:
- Log.e("QSIconView", "Invalid state " + state);
- return 0;
+ private static int getIconColorForState(Context context, QSTile.State state) {
+ if (state.disabledByPolicy || state.state == Tile.STATE_UNAVAILABLE) {
+ return Utils.applyAlpha(QSTileViewImpl.UNAVAILABLE_ALPHA,
+ Utils.getColorAttrDefaultColor(context, android.R.attr.textColorPrimary));
+ } else if (state.state == Tile.STATE_INACTIVE) {
+ return Utils.getColorAttrDefaultColor(context, android.R.attr.textColorPrimary);
+ } else if (state.state == Tile.STATE_ACTIVE) {
+ return Utils.getColorAttrDefaultColor(context,
+ com.android.internal.R.attr.textColorOnAccent);
+ } else {
+ Log.e("QSIconView", "Invalid state " + state);
+ return 0;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
index 2731d64ee4e7..163ee2af600c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
@@ -35,6 +35,7 @@ import android.view.View
import android.view.ViewGroup
import android.view.accessibility.AccessibilityEvent
import android.view.accessibility.AccessibilityNodeInfo
+import android.widget.Button
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.Switch
@@ -144,6 +145,7 @@ open class QSTileViewImpl @JvmOverloads constructor(
superSetVisibility = { super.setVisibility(it) },
superSetTransitionVisibility = { super.setTransitionVisibility(it) },
)
+ private var lastDisabledByPolicy = false
private val locInScreen = IntArray(2)
@@ -376,8 +378,22 @@ open class QSTileViewImpl @JvmOverloads constructor(
super.onInitializeAccessibilityNodeInfo(info)
// Clear selected state so it is not announce by talkback.
info.isSelected = false
+ if (lastDisabledByPolicy) {
+ info.addAction(
+ AccessibilityNodeInfo.AccessibilityAction(
+ AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK.id,
+ resources.getString(
+ R.string.accessibility_tile_disabled_by_policy_action_description
+ )
+ )
+ )
+ }
if (!TextUtils.isEmpty(accessibilityClass)) {
- info.className = accessibilityClass
+ info.className = if (lastDisabledByPolicy) {
+ Button::class.java.name
+ } else {
+ accessibilityClass
+ }
if (Switch::class.java.name == accessibilityClass) {
val label = resources.getString(
if (tileState) R.string.switch_bar_on else R.string.switch_bar_off)
@@ -430,6 +446,10 @@ open class QSTileViewImpl @JvmOverloads constructor(
state.secondaryLabel = stateText
}
}
+ if (state.disabledByPolicy && state.state != Tile.STATE_UNAVAILABLE) {
+ stateDescription.append(", ")
+ stateDescription.append(getUnavailableText(state.spec))
+ }
if (!TextUtils.isEmpty(state.stateDescription)) {
stateDescription.append(", ")
stateDescription.append(state.stateDescription)
@@ -470,38 +490,38 @@ open class QSTileViewImpl @JvmOverloads constructor(
}
// Colors
- if (state.state != lastState) {
+ if (state.state != lastState || state.disabledByPolicy || lastDisabledByPolicy) {
singleAnimator.cancel()
if (allowAnimations) {
singleAnimator.setValues(
colorValuesHolder(
BACKGROUND_NAME,
paintColor,
- getBackgroundColorForState(state.state)
+ getBackgroundColorForState(state.state, state.disabledByPolicy)
),
colorValuesHolder(
LABEL_NAME,
label.currentTextColor,
- getLabelColorForState(state.state)
+ getLabelColorForState(state.state, state.disabledByPolicy)
),
colorValuesHolder(
SECONDARY_LABEL_NAME,
secondaryLabel.currentTextColor,
- getSecondaryLabelColorForState(state.state)
+ getSecondaryLabelColorForState(state.state, state.disabledByPolicy)
),
colorValuesHolder(
CHEVRON_NAME,
chevronView.imageTintList?.defaultColor ?: 0,
- getChevronColorForState(state.state)
+ getChevronColorForState(state.state, state.disabledByPolicy)
)
)
singleAnimator.start()
} else {
setAllColors(
- getBackgroundColorForState(state.state),
- getLabelColorForState(state.state),
- getSecondaryLabelColorForState(state.state),
- getChevronColorForState(state.state)
+ getBackgroundColorForState(state.state, state.disabledByPolicy),
+ getLabelColorForState(state.state, state.disabledByPolicy),
+ getSecondaryLabelColorForState(state.state, state.disabledByPolicy),
+ getChevronColorForState(state.state, state.disabledByPolicy)
)
}
}
@@ -512,6 +532,7 @@ open class QSTileViewImpl @JvmOverloads constructor(
label.isEnabled = !state.disabledByPolicy
lastState = state.state
+ lastDisabledByPolicy = state.disabledByPolicy
}
private fun setAllColors(
@@ -559,13 +580,14 @@ open class QSTileViewImpl @JvmOverloads constructor(
}
}
- private fun getStateText(state: QSTile.State): String {
- if (state.disabledByPolicy) {
- return context.getString(R.string.tile_disabled)
- }
+ private fun getUnavailableText(spec: String?): String {
+ val arrayResId = SubtitleArrayMapping.getSubtitleId(spec)
+ return resources.getStringArray(arrayResId)[Tile.STATE_UNAVAILABLE]
+ }
+ private fun getStateText(state: QSTile.State): String {
return if (state.state == Tile.STATE_UNAVAILABLE || state is BooleanState) {
- var arrayResId = SubtitleArrayMapping.getSubtitleId(state.spec)
+ val arrayResId = SubtitleArrayMapping.getSubtitleId(state.spec)
val array = resources.getStringArray(arrayResId)
array[state.state]
} else {
@@ -587,11 +609,11 @@ open class QSTileViewImpl @JvmOverloads constructor(
return locInScreen.get(1) >= -height
}
- private fun getBackgroundColorForState(state: Int): Int {
- return when (state) {
- Tile.STATE_ACTIVE -> colorActive
- Tile.STATE_INACTIVE -> colorInactive
- Tile.STATE_UNAVAILABLE -> colorUnavailable
+ private fun getBackgroundColorForState(state: Int, disabledByPolicy: Boolean = false): Int {
+ return when {
+ state == Tile.STATE_UNAVAILABLE || disabledByPolicy -> colorUnavailable
+ state == Tile.STATE_ACTIVE -> colorActive
+ state == Tile.STATE_INACTIVE -> colorInactive
else -> {
Log.e(TAG, "Invalid state $state")
0
@@ -599,11 +621,11 @@ open class QSTileViewImpl @JvmOverloads constructor(
}
}
- private fun getLabelColorForState(state: Int): Int {
- return when (state) {
- Tile.STATE_ACTIVE -> colorLabelActive
- Tile.STATE_INACTIVE -> colorLabelInactive
- Tile.STATE_UNAVAILABLE -> colorLabelUnavailable
+ private fun getLabelColorForState(state: Int, disabledByPolicy: Boolean = false): Int {
+ return when {
+ state == Tile.STATE_UNAVAILABLE || disabledByPolicy -> colorLabelUnavailable
+ state == Tile.STATE_ACTIVE -> colorLabelActive
+ state == Tile.STATE_INACTIVE -> colorLabelInactive
else -> {
Log.e(TAG, "Invalid state $state")
0
@@ -611,11 +633,11 @@ open class QSTileViewImpl @JvmOverloads constructor(
}
}
- private fun getSecondaryLabelColorForState(state: Int): Int {
- return when (state) {
- Tile.STATE_ACTIVE -> colorSecondaryLabelActive
- Tile.STATE_INACTIVE -> colorSecondaryLabelInactive
- Tile.STATE_UNAVAILABLE -> colorSecondaryLabelUnavailable
+ private fun getSecondaryLabelColorForState(state: Int, disabledByPolicy: Boolean = false): Int {
+ return when {
+ state == Tile.STATE_UNAVAILABLE || disabledByPolicy -> colorSecondaryLabelUnavailable
+ state == Tile.STATE_ACTIVE -> colorSecondaryLabelActive
+ state == Tile.STATE_INACTIVE -> colorSecondaryLabelInactive
else -> {
Log.e(TAG, "Invalid state $state")
0
@@ -623,7 +645,16 @@ open class QSTileViewImpl @JvmOverloads constructor(
}
}
- private fun getChevronColorForState(state: Int): Int = getSecondaryLabelColorForState(state)
+ private fun getChevronColorForState(state: Int, disabledByPolicy: Boolean = false): Int =
+ getSecondaryLabelColorForState(state, disabledByPolicy)
+
+ @VisibleForTesting
+ internal fun getCurrentColors(): List<Int> = listOf(
+ paintColor,
+ label.currentTextColor,
+ secondaryLabel.currentTextColor,
+ chevronView.imageTintList?.defaultColor ?: 0
+ )
}
@VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
index e910f725a4a6..619e50b47f13 100644
--- a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
@@ -27,6 +27,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.res.ColorStateList;
import android.graphics.Canvas;
+import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
@@ -58,7 +59,6 @@ import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.logging.QSLogger;
-import com.android.systemui.qs.tileimpl.QSIconViewImpl;
import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.util.concurrency.DelayableExecutor;
import com.android.systemui.util.concurrency.MessageRouter;
@@ -304,7 +304,7 @@ public class GarbageMonitor implements Dumpable {
MemoryIconDrawable(Context context) {
baseIcon = context.getDrawable(R.drawable.ic_memory).mutate();
dp = context.getResources().getDisplayMetrics().density;
- paint.setColor(QSIconViewImpl.getIconColorForState(context, STATE_ACTIVE));
+ paint.setColor(Color.WHITE);
}
public void setRss(long rss) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSIconViewImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSIconViewImplTest.java
index 23e51687f9e1..2c76be64aa7c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSIconViewImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSIconViewImplTest.java
@@ -97,7 +97,7 @@ public class QSIconViewImplTest extends SysuiTestCase {
ImageView iv = mock(ImageView.class);
State s = new State();
s.state = Tile.STATE_ACTIVE;
- int desiredColor = mIconView.getColor(s.state);
+ int desiredColor = mIconView.getColor(s);
when(iv.isShown()).thenReturn(true);
mIconView.setIcon(iv, s, true);
@@ -109,7 +109,7 @@ public class QSIconViewImplTest extends SysuiTestCase {
ImageView iv = mock(ImageView.class);
State s = new State();
s.state = Tile.STATE_ACTIVE;
- int desiredColor = mIconView.getColor(s.state);
+ int desiredColor = mIconView.getColor(s);
Icon i = mock(Icon.class);
s.icon = i;
when(i.toString()).thenReturn("MOCK ICON");
@@ -124,6 +124,18 @@ public class QSIconViewImplTest extends SysuiTestCase {
assertFalse(mIconView.toString().contains("lastIcon"));
}
+ @Test
+ public void testIconColorDisabledByPolicy_sameAsUnavailable() {
+ State s1 = new State();
+ s1.state = Tile.STATE_INACTIVE;
+ s1.disabledByPolicy = true;
+
+ State s2 = new State();
+ s2.state = Tile.STATE_UNAVAILABLE;
+
+ assertEquals(mIconView.getColor(s1), mIconView.getColor(s2));
+ }
+
private static Drawable.ConstantState fakeConstantState(Drawable otherDrawable) {
return new Drawable.ConstantState() {
@Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt
index 9fdc2fd60870..d3ec1dd8bfb2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt
@@ -280,6 +280,88 @@ class QSTileViewImplTest : SysuiTestCase() {
assertThat(info.collectionItemInfo).isNull()
}
+ @Test
+ fun testDisabledByPolicyInactive_usesUnavailableColors() {
+ val stateDisabledByPolicy = QSTile.State()
+ stateDisabledByPolicy.state = Tile.STATE_INACTIVE
+ stateDisabledByPolicy.disabledByPolicy = true
+
+ val stateUnavailable = QSTile.State()
+ stateUnavailable.state = Tile.STATE_UNAVAILABLE
+
+ tileView.changeState(stateDisabledByPolicy)
+ val colorsDisabledByPolicy = tileView.getCurrentColors()
+
+ tileView.changeState(stateUnavailable)
+ val colorsUnavailable = tileView.getCurrentColors()
+
+ assertThat(colorsDisabledByPolicy).containsExactlyElementsIn(colorsUnavailable)
+ }
+
+ @Test
+ fun testDisabledByPolicyActive_usesUnavailableColors() {
+ val stateDisabledByPolicy = QSTile.State()
+ stateDisabledByPolicy.state = Tile.STATE_ACTIVE
+ stateDisabledByPolicy.disabledByPolicy = true
+
+ val stateUnavailable = QSTile.State()
+ stateUnavailable.state = Tile.STATE_UNAVAILABLE
+
+ tileView.changeState(stateDisabledByPolicy)
+ val colorsDisabledByPolicy = tileView.getCurrentColors()
+
+ tileView.changeState(stateUnavailable)
+ val colorsUnavailable = tileView.getCurrentColors()
+
+ assertThat(colorsDisabledByPolicy).containsExactlyElementsIn(colorsUnavailable)
+ }
+
+ @Test
+ fun testDisabledByPolicy_secondaryLabelText() {
+ val testA11yLabel = "TEST_LABEL"
+ context.orCreateTestableResources
+ .addOverride(
+ R.string.accessibility_tile_disabled_by_policy_action_description,
+ testA11yLabel
+ )
+
+ val stateDisabledByPolicy = QSTile.State()
+ stateDisabledByPolicy.state = Tile.STATE_INACTIVE
+ stateDisabledByPolicy.disabledByPolicy = true
+
+ tileView.changeState(stateDisabledByPolicy)
+
+ val info = AccessibilityNodeInfo(tileView)
+ tileView.onInitializeAccessibilityNodeInfo(info)
+ assertThat(
+ info.actionList.find {
+ it.id == AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK.id
+ }?.label
+ ).isEqualTo(testA11yLabel)
+ }
+
+ @Test
+ fun testDisabledByPolicy_unavailableInStateDescription() {
+ val state = QSTile.BooleanState()
+ val spec = "internet"
+ state.spec = spec
+ state.disabledByPolicy = true
+ state.state = Tile.STATE_INACTIVE
+
+ val unavailableString = "${spec}_unavailable"
+ val offString = "${spec}_off"
+ val onString = "${spec}_on"
+
+ context.orCreateTestableResources.addOverride(R.array.tile_states_internet, arrayOf(
+ unavailableString,
+ offString,
+ onString
+ ))
+
+ tileView.changeState(state)
+ assertThat(tileView.stateDescription?.contains(unavailableString)).isTrue()
+ }
+
class FakeTileView(
context: Context,
icon: QSIconView,
@@ -289,4 +371,4 @@ class QSTileViewImplTest : SysuiTestCase() {
handleStateChanged(state)
}
}
-} \ No newline at end of file
+}