Announcing the task list as you scroll. (Bug 15699050)

Change-Id: I7453f41a2c87241e538cdc7281cdc20a8710ebbb
This commit is contained in:
Winson Chung
2014-09-09 16:12:59 +02:00
parent 8a8d9611e2
commit ee44595bd5
2 changed files with 64 additions and 0 deletions

View File

@@ -56,6 +56,7 @@ import android.view.Display;
import android.view.DisplayInfo;
import android.view.SurfaceControl;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager;
import com.android.systemui.recents.Constants;
import java.io.IOException;
@@ -73,6 +74,7 @@ public class SystemServicesProxy {
final static BitmapFactory.Options sBitmapOptions;
AccessibilityManager mAccm;
ActivityManager mAm;
IActivityManager mIam;
AppWidgetManager mAwm;
@@ -97,6 +99,7 @@ public class SystemServicesProxy {
/** Private constructor */
public SystemServicesProxy(Context context) {
mAccm = AccessibilityManager.getInstance(context);
mAm = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
mIam = ActivityManagerNative.getDefault();
mAwm = AppWidgetManager.getInstance(context);
@@ -441,6 +444,15 @@ public class SystemServicesProxy {
host.deleteAppWidgetId(appWidgetId);
}
/**
* Returns whether touch exploration is currently enabled.
*/
public boolean isTouchExplorationEnabled() {
if (mAccm == null) return false;
return mAccm.isEnabled() && mAccm.isTouchExplorationEnabled();
}
/**
* Returns a global setting.
*/

View File

@@ -22,11 +22,15 @@ import android.graphics.Rect;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
import com.android.systemui.R;
import com.android.systemui.recents.Constants;
import com.android.systemui.recents.RecentsConfiguration;
import com.android.systemui.recents.misc.DozeTrigger;
import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.recents.model.RecentsPackageMonitor;
import com.android.systemui.recents.model.RecentsTaskLoader;
import com.android.systemui.recents.model.Task;
@@ -67,6 +71,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
DebugOverlayView mDebugOverlay;
Rect mTaskStackBounds = new Rect();
int mFocusedTaskIndex = -1;
int mPrevAccessibilityFocusedIndex = -1;
// Optimizations
int mStackViewsAnimationDuration;
@@ -244,6 +249,9 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
/** Synchronizes the views with the model */
boolean synchronizeStackViewsWithModel() {
if (mStackViewsDirty) {
RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
SystemServicesProxy ssp = loader.getSystemServicesProxy();
// Get all the task transforms
ArrayList<Task> tasks = mStack.getTasks();
float stackScroll = mStackScroller.getStackScroll();
@@ -293,6 +301,18 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
// Animate the task into place
tv.updateViewPropertiesToTaskTransform(mCurrentTaskTransforms.get(taskIndex),
mStackViewsAnimationDuration);
// Request accessibility focus on the next view if we removed the task
// that previously held accessibility focus
childCount = getChildCount();
if (childCount > 0 && ssp.isTouchExplorationEnabled()) {
TaskView atv = (TaskView) getChildAt(childCount - 1);
int indexOfTask = mStack.indexOfTask(atv.getTask());
if (mPrevAccessibilityFocusedIndex != indexOfTask) {
tv.requestAccessibilityFocus();
mPrevAccessibilityFocusedIndex = indexOfTask;
}
}
}
// Reset the request-synchronize params
@@ -431,6 +451,22 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
tv.dismissTask();
}
@Override
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
super.onInitializeAccessibilityEvent(event);
int childCount = getChildCount();
if (childCount > 0) {
TaskView backMostTask = (TaskView) getChildAt(0);
TaskView frontMostTask = (TaskView) getChildAt(childCount - 1);
event.setFromIndex(mStack.indexOfTask(backMostTask.getTask()));
event.setToIndex(mStack.indexOfTask(frontMostTask.getTask()));
event.setContentDescription(frontMostTask.getTask().activityLabel);
}
event.setItemCount(mStack.getTaskCount());
event.setScrollY(mStackScroller.mScroller.getCurrY());
event.setMaxScrollY(mStackScroller.progressToScrollRange(mLayoutAlgorithm.mMaxScrollP));
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return mTouchHandler.onInterceptTouchEvent(ev);
@@ -447,6 +483,8 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
// Synchronize the views
synchronizeStackViewsWithModel();
clipTaskViews();
// Notify accessibility
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SCROLLED);
}
/** Computes the stack and task rects */
@@ -623,6 +661,15 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
mStartEnterAnimationCompleted = true;
// Start dozing
mUIDozeTrigger.startDozing();
// Focus the first view if accessibility is enabled
RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
SystemServicesProxy ssp = loader.getSystemServicesProxy();
int childCount = getChildCount();
if (childCount > 0 && ssp.isTouchExplorationEnabled()) {
TaskView tv = ((TaskView) getChildAt(childCount - 1));
tv.requestAccessibilityFocus();
mPrevAccessibilityFocusedIndex = mStack.indexOfTask(tv.getTask());
}
}
});
}
@@ -812,6 +859,11 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
public void prepareViewToEnterPool(TaskView tv) {
Task task = tv.getTask();
// Clear the accessibility focus for that view
if (tv.isAccessibilityFocused()) {
tv.clearAccessibilityFocus();
}
// Report that this tasks's data is no longer being used
RecentsTaskLoader.getInstance().unloadTaskData(task);