diff options
author | Sunny Goyal <sunnygoyal@google.com> | 2015-05-04 15:50:25 -0700 |
---|---|---|
committer | Sunny Goyal <sunnygoyal@google.com> | 2015-05-06 12:06:48 -0700 |
commit | 1d08f70441999c66b76c97e48b4149e1433be3c3 (patch) | |
tree | a46b0b3ff4cd65b16035366d496ff1030be2c44a /src/com/android/launcher3 | |
parent | deb189fd105a5367d965538fd2ebc4a132346ee4 (diff) | |
download | android_packages_apps_Trebuchet-1d08f70441999c66b76c97e48b4149e1433be3c3.tar.gz android_packages_apps_Trebuchet-1d08f70441999c66b76c97e48b4149e1433be3c3.tar.bz2 android_packages_apps_Trebuchet-1d08f70441999c66b76c97e48b4149e1433be3c3.zip |
Accessibility: Page re-ordering in overview mode
Change-Id: I5fc0ad326a63b6768cb1fae55ee6e05a9fc2b659
Diffstat (limited to 'src/com/android/launcher3')
4 files changed, 160 insertions, 14 deletions
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java index a4593ecb4..0739babea 100644 --- a/src/com/android/launcher3/PagedView.java +++ b/src/com/android/launcher3/PagedView.java @@ -559,7 +559,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc /** * Sets the current page. */ - void setCurrentPage(int currentPage) { + public void setCurrentPage(int currentPage) { if (!mScroller.isFinished()) { abortScrollerAnimation(true); } @@ -2535,7 +2535,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc } } - protected void onStartReordering() { + public void onStartReordering() { // Set the touch state to reordering (allows snapping to pages, dragging a child, etc.) mTouchState = TOUCH_STATE_REORDERING; mIsReordering = true; @@ -2555,7 +2555,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc } } - protected void onEndReordering() { + public void onEndReordering() { mIsReordering = false; } diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index e7a41e09b..f2fa59bcd 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -63,6 +63,7 @@ import com.android.launcher3.Launcher.LauncherOverlay; import com.android.launcher3.LauncherAccessibilityDelegate.AccessibilityDragSource; import com.android.launcher3.LauncherSettings.Favorites; import com.android.launcher3.UninstallDropTarget.UninstallSource; +import com.android.launcher3.accessibility.OverviewScreenAccessibilityDelegate; import com.android.launcher3.compat.UserHandleCompat; import com.android.launcher3.util.LongArrayMap; import com.android.launcher3.util.Thunk; @@ -277,6 +278,8 @@ public class Workspace extends SmoothPagedView // Handles workspace state transitions private WorkspaceStateTransitionAnimation mStateTransitionAnimation; + private AccessibilityDelegate mPagesAccessibilityDelegate; + private final Runnable mBindPages = new Runnable() { @Override public void run() { @@ -2000,14 +2003,14 @@ public class Workspace extends SmoothPagedView range[1] = Math.max(0, end); } - protected void onStartReordering() { + public void onStartReordering() { super.onStartReordering(); showOutlines(); // Reordering handles its own animations, disable the automatic ones. disableLayoutTransitions(); } - protected void onEndReordering() { + public void onEndReordering() { super.onEndReordering(); if (mLauncher.isWorkspaceLoading()) { @@ -2068,11 +2071,45 @@ public class Workspace extends SmoothPagedView return mState; } - private void updateAccessibilityFlags() { - int accessible = mState == State.NORMAL ? - IMPORTANT_FOR_ACCESSIBILITY_NO : - IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS; - setImportantForAccessibility(accessible); + public void updateAccessibilityFlags() { + if (Utilities.isLmpOrAbove()) { + int total = getPageCount(); + for (int i = numCustomPages(); i < total; i++) { + updateAccessibilityFlags((CellLayout) getPageAt(i), i); + } + if (mState == State.NORMAL) { + setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO); + } else { + setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES); + } + } else { + int accessible = mState == State.NORMAL ? + IMPORTANT_FOR_ACCESSIBILITY_NO : + IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS; + setImportantForAccessibility(accessible); + } + } + + private void updateAccessibilityFlags(CellLayout page, int pageNo) { + if (mState == State.OVERVIEW) { + page.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES); + page.getShortcutsAndWidgets().setImportantForAccessibility( + IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS); + page.setContentDescription(getPageDescription(pageNo)); + + if (mPagesAccessibilityDelegate == null) { + mPagesAccessibilityDelegate = new OverviewScreenAccessibilityDelegate(this); + } + page.setAccessibilityDelegate(mPagesAccessibilityDelegate); + } else { + int accessible = mState == State.NORMAL ? + IMPORTANT_FOR_ACCESSIBILITY_NO : + IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS; + page.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO); + page.getShortcutsAndWidgets().setImportantForAccessibility(accessible); + page.setContentDescription(null); + page.setAccessibilityDelegate(null); + } } @Override @@ -4460,11 +4497,15 @@ public class Workspace extends SmoothPagedView } protected String getCurrentPageDescription() { - int page = (mNextPage != INVALID_PAGE) ? mNextPage : mCurrentPage; - int delta = numCustomPages(); if (hasCustomContent() && getNextPage() == 0) { return mCustomContentDescription; } + int page = (mNextPage != INVALID_PAGE) ? mNextPage : mCurrentPage; + return getPageDescription(page); + } + + private String getPageDescription(int page) { + int delta = numCustomPages(); return String.format(getContext().getString(R.string.workspace_scroll_format), page + 1 - delta, getChildCount() - delta); } diff --git a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java index a0cedeb63..61a64e3f3 100644 --- a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java +++ b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java @@ -24,8 +24,11 @@ import android.animation.ValueAnimator; import android.content.Context; import android.content.res.Resources; import android.view.View; +import android.view.ViewGroup; import android.view.accessibility.AccessibilityManager; +import android.view.accessibility.AccessibilityNodeInfo; import android.view.animation.DecelerateInterpolator; + import com.android.launcher3.util.Thunk; import java.util.HashMap; @@ -190,7 +193,7 @@ public class WorkspaceStateTransitionAnimation { final HashMap<View, Integer> layerViews) { AccessibilityManager am = (AccessibilityManager) mLauncher.getSystemService(Context.ACCESSIBILITY_SERVICE); - boolean accessibilityEnabled = am.isEnabled(); + final boolean accessibilityEnabled = am.isEnabled(); // Reinitialize animation arrays for the current workspace state reinitializeAnimationArrays(); @@ -301,7 +304,7 @@ public class WorkspaceStateTransitionAnimation { } final View searchBar = mLauncher.getOrCreateQsbBar(); - final View overviewPanel = mLauncher.getOverviewPanel(); + final ViewGroup overviewPanel = mLauncher.getOverviewPanel(); final View hotseat = mLauncher.getHotseat(); final View pageIndicator = mWorkspace.getPageIndicator(); if (animated) { @@ -424,6 +427,11 @@ public class WorkspaceStateTransitionAnimation { @Override public void onAnimationEnd(Animator animation) { mStateAnimator = null; + + if (accessibilityEnabled && overviewPanel.getVisibility() == View.VISIBLE) { + overviewPanel.getChildAt(0).performAccessibilityAction( + AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null); + } } }); } else { @@ -443,6 +451,11 @@ public class WorkspaceStateTransitionAnimation { mWorkspace.setScaleX(mNewScale); mWorkspace.setScaleY(mNewScale); mWorkspace.setTranslationY(finalWorkspaceTranslationY); + + if (accessibilityEnabled && overviewPanel.getVisibility() == View.VISIBLE) { + overviewPanel.getChildAt(0).performAccessibilityAction( + AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null); + } } if (stateIsNormal) { diff --git a/src/com/android/launcher3/accessibility/OverviewScreenAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/OverviewScreenAccessibilityDelegate.java new file mode 100644 index 000000000..d3f5230b2 --- /dev/null +++ b/src/com/android/launcher3/accessibility/OverviewScreenAccessibilityDelegate.java @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.launcher3.accessibility; + +import android.content.Context; +import android.os.Bundle; +import android.util.SparseArray; +import android.view.View; +import android.view.View.AccessibilityDelegate; +import android.view.accessibility.AccessibilityNodeInfo; +import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction; + +import com.android.launcher3.R; +import com.android.launcher3.Workspace; + +public class OverviewScreenAccessibilityDelegate extends AccessibilityDelegate { + + private static final int MOVE_BACKWARD = R.id.action_move_screen_backwards; + private static final int MOVE_FORWARD = R.id.action_move_screen_forwards; + + private final SparseArray<AccessibilityAction> mActions = new SparseArray<>(); + private final Workspace mWorkspace; + + public OverviewScreenAccessibilityDelegate(Workspace workspace) { + mWorkspace = workspace; + + Context context = mWorkspace.getContext(); + boolean isRtl = mWorkspace.isLayoutRtl(); + mActions.put(MOVE_BACKWARD, new AccessibilityAction(MOVE_BACKWARD, + context.getText(isRtl ? R.string.action_move_screen_right : + R.string.action_move_screen_left))); + mActions.put(MOVE_FORWARD, new AccessibilityAction(MOVE_FORWARD, + context.getText(isRtl ? R.string.action_move_screen_left : + R.string.action_move_screen_right))); + } + + @Override + public boolean performAccessibilityAction(View host, int action, Bundle args) { + if (host != null) { + if (action == AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS ) { + int index = mWorkspace.indexOfChild(host); + mWorkspace.setCurrentPage(index); + } else if (action == MOVE_FORWARD) { + movePage(mWorkspace.indexOfChild(host) + 1, host); + return true; + } else if (action == MOVE_BACKWARD) { + movePage(mWorkspace.indexOfChild(host) - 1, host); + return true; + } + } + + return super.performAccessibilityAction(host, action, args); + } + + private void movePage(int finalIndex, View view) { + mWorkspace.onStartReordering(); + mWorkspace.removeView(view); + mWorkspace.addView(view, finalIndex); + mWorkspace.onEndReordering(); + mWorkspace.announceForAccessibility(mWorkspace.getContext().getText(R.string.screen_moved)); + + mWorkspace.updateAccessibilityFlags(); + view.performAccessibilityAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null); + } + + @Override + public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) { + super.onInitializeAccessibilityNodeInfo(host, info); + + int index = mWorkspace.indexOfChild(host); + if (index < mWorkspace.getChildCount() - 1) { + info.addAction(mActions.get(MOVE_FORWARD)); + } + if (index > mWorkspace.numCustomPages()) { + info.addAction(mActions.get(MOVE_BACKWARD)); + } + } +} |