Skip to content

Commit 0230f20

Browse files
mikejurkaAndroid (Google) Code Review
authored andcommitted
Merge "Fixing accessibility support in Recent Apps"
2 parents 450c9c4 + 7daf95d commit 0230f20

File tree

13 files changed

+119
-115
lines changed

13 files changed

+119
-115
lines changed

packages/SystemUI/res/layout-land/status_bar_recent_item.xml

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -44,20 +44,18 @@
4444
android:layout_height="@dimen/status_bar_recents_thumbnail_height"
4545
android:visibility="invisible"
4646
/>
47-
</FrameLayout>
4847

49-
<ImageView android:id="@+id/app_icon"
50-
android:layout_width="wrap_content"
51-
android:layout_height="wrap_content"
52-
android:layout_alignLeft="@id/app_thumbnail"
53-
android:layout_alignTop="@id/app_thumbnail"
54-
android:layout_marginTop="@dimen/status_bar_recents_app_icon_top_margin"
55-
android:layout_marginLeft="@dimen/status_bar_recents_app_icon_left_margin"
56-
android:maxWidth="@dimen/status_bar_recents_app_icon_max_width"
57-
android:maxHeight="@dimen/status_bar_recents_app_icon_max_height"
58-
android:adjustViewBounds="true"
59-
android:visibility="invisible"
60-
/>
48+
<ImageView android:id="@+id/app_icon"
49+
android:layout_width="wrap_content"
50+
android:layout_height="wrap_content"
51+
android:layout_marginTop="@dimen/status_bar_recents_app_icon_top_margin"
52+
android:layout_marginLeft="@dimen/status_bar_recents_app_icon_left_margin"
53+
android:maxWidth="@dimen/status_bar_recents_app_icon_max_width"
54+
android:maxHeight="@dimen/status_bar_recents_app_icon_max_height"
55+
android:adjustViewBounds="true"
56+
android:visibility="invisible"
57+
/>
58+
</FrameLayout>
6159

6260
<TextView android:id="@+id/app_label"
6361
android:layout_width="@dimen/status_bar_recents_app_label_width"

packages/SystemUI/res/layout-land/status_bar_recent_panel.xml

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,4 @@
7575
android:layout_height="match_parent"
7676
android:visibility="invisible" />
7777

78-
<View android:id="@+id/recents_dismiss_button"
79-
android:layout_width="80px"
80-
android:layout_height="@*android:dimen/status_bar_height"
81-
android:layout_alignParentBottom="true"
82-
android:layout_alignParentLeft="true"
83-
android:background="@drawable/ic_sysbar_back_ime"
84-
android:visibility="gone"
85-
/>
86-
8778
</com.android.systemui.recent.RecentsPanelView>

packages/SystemUI/res/layout-port/status_bar_recent_item.xml

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -42,20 +42,16 @@
4242
android:layout_height="@dimen/status_bar_recents_thumbnail_height"
4343
android:visibility="invisible"
4444
/>
45+
<ImageView android:id="@+id/app_icon"
46+
android:layout_width="wrap_content"
47+
android:layout_height="wrap_content"
48+
android:layout_marginLeft="@dimen/status_bar_recents_app_icon_left_margin"
49+
android:layout_marginTop="@dimen/status_bar_recents_app_icon_top_margin"
50+
android:maxWidth="@dimen/status_bar_recents_app_icon_max_width"
51+
android:maxHeight="@dimen/status_bar_recents_app_icon_max_height"
52+
android:adjustViewBounds="true"
53+
/>
4554
</FrameLayout>
46-
47-
<ImageView android:id="@+id/app_icon"
48-
android:layout_width="wrap_content"
49-
android:layout_height="wrap_content"
50-
android:layout_alignLeft="@id/app_thumbnail"
51-
android:layout_alignTop="@id/app_thumbnail"
52-
android:layout_marginLeft="@dimen/status_bar_recents_app_icon_left_margin"
53-
android:layout_marginTop="@dimen/status_bar_recents_app_icon_top_margin"
54-
android:maxWidth="@dimen/status_bar_recents_app_icon_max_width"
55-
android:maxHeight="@dimen/status_bar_recents_app_icon_max_height"
56-
android:adjustViewBounds="true"
57-
/>
58-
5955
<TextView android:id="@+id/app_label"
6056
android:layout_width="@dimen/status_bar_recents_app_label_width"
6157
android:layout_height="wrap_content"

packages/SystemUI/res/layout-port/status_bar_recent_panel.xml

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,4 @@
7373
android:layout_height="match_parent"
7474
android:visibility="invisible" />
7575

