Quicksettings accessibility.
Bug: 15696340
Change-Id: I6887e2dad4822911d3a1642aaec5703174b57330
diff --git a/packages/SystemUI/res/layout/qs_paged_tile_layout.xml b/packages/SystemUI/res/layout/qs_paged_tile_layout.xml
index 68129ce..ee55ec2 100644
--- a/packages/SystemUI/res/layout/qs_paged_tile_layout.xml
+++ b/packages/SystemUI/res/layout/qs_paged_tile_layout.xml
@@ -47,7 +47,8 @@
android:textAppearance="@style/TextAppearance.QS.DetailButton"
android:textColor="#64FFFFFF"
android:focusable="true"
- android:text="@string/qs_edit" />
+ android:text="@string/qs_edit"
+ android:contentDescription="@string/accessibility_quick_settings_edit"/>
</FrameLayout>
diff --git a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
index a4f9df3..8611942 100644
--- a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
@@ -26,6 +26,7 @@
android:clipChildren="false"
android:clipToPadding="false"
android:baselineAligned="false"
+ android:clickable="false"
>
<LinearLayout
@@ -64,7 +65,7 @@
android:layout_height="match_parent"
android:background="@drawable/ripple_drawable"
android:src="@drawable/ic_settings"
- android:contentDescription="@string/accessibility_desc_settings" />
+ android:contentDescription="@string/accessibility_quick_settings_settings" />
<com.android.systemui.statusbar.AlphaOptimizedImageView android:id="@+id/tuner_icon"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -102,7 +103,8 @@
android:textAppearance="@style/TextAppearance.StatusBar.Expanded.EmergencyCallsOnly"
android:text="@*android:string/emergency_calls_only"
android:singleLine="true"
- android:gravity="center_vertical" />
+ android:gravity="center_vertical"
+ android:focusable="true" />
<LinearLayout
android:id="@+id/date_time_alarm_group"
@@ -118,7 +120,8 @@
android:id="@+id/date_time_group"
android:layout_width="wrap_content"
android:layout_height="19dp"
- android:orientation="horizontal">
+ android:orientation="horizontal"
+ android:focusable="true" >
<include layout="@layout/split_clock_view"
android:layout_width="wrap_content"
@@ -176,7 +179,11 @@
android:layout_marginEnd="12dp"
android:layout_alignParentEnd="true"
android:clipChildren="false"
- android:clipToPadding="false" />
+ android:clipToPadding="false"
+ android:importantForAccessibility="yes"
+ android:focusable="true"
+ android:accessibilityTraversalAfter="@id/date_time_group"
+ android:accessibilityTraversalBefore="@id/expand_indicator" />
<com.android.systemui.statusbar.AlphaOptimizedImageView
android:id="@+id/qs_detail_header_progress"
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
index 6081248..f07e8fc 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
@@ -203,6 +203,7 @@
public TilePage(Context context, AttributeSet attrs) {
super(context, attrs);
updateResources();
+ setContentDescription(mContext.getString(R.string.accessibility_desc_quick_settings));
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 413bc01..0e8d76a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -272,12 +272,16 @@
}
public void setTiles(Collection<QSTile<?>> tiles) {
+ setTiles(tiles, false);
+ }
+
+ public void setTiles(Collection<QSTile<?>> tiles, boolean collapsedView) {
for (TileRecord record : mRecords) {
mTileLayout.removeTile(record);
}
mRecords.clear();
for (QSTile<?> tile : tiles) {
- addTile(tile);
+ addTile(tile, collapsedView);
}
}
@@ -285,14 +289,14 @@
r.tileView.onStateChanged(state);
}
- protected QSTileBaseView createTileView(QSTile<?> tile) {
- return new QSTileView(mContext, tile.createTileView(mContext));
+ protected QSTileBaseView createTileView(QSTile<?> tile, boolean collapsedView) {
+ return new QSTileView(mContext, tile.createTileView(mContext), collapsedView);
}
- protected void addTile(final QSTile<?> tile) {
+ protected void addTile(final QSTile<?> tile, boolean collapsedView) {
final TileRecord r = new TileRecord();
r.tile = tile;
- r.tileView = createTileView(tile);
+ r.tileView = createTileView(tile, collapsedView);
final QSTile.Callback callback = new QSTile.Callback() {
@Override
public void onStateChanged(QSTile.State state) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
index 7692598..0cc30a8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
@@ -513,9 +513,12 @@
public CharSequence label;
public CharSequence contentDescription;
public CharSequence dualLabelContentDescription;
+ public CharSequence minimalContentDescription;
public boolean autoMirrorDrawable = true;
public boolean disabledByPolicy;
public EnforcedAdmin enforcedAdmin;
+ public String minimalAccessibilityClassName;
+ public String expandedAccessibilityClassName;
public boolean copyTo(State other) {
if (other == null) throw new IllegalArgumentException();
@@ -526,12 +529,21 @@
|| !Objects.equals(other.autoMirrorDrawable, autoMirrorDrawable)
|| !Objects.equals(other.dualLabelContentDescription,
dualLabelContentDescription)
+ || !Objects.equals(other.minimalContentDescription,
+ minimalContentDescription)
+ || !Objects.equals(other.minimalAccessibilityClassName,
+ minimalAccessibilityClassName)
+ || !Objects.equals(other.expandedAccessibilityClassName,
+ expandedAccessibilityClassName)
|| !Objects.equals(other.disabledByPolicy, disabledByPolicy)
|| !Objects.equals(other.enforcedAdmin, enforcedAdmin);
other.icon = icon;
other.label = label;
other.contentDescription = contentDescription;
other.dualLabelContentDescription = dualLabelContentDescription;
+ other.minimalContentDescription = minimalContentDescription;
+ other.minimalAccessibilityClassName = minimalAccessibilityClassName;
+ other.expandedAccessibilityClassName = expandedAccessibilityClassName;
other.autoMirrorDrawable = autoMirrorDrawable;
other.disabledByPolicy = disabledByPolicy;
if (enforcedAdmin == null) {
@@ -555,6 +567,9 @@
sb.append(",label=").append(label);
sb.append(",contentDescription=").append(contentDescription);
sb.append(",dualLabelContentDescription=").append(dualLabelContentDescription);
+ sb.append(",minimalContentDescription=").append(minimalContentDescription);
+ sb.append(",minimalAccessibilityClassName=").append(minimalAccessibilityClassName);
+ sb.append(",expandedAccessibilityClassName=").append(expandedAccessibilityClassName);
sb.append(",autoMirrorDrawable=").append(autoMirrorDrawable);
sb.append(",disabledByPolicy=").append(disabledByPolicy);
sb.append(",enforcedAdmin=").append(enforcedAdmin);
@@ -581,8 +596,7 @@
}
}
- public static final class SignalState extends State {
- public boolean enabled;
+ public static final class SignalState extends BooleanState {
public boolean connected;
public boolean activityIn;
public boolean activityOut;
@@ -593,12 +607,10 @@
@Override
public boolean copyTo(State other) {
final SignalState o = (SignalState) other;
- final boolean changed = o.enabled != enabled
- || o.connected != connected || o.activityIn != activityIn
+ final boolean changed = o.connected != connected || o.activityIn != activityIn
|| o.activityOut != activityOut
|| o.overlayIconId != overlayIconId
|| o.isOverlayIconWide != isOverlayIconWide;
- o.enabled = enabled;
o.connected = connected;
o.activityIn = activityIn;
o.activityOut = activityOut;
@@ -611,7 +623,6 @@
@Override
protected StringBuilder toStringBuilder() {
final StringBuilder rt = super.toStringBuilder();
- rt.insert(rt.length() - 1, ",enabled=" + enabled);
rt.insert(rt.length() - 1, ",connected=" + connected);
rt.insert(rt.length() - 1, ",activityIn=" + activityIn);
rt.insert(rt.length() - 1, ",activityOut=" + activityOut);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileBaseView.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileBaseView.java
index 44b38f1..f05aa3c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileBaseView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileBaseView.java
@@ -22,8 +22,12 @@
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
+import android.text.TextUtils;
import android.view.View;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.LinearLayout;
+import android.widget.Switch;
import com.android.systemui.R;
@@ -33,8 +37,15 @@
private QSIconView mIcon;
private RippleDrawable mRipple;
private Drawable mTileBackground;
+ private String mAccessibilityClass;
+ private boolean mTileState;
+ private boolean mCollapsedView;
public QSTileBaseView(Context context, QSIconView icon) {
+ this(context, icon, false);
+ }
+
+ public QSTileBaseView(Context context, QSIconView icon, boolean collapsedView) {
super(context);
mIcon = icon;
addView(mIcon);
@@ -51,6 +62,7 @@
setPadding(0, padding, 0, padding);
setClipChildren(false);
setClipToPadding(false);
+ mCollapsedView = collapsedView;
}
private Drawable newTileBackground() {
@@ -116,13 +128,54 @@
protected void handleStateChanged(QSTile.State state) {
mIcon.setIcon(state);
- setContentDescription(state.contentDescription);
+ if (mCollapsedView && !TextUtils.isEmpty(state.minimalContentDescription)) {
+ setContentDescription(state.minimalContentDescription);
+ } else {
+ setContentDescription(state.contentDescription);
+ }
+ if (mCollapsedView) {
+ mAccessibilityClass = state.minimalAccessibilityClassName;
+ } else {
+ mAccessibilityClass = state.expandedAccessibilityClassName;
+ }
+ if (state instanceof QSTile.BooleanState) {
+ mTileState = ((QSTile.BooleanState) state).value;
+ }
}
public QSIconView getIcon() {
return mIcon;
}
+ @Override
+ public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+ super.onInitializeAccessibilityEvent(event);
+ if (!TextUtils.isEmpty(mAccessibilityClass)) {
+ event.setClassName(mAccessibilityClass);
+ if (Switch.class.getName().equals(mAccessibilityClass)) {
+ String label = getResources()
+ .getString(mTileState ? R.string.switch_bar_on : R.string.switch_bar_off);
+ event.setContentDescription(label);
+ event.setChecked(mTileState);
+ }
+ }
+ }
+
+ @Override
+ public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(info);
+ if (!TextUtils.isEmpty(mAccessibilityClass)) {
+ info.setClassName(mAccessibilityClass);
+ if (Switch.class.getName().equals(mAccessibilityClass)) {
+ String label = getResources()
+ .getString(mTileState ? R.string.switch_bar_on : R.string.switch_bar_off);
+ info.setText(label);
+ info.setChecked(mTileState);
+ info.setCheckable(true);
+ }
+ }
+ }
+
private class H extends Handler {
private static final int STATE_CHANGED = 1;
public H() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
index c3766e8..9247794 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
@@ -40,7 +40,11 @@
private ImageView mPadLock;
public QSTileView(Context context, QSIconView icon) {
- super(context, icon);
+ this(context, icon, false);
+ }
+
+ public QSTileView(Context context, QSIconView icon, boolean collapsedView) {
+ super(context, icon, collapsedView);
mContext = context;
final Resources res = context.getResources();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
index 2ef3672..a11a6e5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -23,6 +23,7 @@
import android.view.View;
import android.widget.LinearLayout;
import android.widget.Space;
+
import com.android.systemui.R;
import com.android.systemui.qs.QSTile.SignalState;
import com.android.systemui.qs.QSTile.State;
@@ -93,8 +94,8 @@
}
@Override
- protected QSTileBaseView createTileView(QSTile<?> tile) {
- return new QSTileBaseView(mContext, tile.createTileView(mContext));
+ protected QSTileBaseView createTileView(QSTile<?> tile, boolean collapsedView) {
+ return new QSTileBaseView(mContext, tile.createTileView(mContext), collapsedView);
}
@Override
@@ -133,7 +134,7 @@
break;
}
}
- super.setTiles(quickTiles);
+ super.setTiles(quickTiles, true);
}
private final Tunable mNumTiles = new Tunable() {
@@ -150,6 +151,7 @@
private static class HeaderTileLayout extends LinearLayout implements QSTileLayout {
private final Space mEndSpacer;
+ protected final ArrayList<TileRecord> mRecords = new ArrayList<>();
public HeaderTileLayout(Context context) {
super(context);
@@ -185,6 +187,7 @@
// Add a spacer.
addView(new Space(mContext), getChildCount() - 1 /* Leave icon at end */,
generateSpaceParams());
+ mRecords.add(tile);
}
private LayoutParams generateSpaceParams() {
@@ -209,6 +212,7 @@
removeViewAt(childIndex);
// Remove its spacer as well.
removeViewAt(childIndex);
+ mRecords.remove(tile);
}
private int getChildIndex(QSTileBaseView tileView) {
@@ -236,5 +240,21 @@
public boolean hasOverlappingRendering() {
return false;
}
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ if (mRecords != null && mRecords.size() > 0) {
+ View previousView = this;
+ for (TileRecord record : mRecords) {
+ if (record.tileView.getVisibility() == GONE) continue;
+ previousView = record.tileView.updateAccessibilityOrder(previousView);
+ }
+ mRecords.get(0).tileView.setAccessibilityTraversalAfter(
+ R.id.alarm_status_collapsed);
+ mRecords.get(mRecords.size() - 1).tileView.setAccessibilityTraversalBefore(
+ R.id.expand_indicator);
+ }
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
index 1e3c458..a578e6c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
@@ -32,6 +32,7 @@
public TileLayout(Context context, AttributeSet attrs) {
super(context, attrs);
+ setFocusableInTouchMode(true);
updateResources();
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
index 5f5a87e..a980a7f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
@@ -23,6 +23,7 @@
import android.net.ConnectivityManager;
import android.provider.Settings;
import android.provider.Settings.Global;
+import android.widget.Switch;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsProto.MetricsEvent;
@@ -88,13 +89,12 @@
state.label = mContext.getString(R.string.airplane_mode);
if (airplaneMode) {
state.icon = mEnable;
- state.contentDescription = mContext.getString(
- R.string.accessibility_quick_settings_airplane_on);
} else {
state.icon = mDisable;
- state.contentDescription = mContext.getString(
- R.string.accessibility_quick_settings_airplane_off);
}
+ state.contentDescription = state.label;
+ state.minimalAccessibilityClassName = state.expandedAccessibilityClassName
+ = Switch.class.getName();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
index 77eaa3b..985bc9f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
@@ -31,6 +31,7 @@
import android.view.View.OnAttachStateChangeListener;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
+import android.widget.Button;
import android.widget.Checkable;
import android.widget.ImageView;
import android.widget.TextView;
@@ -131,7 +132,13 @@
};
state.label = percentage;
state.contentDescription = mContext.getString(R.string.accessibility_quick_settings_battery,
- percentage);
+ percentage) + "," +
+ (mPowerSave ? mContext.getString(R.string.battery_saver_notification_title)
+ : mCharging ? mContext.getString(R.string.expanded_header_battery_charging)
+ : "")
+ + "," + mContext.getString(R.string.accessibility_battery_details);
+ state.minimalAccessibilityClassName = state.expandedAccessibilityClassName
+ = Button.class.getName();
}
@Override
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 63c85db..7a23910 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -24,6 +24,8 @@
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.Switch;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsProto.MetricsEvent;
@@ -107,22 +109,31 @@
final boolean connecting = mController.isBluetoothConnecting();
state.value = enabled;
state.autoMirrorDrawable = false;
+ state.minimalContentDescription =
+ mContext.getString(R.string.accessibility_quick_settings_bluetooth);
if (enabled) {
state.label = null;
if (connected) {
state.icon = ResourceIcon.get(R.drawable.ic_qs_bluetooth_connected);
- state.contentDescription = mContext.getString(
- R.string.accessibility_quick_settings_bluetooth_connected);
state.label = mController.getLastDeviceName();
+ state.contentDescription = mContext.getString(
+ R.string.accessibility_bluetooth_name, state.label);
+ state.minimalContentDescription = state.minimalContentDescription + ","
+ + state.contentDescription;
} else if (connecting) {
state.icon = ResourceIcon.get(R.drawable.ic_qs_bluetooth_connecting);
state.contentDescription = mContext.getString(
R.string.accessibility_quick_settings_bluetooth_connecting);
state.label = mContext.getString(R.string.quick_settings_bluetooth_label);
+ state.minimalContentDescription = state.minimalContentDescription + ","
+ + state.contentDescription;
} else {
state.icon = ResourceIcon.get(R.drawable.ic_qs_bluetooth_on);
state.contentDescription = mContext.getString(
- R.string.accessibility_quick_settings_bluetooth_on);
+ R.string.accessibility_quick_settings_bluetooth_on) + ","
+ + mContext.getString(R.string.accessibility_not_connected);
+ state.minimalContentDescription = state.minimalContentDescription + ","
+ + mContext.getString(R.string.accessibility_not_connected);
}
if (TextUtils.isEmpty(state.label)) {
state.label = mContext.getString(R.string.quick_settings_bluetooth_label);
@@ -140,6 +151,10 @@
R.string.accessibility_bluetooth_name, state.label);
}
state.dualLabelContentDescription = bluetoothName;
+ state.contentDescription = state.contentDescription + "," + mContext.getString(
+ R.string.accessibility_quick_settings_open_settings, getTileLabel());
+ state.expandedAccessibilityClassName = Button.class.getName();
+ state.minimalAccessibilityClassName = Switch.class.getName();
}
@Override
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 bea1e15..c3e9b6e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -23,6 +23,7 @@
import android.view.View;
import android.view.View.OnAttachStateChangeListener;
import android.view.ViewGroup;
+import android.widget.Button;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsProto.MetricsEvent;
@@ -115,6 +116,7 @@
@Override
protected void handleUpdateState(BooleanState state, Object arg) {
state.label = mContext.getString(R.string.quick_settings_cast_title);
+ state.contentDescription = state.label;
state.value = false;
state.autoMirrorDrawable = false;
final Set<CastDevice> devices = mController.getCastDevices();
@@ -123,6 +125,8 @@
if (device.state == CastDevice.STATE_CONNECTED) {
state.value = true;
state.label = getDeviceName(device);
+ state.contentDescription = state.contentDescription + "," +
+ mContext.getString(R.string.accessibility_cast_name, state.label);
} else if (device.state == CastDevice.STATE_CONNECTING) {
connecting = true;
}
@@ -133,6 +137,10 @@
state.icon = ResourceIcon.get(state.value ? R.drawable.ic_qs_cast_on
: R.drawable.ic_qs_cast_off);
mDetailAdapter.updateItems(devices);
+ state.minimalAccessibilityClassName = state.expandedAccessibilityClassName =
+ Button.class.getName();
+ state.contentDescription = state.contentDescription + ","
+ + mContext.getString(R.string.accessibility_quick_settings_open_details);
}
@Override
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 55b00b5..18191cf 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -23,6 +23,8 @@
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.Switch;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsProto.MetricsEvent;
@@ -132,13 +134,28 @@
final String signalContentDesc = cb.enabled && (cb.mobileSignalIconId > 0)
? cb.signalContentDescription
: r.getString(R.string.accessibility_no_signal);
- final String dataContentDesc = cb.enabled && (cb.dataTypeIconId > 0) && !cb.wifiEnabled
- ? cb.dataContentDescription
- : r.getString(R.string.accessibility_no_data);
- state.contentDescription = r.getString(
- R.string.accessibility_quick_settings_mobile,
- signalContentDesc, dataContentDesc,
- state.label);
+
+ if (cb.noSim) {
+ state.contentDescription = state.label;
+ } else {
+ String enabledDesc = cb.enabled ? r.getString(R.string.accessibility_cell_data_on)
+ : r.getString(R.string.accessibility_cell_data_off);
+
+ state.contentDescription = r.getString(
+ R.string.accessibility_quick_settings_mobile,
+ enabledDesc, signalContentDesc,
+ state.label);
+ state.minimalContentDescription = r.getString(
+ R.string.accessibility_quick_settings_mobile,
+ r.getString(R.string.accessibility_cell_data), signalContentDesc,
+ state.label);
+ }
+ state.contentDescription = state.contentDescription + "," + r.getString(
+ R.string.accessibility_quick_settings_open_settings, getTileLabel());
+ state.expandedAccessibilityClassName = Button.class.getName();
+ state.minimalAccessibilityClassName = Switch.class.getName();
+ state.value = mDataController.isMobileDataSupported()
+ && mDataController.isMobileDataEnabled();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
index 416132e..5ae7a76 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
@@ -19,6 +19,7 @@
import android.content.Intent;
import android.provider.Settings;
import android.provider.Settings.Secure;
+import android.widget.Switch;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsProto.MetricsEvent;
@@ -96,6 +97,9 @@
state.value = enabled;
state.label = mContext.getString(R.string.quick_settings_inversion_label);
state.icon = enabled ? mEnable : mDisable;
+ state.minimalAccessibilityClassName = state.expandedAccessibilityClassName
+ = Switch.class.getName();
+ state.contentDescription = state.label;
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
index b22e1ec..aabafe1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
@@ -16,6 +16,7 @@
import android.content.DialogInterface;
import android.content.Intent;
+import android.widget.Switch;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsProto.MetricsEvent;
@@ -96,10 +97,11 @@
state.value = arg instanceof Boolean ? (Boolean) arg
: mDataSaverController.isDataSaverEnabled();
state.label = mContext.getString(R.string.data_saver);
- state.contentDescription = mContext.getString(state.value
- ? R.string.accessibility_data_saver_on : R.string.accessibility_data_saver_off);
+ state.contentDescription = state.label;
state.icon = ResourceIcon.get(state.value ? R.drawable.ic_data_saver
: R.drawable.ic_data_saver_off);
+ state.minimalAccessibilityClassName = state.expandedAccessibilityClassName
+ = Switch.class.getName();
}
@Override
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 11efd56..04cb553 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -29,6 +29,7 @@
import android.view.View;
import android.view.View.OnAttachStateChangeListener;
import android.view.ViewGroup;
+import android.widget.Switch;
import android.widget.Toast;
import com.android.internal.logging.MetricsLogger;
@@ -162,7 +163,7 @@
state.icon = TOTAL_SILENCE.equals(state.icon) ? mDisableTotalSilence : mDisable;
state.label = mContext.getString(R.string.quick_settings_dnd_label);
state.contentDescription = mContext.getString(
- R.string.accessibility_quick_settings_dnd_off);
+ R.string.accessibility_quick_settings_dnd);
break;
}
if (mShowingDetail && !state.value) {
@@ -171,6 +172,8 @@
if (valueChanged) {
fireToggleStateChanged(state.value);
}
+ state.minimalAccessibilityClassName = state.expandedAccessibilityClassName
+ = Switch.class.getName();
}
@Override
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 69e71bc..5ff0bd0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
@@ -22,6 +22,8 @@
import android.provider.MediaStore;
import android.text.SpannableStringBuilder;
import android.text.style.ForegroundColorSpan;
+import android.widget.Switch;
+
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.systemui.R;
@@ -122,10 +124,9 @@
}
final AnimationIcon icon = state.value ? mEnable : mDisable;
state.icon = icon;
- int onOrOffId = state.value
- ? R.string.accessibility_quick_settings_flashlight_on
- : R.string.accessibility_quick_settings_flashlight_off;
- state.contentDescription = mContext.getString(onOrOffId);
+ state.contentDescription = mContext.getString(R.string.quick_settings_flashlight_label);
+ state.minimalAccessibilityClassName = state.expandedAccessibilityClassName
+ = Switch.class.getName();
}
@Override
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 25a3eff..3587262 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
@@ -20,6 +20,8 @@
import android.os.UserManager;
import android.provider.Settings;
+import android.widget.Switch;
+
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.systemui.R;
@@ -94,6 +96,9 @@
state.value = mController.isHotspotEnabled();
}
state.icon = state.value ? mEnable : mDisable;
+ state.minimalAccessibilityClassName = state.expandedAccessibilityClassName
+ = Switch.class.getName();
+ state.contentDescription = state.label;
}
@Override
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 6286f5e..5b5ecae 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
@@ -20,6 +20,8 @@
import android.os.UserManager;
import android.provider.Settings;
+import android.widget.Switch;
+
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.systemui.R;
@@ -113,6 +115,8 @@
state.contentDescription = mContext.getString(
R.string.accessibility_quick_settings_location_off);
}
+ state.minimalAccessibilityClassName = state.expandedAccessibilityClassName
+ = Switch.class.getName();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
index 38b3706..521df37 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
@@ -21,6 +21,8 @@
import android.content.res.Configuration;
import android.provider.Settings;
+import android.widget.Switch;
+
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.systemui.R;
@@ -106,10 +108,9 @@
state.label = mContext.getString(R.string.quick_settings_rotation_unlocked_label);
state.icon = portrait ? mPortraitToAuto : mLandscapeToAuto;
}
- state.contentDescription = getAccessibilityString(rotationLocked,
- R.string.accessibility_rotation_lock_on_portrait,
- R.string.accessibility_rotation_lock_on_landscape,
- R.string.accessibility_rotation_lock_off);
+ state.contentDescription = getAccessibilityString(rotationLocked);
+ state.minimalAccessibilityClassName = state.expandedAccessibilityClassName
+ = Switch.class.getName();
}
public static boolean isCurrentOrientationLockPortrait(RotationLockController controller,
@@ -133,29 +134,25 @@
* Get the correct accessibility string based on the state
*
* @param locked Whether or not rotation is locked.
- * @param idWhenPortrait The id which should be used when locked in portrait.
- * @param idWhenLandscape The id which should be used when locked in landscape.
- * @param idWhenOff The id which should be used when the rotation lock is off.
- * @return
*/
- private String getAccessibilityString(boolean locked, int idWhenPortrait, int idWhenLandscape,
- int idWhenOff) {
- int stringID;
+ private String getAccessibilityString(boolean locked) {
if (locked) {
- stringID = isCurrentOrientationLockPortrait(mController, mContext) ? idWhenPortrait
- : idWhenLandscape;
+ return mContext.getString(R.string.accessibility_quick_settings_rotation) + ","
+ + mContext.getString(R.string.accessibility_quick_settings_rotation_value,
+ isCurrentOrientationLockPortrait(mController, mContext)
+ ? mContext.getString(
+ R.string.quick_settings_rotation_locked_portrait_label)
+ : mContext.getString(
+ R.string.quick_settings_rotation_locked_landscape_label));
+
} else {
- stringID = idWhenOff;
+ return mContext.getString(R.string.accessibility_quick_settings_rotation);
}
- return mContext.getString(stringID);
}
@Override
protected String composeChangeAnnouncement() {
- return getAccessibilityString(mState.value,
- R.string.accessibility_rotation_lock_on_portrait_changed,
- R.string.accessibility_rotation_lock_on_landscape_changed,
- R.string.accessibility_rotation_lock_off_changed);
+ return getAccessibilityString(mState.value);
}
private final RotationLockControllerCallback mCallback = new RotationLockControllerCallback() {
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 c72bbf3..661212c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -24,6 +24,8 @@
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.Switch;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsProto.MetricsEvent;
@@ -101,8 +103,8 @@
protected void handleSecondaryClick() {
// Secondary clicks are header clicks, just toggle.
mState.copyTo(mStateBeforeClick);
- MetricsLogger.action(mContext, getMetricsCategory(), !mState.enabled);
- mController.setWifiEnabled(!mState.enabled);
+ MetricsLogger.action(mContext, getMetricsCategory(), !mState.value);
+ mController.setWifiEnabled(!mState.value);
}
@Override
@@ -111,9 +113,9 @@
mHost.startActivityDismissingKeyguard(new Intent(Settings.ACTION_WIFI_SETTINGS));
return;
}
- if (!mState.enabled) {
+ if (!mState.value) {
mController.setWifiEnabled(true);
- mState.enabled = true;
+ mState.value = true;
}
showDetail(true);
}
@@ -133,43 +135,58 @@
boolean wifiConnected = cb.enabled && (cb.wifiSignalIconId > 0) && (cb.enabledDesc != null);
boolean wifiNotConnected = (cb.wifiSignalIconId > 0) && (cb.enabledDesc == null);
- boolean enabledChanging = state.enabled != cb.enabled;
+ boolean enabledChanging = state.value != cb.enabled;
if (enabledChanging) {
mDetailAdapter.setItemsVisible(cb.enabled);
fireToggleStateChanged(cb.enabled);
}
- state.enabled = cb.enabled;
+ state.value = cb.enabled;
state.connected = wifiConnected;
state.activityIn = cb.enabled && cb.activityIn;
state.activityOut = cb.enabled && cb.activityOut;
state.filter = true;
- final String signalContentDescription;
+ final StringBuffer minimalContentDescription = new StringBuffer();
+ final StringBuffer expandedContentDescription = new StringBuffer();
final Resources r = mContext.getResources();
- if (!state.enabled) {
+ if (!state.value) {
state.icon = ResourceIcon.get(R.drawable.ic_qs_wifi_disabled);
state.label = r.getString(R.string.quick_settings_wifi_label);
- signalContentDescription = r.getString(R.string.accessibility_wifi_off);
} else if (wifiConnected) {
state.icon = ResourceIcon.get(cb.wifiSignalIconId);
state.label = removeDoubleQuotes(cb.enabledDesc);
- signalContentDescription = cb.wifiSignalContentDescription;
} else if (wifiNotConnected) {
state.icon = ResourceIcon.get(R.drawable.ic_qs_wifi_disconnected);
state.label = r.getString(R.string.quick_settings_wifi_label);
- signalContentDescription = r.getString(R.string.accessibility_no_wifi);
} else {
state.icon = ResourceIcon.get(R.drawable.ic_qs_wifi_no_network);
state.label = r.getString(R.string.quick_settings_wifi_label);
- signalContentDescription = r.getString(R.string.accessibility_wifi_off);
}
- state.contentDescription = mContext.getString(
- R.string.accessibility_quick_settings_wifi,
- signalContentDescription);
+ minimalContentDescription.append(
+ mContext.getString(R.string.quick_settings_wifi_label)).append(",");
+ if (state.value) {
+ expandedContentDescription.append(
+ r.getString(R.string.quick_settings_wifi_on_label)).append(",");
+ if (wifiConnected) {
+ minimalContentDescription.append(cb.wifiSignalContentDescription).append(",");
+ minimalContentDescription.append(removeDoubleQuotes(cb.enabledDesc));
+ expandedContentDescription.append(cb.wifiSignalContentDescription).append(",");
+ expandedContentDescription.append(removeDoubleQuotes(cb.enabledDesc));
+ }
+ } else {
+ expandedContentDescription.append(
+ r.getString(R.string.quick_settings_wifi_off_label));
+ }
+ state.minimalContentDescription = minimalContentDescription;
+ expandedContentDescription.append(",").append(
+ r.getString(R.string.accessibility_quick_settings_open_settings, getTileLabel()));
+ state.contentDescription = expandedContentDescription;
CharSequence wifiName = state.label;
if (state.connected) {
wifiName = r.getString(R.string.accessibility_wifi_name, state.label);
}
state.dualLabelContentDescription = wifiName;
+ state.expandedAccessibilityClassName = Button.class.getName();
+ state.minimalAccessibilityClassName = Switch.class.getName();
}
@Override
@@ -179,12 +196,12 @@
@Override
protected boolean shouldAnnouncementBeDelayed() {
- return mStateBeforeClick.enabled == mState.enabled;
+ return mStateBeforeClick.value == mState.value;
}
@Override
protected String composeChangeAnnouncement() {
- if (mState.enabled) {
+ if (mState.value) {
return mContext.getString(R.string.accessibility_quick_settings_wifi_changed_on);
} else {
return mContext.getString(R.string.accessibility_quick_settings_wifi_changed_off);
@@ -263,7 +280,7 @@
@Override
public Boolean getToggleState() {
- return mState.enabled;
+ return mState.value;
}
@Override
@@ -291,7 +308,7 @@
mItems.setEmptyState(R.drawable.ic_qs_wifi_detail_empty,
R.string.quick_settings_wifi_detail_empty_text);
updateItems();
- setItemsVisible(mState.enabled);
+ setItemsVisible(mState.value);
return mItems;
}
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 2c5f7d5..459e8ec 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
@@ -18,6 +18,8 @@
import android.content.Intent;
import android.provider.Settings;
+import android.widget.Switch;
+
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.systemui.R;
@@ -104,6 +106,8 @@
state.contentDescription = mContext.getString(
R.string.accessibility_quick_settings_work_mode_off);
}
+ state.minimalAccessibilityClassName = state.expandedAccessibilityClassName
+ = Switch.class.getName();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ExpandableIndicator.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ExpandableIndicator.java
index 3fdc35c..a295cfa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ExpandableIndicator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ExpandableIndicator.java
@@ -34,6 +34,7 @@
super.onFinishInflate();
final int res = getDrawableResourceId(mExpanded);
setImageResource(res);
+ setContentDescription(getContentDescription(mExpanded));
}
public void setExpanded(boolean expanded) {
@@ -46,6 +47,7 @@
setImageDrawable(avd);
avd.forceAnimationOnUI();
avd.start();
+ setContentDescription(getContentDescription(expanded));
}
/** Whether the icons are using the default direction or the opposite */
@@ -62,4 +64,9 @@
: R.drawable.ic_volume_collapse_animation;
}
}
+
+ private String getContentDescription(boolean expanded) {
+ return expanded ? mContext.getString(R.string.accessibility_quick_settings_collapse)
+ : mContext.getString(R.string.accessibility_quick_settings_expand);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
index 6698d13..0186d34 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
@@ -25,6 +25,9 @@
import android.util.AttributeSet;
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.FrameLayout;
import com.android.systemui.R;
@@ -150,24 +153,11 @@
}
String text = null;
- if (isClickable()) {
- if (mUserManager.isUserSwitcherEnabled()) {
- if (TextUtils.isEmpty(currentUser)) {
- text = mContext.getString(R.string.accessibility_multi_user_switch_switcher);
- } else {
- text = mContext.getString(
- R.string.accessibility_multi_user_switch_switcher_with_current,
- currentUser);
- }
- } else {
- text = mContext.getString(R.string.accessibility_multi_user_switch_quick_contact);
- }
- } else {
- if (!TextUtils.isEmpty(currentUser)) {
- text = mContext.getString(
- R.string.accessibility_multi_user_switch_inactive,
- currentUser);
- }
+
+ if (!TextUtils.isEmpty(currentUser)) {
+ text = mContext.getString(
+ R.string.accessibility_quick_settings_user,
+ currentUser);
}
if (!TextUtils.equals(getContentDescription(), text)) {
@@ -176,6 +166,18 @@
}
@Override
+ public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+ super.onInitializeAccessibilityEvent(event);
+ event.setClassName(Button.class.getName());
+ }
+
+ @Override
+ public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(info);
+ info.setClassName(Button.class.getName());
+ }
+
+ @Override
public boolean hasOverlappingRendering() {
return false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
index 4a8d27f..e32d51a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
@@ -224,7 +224,12 @@
public void onNextAlarmChanged(AlarmManager.AlarmClockInfo nextAlarm) {
mNextAlarm = nextAlarm;
if (nextAlarm != null) {
- mAlarmStatus.setText(KeyguardStatusView.formatNextAlarm(getContext(), nextAlarm));
+ String alarmString = KeyguardStatusView.formatNextAlarm(getContext(), nextAlarm);
+ mAlarmStatus.setText(alarmString);
+ mAlarmStatus.setContentDescription(mContext.getString(
+ R.string.accessibility_quick_settings_alarm, alarmString));
+ mAlarmStatusCollapsed.setContentDescription(mContext.getString(
+ R.string.accessibility_quick_settings_alarm, alarmString));
}
if (mAlarmShowing != (nextAlarm != null)) {
mAlarmShowing = nextAlarm != null;
@@ -281,6 +286,7 @@
public void updateEverything() {
updateDateTimePosition();
updateVisibilities();
+ setClickable(false);
}
protected void updateVisibilities() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
index a6ed04f..b890a30 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
@@ -30,6 +30,8 @@
import com.android.systemui.statusbar.policy.NetworkController.IconState;
import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
+import com.android.systemui.R;
+
import java.util.Objects;
@@ -80,6 +82,10 @@
String wifiDesc = wifiVisible ? mCurrentState.ssid : null;
boolean ssidPresent = wifiVisible && mCurrentState.ssid != null;
String contentDescription = getStringIfExists(getContentDescription());
+ if (mCurrentState.inetCondition == 0) {
+ contentDescription +=
+ ("," + mContext.getString(R.string.accessibility_quick_settings_no_internet));
+ }
IconState statusIcon = new IconState(wifiVisible, getCurrentIconId(), contentDescription);
IconState qsIcon = new IconState(mCurrentState.connected, getQsCurrentIconId(),