Merge "Hybrid Hotseat a11y" into ub-launcher3-master
This commit is contained in:
committed by
Android (Google) Code Review
commit
402e7be703
+1
@@ -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);
|
||||
|
||||
+4
-1
@@ -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));
|
||||
|
||||
+36
-2
@@ -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);
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user