From c22fff6cf6cc030838b6c0435c5a2bc011653291 Mon Sep 17 00:00:00 2001 From: Selim Cinek Date: Fri, 20 May 2016 12:44:30 -0700 Subject: [PATCH] Added accessibility action for scrolling the notifications Also made the stackscroller focusable if and only if it is scrollable. This will allow it to be important for accessibility again. Change-Id: I7773ed3a19d23f6bc62a1b9a23464cfbecd0ec03 Fixes: 25673942 --- .../res/layout/status_bar_expanded.xml | 3 +- .../stack/NotificationStackScrollLayout.java | 76 ++++++++++++++++++- 2 files changed, 76 insertions(+), 3 deletions(-) diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml index 658571e8674d2..2c8a55955b4b6 100644 --- a/packages/SystemUI/res/layout/status_bar_expanded.xml +++ b/packages/SystemUI/res/layout/status_bar_expanded.xml @@ -53,8 +53,7 @@ android:layout_width="@dimen/notification_panel_width" android:layout_height="match_parent" android:layout_gravity="@integer/notification_panel_layout_gravity" - android:layout_marginBottom="@dimen/close_handle_underlap" - android:importantForAccessibility="no" /> + android:layout_marginBottom="@dimen/close_handle_underlap" /> BACKGROUND_FADE = @@ -443,7 +447,6 @@ public class NotificationStackScrollLayout extends ViewGroup private void initView(Context context) { mScroller = new OverScroller(getContext()); - setFocusable(true); setDescendantFocusability(FOCUS_AFTER_DESCENDANTS); setClipChildren(false); final ViewConfiguration configuration = ViewConfiguration.get(context); @@ -1728,6 +1731,15 @@ public class NotificationStackScrollLayout extends ViewGroup } } mContentHeight = height + mTopPadding; + updateScrollability(); + } + + private void updateScrollability() { + boolean scrollable = getScrollRange() > 0; + if (scrollable != mScrollable) { + mScrollable = scrollable; + setFocusable(scrollable); + } } private void updateBackground() { @@ -3534,6 +3546,68 @@ public class NotificationStackScrollLayout extends ViewGroup mPhoneStatusBar.requestNotificationUpdate(); } + /** @hide */ + @Override + public void onInitializeAccessibilityEventInternal(AccessibilityEvent event) { + super.onInitializeAccessibilityEventInternal(event); + event.setScrollable(mScrollable); + event.setScrollX(mScrollX); + event.setScrollY(mOwnScrollY); + event.setMaxScrollX(mScrollX); + event.setMaxScrollY(getScrollRange()); + } + + @Override + public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) { + super.onInitializeAccessibilityNodeInfoInternal(info); + final int scrollRange = getScrollRange(); + if (scrollRange > 0) { + info.setScrollable(true); + if (mScrollY > 0) { + info.addAction( + AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_BACKWARD); + info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_UP); + } + if (mScrollY < scrollRange) { + info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD); + info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_DOWN); + } + } + } + + /** @hide */ + @Override + public boolean performAccessibilityActionInternal(int action, Bundle arguments) { + if (super.performAccessibilityActionInternal(action, arguments)) { + return true; + } + if (!isEnabled()) { + return false; + } + int direction = -1; + switch (action) { + case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: + // fall through + case android.R.id.accessibilityActionScrollDown: + direction = 1; + // fall through + case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: + // fall through + case android.R.id.accessibilityActionScrollUp: + final int viewportHeight = getHeight() - mPaddingBottom - mTopPadding - mPaddingTop + - mBottomStackPeekSize - mBottomStackSlowDownHeight; + final int targetScrollY = Math.max(0, + Math.min(mOwnScrollY + direction * viewportHeight, getScrollRange())); + if (targetScrollY != mOwnScrollY) { + mScroller.startScroll(mScrollX, mOwnScrollY, 0, targetScrollY - mOwnScrollY); + postInvalidateOnAnimation(); + return true; + } + break; + } + return false; + } + @Override public void onGroupsChanged() { mPhoneStatusBar.requestNotificationUpdate();