diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 0099806aa0..9f7575d500 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -528,6 +528,7 @@ public class Launcher extends StatefulActivity mAppWidgetManager = new WidgetManagerHelper(this); mAppWidgetHolder = createAppWidgetHolder(); mAppWidgetHolder.startListening(); + mAppWidgetHolder.addProviderChangeListener(() -> refreshAndBindWidgetsForPackageUser(null)); mPopupDataProvider = new PopupDataProvider(this::updateNotificationDots); diff --git a/src/com/android/launcher3/model/PackageUpdatedTask.java b/src/com/android/launcher3/model/PackageUpdatedTask.java index 9a0a6eb2cc..4f2d398b42 100644 --- a/src/com/android/launcher3/model/PackageUpdatedTask.java +++ b/src/com/android/launcher3/model/PackageUpdatedTask.java @@ -34,7 +34,6 @@ import android.util.Log; import androidx.annotation.NonNull; import com.android.launcher3.Flags; -import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherSettings; import com.android.launcher3.LauncherSettings.Favorites; @@ -136,14 +135,6 @@ public class PackageUpdatedTask extends BaseModelUpdateTask { iconCache.updateIconsForPkg(packages[i], mUser); activitiesLists.put( packages[i], appsList.updatePackage(context, packages[i], mUser)); - - // The update may have changed which shortcuts/widgets are available. - // Refresh the widgets for the package if we have an activity running. - Launcher launcher = Launcher.ACTIVITY_TRACKER.getCreatedActivity(); - if (launcher != null) { - launcher.refreshAndBindWidgetsForPackageUser( - new PackageUserKey(packages[i], mUser)); - } } } // Since package was just updated, the target must be available now. diff --git a/src/com/android/launcher3/touch/ItemLongClickListener.java b/src/com/android/launcher3/touch/ItemLongClickListener.java index 96cc412845..9e7d4dcb6e 100644 --- a/src/com/android/launcher3/touch/ItemLongClickListener.java +++ b/src/com/android/launcher3/touch/ItemLongClickListener.java @@ -24,9 +24,12 @@ import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.OVERVIEW; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_ITEM_LONG_PRESSED; +import android.graphics.Point; +import android.graphics.Rect; import android.view.View; import android.view.View.OnLongClickListener; +import com.android.launcher3.DragSource; import com.android.launcher3.DropTarget; import com.android.launcher3.Launcher; import com.android.launcher3.celllayout.CellInfo; @@ -40,6 +43,10 @@ import com.android.launcher3.testing.TestLogging; import com.android.launcher3.testing.shared.TestProtocol; import com.android.launcher3.views.BubbleTextHolder; import com.android.launcher3.widget.LauncherAppWidgetHostView; +import com.android.launcher3.widget.NavigableAppWidgetHostView; +import com.android.launcher3.widget.PendingItemDragHelper; +import com.android.launcher3.widget.WidgetCell; +import com.android.launcher3.widget.WidgetImageView; /** * Class to handle long-clicks on workspace items and start drag as a result. @@ -91,7 +98,46 @@ public class ItemLongClickListener { launcher.getWorkspace().startDrag(longClickCellInfo, dragOptions); } + private static boolean onWidgetItemLongClick(WidgetCell v) { + // Get the widget preview as the drag representation + WidgetImageView image = v.getWidgetView(); + Launcher launcher = Launcher.getLauncher(v.getContext()); + DragSource dragSource = (target, dragObject, success) -> { }; + + // If the ImageView doesn't have a drawable yet, the widget preview hasn't been loaded and + // we abort the drag. + if (image.getDrawable() == null && v.getAppWidgetHostViewPreview() == null) { + return false; + } + + PendingItemDragHelper dragHelper = new PendingItemDragHelper(v); + // RemoteViews are being rendered in AppWidgetHostView in WidgetCell. And thus, the scale of + // RemoteViews is equivalent to the AppWidgetHostView scale. + dragHelper.setRemoteViewsPreview(v.getRemoteViewsPreview(), v.getAppWidgetHostViewScale()); + dragHelper.setAppWidgetHostViewPreview(v.getAppWidgetHostViewPreview()); + + if (image.getDrawable() != null) { + int[] loc = new int[2]; + launcher.getDragLayer().getLocationInDragLayer(image, loc); + + dragHelper.startDrag(image.getBitmapBounds(), image.getDrawable().getIntrinsicWidth(), + image.getWidth(), new Point(loc[0], loc[1]), dragSource, new DragOptions()); + } else { + NavigableAppWidgetHostView preview = v.getAppWidgetHostViewPreview(); + int[] loc = new int[2]; + launcher.getDragLayer().getLocationInDragLayer(preview, loc); + Rect r = new Rect(); + preview.getWorkspaceVisualDragBounds(r); + dragHelper.startDrag(r, preview.getMeasuredWidth(), preview.getMeasuredWidth(), + new Point(loc[0], loc[1]), dragSource, new DragOptions()); + } + return true; + } + private static boolean onAllAppsItemLongClick(View view) { + if (view instanceof WidgetCell wc) { + return onWidgetItemLongClick(wc); + } TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "onAllAppsItemLongClick"); view.cancelLongPress(); View v = (view instanceof BubbleTextHolder) diff --git a/src/com/android/launcher3/views/WidgetsEduView.java b/src/com/android/launcher3/views/WidgetsEduView.java index e70b1cbd16..40c611591c 100644 --- a/src/com/android/launcher3/views/WidgetsEduView.java +++ b/src/com/android/launcher3/views/WidgetsEduView.java @@ -20,15 +20,15 @@ import android.graphics.Rect; import android.util.AttributeSet; import android.view.LayoutInflater; +import com.android.launcher3.BaseActivity; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Insettable; -import com.android.launcher3.Launcher; import com.android.launcher3.R; /** * Education view about widgets. */ -public class WidgetsEduView extends AbstractSlideInView implements Insettable { +public class WidgetsEduView extends AbstractSlideInView implements Insettable { private static final int DEFAULT_CLOSE_DURATION = 200; @@ -124,10 +124,10 @@ public class WidgetsEduView extends AbstractSlideInView implements Ins } /** Shows widget education dialog. */ - public static WidgetsEduView showEducationDialog(Launcher launcher) { - LayoutInflater layoutInflater = LayoutInflater.from(launcher); + public static WidgetsEduView showEducationDialog(BaseActivity activity) { + LayoutInflater layoutInflater = LayoutInflater.from(activity); WidgetsEduView v = (WidgetsEduView) layoutInflater.inflate( - R.layout.widgets_edu, launcher.getDragLayer(), false); + R.layout.widgets_edu, activity.getDragLayer(), false); v.show(); return v; } diff --git a/src/com/android/launcher3/widget/BaseWidgetSheet.java b/src/com/android/launcher3/widget/BaseWidgetSheet.java index fc9c7744a7..26e191d19e 100644 --- a/src/com/android/launcher3/widget/BaseWidgetSheet.java +++ b/src/com/android/launcher3/widget/BaseWidgetSheet.java @@ -21,7 +21,6 @@ import static com.android.launcher3.LauncherPrefs.WIDGETS_EDUCATION_TIP_SEEN; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; -import android.graphics.Point; import android.graphics.Rect; import android.util.AttributeSet; import android.view.View; @@ -35,32 +34,28 @@ import androidx.annotation.Nullable; import androidx.annotation.Px; import androidx.core.view.ViewCompat; +import com.android.launcher3.BaseActivity; import com.android.launcher3.DeviceProfile; import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener; -import com.android.launcher3.DragSource; -import com.android.launcher3.DropTarget.DragObject; import com.android.launcher3.Insettable; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherPrefs; import com.android.launcher3.R; import com.android.launcher3.Utilities; -import com.android.launcher3.dragndrop.DragOptions; import com.android.launcher3.popup.PopupDataProvider; import com.android.launcher3.testing.TestLogging; import com.android.launcher3.testing.shared.TestProtocol; -import com.android.launcher3.touch.ItemLongClickListener; import com.android.launcher3.util.SystemUiController; import com.android.launcher3.util.Themes; import com.android.launcher3.util.window.WindowManagerProxy; import com.android.launcher3.views.AbstractSlideInView; -import com.android.launcher3.views.ActivityContext; import com.android.launcher3.views.ArrowTipView; /** * Base class for various widgets popup */ -public abstract class BaseWidgetSheet extends AbstractSlideInView - implements OnClickListener, OnLongClickListener, DragSource, +public abstract class BaseWidgetSheet extends AbstractSlideInView + implements OnClickListener, OnLongClickListener, PopupDataProvider.PopupDataChangeListener, Insettable, OnDeviceProfileChangeListener { /** The default number of cells that can fit horizontally in a widget sheet. */ public static final int DEFAULT_MAX_HORIZONTAL_SPANS = 4; @@ -129,21 +124,25 @@ public abstract class BaseWidgetSheet extends AbstractSlideInView } else { mWidgetInstructionToast = showWidgetToast(getContext(), mWidgetInstructionToast); } - } @Override public boolean onLongClick(View v) { TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "Widgets.onLongClick"); v.cancelLongPress(); - if (!ItemLongClickListener.canStartDrag(mActivityContext)) return false; + boolean result = false; if (v instanceof WidgetCell) { - return beginDraggingWidget((WidgetCell) v); - } else if (v.getParent() instanceof WidgetCell) { - return beginDraggingWidget((WidgetCell) v.getParent()); + result = mActivityContext.getAllAppsItemLongClickListener().onLongClick(v); + } else if (v.getParent() instanceof WidgetCell wc) { + result = mActivityContext.getAllAppsItemLongClickListener().onLongClick(wc); + } else { + return true; } - return true; + if (result) { + close(true); + } + return result; } @Override @@ -212,55 +211,12 @@ public abstract class BaseWidgetSheet extends AbstractSlideInView MeasureSpec.getSize(heightMeasureSpec)); } - private boolean beginDraggingWidget(WidgetCell v) { - // Get the widget preview as the drag representation - WidgetImageView image = v.getWidgetView(); - - // If the ImageView doesn't have a drawable yet, the widget preview hasn't been loaded and - // we abort the drag. - if (image.getDrawable() == null && v.getAppWidgetHostViewPreview() == null) { - return false; - } - - PendingItemDragHelper dragHelper = new PendingItemDragHelper(v); - // RemoteViews are being rendered in AppWidgetHostView in WidgetCell. And thus, the scale of - // RemoteViews is equivalent to the AppWidgetHostView scale. - dragHelper.setRemoteViewsPreview(v.getRemoteViewsPreview(), v.getAppWidgetHostViewScale()); - dragHelper.setAppWidgetHostViewPreview(v.getAppWidgetHostViewPreview()); - - if (image.getDrawable() != null) { - int[] loc = new int[2]; - getPopupContainer().getLocationInDragLayer(image, loc); - - dragHelper.startDrag(image.getBitmapBounds(), image.getDrawable().getIntrinsicWidth(), - image.getWidth(), new Point(loc[0], loc[1]), this, new DragOptions()); - } else { - NavigableAppWidgetHostView preview = v.getAppWidgetHostViewPreview(); - int[] loc = new int[2]; - getPopupContainer().getLocationInDragLayer(preview, loc); - Rect r = new Rect(); - preview.getWorkspaceVisualDragBounds(r); - dragHelper.startDrag(r, preview.getMeasuredWidth(), preview.getMeasuredWidth(), - new Point(loc[0], loc[1]), this, new DragOptions()); - } - close(true); - return true; - } - @Override protected Interpolator getIdleInterpolator() { return mActivityContext.getDeviceProfile().isTablet ? EMPHASIZED : super.getIdleInterpolator(); } - // - // Drag related handling methods that implement {@link DragSource} interface. - // - - @Override - public void onDropCompleted(View target, DragObject d, boolean success) { } - - protected void onCloseComplete() { super.onCloseComplete(); clearNavBarColor(); @@ -344,7 +300,8 @@ public abstract class BaseWidgetSheet extends AbstractSlideInView @Override protected void setTranslationShift(float translationShift) { super.setTranslationShift(translationShift); - Launcher launcher = ActivityContext.lookupContext(getContext()); - launcher.onWidgetsTransition(1 - translationShift); + if (mActivityContext instanceof Launcher ls) { + ls.onWidgetsTransition(1 - translationShift); + } } } diff --git a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java index af77d03f57..953ecda308 100644 --- a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java +++ b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java @@ -55,8 +55,9 @@ import androidx.annotation.VisibleForTesting; import androidx.recyclerview.widget.DefaultItemAnimator; import androidx.recyclerview.widget.RecyclerView; +import com.android.launcher3.BaseActivity; import com.android.launcher3.DeviceProfile; -import com.android.launcher3.Launcher; +import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherPrefs; import com.android.launcher3.R; import com.android.launcher3.Utilities; @@ -72,7 +73,6 @@ import com.android.launcher3.views.SpringRelativeLayout; import com.android.launcher3.views.StickyHeaderLayout; import com.android.launcher3.views.WidgetsEduView; import com.android.launcher3.widget.BaseWidgetSheet; -import com.android.launcher3.widget.LauncherWidgetHolder.ProviderChangedListener; import com.android.launcher3.widget.model.WidgetsListBaseEntry; import com.android.launcher3.widget.picker.search.SearchModeListener; import com.android.launcher3.widget.picker.search.WidgetsSearchBar; @@ -89,7 +89,7 @@ import java.util.stream.IntStream; * Popup for showing the full list of available widgets */ public class WidgetsFullSheet extends BaseWidgetSheet - implements ProviderChangedListener, OnActivePageChangedListener, + implements OnActivePageChangedListener, WidgetsRecyclerView.HeaderViewDimensionsProvider, SearchModeListener { private static final long FADE_IN_DURATION = 150; @@ -166,7 +166,7 @@ public class WidgetsFullSheet extends BaseWidgetSheet private boolean mIsInSearchMode; private boolean mIsNoWidgetsViewNeeded; @Px private int mMaxSpanPerRow; - private DeviceProfile mDeviceProfile; + private final DeviceProfile mDeviceProfile; private int mOrientation; @@ -181,7 +181,7 @@ public class WidgetsFullSheet extends BaseWidgetSheet public WidgetsFullSheet(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); - mDeviceProfile = Launcher.getLauncher(context).getDeviceProfile(); + mDeviceProfile = mActivityContext.getDeviceProfile(); mHasWorkProfile = context.getSystemService(LauncherApps.class).getProfiles().size() > 1; mOrientation = context.getResources().getConfiguration().orientation; mAdapters.put(AdapterHolder.PRIMARY, new AdapterHolder(AdapterHolder.PRIMARY)); @@ -353,15 +353,14 @@ public class WidgetsFullSheet extends BaseWidgetSheet @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); - mActivityContext.getAppWidgetHolder().addProviderChangeListener(this); - notifyWidgetProvidersChanged(); + LauncherAppState.getInstance(mActivityContext).getModel() + .refreshAndBindWidgetsAndShortcuts(null); onRecommendedWidgetsBound(); } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); - mActivityContext.getAppWidgetHolder().removeProviderChangeListener(this); mAdapters.get(AdapterHolder.PRIMARY).mWidgetsRecyclerView .removeOnAttachStateChangeListener(mBindScrollbarInSearchMode); if (mHasWorkProfile) { @@ -481,11 +480,6 @@ public class WidgetsFullSheet extends BaseWidgetSheet setTranslationShift(mTranslationShift); } - @Override - public void notifyWidgetProvidersChanged() { - mActivityContext.refreshAndBindWidgetsForPackageUser(null); - } - @Override public void onWidgetsBound() { if (mIsInSearchMode) { @@ -682,22 +676,22 @@ public class WidgetsFullSheet extends BaseWidgetSheet } /** Shows the {@link WidgetsFullSheet} on the launcher. */ - public static WidgetsFullSheet show(Launcher launcher, boolean animate) { - boolean isTwoPane = launcher.getDeviceProfile().isTablet - && launcher.getDeviceProfile().isLandscape - && (!launcher.getDeviceProfile().isTwoPanels + public static WidgetsFullSheet show(BaseActivity activity, boolean animate) { + boolean isTwoPane = activity.getDeviceProfile().isTablet + && activity.getDeviceProfile().isLandscape + && (!activity.getDeviceProfile().isTwoPanels || FeatureFlags.UNFOLDED_WIDGET_PICKER.get()); WidgetsFullSheet sheet; if (isTwoPane) { - sheet = (WidgetsTwoPaneSheet) launcher.getLayoutInflater().inflate( + sheet = (WidgetsTwoPaneSheet) activity.getLayoutInflater().inflate( R.layout.widgets_two_pane_sheet, - launcher.getDragLayer(), + activity.getDragLayer(), false); } else { - sheet = (WidgetsFullSheet) launcher.getLayoutInflater().inflate( + sheet = (WidgetsFullSheet) activity.getLayoutInflater().inflate( R.layout.widgets_full_sheet, - launcher.getDragLayer(), + activity.getDragLayer(), false); } @@ -754,7 +748,7 @@ public class WidgetsFullSheet extends BaseWidgetSheet /** Gets the {@link WidgetsRecyclerView} which shows all widgets in {@link WidgetsFullSheet}. */ @VisibleForTesting - public static WidgetsRecyclerView getWidgetsView(Launcher launcher) { + public static WidgetsRecyclerView getWidgetsView(BaseActivity launcher) { return launcher.findViewById(R.id.primary_widgets_list_view); } @@ -803,7 +797,7 @@ public class WidgetsFullSheet extends BaseWidgetSheet mOrientation = newConfig.orientation; if (mDeviceProfile.isTablet && !mDeviceProfile.isTwoPanels) { handleClose(false); - show(Launcher.getLauncher(getContext()), false); + show(BaseActivity.fromContext(getContext()), false); } else { reset(); }