76-
<View android:id="@+id/recents_dismiss_button"
77-
android:layout_width="80px"
78-
android:layout_height="@*android:dimen/status_bar_height"
79-
android:layout_alignParentBottom="true"
80-
android:layout_alignParentLeft="true"
81-
android:background="@drawable/ic_sysbar_back_ime"
82-
android:visibility="gone"
83-
/>
84-
8576
</com.android.systemui.recent.RecentsPanelView>

packages/SystemUI/res/layout-sw600dp/status_bar.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
android:layout_width="80dip"
7474
android:layout_height="match_parent"
7575
android:src="@drawable/ic_sysbar_recent"
76-
android:contentDescription="@string/accessibility_menu"
76+
android:contentDescription="@string/accessibility_recent"
7777
systemui:glowBackground="@drawable/ic_sysbar_highlight"
7878
/>
7979
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu"

packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,20 +37,17 @@
3737
android:layout_height="@dimen/status_bar_recents_thumbnail_height"
3838
android:visibility="invisible"
3939
/>
40+
<ImageView android:id="@+id/app_icon"
41+
android:layout_width="wrap_content"
42+
android:layout_height="wrap_content"
43+
android:layout_marginLeft="@dimen/status_bar_recents_app_icon_left_margin"
44+
android:layout_marginTop="@dimen/status_bar_recents_app_icon_top_margin"
45+
android:maxWidth="@dimen/status_bar_recents_app_icon_max_width"
46+
android:maxHeight="@dimen/status_bar_recents_app_icon_max_height"
47+
android:adjustViewBounds="true"
48+
/>
4049
</FrameLayout>
4150

42-
<ImageView android:id="@+id/app_icon"
43-
android:layout_width="wrap_content"
44-
android:layout_height="wrap_content"
45-
android:layout_alignLeft="@id/app_thumbnail"
46-
android:layout_alignTop="@id/app_thumbnail"
47-
android:layout_marginLeft="@dimen/status_bar_recents_app_icon_left_margin"
48-
android:layout_marginTop="@dimen/status_bar_recents_app_icon_top_margin"
49-
android:maxWidth="@dimen/status_bar_recents_app_icon_max_width"
50-
android:maxHeight="@dimen/status_bar_recents_app_icon_max_height"
51-
android:adjustViewBounds="true"
52-
/>
53-
5451
<TextView android:id="@+id/app_label"
5552
android:layout_width="@dimen/status_bar_recents_app_label_width"
5653
android:layout_height="wrap_content"

packages/SystemUI/res/layout-sw600dp/status_bar_recent_panel.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
android:layout_alignParentBottom="true"
8080
android:layout_alignParentLeft="true"
8181
android:background="@drawable/ic_sysbar_back_ime"
82+
android:contentDescription="@string/status_bar_accessibility_dismiss_recents"
8283
/>
8384

8485
</com.android.systemui.recent.RecentsPanelView>

packages/SystemUI/res/values/strings.xml

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,19 @@
4242
<string name="status_bar_recent_inspect_item_title">App info</string>
4343

4444
<!-- Message shown in the middle of the screen after clicking on the recent apps button
45-
when there are no recent apps to show [CHAR LIMIT=45]-->
45+
when there are no recent apps to show. Also used for accessibility. [CHAR LIMIT=45]-->
4646
<string name="status_bar_no_recent_apps">No recent apps</string>
4747

48+
<!-- Content description for the button to dismiss Recent Apps (only present on large
49+
devices) -->
50+
<string name="status_bar_accessibility_dismiss_recents">Dismiss recent apps</string>
51+
52+
<!-- Message that is read when you enter recent apps in TalkBack -->
53+
<plurals name="status_bar_accessibility_recent_apps">
54+
<item quantity="one">1 recent app</item>
55+
<item quantity="other">%d recent apps</item>
56+
</plurals>
57+
4858
<!-- The label in the bar at the top of the status bar when there are no notifications
4959
showing. [CHAR LIMIT=40]-->
5060
<string name="status_bar_no_notifications_title">No notifications</string>
@@ -109,14 +119,6 @@
109119
<!-- Separator for PLMN and SPN in network name. -->
110120
<string name="status_bar_network_name_separator" translatable="false">"\n"</string>
111121

