OSDN Git Service

Update accessibility for popup
authorTony <twickham@google.com>
Thu, 11 May 2017 02:23:57 +0000 (21:23 -0500)
committerTony Wickham <twickham@google.com>
Thu, 11 May 2017 20:59:52 +0000 (13:59 -0700)
- Content description includes count of notifications.
- Notifications have a dismiss action.
- All icons that support shortcuts will have action to show
  shortcut menu, since there will be system shortcuts even if
  there are no deep shortcuts.

Bug: 36564782
Change-Id: I51b085fa26754f2dcd93c7db6548f2edf054f494

res/values/config.xml
res/values/strings.xml
src/com/android/launcher3/BubbleTextView.java
src/com/android/launcher3/Launcher.java
src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
src/com/android/launcher3/accessibility/ShortcutMenuAccessibilityDelegate.java
src/com/android/launcher3/notification/NotificationFooterLayout.java
src/com/android/launcher3/notification/NotificationItemView.java
src/com/android/launcher3/notification/NotificationMainView.java
src/com/android/launcher3/popup/PopupContainerWithArrow.java

index 19966f6..d8e6b1a 100644 (file)
     <item type="id" name="action_move_screen_forwards" />
     <item type="id" name="action_resize" />
     <item type="id" name="action_deep_shortcuts" />
+    <item type="id" name="action_dismiss_notification" />
 </resources>
index 4bee87d..f906a78 100644 (file)
 
     <!-- Accessibility description for the shortcuts menu shown for an app. -->
     <string name="shortcuts_menu_description"><xliff:g id="number_of_shortcuts" example="3">%1$d</xliff:g> shortcuts for <xliff:g id="app_name" example="Messenger">%2$s</xliff:g></string>
+    <!-- Accessibility description when the shortcuts menu has notifications as well as shortcuts. -->
+    <string name="shortcuts_menu_with_notifications_description"><xliff:g id="number_of_shortcuts" example="3">%1$d</xliff:g> shortcuts and <xliff:g id="number_of_notifications" example="3">%2$d</xliff:g> notifications for <xliff:g id="app_name" example="Messenger">%3$s</xliff:g></string>
+
+    <!-- Accessibility action to dismiss a notification in the shortcuts menu for an icon. [CHAR_LIMIT=30] -->
+    <string name="action_dismiss_notification">Dismiss</string>
+
+    <!-- Accessibility confirmation for notification being dismissed. -->
+    <string name="notification_dismissed">Notification dismissed</string>
 
 </resources>
index cb40d3d..d93b655 100644 (file)
@@ -660,14 +660,6 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver {
     }
 
     /**
-     * Returns true if the view can show custom shortcuts.
-     */
-    public boolean hasDeepShortcuts() {
-        return !mLauncher.getPopupDataProvider().getShortcutIdsForItem((ItemInfo) getTag())
-                .isEmpty();
-    }
-
-    /**
      * Interface to be implemented by the grand parent to allow click shadow effect.
      */
     public interface BubbleTextShadowHandler {
index eef578d..2de1003 100644 (file)
@@ -4061,8 +4061,8 @@ public class Launcher extends BaseActivity
             shortcutInfos.add(new KeyboardShortcutInfo(getString(R.string.custom_actions),
                     KeyEvent.KEYCODE_O, KeyEvent.META_CTRL_ON));
         }
