Merge "Hybrid Hotseat a11y" into ub-launcher3-master

This commit is contained in:
TreeHugger Robot
2020-04-02 22:27:32 +00:00
committed by Android (Google) Code Review
7 changed files with 72 additions and 6 deletions
@@ -210,6 +210,7 @@ public class HotseatEduDialog extends AbstractSlideInView implements Insettable
WorkspaceItemInfo info = predictions.get(i);
PredictedAppIcon icon = PredictedAppIcon.createIcon(mSampleHotseat, info);
icon.setEnabled(false);
icon.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
icon.verifyHighRes();
CellLayout.LayoutParams lp = new CellLayout.LayoutParams(i, 0, 1, 1);
mSampleHotseat.addViewToCellLayout(icon, i, info.getViewId(), lp, true);
@@ -349,7 +349,10 @@ public class HotseatPredictionController implements DragController.DragListener,
mHotSeatItemsCount);
}
private void pinPrediction(ItemInfo info) {
/**
* Pins a predicted app icon into place.
*/
public void pinPrediction(ItemInfo info) {
PredictedAppIcon icon = (PredictedAppIcon) mHotseat.getChildAt(
mHotseat.getCellXFromOrder(info.rank),
mHotseat.getCellYFromOrder(info.rank));
@@ -15,6 +15,7 @@
*/
package com.android.launcher3.uioverrides;
import static com.android.launcher3.accessibility.LauncherAccessibilityDelegate.PIN_PREDICTION;
import static com.android.launcher3.graphics.IconShape.getShape;
import android.content.Context;
@@ -26,15 +27,19 @@ import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityNodeInfo;
import androidx.core.graphics.ColorUtils;
import com.android.launcher3.CellLayout;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.WorkspaceItemInfo;
import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
import com.android.launcher3.graphics.IconPalette;
import com.android.launcher3.hybridhotseat.HotseatPredictionController;
import com.android.launcher3.icons.IconNormalizer;
import com.android.launcher3.touch.ItemClickHandler;
import com.android.launcher3.touch.ItemLongClickListener;
@@ -43,7 +48,8 @@ import com.android.launcher3.views.DoubleShadowBubbleTextView;
/**
* A BubbleTextView with a ring around it's drawable
*/
public class PredictedAppIcon extends DoubleShadowBubbleTextView {
public class PredictedAppIcon extends DoubleShadowBubbleTextView implements
LauncherAccessibilityDelegate.AccessibilityActionHandler {
private static final float RING_EFFECT_RATIO = 0.11f;
@@ -97,6 +103,13 @@ public class PredictedAppIcon extends DoubleShadowBubbleTextView {
super.applyFromWorkspaceItem(info);
int color = IconPalette.getMutedColor(info.bitmap.color, 0.54f);
mIconRingPaint.setColor(ColorUtils.setAlphaComponent(color, 200));
if (mIsPinned) {
setContentDescription(info.contentDescription);
} else {
setContentDescription(
getContext().getString(R.string.hotseat_prediction_content_description,
info.contentDescription));
}
}
/**
@@ -104,9 +117,9 @@ public class PredictedAppIcon extends DoubleShadowBubbleTextView {
*/
public void pin(WorkspaceItemInfo info) {
if (mIsPinned) return;
mIsPinned = true;
applyFromWorkspaceItem(info);
setOnLongClickListener(ItemLongClickListener.INSTANCE_WORKSPACE);
mIsPinned = true;
((CellLayout.LayoutParams) getLayoutParams()).canReorder = true;
invalidate();
}
@@ -121,6 +134,27 @@ public class PredictedAppIcon extends DoubleShadowBubbleTextView {
verifyHighRes();
}
@Override
public void addSupportedAccessibilityActions(AccessibilityNodeInfo accessibilityNodeInfo) {
accessibilityNodeInfo.addAction(
new AccessibilityNodeInfo.AccessibilityAction(PIN_PREDICTION,
getContext().getText(R.string.pin_prediction)));
}
@Override
public boolean performAccessibilityAction(int action, ItemInfo info) {
QuickstepLauncher launcher = Launcher.cast(Launcher.getLauncher(getContext()));
if (action == PIN_PREDICTION) {
if (launcher == null || launcher.getHotseatPredictionController() == null) {
return false;
}
HotseatPredictionController controller = launcher.getHotseatPredictionController();
controller.pinPrediction(info);
return true;
}
return false;
}
@Override
public void getIconBounds(Rect outBounds) {
super.getIconBounds(outBounds);
+3
View File
@@ -90,6 +90,9 @@
<!-- tip shown if user declines migration and has some open spots for prediction -->
<string name="hotseat_tip_gaps_filled">App suggestions added to empty space</string>
<!-- content description for hotseat items -->
<string name="hotseat_prediction_content_description">Predicted app: <xliff:g id="title" example="Chrome">%1$s</xliff:g></string>
<!-- Title shown during interactive part of Back gesture tutorial for right edge. [CHAR LIMIT=30] -->
<string name="back_gesture_tutorial_playground_title_swipe_inward_right_edge" translatable="false">Try the back gesture</string>
+1
View File
@@ -109,6 +109,7 @@
<item type="id" name="action_dismiss_notification" />
<item type="id" name="action_remote_action_shortcut" />
<item type="id" name="action_dismiss_prediction" />
<item type="id" name="action_pin_prediction"/>
<!-- QSB IDs. DO not change -->
<item type="id" name="search_container_workspace" />
@@ -67,7 +67,7 @@ public class DeleteDropTarget extends ButtonDropTarget {
public boolean supportsAccessibilityDrop(ItemInfo info, View view) {
if (info instanceof WorkspaceItemInfo) {
// Support the action unless the item is in a context menu.
return info.screenId >= 0;
return canRemove(info);
}
return (info instanceof LauncherAppWidgetInfo)
@@ -56,6 +56,7 @@ public class LauncherAccessibilityDelegate extends AccessibilityDelegate impleme
public static final int REMOVE = R.id.action_remove;
public static final int UNINSTALL = R.id.action_uninstall;
public static final int DISMISS_PREDICTION = R.id.action_dismiss_prediction;
public static final int PIN_PREDICTION = R.id.action_pin_prediction;
public static final int RECONFIGURE = R.id.action_reconfigure;
protected static final int ADD_TO_WORKSPACE = R.id.action_add_to_workspace;
protected static final int MOVE = R.id.action_move;
@@ -120,6 +121,10 @@ public class LauncherAccessibilityDelegate extends AccessibilityDelegate impleme
if (!(host.getTag() instanceof ItemInfo)) return;
ItemInfo item = (ItemInfo) host.getTag();
if (host instanceof AccessibilityActionHandler) {
((AccessibilityActionHandler) host).addSupportedAccessibilityActions(info);
}
// If the request came from keyboard, do not add custom shortcuts as that is already
// exposed as a direct shortcut
if (!fromKeyboard && ShortcutUtil.supportsShortcuts(item)) {
@@ -164,7 +169,7 @@ public class LauncherAccessibilityDelegate extends AccessibilityDelegate impleme
private boolean itemSupportsAccessibleDrag(ItemInfo item) {
if (item instanceof WorkspaceItemInfo) {
// Support the action unless the item is in a context menu.
return item.screenId >= 0;
return item.screenId >= 0 && item.container != Favorites.CONTAINER_HOTSEAT_PREDICTION;
}
return (item instanceof LauncherAppWidgetInfo)
|| (item instanceof FolderInfo);
@@ -195,7 +200,10 @@ public class LauncherAccessibilityDelegate extends AccessibilityDelegate impleme
}
}
}
if (host instanceof AccessibilityActionHandler
&& ((AccessibilityActionHandler) host).performAccessibilityAction(action, item)) {
return true;
}
if (action == MOVE) {
beginAccessibleDrag(host, item);
} else if (action == ADD_TO_WORKSPACE) {
@@ -466,4 +474,20 @@ public class LauncherAccessibilityDelegate extends AccessibilityDelegate impleme
}
return screenId;
}
/**
* An interface allowing views to handle their own action.
*/
public interface AccessibilityActionHandler {
/**
* performs accessibility action and returns true on success
*/
boolean performAccessibilityAction(int action, ItemInfo itemInfo);
/**
* adds all the accessibility actions that can be handled.
*/
void addSupportedAccessibilityActions(AccessibilityNodeInfo accessibilityNodeInfo);
}
}