diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
index 01811e9cdcedc..f607cc8f7e156 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
@@ -118,6 +118,7 @@ public interface QSTile {
public CharSequence label;
public CharSequence secondaryLabel;
public CharSequence contentDescription;
+ public CharSequence stateDescription;
public CharSequence dualLabelContentDescription;
public boolean disabledByPolicy;
public boolean dualTarget = false;
@@ -135,6 +136,7 @@ public interface QSTile {
|| !Objects.equals(other.label, label)
|| !Objects.equals(other.secondaryLabel, secondaryLabel)
|| !Objects.equals(other.contentDescription, contentDescription)
+ || !Objects.equals(other.stateDescription, stateDescription)
|| !Objects.equals(other.dualLabelContentDescription,
dualLabelContentDescription)
|| !Objects.equals(other.expandedAccessibilityClassName,
@@ -151,6 +153,7 @@ public interface QSTile {
other.label = label;
other.secondaryLabel = secondaryLabel;
other.contentDescription = contentDescription;
+ other.stateDescription = stateDescription;
other.dualLabelContentDescription = dualLabelContentDescription;
other.expandedAccessibilityClassName = expandedAccessibilityClassName;
other.disabledByPolicy = disabledByPolicy;
@@ -177,6 +180,7 @@ public interface QSTile {
sb.append(",label=").append(label);
sb.append(",secondaryLabel=").append(secondaryLabel);
sb.append(",contentDescription=").append(contentDescription);
+ sb.append(",stateDescription=").append(stateDescription);
sb.append(",dualLabelContentDescription=").append(dualLabelContentDescription);
sb.append(",expandedAccessibilityClassName=").append(expandedAccessibilityClassName);
sb.append(",disabledByPolicy=").append(disabledByPolicy);
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index ebaf55fd7e9ce..8f9e934c97e53 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2032,6 +2032,9 @@
Off
+
+ Unavailable
+
Navigation bar
@@ -2586,6 +2589,4 @@
Controls
Choose controls for quick access
-
-
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
index ae6162219afa8..c118630fe91a1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
@@ -191,6 +191,7 @@ public class CustomTile extends QSTileImpl implements TileChangeListener
mTile.setLabel(tile.getLabel());
mTile.setSubtitle(tile.getSubtitle());
mTile.setContentDescription(tile.getContentDescription());
+ mTile.setStateDescription(tile.getStateDescription());
mTile.setState(tile.getState());
}
@@ -345,6 +346,12 @@ public class CustomTile extends QSTileImpl implements TileChangeListener
state.contentDescription = state.label;
}
+ if (mTile.getStateDescription() != null) {
+ state.stateDescription = mTile.getStateDescription();
+ } else {
+ state.stateDescription = null;
+ }
+
if (state instanceof BooleanState) {
state.expandedAccessibilityClassName = Switch.class.getName();
((BooleanState) state).value = (state.state == Tile.STATE_ACTIVE);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java
index 2fe64d26f3acd..8feee10c7e834 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java
@@ -63,7 +63,6 @@ public class QSTileBaseView extends com.android.systemui.plugins.qs.QSTileView {
private String mAccessibilityClass;
private boolean mTileState;
private boolean mCollapsedView;
- private boolean mClicked;
private boolean mShowRippleEffect = true;
private final ImageView mBg;
@@ -230,13 +229,35 @@ public class QSTileBaseView extends com.android.systemui.plugins.qs.QSTileView {
setLongClickable(state.handlesLongClick);
mIcon.setIcon(state, allowAnimations);
setContentDescription(state.contentDescription);
+ final StringBuilder stateDescription = new StringBuilder();
+ switch (state.state) {
+ case Tile.STATE_UNAVAILABLE:
+ stateDescription.append(mContext.getString(R.string.tile_unavailable));
+ break;
+ case Tile.STATE_INACTIVE:
+ if (state instanceof QSTile.BooleanState) {
+ stateDescription.append(mContext.getString(R.string.switch_bar_off));
+ }
+ break;
+ case Tile.STATE_ACTIVE:
+ if (state instanceof QSTile.BooleanState) {
+ stateDescription.append(mContext.getString(R.string.switch_bar_on));
+ }
+ break;
+ default:
+ break;
+ }
+ if (!TextUtils.isEmpty(state.stateDescription)) {
+ stateDescription.append(", ");
+ stateDescription.append(state.stateDescription);
+ }
+ setStateDescription(stateDescription.toString());
mAccessibilityClass =
state.state == Tile.STATE_UNAVAILABLE ? null : state.expandedAccessibilityClassName;
if (state instanceof QSTile.BooleanState) {
boolean newState = ((BooleanState) state).value;
if (mTileState != newState) {
- mClicked = false;
mTileState = newState;
}
}
@@ -287,24 +308,11 @@ public class QSTileBaseView extends com.android.systemui.plugins.qs.QSTileView {
return mIconFrame;
}
- @Override
- public boolean performClick() {
- mClicked = true;
- return super.performClick();
- }
-
@Override
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
super.onInitializeAccessibilityEvent(event);
if (!TextUtils.isEmpty(mAccessibilityClass)) {
event.setClassName(mAccessibilityClass);
- if (Switch.class.getName().equals(mAccessibilityClass)) {
- boolean b = mClicked ? !mTileState : mTileState;
- String label = getResources()
- .getString(b ? R.string.switch_bar_on : R.string.switch_bar_off);
- event.setContentDescription(label);
- event.setChecked(b);
- }
}
}
@@ -316,11 +324,13 @@ public class QSTileBaseView extends com.android.systemui.plugins.qs.QSTileView {
if (!TextUtils.isEmpty(mAccessibilityClass)) {
info.setClassName(mAccessibilityClass);
if (Switch.class.getName().equals(mAccessibilityClass)) {
- boolean b = mClicked ? !mTileState : mTileState;
- String label = getResources()
- .getString(b ? R.string.switch_bar_on : R.string.switch_bar_off);
+ String label = getResources().getString(
+ mTileState ? R.string.switch_bar_on : R.string.switch_bar_off);
+ // Set the text here for tests in
+ // android.platform.test.scenario.sysui.quicksettings. Can be removed when
+ // UiObject2 has a new getStateDescription() API and tests are updated.
info.setText(label);
- info.setChecked(b);
+ info.setChecked(mTileState);
info.setCheckable(true);
if (isLongClickable()) {
info.addAction(
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index 9282a2e3b3121..361b6c1b12600 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -134,25 +134,27 @@ public class BluetoothTile extends QSTileImpl {
state.label = mContext.getString(R.string.quick_settings_bluetooth_label);
state.secondaryLabel = TextUtils.emptyIfNull(
getSecondaryLabel(enabled, connecting, connected, state.isTransient));
+ state.contentDescription = state.label;
+ state.stateDescription = "";
if (enabled) {
if (connected) {
state.icon = new BluetoothConnectedTileIcon();
if (!TextUtils.isEmpty(mController.getConnectedDeviceName())) {
state.label = mController.getConnectedDeviceName();
}
- state.contentDescription =
+ state.stateDescription =
mContext.getString(R.string.accessibility_bluetooth_name, state.label)
+ ", " + state.secondaryLabel;
} else if (state.isTransient) {
state.icon = ResourceIcon.get(
com.android.internal.R.drawable.ic_bluetooth_transient_animation);
- state.contentDescription = state.secondaryLabel;
+ state.stateDescription = state.secondaryLabel;
} else {
state.icon =
ResourceIcon.get(com.android.internal.R.drawable.ic_qs_bluetooth);
state.contentDescription = mContext.getString(
- R.string.accessibility_quick_settings_bluetooth) + ","
- + mContext.getString(R.string.accessibility_not_connected);
+ R.string.accessibility_quick_settings_bluetooth);
+ state.stateDescription = mContext.getString(R.string.accessibility_not_connected);
}
state.state = Tile.STATE_ACTIVE;
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index 32b051e356040..58de0575fa753 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -183,6 +183,7 @@ public class CastTile extends QSTileImpl {
protected void handleUpdateState(BooleanState state, Object arg) {
state.label = mContext.getString(R.string.quick_settings_cast_title);
state.contentDescription = state.label;
+ state.stateDescription = "";
state.value = false;
final List devices = mController.getCastDevices();
boolean connecting = false;
@@ -192,8 +193,9 @@ public class CastTile extends QSTileImpl {
if (device.state == CastDevice.STATE_CONNECTED) {
state.value = true;
state.secondaryLabel = getDeviceName(device);
- state.contentDescription = state.contentDescription + ","
- + mContext.getString(R.string.accessibility_cast_name, state.label);
+ state.stateDescription = state.stateDescription + ","
+ + mContext.getString(
+ R.string.accessibility_cast_name, state.label);
connecting = false;
break;
} else if (device.state == CastDevice.STATE_CONNECTING) {
@@ -217,9 +219,8 @@ public class CastTile extends QSTileImpl {
state.state = Tile.STATE_UNAVAILABLE;
String noWifi = mContext.getString(R.string.quick_settings_cast_no_wifi);
state.secondaryLabel = noWifi;
- state.contentDescription = state.contentDescription + ", " + mContext.getString(
- R.string.accessibility_quick_settings_not_available, noWifi);
}
+ state.stateDescription = state.stateDescription + ", " + state.secondaryLabel;
mDetailAdapter.updateItems(devices);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index 22470c7f5af59..d5f86c9514072 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -194,17 +194,13 @@ public class CellularTile extends QSTileImpl {
state.secondaryLabel = r.getString(R.string.cell_data_off);
}
-
- // TODO(b/77881974): Instead of switching out the description via a string check for
- // we need to have two strings provided by the MobileIconGroup.
- final CharSequence contentDescriptionSuffix;
+ state.contentDescription = state.label;
if (state.state == Tile.STATE_INACTIVE) {
- contentDescriptionSuffix = r.getString(R.string.cell_data_off_content_description);
+ // This information is appended later by converting the Tile.STATE_INACTIVE state.
+ state.stateDescription = "";
} else {
- contentDescriptionSuffix = state.secondaryLabel;
+ state.stateDescription = state.secondaryLabel;
}
-
- state.contentDescription = state.label + ", " + contentDescriptionSuffix;
}
private CharSequence appendMobileDataType(CharSequence current, CharSequence dataType) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index 52d1a5b3b9910..9215da4cda9a3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -240,6 +240,8 @@ public class DndTile extends QSTileImpl {
zen != Global.ZEN_MODE_OFF, mController.getConfig(), false));
state.icon = ResourceIcon.get(com.android.internal.R.drawable.ic_qs_dnd);
checkIfRestrictionEnforcedByAdminOnly(state, UserManager.DISALLOW_ADJUST_VOLUME);
+ // Keeping the secondaryLabel in contentDescription instead of stateDescription is easier
+ // to understand.
switch (zen) {
case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
state.contentDescription =
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
index dafdd89ee62c5..792c364779621 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
@@ -102,14 +102,13 @@ public class FlashlightTile extends QSTileImpl implements
}
state.label = mHost.getContext().getString(R.string.quick_settings_flashlight_label);
state.secondaryLabel = "";
+ state.stateDescription = "";
if (!mFlashlightController.isAvailable()) {
state.icon = mIcon;
state.slash.isSlashed = true;
state.secondaryLabel = mContext.getString(
R.string.quick_settings_flashlight_camera_in_use);
- state.contentDescription = mContext.getString(
- R.string.accessibility_quick_settings_flashlight_unavailable)
- + ", " + state.secondaryLabel;
+ state.stateDescription = state.secondaryLabel;
state.state = Tile.STATE_UNAVAILABLE;
return;
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
index 42f80109e0453..91b3ae480af96 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
@@ -148,6 +148,7 @@ public class HotspotTile extends QSTileImpl {
state.secondaryLabel = getSecondaryLabel(
isTileActive, isTransient, isDataSaverEnabled, numConnectedDevices);
+ state.stateDescription = state.secondaryLabel;
}
@Nullable
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
index fbdca3ba1c7b4..e617867eb10ea 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
@@ -105,15 +105,8 @@ public class LocationTile extends QSTileImpl {
}
state.icon = mIcon;
state.slash.isSlashed = !state.value;
- if (locationEnabled) {
- state.label = mContext.getString(R.string.quick_settings_location_label);
- state.contentDescription = mContext.getString(
- R.string.accessibility_quick_settings_location_on);
- } else {
- state.label = mContext.getString(R.string.quick_settings_location_label);
- state.contentDescription = mContext.getString(
- R.string.accessibility_quick_settings_location_off);
- }
+ state.label = mContext.getString(R.string.quick_settings_location_label);
+ state.contentDescription = state.label;
state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
state.expandedAccessibilityClassName = Switch.class.getName();
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index b7ce101cacab9..6e8dcf36baccc 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -195,6 +195,7 @@ public class WifiTile extends QSTileImpl {
state.activityIn = cb.enabled && cb.activityIn;
state.activityOut = cb.enabled && cb.activityOut;
final StringBuffer minimalContentDescription = new StringBuffer();
+ final StringBuffer minimalStateDescription = new StringBuffer();
final Resources r = mContext.getResources();
if (isTransient) {
state.icon = ResourceIcon.get(
@@ -219,13 +220,14 @@ public class WifiTile extends QSTileImpl {
mContext.getString(R.string.quick_settings_wifi_label)).append(",");
if (state.value) {
if (wifiConnected) {
- minimalContentDescription.append(cb.wifiSignalContentDescription).append(",");
+ minimalStateDescription.append(cb.wifiSignalContentDescription);
minimalContentDescription.append(removeDoubleQuotes(cb.ssid));
if (!TextUtils.isEmpty(state.secondaryLabel)) {
minimalContentDescription.append(",").append(state.secondaryLabel);
}
}
}
+ state.stateDescription = minimalStateDescription.toString();
state.contentDescription = minimalContentDescription.toString();
state.dualLabelContentDescription = r.getString(
R.string.accessibility_quick_settings_open_settings, getTileLabel());
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
index 7853dc388bcbb..e54ee51fb9d45 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
@@ -103,14 +103,11 @@ public class WorkModeTile extends QSTileImpl implements
state.icon = mIcon;
if (state.value) {
state.slash.isSlashed = false;
- state.contentDescription = mContext.getString(
- R.string.accessibility_quick_settings_work_mode_on);
} else {
state.slash.isSlashed = true;
- state.contentDescription = mContext.getString(
- R.string.accessibility_quick_settings_work_mode_off);
}
state.label = mContext.getString(R.string.quick_settings_work_mode_label);
+ state.contentDescription = state.label;
state.expandedAccessibilityClassName = Switch.class.getName();
state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
}