Filter widgets in widget picker activity by size.

Bug: 322191186
Test: atest Launcher3Tests
Flag: NA

Change-Id: I003e05cc16ae576cda07d249d036d2f9dbacdcc2
This commit is contained in:
Will Leshner
2024-01-26 14:39:10 -08:00
parent 64af5ca348
commit f0be49e693

View File

@@ -28,6 +28,7 @@ import android.content.ClipData;
import android.content.ClipDescription;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.WindowInsetsController;
import android.view.WindowManager;
@@ -35,6 +36,7 @@ import android.view.WindowManager;
import androidx.annotation.NonNull;
import com.android.launcher3.dragndrop.SimpleDragLayer;
import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.model.WidgetsModel;
import com.android.launcher3.popup.PopupDataProvider;
import com.android.launcher3.widget.BaseWidgetSheet;
@@ -43,9 +45,13 @@ import com.android.launcher3.widget.model.WidgetsListBaseEntry;
import com.android.launcher3.widget.picker.WidgetsFullSheet;
import java.util.ArrayList;
import java.util.Locale;
/** An Activity that can host Launcher's widget picker. */
public class WidgetPickerActivity extends BaseActivity {
private static final String TAG = "WidgetPickerActivity";
private static final boolean DEBUG = false;
/**
* Name of the extra that indicates that a widget being dragged.
*
@@ -54,10 +60,19 @@ public class WidgetPickerActivity extends BaseActivity {
*/
private static final String EXTRA_IS_PENDING_WIDGET_DRAG = "is_pending_widget_drag";
// Intent extras that specify the desired widget width and height. If these are not specified in
// the intent, then widgets will not be filtered for size.
private static final String EXTRA_DESIRED_WIDGET_WIDTH = "desired_widget_width";
private static final String EXTRA_DESIRED_WIDGET_HEIGHT = "desired_widget_height";
private SimpleDragLayer<WidgetPickerActivity> mDragLayer;
private WidgetsModel mModel;
private final PopupDataProvider mPopupDataProvider = new PopupDataProvider(i -> {});
private int mDesiredWidgetWidth;
private int mDesiredWidgetHeight;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -82,6 +97,13 @@ public class WidgetPickerActivity extends BaseActivity {
widgetSheet.disableNavBarScrim(true);
widgetSheet.addOnCloseListener(this::finish);
// A value of 0 for either size means that no filtering will occur in that dimension. If
// both values are 0, then no size filtering will occur.
mDesiredWidgetWidth =
getIntent().getIntExtra(EXTRA_DESIRED_WIDGET_WIDTH, 0);
mDesiredWidgetHeight =
getIntent().getIntExtra(EXTRA_DESIRED_WIDGET_HEIGHT, 0);
refreshAndBindWidgets();
}
@@ -160,9 +182,108 @@ public class WidgetPickerActivity extends BaseActivity {
final ArrayList<WidgetsListBaseEntry> widgets =
mModel.getFilteredWidgetsListForPicker(
app.getContext(),
/*widgetItemFilter=*/ item -> item.widgetInfo != null
/*widgetItemFilter=*/ widget -> {
final WidgetAcceptabilityVerdict verdict =
isWidgetAcceptable(widget);
verdict.maybeLogVerdict();
return verdict.isAcceptable;
}
);
MAIN_EXECUTOR.execute(() -> mPopupDataProvider.setAllWidgets(widgets));
});
}
private WidgetAcceptabilityVerdict isWidgetAcceptable(WidgetItem widget) {
final AppWidgetProviderInfo info = widget.widgetInfo;
if (info == null) {
return rejectWidget(widget, "shortcut");
}
if (mDesiredWidgetWidth == 0 && mDesiredWidgetHeight == 0) {
// Accept the widget if the desired dimensions are unspecified.
return acceptWidget(widget);
}
final boolean isHorizontallyResizable =
(info.resizeMode & AppWidgetProviderInfo.RESIZE_HORIZONTAL) != 0;
if (mDesiredWidgetWidth > 0 && isHorizontallyResizable) {
if (info.maxResizeWidth > 0 && info.maxResizeWidth < mDesiredWidgetWidth) {
return rejectWidget(
widget,
String.format(
Locale.ENGLISH,
"maxResizeWidth[%d] < mDesiredWidgetWidth[%d]",
info.maxResizeWidth,
mDesiredWidgetWidth));
}
final int minWidth = info.minResizeWidth > 0 ? info.minResizeWidth : info.minWidth;
if (minWidth > mDesiredWidgetWidth) {
return rejectWidget(
widget,
String.format(
Locale.ENGLISH,
"minWidth[%d] > mDesiredWidgetWidth[%d]",
minWidth,
mDesiredWidgetWidth));
}
}
final boolean isVerticallyResizable =
(info.resizeMode & AppWidgetProviderInfo.RESIZE_VERTICAL) != 0;
if (mDesiredWidgetHeight > 0 && isVerticallyResizable) {
if (info.maxResizeHeight > 0 && info.maxResizeHeight < mDesiredWidgetHeight) {
return rejectWidget(
widget,
String.format(
Locale.ENGLISH,
"maxResizeHeight[%d] < mDesiredWidgetHeight[%d]",
info.maxResizeHeight,
mDesiredWidgetHeight));
}
final int minHeight = info.minResizeHeight > 0 ? info.minResizeHeight : info.minHeight;
if (minHeight > mDesiredWidgetHeight) {
return rejectWidget(
widget,
String.format(
Locale.ENGLISH,
"minHeight[%d] > mDesiredWidgetHeight[%d]",
minHeight,
mDesiredWidgetHeight));
}
}
if (!isHorizontallyResizable
&& !isVerticallyResizable
&& (info.minWidth < mDesiredWidgetWidth || info.minHeight < mDesiredWidgetHeight)) {
return rejectWidget(widget, "too small and not resizeable");
}
return acceptWidget(widget);
}
private static WidgetAcceptabilityVerdict rejectWidget(
WidgetItem widget, String rejectionReason) {
return new WidgetAcceptabilityVerdict(false, widget.label, rejectionReason);
}
private static WidgetAcceptabilityVerdict acceptWidget(WidgetItem widget) {
return new WidgetAcceptabilityVerdict(true, widget.label, "");
}
private record WidgetAcceptabilityVerdict(
boolean isAcceptable, String widgetLabel, String reason) {
void maybeLogVerdict() {
// Only log a verdict if a reason is specified.
if (DEBUG && !reason.isEmpty()) {
Log.i(TAG, String.format(
Locale.ENGLISH,
"%s: %s because %s",
widgetLabel,
isAcceptable ? "accepted" : "rejected",
reason));
}
}
}
}