112-
<!-- Recent Tasks dialog: title [CHAR LIMIT=30] -->
113-
<string name="recent_tasks_title">Recent</string>
114-
<!-- Recent Tasks dialog: message when there are no recent applications [CHAR LIMIT=NONE]-->
115-
<string name="recent_tasks_empty">No recent applications.</string>
116-
117-
<!-- Recent apps label. Shown as title on recent apps panel -->
118-
<string name="recent_tasks_app_label">Apps</string>
119-
120122
<!-- Network connection string for Bluetooth Reverse Tethering -->
121123
<string name="bluetooth_tethered">Bluetooth tethered</string>
122124
<!-- Title of a button to open the settings for input methods [CHAR LIMIT=30] -->
@@ -187,7 +189,7 @@
187189
<!-- Content description of the menu button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
188190
<string name="accessibility_menu">Menu</string>
189191
<!-- Content description of the recents button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
190-
<string name="accessibility_recent">Recent applications</string>
192+
<string name="accessibility_recent">Recent apps</string>
191193

192194
<!-- Content description of the switch input method button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
193195
<string name="accessibility_ime_switch_button">Switch input method button.</string>

packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import android.view.MotionEvent;
2727
import android.view.View;
2828
import android.view.ViewConfiguration;
29+
import android.view.View.OnTouchListener;
2930
import android.widget.HorizontalScrollView;
3031
import android.widget.LinearLayout;
3132

@@ -65,6 +66,13 @@ private void update() {
6566
mPerformanceHelper.addViewCallback(view);
6667
}
6768

