Merge "Add Widget Resize Frame actions" into main

This commit is contained in:
Ana Salazar Maldonado
2025-03-11 15:01:43 -07:00
committed by Android (Google) Code Review
3 changed files with 49 additions and 6 deletions

View File

@@ -471,6 +471,12 @@
<!-- Accessibility action to show quick actions menu for an icon. [CHAR_LIMIT=30] -->
<string name="action_deep_shortcut">Shortcut Menu</string>
<!-- Accessibility name for the app widget resize frame. -->
<string name="widget_frame_name">Widget Resize Frame for <xliff:g id="string" example="Clock">%1$s</xliff:g></string>
<!-- Accessibility action to close the widget resize frame. [CHAR_LIMIT=30] -->
<string name="action_close">Close</string>
<!-- Accessibility action to dismiss a notification in the shortcuts menu for an icon. [CHAR_LIMIT=30] -->
<string name="action_dismiss_notification">Dismiss</string>

View File

@@ -216,6 +216,13 @@ public class AppWidgetResizeFrame extends AbstractFloatingView implements View.O
AppWidgetResizeFrame frame = (AppWidgetResizeFrame) launcher.getLayoutInflater()
.inflate(R.layout.app_widget_resize_frame, dl, false);
frame.setupForWidget(widget, cellLayout, dl);
// Save widget item info as tag on resize frame; so that, the accessibility delegate can
// attach actions that typically happen on widget (e.g. resize, move) also on the resize
// frame.
frame.setTag(widget.getTag());
frame.setAccessibilityDelegate(launcher.getAccessibilityDelegate());
frame.setContentDescription(launcher.asContext().getString(R.string.widget_frame_name,
widget.getContentDescription()));
((DragLayer.LayoutParams) frame.getLayoutParams()).customPosition = true;
dl.addView(frame);
@@ -235,6 +242,13 @@ public class AppWidgetResizeFrame extends AbstractFloatingView implements View.O
}
}
/**
* Retrieves the view where accessibility actions happen.
*/
public View getViewForAccessibility() {
return mWidgetView;
}
private void setupForWidget(LauncherAppWidgetHostView widgetView, CellLayout cellLayout,
DragLayer dragLayer) {
mCellLayout = cellLayout;

View File

@@ -25,6 +25,7 @@ import android.view.accessibility.AccessibilityEvent;
import androidx.annotation.Nullable;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.AppWidgetResizeFrame;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.ButtonDropTarget;
import com.android.launcher3.CellLayout;
@@ -82,6 +83,7 @@ public class LauncherAccessibilityDelegate extends BaseAccessibilityDelegate<Lau
protected static final int MOVE_TO_WORKSPACE = R.id.action_move_to_workspace;
protected static final int RESIZE = R.id.action_resize;
public static final int DEEP_SHORTCUTS = R.id.action_deep_shortcuts;
public static final int CLOSE = R.id.action_close;
public LauncherAccessibilityDelegate(Launcher launcher) {
super(launcher);
@@ -104,6 +106,8 @@ public class LauncherAccessibilityDelegate extends BaseAccessibilityDelegate<Lau
RESIZE, R.string.action_resize, KeyEvent.KEYCODE_R));
mActions.put(DEEP_SHORTCUTS, new LauncherAction(DEEP_SHORTCUTS,
R.string.action_deep_shortcut, KeyEvent.KEYCODE_S));
mActions.put(CLOSE, new LauncherAction(CLOSE,
R.string.action_close, KeyEvent.KEYCODE_X));
}
private static boolean isNotInShortcutMenu(@Nullable View view) {
@@ -137,6 +141,10 @@ public class LauncherAccessibilityDelegate extends BaseAccessibilityDelegate<Lau
}
}
if (host instanceof AppWidgetResizeFrame) {
out.add(mActions.get(CLOSE));
}
if (supportAddToWorkSpace(item)) {
out.add(mActions.get(ADD_TO_WORKSPACE));
}
@@ -183,22 +191,28 @@ public class LauncherAccessibilityDelegate extends BaseAccessibilityDelegate<Lau
}
return dragCondition != null;
} else if (action == MOVE) {
return beginAccessibleDrag(host, item, fromKeyboard);
final View itemView = (host instanceof AppWidgetResizeFrame)
? ((AppWidgetResizeFrame) host).getViewForAccessibility()
: host;
return beginAccessibleDrag(itemView, item, fromKeyboard);
} else if (action == ADD_TO_WORKSPACE) {
return addToWorkspace(item, true /*accessibility*/, null /*finishCallback*/);
} else if (action == MOVE_TO_WORKSPACE) {
return moveToWorkspace(item);
} else if (action == RESIZE) {
final View itemView = (host instanceof AppWidgetResizeFrame)
? ((AppWidgetResizeFrame) host).getViewForAccessibility()
: host;
final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) item;
List<OptionItem> actions = getSupportedResizeActions(host, info);
List<OptionItem> actions = getSupportedResizeActions(itemView, info);
Rect pos = new Rect();
mContext.getDragLayer().getDescendantRectRelativeToSelf(host, pos);
mContext.getDragLayer().getDescendantRectRelativeToSelf(itemView, pos);
ArrowPopup popup = OptionsPopupView.show(mContext, new RectF(pos), actions, false);
popup.requestFocus();
popup.addOnCloseCallback(() -> {
host.requestFocus();
host.sendAccessibilityEvent(TYPE_VIEW_FOCUSED);
host.performAccessibilityAction(ACTION_ACCESSIBILITY_FOCUS, null);
itemView.requestFocus();
itemView.sendAccessibilityEvent(TYPE_VIEW_FOCUSED);
itemView.performAccessibilityAction(ACTION_ACCESSIBILITY_FOCUS, null);
AbstractFloatingView.closeOpenViews(mContext, /* animate= */ false,
AbstractFloatingView.TYPE_WIDGET_RESIZE_FRAME);
});
@@ -208,6 +222,11 @@ public class LauncherAccessibilityDelegate extends BaseAccessibilityDelegate<Lau
: (host instanceof BubbleTextHolder
? ((BubbleTextHolder) host).getBubbleText() : null);
return btv != null && PopupContainerWithArrow.showForIcon(btv) != null;
} else if (action == CLOSE) {
if (host instanceof AppWidgetResizeFrame) {
AbstractFloatingView.closeOpenViews(mContext, /* animate= */ false,
AbstractFloatingView.TYPE_WIDGET_RESIZE_FRAME);
}
} else {
for (ButtonDropTarget dropTarget : mContext.getDropTargetBar().getDropTargets()) {
if (dropTarget.supportsAccessibilityDrop(item, host)
@@ -222,6 +241,10 @@ public class LauncherAccessibilityDelegate extends BaseAccessibilityDelegate<Lau
private List<OptionItem> getSupportedResizeActions(View host, LauncherAppWidgetInfo info) {
List<OptionItem> actions = new ArrayList<>();
if (host instanceof AppWidgetResizeFrame) {
return getSupportedResizeActions(
((AppWidgetResizeFrame) host).getViewForAccessibility(), info);
}
AppWidgetProviderInfo providerInfo = ((LauncherAppWidgetHostView) host).getAppWidgetInfo();
if (providerInfo == null) {
return actions;