-        if (currentFocus instanceof BubbleTextView &&
-                ((BubbleTextView) currentFocus).hasDeepShortcuts()) {
+        if (currentFocus.getTag() instanceof ItemInfo
+                && DeepShortcutManager.supportsShortcuts((ItemInfo) currentFocus.getTag())) {
             shortcutInfos.add(new KeyboardShortcutInfo(getString(R.string.action_deep_shortcut),
                     KeyEvent.KEYCODE_S, KeyEvent.META_CTRL_ON));
         }
index a476650..70e5781 100644 (file)
@@ -37,6 +37,7 @@ import com.android.launcher3.Workspace;
 import com.android.launcher3.dragndrop.DragController.DragListener;
 import com.android.launcher3.dragndrop.DragOptions;
 import com.android.launcher3.folder.Folder;
+import com.android.launcher3.shortcuts.DeepShortcutManager;
 import com.android.launcher3.util.Thunk;
 
 import java.util.ArrayList;
@@ -104,8 +105,7 @@ public class LauncherAccessibilityDelegate extends AccessibilityDelegate impleme
 
         // If the request came from keyboard, do not add custom shortcuts as that is already
         // exposed as a direct shortcut
-        if (!fromKeyboard && host instanceof BubbleTextView
-                && ((BubbleTextView) host).hasDeepShortcuts()) {
+        if (!fromKeyboard && DeepShortcutManager.supportsShortcuts(item)) {
             info.addAction(mActions.get(DEEP_SHORTCUTS));
         }
 
index b784fe7..8161219 100644 (file)
@@ -18,14 +18,15 @@ package com.android.launcher3.accessibility;
 
 import android.view.View;
 import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
 
 import com.android.launcher3.AbstractFloatingView;
 import com.android.launcher3.ItemInfo;
 import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherModel;
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.R;
 import com.android.launcher3.ShortcutInfo;
+import com.android.launcher3.notification.NotificationMainView;
 import com.android.launcher3.shortcuts.DeepShortcutView;
 
 import java.util.ArrayList;
@@ -36,14 +37,23 @@ import java.util.ArrayList;
  */
 public class ShortcutMenuAccessibilityDelegate extends LauncherAccessibilityDelegate {
 
+    private static final int DISMISS_NOTIFICATION = R.id.action_dismiss_notification;
+
     public ShortcutMenuAccessibilityDelegate(Launcher launcher) {
         super(launcher);
+        mActions.put(DISMISS_NOTIFICATION, new AccessibilityAction(DISMISS_NOTIFICATION,
+                launcher.getText(R.string.action_dismiss_notification)));
     }
 
     @Override
     public void addSupportedActions(View host, AccessibilityNodeInfo info, boolean fromKeyboard) {
         if ((host.getParent() instanceof DeepShortcutView)) {
             info.addAction(mActions.get(ADD_TO_WORKSPACE));
+        } else if (host instanceof NotificationMainView) {
+            NotificationMainView notificationView = (NotificationMainView) host;
+            if (notificationView.canChildBeDismissed(notificationView)) {
+                info.addAction(mActions.get(DISMISS_NOTIFICATION));
+            }
         }
     }
 
@@ -74,6 +84,14 @@ public class ShortcutMenuAccessibilityDelegate extends LauncherAccessibilityDele
                 onComplete.run();
             }
             return true;
+        } else if (action == DISMISS_NOTIFICATION) {
+            if (!(host instanceof NotificationMainView)) {
+                return false;
+            }
+            NotificationMainView notificationView = (NotificationMainView) host;
+            notificationView.onChildDismissed(notificationView);
+            announceConfirmation(R.string.notification_dismissed);
+            return true;
         }
         return false;
     }
index 1eef743..051c033 100644 (file)
@@ -141,6 +141,7 @@ public class NotificationFooterLayout extends FrameLayout {
         icon.setBackground(info.getIconForBackground(getContext(), mBackgroundColor));
         icon.setOnClickListener(info);
         icon.setTag(info);
+        icon.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
         mIconRow.addView(icon, 0, mIconLayoutParams);
         return icon;
     }
index dd272b3..997def2 100644 (file)
@@ -77,6 +77,10 @@ public class NotificationItemView extends PopupItemView implements LogContainerP
         mSwipeHelper.setDisableHardwareLayers(true);
     }
 
+    public NotificationMainView getMainView() {
+        return mMainView;
+    }
+
     public int getHeightMinusFooter() {
         int footerHeight = mFooter.getParent() == null ? 0 : mFooter.getHeight();
         return getHeight() - footerHeight;
index d6e0272..0d6da77 100644 (file)
@@ -122,7 +122,7 @@ public class NotificationMainView extends FrameLayout implements SwipeHelper.Cal
 
     @Override
     public boolean canChildBeDismissed(View v) {
-        return mNotificationInfo.dismissable;
+        return mNotificationInfo != null && mNotificationInfo.dismissable;
     }
 
     @Override
index d4ee3b8..ccead37 100644 (file)
@@ -114,7 +114,6 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra
 
         mStartDragThreshold = getResources().getDimensionPixelSize(
                 R.dimen.deep_shortcuts_start_drag_threshold);
-        // TODO: make sure the delegate works for all items, not just shortcuts.
         mAccessibilityDelegate = new ShortcutMenuAccessibilityDelegate(mLauncher);
         mIsRtl = Utilities.isRtl(getResources());
     }