69+
OnTouchListener noOpListener = new OnTouchListener() {
70+
@Override
71+
public boolean onTouch(View v, MotionEvent event) {
72+
return true;
73+
}
74+
};
75+
6876
view.setOnClickListener(new OnClickListener() {
6977
public void onClick(View v) {
7078
mCallback.dismiss();
@@ -78,22 +86,25 @@ public void onClick(View v) {
7886
mCallback.handleOnClick(view);
7987
}
8088
};
89+
90+
final View thumbnailView = view.findViewById(R.id.app_thumbnail);
8191
OnLongClickListener longClickListener = new OnLongClickListener() {
8292
public boolean onLongClick(View v) {
8393
final View anchorView = view.findViewById(R.id.app_description);
84-
final View thumbnailView = view.findViewById(R.id.app_thumbnail);
8594
mCallback.handleLongPress(view, anchorView, thumbnailView);
8695
return true;
8796
}
8897
};
89-
final View thumbnail = view.findViewById(R.id.app_thumbnail);
90-
thumbnail.setClickable(true);
91-
thumbnail.setOnClickListener(launchAppListener);
92-
thumbnail.setOnLongClickListener(longClickListener);
98+
thumbnailView.setClickable(true);
99+
thumbnailView.setOnClickListener(launchAppListener);
100+
thumbnailView.setOnLongClickListener(longClickListener);
101+
102+
// We don't want to dismiss recents if a user clicks on the app title
103+
// (we also don't want to launch the app either, though, because the
104+
// app title is a small target and doesn't have great click feedback)
93105
final View appTitle = view.findViewById(R.id.app_label);
94-
appTitle.setClickable(true);
95-
appTitle.setOnClickListener(launchAppListener);
96-
appTitle.setOnLongClickListener(longClickListener);
106+
appTitle.setContentDescription(" ");
107+
appTitle.setOnTouchListener(noOpListener);
97108
mLinearLayout.addView(view);
98109
}
99110
// Scroll to end after layout.

packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,9 @@
3232
import android.graphics.Bitmap;
3333
import android.graphics.Canvas;
3434
import android.graphics.Matrix;
35-
import android.graphics.Paint;
36-
import android.graphics.RectF;
3735
import android.graphics.Shader.TileMode;
3836
import android.graphics.drawable.BitmapDrawable;
3937
import android.graphics.drawable.Drawable;
40-
import android.graphics.drawable.StateListDrawable;
4138
import android.net.Uri;
4239
import android.os.AsyncTask;
4340
import android.os.Handler;
@@ -56,7 +53,6 @@
5653
import android.view.animation.AnimationUtils;
5754
import android.widget.AdapterView;
5855
import android.widget.BaseAdapter;
59-
import android.widget.FrameLayout;
6056
import android.widget.HorizontalScrollView;
6157
import android.widget.ImageView;
6258
import android.widget.PopupMenu;
@@ -202,6 +198,7 @@ public View getView(int position, View convertView, ViewGroup parent) {
202198
holder.descriptionView.setText(activityDescription.recentTaskInfo.description);
203199
holder.thumbnailView.setTag(activityDescription);
204200
holder.thumbnailView.setOnLongClickListener(new OnLongClickDelegate(convertView));
201+
holder.thumbnailView.setContentDescription(activityDescription.getLabel());
205202
holder.activityDescription = activityDescription;
206203

207204
return convertView;
@@ -228,6 +225,23 @@ public boolean isInContentArea(int x, int y) {
228225
}
229226

230227
public void show(boolean show, boolean animate) {
228+
if (show) {
229+
// Need to update list of recent apps before we set visibility so this view's
230+
// content description is updated before it gets focus for TalkBack mode
231+
refreshApplicationList();
232+
233+
// if there are no apps, either bring up a "No recent apps" message, or just
234+
// quit early
235+
boolean noApps = (mActivityDescriptions.size() == 0);
236+
if (mRecentsNoApps != null) { // doesn't exist on large devices
237+
mRecentsNoApps.setVisibility(noApps ? View.VISIBLE : View.INVISIBLE);
238+
} else {
239+
if (noApps) {
240+
if (DEBUG) Log.v(TAG, "Nothing to show");
241+
return;
242+
}
243+
}
244+
}
231245
if (animate) {
232246
if (mShowing != show) {
233247
mShowing = show;
@@ -378,11 +392,13 @@ protected void onFinishInflate() {
378392
mRecentsNoApps = findViewById(R.id.recents_no_apps);
379393
mChoreo = new Choreographer(this, mRecentsScrim, mRecentsGlowView, mRecentsNoApps, this);
380394
mRecentsDismissButton = findViewById(R.id.recents_dismiss_button);
381-
mRecentsDismissButton.setOnClickListener(new OnClickListener() {
382-
public void onClick(View v) {
383-
hide(true);
384-
}
385-
});
395+
if (mRecentsDismissButton != null) {
396+
mRecentsDismissButton.setOnClickListener(new OnClickListener() {
397+
public void onClick(View v) {
398+
hide(true);
399+
}
400+
});
401+
}
386402

387403
// In order to save space, we make the background texture repeat in the Y direction
388404
if (mRecentsScrim != null && mRecentsScrim.getBackground() instanceof BitmapDrawable) {
@@ -400,9 +416,6 @@ private void createCustomAnimations(LayoutTransition transitioner) {
400416
protected void onVisibilityChanged(View changedView, int visibility) {
401417
super.onVisibilityChanged(changedView, visibility);
402418
if (DEBUG) Log.v(TAG, "onVisibilityChanged(" + changedView + ", " + visibility + ")");
403-
if (visibility == View.VISIBLE && changedView == this) {
404-
refreshApplicationList();
405-
}
406419

407420
if (mRecentsContainer instanceof RecentsHorizontalScrollView) {
408421
((RecentsHorizontalScrollView) mRecentsContainer).onRecentsVisibilityChanged();
@@ -553,6 +566,7 @@ void applyActivityDescription(ActivityDescription ad, int index, boolean anim) {
553566
}
554567
h.iconView.setVisibility(View.VISIBLE);
555568
h.labelView.setText(ad.getLabel());
569+
h.thumbnailView.setContentDescription(ad.getLabel());
556570
if (anim) {
557571
h.labelView.setAnimation(AnimationUtils.loadAnimation(
558572
mContext, R.anim.recent_appear));
@@ -582,10 +596,18 @@ private void refreshApplicationList() {
582596
mThumbnailLoader.cancel(false);
583597
mThumbnailLoader = null;
584598
}
585-
if (mRecentsNoApps != null) { // doesn't exist on large devices
586-
mRecentsNoApps.setVisibility(View.INVISIBLE);
587-
}
599+
588600
mActivityDescriptions = getRecentTasks();
601+
int numRecentApps = mActivityDescriptions.size();
602+
String recentAppsAccessibilityDescription;
603+
if (numRecentApps == 0) {
604+
recentAppsAccessibilityDescription =
605+
getResources().getString(R.string.status_bar_no_recent_apps);
606+
} else {
607+
recentAppsAccessibilityDescription = getResources().getQuantityString(
608+
R.plurals.status_bar_accessibility_recent_apps, numRecentApps, numRecentApps);
609+
}
610+
setContentDescription(recentAppsAccessibilityDescription);
589611
for (ActivityDescription ad : mActivityDescriptions) {
590612
ad.setThumbnail(mDefaultThumbnailBackground);
591613
}
@@ -649,14 +671,6 @@ protected Void doInBackground(Void... params) {
649671
};
650672
mThumbnailLoader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
651673
}
652-
} else {
653-
// Immediately hide this panel
654-
if (DEBUG) Log.v(TAG, "Nothing to show");
655-
if (mRecentsNoApps != null) { // doesn't exist on large devices
656-
mRecentsNoApps.setVisibility(View.VISIBLE);
657-
} else {
658-
hide(false);
659-
}
660674
}
661675
}
662676

0 commit comments

Comments
 (0)