@@ -176,7 +175,7 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra
         // Add dummy views first, and populate with real info when ready.
         PopupPopulator.Item[] itemsToPopulate = PopupPopulator
                 .getItemsToPopulate(shortcutIds, notificationKeys, systemShortcuts);
-        addDummyViews(originalIcon, itemsToPopulate, notificationKeys.size() > 1);
+        addDummyViews(itemsToPopulate, notificationKeys.size() > 1);
 
         measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
         orientAboutIcon(originalIcon, arrowHeight + arrowVerticalOffset);
@@ -187,7 +186,7 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra
             mNotificationItemView = null;
             mShortcutsItemView = null;
             itemsToPopulate = PopupPopulator.reverseItems(itemsToPopulate);
-            addDummyViews(originalIcon, itemsToPopulate, notificationKeys.size() > 1);
+            addDummyViews(itemsToPopulate, notificationKeys.size() > 1);
 
             measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
             orientAboutIcon(originalIcon, arrowHeight + arrowVerticalOffset);
@@ -204,6 +203,17 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra
             updateNotificationHeader();
         }
 
+        int numShortcuts = shortcutViews.size() + systemShortcutViews.size();
+        int numNotifications = notificationKeys.size();
+        if (numNotifications == 0) {
+            setContentDescription(getContext().getString(R.string.shortcuts_menu_description,
+                    numShortcuts, originalIcon.getContentDescription().toString()));
+        } else {
+            setContentDescription(getContext().getString(
+                    R.string.shortcuts_menu_with_notifications_description, numShortcuts,
+                    numNotifications, originalIcon.getContentDescription().toString()));
+        }
+
         // Add the arrow.
         final int arrowHorizontalOffset = resources.getDimensionPixelSize(isAlignedWithStart() ?
                 R.dimen.popup_arrow_horizontal_offset_start :
@@ -225,8 +235,8 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra
                 systemShortcuts, systemShortcutViews));
     }
 
-    private void addDummyViews(BubbleTextView originalIcon,
-            PopupPopulator.Item[] itemTypesToPopulate, boolean notificationFooterHasIcons) {
+    private void addDummyViews(PopupPopulator.Item[] itemTypesToPopulate,
+            boolean notificationFooterHasIcons) {
         final Resources res = getResources();
         final int spacing = res.getDimensionPixelSize(R.dimen.popup_items_spacing);
         final LayoutInflater inflater = mLauncher.getLayoutInflater();
@@ -243,12 +253,14 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra
                 int footerHeight = notificationFooterHasIcons ?
                         res.getDimensionPixelSize(R.dimen.notification_footer_height) : 0;
                 item.findViewById(R.id.footer).getLayoutParams().height = footerHeight;
+                mNotificationItemView.getMainView().setAccessibilityDelegate(mAccessibilityDelegate);
+            } else if (itemTypeToPopulate == PopupPopulator.Item.SHORTCUT) {
+                item.setAccessibilityDelegate(mAccessibilityDelegate);
             }
 
             boolean shouldAddBottomMargin = nextItemTypeToPopulate != null
                     && itemTypeToPopulate.isShortcut ^ nextItemTypeToPopulate.isShortcut;
 
-            item.setAccessibilityDelegate(mAccessibilityDelegate);
             if (itemTypeToPopulate.isShortcut) {
                 if (mShortcutsItemView == null) {
                     mShortcutsItemView = (ShortcutsItemView) inflater.inflate(
@@ -266,9 +278,6 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra
                 }
             }
         }
-        // TODO: update this, since not all items are shortcuts
-        setContentDescription(getContext().getString(R.string.shortcuts_menu_description,
-                numItems, originalIcon.getContentDescription().toString()));
     }
 
     protected PopupItemView getItemViewAt(int index) {