Merge "Revert "Revert "Revert "Changing GridMigrationTask to use ModelDbController directly"""" into udc-dev
diff --git a/protos/launcher_atom.proto b/protos/launcher_atom.proto
index 55301ff..cebcd42 100644
--- a/protos/launcher_atom.proto
+++ b/protos/launcher_atom.proto
@@ -135,7 +135,7 @@
}
}
-// Next value 45
+// Next value 48
enum Attribute {
option allow_alias = true;
@@ -187,6 +187,11 @@
ALL_APPS_SEARCH_RESULT_SYSTEM_POINTER = 42;
ALL_APPS_SEARCH_RESULT_EDUCARD = 43;
+ // Result sources
+ DATA_SOURCE_APPSEARCH_APP_PREVIEW = 45;
+ DATA_SOURCE_APPSEARCH_APP_SRP_PREVIEW = 46;
+ DATA_SOURCE_AIAI_SEARCH_ROOT = 47;
+
// Web suggestions provided by AGA
ALL_APPS_SEARCH_RESULT_WEB_SUGGEST = 39;
diff --git a/quickstep/res/layout/transient_taskbar.xml b/quickstep/res/layout/transient_taskbar.xml
index 62c6933..bf4b811 100644
--- a/quickstep/res/layout/transient_taskbar.xml
+++ b/quickstep/res/layout/transient_taskbar.xml
@@ -38,6 +38,20 @@
android:layout_width="match_parent"
android:layout_height="match_parent"/>
+ <com.android.launcher3.taskbar.bubbles.BubbleBarView
+ android:id="@+id/taskbar_bubbles"
+ android:layout_width="wrap_content"
+ android:layout_height="@dimen/bubblebar_size"
+ android:layout_gravity="bottom|end"
+ android:layout_marginEnd="@dimen/transient_taskbar_bottom_margin"
+ android:layout_marginBottom="@dimen/transient_taskbar_bottom_margin"
+ android:paddingEnd="@dimen/taskbar_icon_spacing"
+ android:paddingStart="@dimen/taskbar_icon_spacing"
+ android:visibility="gone"
+ android:gravity="center"
+ android:clipChildren="false"
+ />
+
<FrameLayout
android:id="@+id/navbuttons_view"
android:layout_width="match_parent"
@@ -74,10 +88,20 @@
<com.android.launcher3.taskbar.StashedHandleView
android:id="@+id/stashed_handle"
tools:comment1="The actual size and shape will be set as a ViewOutlineProvider at runtime"
- android:layout_width="match_parent"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/taskbar_stashed_handle_dark_color"
android:clipToOutline="true"
android:layout_gravity="bottom"/>
+ <com.android.launcher3.taskbar.StashedHandleView
+ android:id="@+id/stashed_bubble_handle"
+ tools:comment1="The actual size and shape will be set as a ViewOutlineProvider at runtime"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:visibility="gone"
+ android:background="@color/taskbar_stashed_handle_dark_color"
+ android:clipToOutline="true"
+ android:layout_gravity="bottom"/>
+
</com.android.launcher3.taskbar.TaskbarDragLayer>
\ No newline at end of file
diff --git a/quickstep/src/com/android/launcher3/taskbar/DesktopNavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/DesktopNavbarButtonsViewController.java
index 268024f..885afff 100644
--- a/quickstep/src/com/android/launcher3/taskbar/DesktopNavbarButtonsViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/DesktopNavbarButtonsViewController.java
@@ -47,9 +47,7 @@
mStartContextualContainer = mNavButtonsView.findViewById(R.id.start_contextual_buttons);
mAllAppsButton = LayoutInflater.from(context)
.inflate(R.layout.taskbar_all_apps_button, mStartContextualContainer, false);
- mAllAppsButton.setOnClickListener((View v) -> {
- mControllers.taskbarAllAppsController.show();
- });
+ mAllAppsButton.setOnClickListener(v -> mControllers.taskbarAllAppsController.toggle());
}
/**
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 37f6284..d94d8f7 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -24,6 +24,7 @@
import static com.android.launcher3.AbstractFloatingView.TYPE_ALL;
import static com.android.launcher3.AbstractFloatingView.TYPE_REBIND_SAFE;
+import static com.android.launcher3.AbstractFloatingView.TYPE_TASKBAR_OVERLAY_PROXY;
import static com.android.launcher3.Utilities.isRunningInTestHarness;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_OPEN;
import static com.android.launcher3.taskbar.TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_DRAGGING;
@@ -83,6 +84,12 @@
import com.android.launcher3.taskbar.TaskbarAutohideSuspendController.AutohideSuspendFlag;
import com.android.launcher3.taskbar.TaskbarTranslationController.TransitionCallback;
import com.android.launcher3.taskbar.allapps.TaskbarAllAppsController;
+import com.android.launcher3.taskbar.bubbles.BubbleBarController;
+import com.android.launcher3.taskbar.bubbles.BubbleBarView;
+import com.android.launcher3.taskbar.bubbles.BubbleBarViewController;
+import com.android.launcher3.taskbar.bubbles.BubbleControllers;
+import com.android.launcher3.taskbar.bubbles.BubbleStashController;
+import com.android.launcher3.taskbar.bubbles.BubbleStashedHandleViewController;
import com.android.launcher3.taskbar.overlay.TaskbarOverlayController;
import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.testing.shared.TestProtocol;
@@ -106,6 +113,7 @@
import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider;
import java.io.PrintWriter;
+import java.util.Optional;
/**
* The {@link ActivityContext} with which we inflate Taskbar-related Views. This allows UI elements
@@ -195,11 +203,23 @@
TaskbarScrimView taskbarScrimView = mDragLayer.findViewById(R.id.taskbar_scrim);
FrameLayout navButtonsView = mDragLayer.findViewById(R.id.navbuttons_view);
StashedHandleView stashedHandleView = mDragLayer.findViewById(R.id.stashed_handle);
+ BubbleBarView bubbleBarView = mDragLayer.findViewById(R.id.taskbar_bubbles);
+ StashedHandleView bubbleHandleView = mDragLayer.findViewById(R.id.stashed_bubble_handle);
mAccessibilityDelegate = new TaskbarShortcutMenuAccessibilityDelegate(this);
final boolean isDesktopMode = getPackageManager().hasSystemFeature(FEATURE_PC);
+ // If Bubble bar is present, TaskbarControllers depends on it so build it first.
+ Optional<BubbleControllers> bubbleControllersOptional = Optional.empty();
+ if (BubbleBarController.BUBBLE_BAR_ENABLED) {
+ bubbleControllersOptional = Optional.of(new BubbleControllers(
+ new BubbleBarController(this, bubbleBarView),
+ new BubbleBarViewController(this, bubbleBarView),
+ new BubbleStashController(this),
+ new BubbleStashedHandleViewController(this, bubbleHandleView)));
+ }
+
// Construct controllers.
mControllers = new TaskbarControllers(this,
new TaskbarDragController(this),
@@ -239,7 +259,8 @@
: TaskbarRecentAppsController.DEFAULT,
new TaskbarEduTooltipController(this),
new KeyboardQuickSwitchController(),
- new TaskbarDividerPopupController(this));
+ new TaskbarDividerPopupController(this),
+ bubbleControllersOptional);
}
public void init(@NonNull TaskbarSharedState sharedState) {
@@ -661,7 +682,10 @@
void onDragEndOrViewRemoved() {
boolean isDragInProgress = mControllers.taskbarDragController.isSystemDragInProgress();
- if (!isDragInProgress && !AbstractFloatingView.hasOpenView(this, TYPE_ALL)) {
+ // Overlay AFVs are in a separate window and do not require Taskbar to be fullscreen.
+ if (!isDragInProgress
+ && !AbstractFloatingView.hasOpenView(
+ this, TYPE_ALL & ~TYPE_TASKBAR_OVERLAY_PROXY)) {
// Reverts Taskbar window to its original size
setTaskbarWindowFullscreen(false);
}
@@ -773,6 +797,7 @@
}
protected void onTaskbarIconClicked(View view) {
+ boolean shouldCloseAllOpenViews = true;
Object tag = view.getTag();
if (tag instanceof Task) {
Task task = (Task) tag;
@@ -780,6 +805,7 @@
ActivityOptions.makeBasic());
mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(true);
} else if (tag instanceof FolderInfo) {
+ shouldCloseAllOpenViews = false;
FolderIcon folderIcon = (FolderIcon) view;
Folder folder = folderIcon.getFolder();
@@ -876,7 +902,9 @@
Log.e(TAG, "Unknown type clicked: " + tag);
}
- AbstractFloatingView.closeAllOpenViews(this);
+ if (shouldCloseAllOpenViews) {
+ AbstractFloatingView.closeAllOpenViews(this);
+ }
}
/**
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
index 1cd6f50..66c2eb3 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
@@ -23,12 +23,14 @@
import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.taskbar.allapps.TaskbarAllAppsController;
+import com.android.launcher3.taskbar.bubbles.BubbleControllers;
import com.android.launcher3.taskbar.overlay.TaskbarOverlayController;
import com.android.systemui.shared.rotation.RotationButtonController;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
+import java.util.Optional;
/**
* Hosts various taskbar controllers to facilitate passing between one another.
@@ -61,6 +63,7 @@
public final TaskbarEduTooltipController taskbarEduTooltipController;
public final KeyboardQuickSwitchController keyboardQuickSwitchController;
public final TaskbarDividerPopupController taskbarPinningController;
+ public final Optional<BubbleControllers> bubbleControllers;
@Nullable private LoggableTaskbarController[] mControllersToLog = null;
@Nullable private BackgroundRendererController[] mBackgroundRendererControllers = null;
@@ -107,7 +110,8 @@
TaskbarRecentAppsController taskbarRecentAppsController,
TaskbarEduTooltipController taskbarEduTooltipController,
KeyboardQuickSwitchController keyboardQuickSwitchController,
- TaskbarDividerPopupController taskbarPinningController) {
+ TaskbarDividerPopupController taskbarPinningController,
+ Optional<BubbleControllers> bubbleControllers) {
this.taskbarActivityContext = taskbarActivityContext;
this.taskbarDragController = taskbarDragController;
this.navButtonController = navButtonController;
@@ -133,6 +137,7 @@
this.taskbarEduTooltipController = taskbarEduTooltipController;
this.keyboardQuickSwitchController = keyboardQuickSwitchController;
this.taskbarPinningController = taskbarPinningController;
+ this.bubbleControllers = bubbleControllers;
}
/**
@@ -167,6 +172,7 @@
taskbarEduTooltipController.init(this);
keyboardQuickSwitchController.init(this);
taskbarPinningController.init(this);
+ bubbleControllers.ifPresent(controllers -> controllers.init(this));
mControllersToLog = new LoggableTaskbarController[] {
taskbarDragController, navButtonController, navbarButtonsViewController,
@@ -226,6 +232,7 @@
taskbarRecentAppsController.onDestroy();
keyboardQuickSwitchController.onDestroy();
taskbarStashController.onDestroy();
+ bubbleControllers.ifPresent(controllers -> controllers.onDestroy());
mControllersToLog = null;
mBackgroundRendererControllers = null;
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
index 41093bd..72add4f 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
@@ -308,15 +308,12 @@
// Pre-drag has ended, start the global system drag.
if (mDisallowGlobalDrag) {
AbstractFloatingView.closeAllOpenViewsExcept(mActivity, TYPE_TASKBAR_ALL_APPS);
- } else {
- AbstractFloatingView.closeAllOpenViews(mActivity);
+ return;
}
-
startSystemDrag((BubbleTextView) mDragObject.originalView);
}
private void startSystemDrag(BubbleTextView btv) {
- if (mDisallowGlobalDrag) return;
View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(btv) {
@Override
@@ -412,6 +409,9 @@
.log(StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DRAG_STARTED);
}
}
+
+ // Wait to close until after system drag has started, if applicable.
+ AbstractFloatingView.closeAllOpenViews(mActivity);
}
private void onSystemDragStarted(BubbleTextView btv) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
index 19b9a18..4422fd4 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
@@ -34,8 +34,6 @@
import android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD
import android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION
import com.android.internal.policy.GestureNavigationSettingsObserver
-import com.android.launcher3.AbstractFloatingView
-import com.android.launcher3.AbstractFloatingView.TYPE_TASKBAR_OVERLAY_PROXY
import com.android.launcher3.DeviceProfile
import com.android.launcher3.R
import com.android.launcher3.anim.AlphaUpdateListener
@@ -190,7 +188,7 @@
/**
* Called to update the touchable insets.
*
- * @see InternalInsetsInfo.setTouchableInsets
+ * @see ViewTreeObserver.InternalInsetsInfo.setTouchableInsets
*/
fun updateInsetsTouchability(insetsInfo: ViewTreeObserver.InternalInsetsInfo) {
insetsInfo.touchableRegion.setEmpty()
@@ -205,7 +203,7 @@
insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION)
} else if (
controllers.navbarButtonsViewController.isImeVisible &&
- controllers.taskbarStashController.isStashed()
+ controllers.taskbarStashController.isStashed
) {
insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION)
} else if (!controllers.uiController.isTaskbarTouchable) {
@@ -214,26 +212,16 @@
} else if (controllers.taskbarDragController.isSystemDragInProgress) {
// Let touches pass through us.
insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION)
- } else if (AbstractFloatingView.hasOpenView(context, TYPE_TASKBAR_OVERLAY_PROXY)) {
- // Let touches pass through us if icons are hidden.
- if (controllers.taskbarViewController.areIconsVisible()) {
- insetsInfo.touchableRegion.set(touchableRegion)
- }
- insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION)
+ } else if (context.isTaskbarWindowFullscreen) {
+ // Intercept entire fullscreen window.
+ insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_FRAME)
+ insetsIsTouchableRegion = false
} else if (
- controllers.taskbarViewController.areIconsVisible() ||
- AbstractFloatingView.hasOpenView(context, AbstractFloatingView.TYPE_ALL) ||
- context.isNavBarKidsModeActive
+ controllers.taskbarViewController.areIconsVisible() || context.isNavBarKidsModeActive
) {
// Taskbar has some touchable elements, take over the full taskbar area
- insetsInfo.setTouchableInsets(
- if (context.isTaskbarWindowFullscreen) {
- TOUCHABLE_INSETS_FRAME
- } else {
- insetsInfo.touchableRegion.set(touchableRegion)
- TOUCHABLE_INSETS_REGION
- }
- )
+ insetsInfo.touchableRegion.set(touchableRegion)
+ insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION)
insetsIsTouchableRegion = false
} else {
insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION)
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
index ed78e2d..75cfd05 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
@@ -207,6 +207,10 @@
com.android.launcher3.taskbar.Utilities.setOverviewDragState(
mControllers, finalState.disallowTaskbarGlobalDrag(),
disallowLongClick, finalState.allowTaskbarInitialSplitSelection());
+ // LauncherTaskbarUIController depends on the state when checking whether
+ // to handle resume, so it should also be poked if current state changes
+ mLauncher.getTaskbarUIController().onLauncherResumedOrPaused(
+ mLauncher.hasBeenResumed());
}
};
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
index 5de5904..c2175f2 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
@@ -934,20 +934,6 @@
}
/**
- * Resets the flag if no system gesture is in progress.
- * <p>
- * Otherwise, the reset should be deferred until after the gesture is finished.
- *
- * @see #setSystemGestureInProgress
- */
- public void resetFlagIfNoGestureInProgress(int flag) {
- if (!mIsSystemGestureInProgress) {
- updateStateForFlag(flag, false);
- applyState(mControllers.taskbarOverlayController.getCloseDuration());
- }
- }
-
- /**
* When hiding the IME, delay the unstash animation to align with the end of the transition.
*/
private long getTaskbarStashStartDelayForIme() {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
index a7e2daa..7429185 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
@@ -639,7 +639,7 @@
public View.OnClickListener getAllAppsButtonClickListener() {
return v -> {
mActivity.getStatsLogManager().logger().log(LAUNCHER_TASKBAR_ALLAPPS_BUTTON_TAP);
- mControllers.taskbarAllAppsController.show();
+ mControllers.taskbarAllAppsController.toggle();
};
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java
index 4266c71..459a658 100644
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java
@@ -100,9 +100,13 @@
}
}
- /** Opens the {@link TaskbarAllAppsContainerView} in a new window. */
- public void show() {
- show(true);
+ /** Toggles visibility of {@link TaskbarAllAppsContainerView} in the overlay window. */
+ public void toggle() {
+ if (isOpen()) {
+ mSlideInView.close(true);
+ } else {
+ show(true);
+ }
}
/** Returns {@code true} if All Apps is open. */
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java
index 7a3b3e8..01342af 100644
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java
@@ -16,7 +16,6 @@
package com.android.launcher3.taskbar.allapps;
import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_STASHED_IN_TASKBAR_ALL_APPS;
-import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.OnboardingPrefs.ALL_APPS_VISITED_COUNT;
import com.android.launcher3.AbstractFloatingView;
@@ -88,8 +87,10 @@
}
private void setUpTaskbarStashing() {
- mTaskbarStashController.updateStateForFlag(FLAG_STASHED_IN_TASKBAR_ALL_APPS, true);
- mTaskbarStashController.applyState(mOverlayController.getOpenDuration());
+ if (DisplayController.isTransientTaskbar(mContext)) {
+ mTaskbarStashController.updateStateForFlag(FLAG_STASHED_IN_TASKBAR_ALL_APPS, true);
+ mTaskbarStashController.applyState(mOverlayController.getOpenDuration());
+ }
mNavbarButtonsViewController.setSlideInViewVisible(true);
mSlideInView.setOnCloseBeginListener(() -> {
@@ -100,11 +101,6 @@
if (DisplayController.isTransientTaskbar(mContext)) {
mTaskbarStashController.updateStateForFlag(FLAG_STASHED_IN_TASKBAR_ALL_APPS, false);
mTaskbarStashController.applyState(mOverlayController.getCloseDuration());
- } else {
- // Post in case view is closing due to gesture navigation. If a gesture is in
- // progress, wait to unstash until after the gesture is finished.
- MAIN_EXECUTOR.post(() -> mTaskbarStashController.resetFlagIfNoGestureInProgress(
- FLAG_STASHED_IN_TASKBAR_ALL_APPS));
}
});
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java
index 228aabd..a466548 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java
@@ -152,7 +152,9 @@
mContext = context;
mBarView = bubbleView; // Need the view for inflating bubble views.
- // TODO: register the listener with SysUiProxu
+ if (BUBBLE_BAR_ENABLED) {
+ SystemUiProxy.INSTANCE.get(context).setBubblesListener(this);
+ }
mMainExecutor = MAIN_EXECUTOR;
mLauncherApps = context.getSystemService(LauncherApps.class);
mIconFactory = new BubbleIconFactory(context,
@@ -164,7 +166,7 @@
}
public void onDestroy() {
- // TODO: unregister the listener with SysUiProxy
+ SystemUiProxy.INSTANCE.get(mContext).setBubblesListener(null);
}
public void init(TaskbarControllers controllers, BubbleControllers bubbleControllers) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
index 0afc2cb..82494c6 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
@@ -30,6 +30,7 @@
import com.android.launcher3.taskbar.TaskbarControllers;
import com.android.launcher3.util.MultiPropertyFactory;
import com.android.launcher3.util.MultiValueAlpha;
+import com.android.quickstep.SystemUiProxy;
import java.util.List;
import java.util.Objects;
@@ -42,6 +43,7 @@
private static final String TAG = BubbleBarViewController.class.getSimpleName();
+ private final SystemUiProxy mSystemUiProxy;
private final TaskbarActivityContext mActivity;
private final BubbleBarView mBarView;
private final int mIconSize;
@@ -69,6 +71,7 @@
public BubbleBarViewController(TaskbarActivityContext activity, BubbleBarView barView) {
mActivity = activity;
mBarView = barView;
+ mSystemUiProxy = SystemUiProxy.INSTANCE.get(mActivity);
mBubbleBarAlpha = new MultiValueAlpha(mBarView, 1 /* num alpha channels */);
mBubbleBarAlpha.setUpdateVisibility(true);
mIconSize = activity.getResources().getDimensionPixelSize(R.dimen.bubblebar_icon_size);
@@ -101,7 +104,8 @@
mBubbleStashController.stashBubbleBar();
} else {
mBubbleBarController.setSelectedBubble(bubble);
- // TODO: Tell SysUi to show the expanded view for this bubble.
+ mSystemUiProxy.showBubble(bubble.getKey(),
+ mBubbleStashController.isBubblesShowingOnHome());
}
}
@@ -270,11 +274,12 @@
if (isExpanded != mBarView.isExpanded()) {
mBarView.setExpanded(isExpanded);
if (!isExpanded) {
- // TODO: Tell SysUi to collapse the bubble
+ mSystemUiProxy.collapseBubbles();
} else {
final String selectedKey = mBubbleBarController.getSelectedBubbleKey();
if (selectedKey != null) {
- // TODO: Tell SysUi to show the bubble
+ mSystemUiProxy.showBubble(selectedKey,
+ mBubbleStashController.isBubblesShowingOnHome());
} else {
Log.w(TAG, "trying to expand bubbles when there isn't one selected");
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayContext.java b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayContext.java
index 66d5918..84a5228 100644
--- a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayContext.java
@@ -80,6 +80,12 @@
return mOverlayController;
}
+ /** Returns {@code true} if overlay or Taskbar windows are handling a system drag. */
+ boolean isAnySystemDragInProgress() {
+ return mDragController.isSystemDragInProgress()
+ || mTaskbarContext.getDragController().isSystemDragInProgress();
+ }
+
@Override
public DeviceProfile getDeviceProfile() {
return mOverlayController.getLauncherDeviceProfile();
diff --git a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java
index 2c3e1ac..b4ec682 100644
--- a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java
+++ b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java
@@ -112,7 +112,7 @@
@Override
public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo inoutInfo) {
- if (mActivity.getDragController().isSystemDragInProgress()) {
+ if (mActivity.isAnySystemDragInProgress()) {
inoutInfo.touchableRegion.setEmpty();
inoutInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION);
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsFragment.java b/quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsFragment.java
index e1ce9b1..b901a87 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsFragment.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsFragment.java
@@ -359,18 +359,6 @@
return true;
});
sandboxCategory.addPreference(launchOverviewTutorialPreference);
- Preference launchSandboxModeTutorialPreference = new Preference(context);
- launchSandboxModeTutorialPreference.setKey("launchSandboxMode");
- launchSandboxModeTutorialPreference.setTitle("Launch Sandbox Mode");
- launchSandboxModeTutorialPreference.setSummary("Practice navigation gestures");
- launchSandboxModeTutorialPreference.setOnPreferenceClickListener(preference -> {
- startActivity(launchSandboxIntent
- .putExtra("use_tutorial_menu", false)
- .putExtra("tutorial_steps", new String[] {"SANDBOX_MODE"}));
- return true;
- });
- sandboxCategory.addPreference(launchSandboxModeTutorialPreference);
-
Preference launchSecondaryDisplayPreference = new Preference(context);
launchSecondaryDisplayPreference.setKey("launchSecondaryDisplay");
launchSecondaryDisplayPreference.setTitle("Launch Secondary Display");
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 5333cbe..7d47945 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -2114,12 +2114,11 @@
}
protected void linkRecentsViewScroll() {
- SurfaceTransactionApplier.create(mRecentsView, applier -> {
- runActionOnRemoteHandles(remoteTargetHandle -> remoteTargetHandle.getTransformParams()
- .setSyncTransactionApplier(applier));
- runOnRecentsAnimationAndLauncherBound(() ->
- mRecentsAnimationTargets.addReleaseCheck(applier));
- });
+ SurfaceTransactionApplier applier = new SurfaceTransactionApplier(mRecentsView);
+ runActionOnRemoteHandles(remoteTargetHandle -> remoteTargetHandle.getTransformParams()
+ .setSyncTransactionApplier(applier));
+ runOnRecentsAnimationAndLauncherBound(() ->
+ mRecentsAnimationTargets.addReleaseCheck(applier));
mRecentsView.addOnScrollChangedListener(mOnRecentsScrollListener);
runOnRecentsAnimationAndLauncherBound(() ->
diff --git a/quickstep/src/com/android/quickstep/RecentsModel.java b/quickstep/src/com/android/quickstep/RecentsModel.java
index 913f08f..d798e62 100644
--- a/quickstep/src/com/android/quickstep/RecentsModel.java
+++ b/quickstep/src/com/android/quickstep/RecentsModel.java
@@ -145,6 +145,9 @@
* @param filter Returns true if GroupTask should be in the list of considerations
*/
public void isTaskRemoved(int taskId, Consumer<Boolean> callback, Predicate<GroupTask> filter) {
+ // Invalidate the existing list before checking to ensure this reflects the current state in
+ // the system
+ mTaskList.onRecentTasksChanged();
mTaskList.getTasks(true /* loadKeysOnly */, (taskGroups) -> {
for (GroupTask group : taskGroups) {
if (group.containsTask(taskId)) {
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
index 89f06f6..0549d9f 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.java
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -51,6 +51,7 @@
import android.window.TaskSnapshot;
import android.window.TransitionFilter;
+import androidx.annotation.MainThread;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
@@ -58,6 +59,7 @@
import com.android.internal.util.ScreenshotRequest;
import com.android.internal.view.AppearanceRegion;
import com.android.launcher3.util.MainThreadInitializedObject;
+import com.android.launcher3.util.Preconditions;
import com.android.launcher3.util.SplitConfigurationOptions;
import com.android.systemui.shared.recents.ISystemUiProxy;
import com.android.systemui.shared.recents.model.ThumbnailData;
@@ -69,6 +71,8 @@
import com.android.systemui.unfold.progress.IUnfoldAnimation;
import com.android.systemui.unfold.progress.IUnfoldTransitionListener;
import com.android.wm.shell.back.IBackAnimation;
+import com.android.wm.shell.bubbles.IBubbles;
+import com.android.wm.shell.bubbles.IBubblesListener;
import com.android.wm.shell.desktopmode.IDesktopMode;
import com.android.wm.shell.draganddrop.IDragAndDrop;
import com.android.wm.shell.onehanded.IOneHanded;
@@ -101,6 +105,7 @@
private ISystemUiProxy mSystemUiProxy;
private IPip mPip;
+ private IBubbles mBubbles;
private ISysuiUnlockAnimationController mSysuiUnlockAnimationController;
private ISplitScreen mSplitScreen;
private IOneHanded mOneHanded;
@@ -119,6 +124,7 @@
// up to the caller to clear the listeners to prevent leaks as these can be held indefinitely
// in case SysUI needs to rebind.
private IPipAnimationListener mPipAnimationListener;
+ private IBubblesListener mBubblesListener;
private ISplitScreenListener mSplitScreenListener;
private IStartingWindowListener mStartingWindowListener;
private ILauncherUnlockAnimationController mLauncherUnlockAnimationController;
@@ -200,15 +206,21 @@
return null;
}
- public void setProxy(ISystemUiProxy proxy, IPip pip, ISplitScreen splitScreen,
+ /**
+ * Sets proxy state, including death linkage, various listeners, and other configuration objects
+ */
+ @MainThread
+ public void setProxy(ISystemUiProxy proxy, IPip pip, IBubbles bubbles, ISplitScreen splitScreen,
IOneHanded oneHanded, IShellTransitions shellTransitions,
IStartingWindow startingWindow, IRecentTasks recentTasks,
ISysuiUnlockAnimationController sysuiUnlockAnimationController,
IBackAnimation backAnimation, IDesktopMode desktopMode,
IUnfoldAnimation unfoldAnimation, IDragAndDrop dragAndDrop) {
+ Preconditions.assertUIThread();
unlinkToDeath();
mSystemUiProxy = proxy;
mPip = pip;
+ mBubbles = bubbles;
mSplitScreen = splitScreen;
mOneHanded = oneHanded;
mShellTransitions = shellTransitions;
@@ -222,6 +234,7 @@
linkToDeath();
// re-attach the listeners once missing due to setProxy has not been initialized yet.
setPipAnimationListener(mPipAnimationListener);
+ setBubblesListener(mBubblesListener);
registerSplitScreenListener(mSplitScreenListener);
setStartingWindowListener(mStartingWindowListener);
setLauncherUnlockAnimationController(mLauncherUnlockAnimationController);
@@ -232,8 +245,12 @@
setUnfoldAnimationListener(mUnfoldAnimationListener);
}
+ /**
+ * Clear the proxy to release held resources and turn the majority of its operations into no-ops
+ */
+ @MainThread
public void clearProxy() {
- setProxy(null, null, null, null, null, null, null, null, null, null, null, null);
+ setProxy(null, null, null, null, null, null, null, null, null, null, null, null, null);
}
// TODO(141886704): Find a way to remove this
@@ -292,8 +309,10 @@
}
}
+ @MainThread
@Override
public void onStatusBarMotionEvent(MotionEvent event) {
+ Preconditions.assertUIThread();
if (mSystemUiProxy != null) {
try {
mSystemUiProxy.onStatusBarMotionEvent(event);
@@ -572,6 +591,59 @@
}
//
+ // Bubbles
+ //
+
+ /**
+ * Sets the listener to be notified of bubble state changes.
+ */
+ public void setBubblesListener(IBubblesListener listener) {
+ if (mBubbles != null) {
+ try {
+ if (mBubblesListener != null) {
+ // Clear out any previous listener
+ mBubbles.unregisterBubbleListener(mBubblesListener);
+ }
+ if (listener != null) {
+ mBubbles.registerBubbleListener(listener);
+ }
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed call registerBubblesListener");
+ }
+ }
+ mBubblesListener = listener;
+ }
+
+ /**
+ * Tells SysUI to show the bubble with the provided key.
+ * @param key the key of the bubble to show.
+ * @param onLauncherHome whether the bubble is showing on launcher home or not (modifies where
+ * the expanded bubble view is placed).
+ */
+ public void showBubble(String key, boolean onLauncherHome) {
+ if (mBubbles != null) {
+ try {
+ mBubbles.showBubble(key, onLauncherHome);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed call showBubble");
+ }
+ }
+ }
+
+ /**
+ * Tells SysUI to collapse the bubbles.
+ */
+ public void collapseBubbles() {
+ if (mBubbles != null) {
+ try {
+ mBubbles.collapseBubbles();
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed call collapseBubbles");
+ }
+ }
+ }
+
+ //
// Splitscreen
//
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 66aeee7..682763f 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -43,6 +43,7 @@
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_TRACING_ENABLED;
import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_BACK_ANIMATION;
+import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_BUBBLES;
import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_DESKTOP_MODE;
import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_DRAG_AND_DROP;
import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_ONE_HANDED;
@@ -126,6 +127,7 @@
import com.android.systemui.shared.tracing.ProtoTraceable;
import com.android.systemui.unfold.progress.IUnfoldAnimation;
import com.android.wm.shell.back.IBackAnimation;
+import com.android.wm.shell.bubbles.IBubbles;
import com.android.wm.shell.desktopmode.IDesktopMode;
import com.android.wm.shell.draganddrop.IDragAndDrop;
import com.android.wm.shell.onehanded.IOneHanded;
@@ -169,6 +171,7 @@
ISystemUiProxy proxy = ISystemUiProxy.Stub.asInterface(
bundle.getBinder(KEY_EXTRA_SYSUI_PROXY));
IPip pip = IPip.Stub.asInterface(bundle.getBinder(KEY_EXTRA_SHELL_PIP));
+ IBubbles bubbles = IBubbles.Stub.asInterface(bundle.getBinder(KEY_EXTRA_SHELL_BUBBLES));
ISplitScreen splitscreen = ISplitScreen.Stub.asInterface(bundle.getBinder(
KEY_EXTRA_SHELL_SPLIT_SCREEN));
IOneHanded onehanded = IOneHanded.Stub.asInterface(
@@ -192,7 +195,7 @@
bundle.getBinder(KEY_EXTRA_SHELL_DRAG_AND_DROP));
MAIN_EXECUTOR.execute(() -> {
SystemUiProxy.INSTANCE.get(TouchInteractionService.this).setProxy(proxy, pip,
- splitscreen, onehanded, shellTransitions, startingWindow,
+ bubbles, splitscreen, onehanded, shellTransitions, startingWindow,
recentTasks, launcherUnlockAnimationController, backAnimation, desktopMode,
unfoldTransition, dragAndDrop);
TouchInteractionService.this.initInputMonitor("TISBinder#onInitialize()");
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
index 4b1dd43..074aedd 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -79,7 +79,7 @@
}
@Override
- public void startHome() {
+ public void startHome(boolean animated) {
mActivity.startHome();
AbstractFloatingView.closeAllOpenViews(mActivity, mActivity.isStarted());
}
diff --git a/quickstep/src/com/android/quickstep/interaction/SandboxModeTutorialController.java b/quickstep/src/com/android/quickstep/interaction/SandboxModeTutorialController.java
deleted file mode 100644
index f0bd4f9..0000000
--- a/quickstep/src/com/android/quickstep/interaction/SandboxModeTutorialController.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.quickstep.interaction;
-
-import android.graphics.PointF;
-
-import com.android.launcher3.R;
-import com.android.quickstep.interaction.EdgeBackGestureHandler.BackGestureResult;
-import com.android.quickstep.interaction.NavBarGestureHandler.NavBarGestureResult;
-
-/** A {@link TutorialController} for the Sandbox Mode. */
-public class SandboxModeTutorialController extends SwipeUpGestureTutorialController {
-
- SandboxModeTutorialController(SandboxModeTutorialFragment fragment, TutorialType tutorialType) {
- super(fragment, tutorialType);
- }
-
- @Override
- public void onBackGestureAttempted(BackGestureResult result) {
- switch (result) {
- case BACK_COMPLETED_FROM_LEFT:
- case BACK_COMPLETED_FROM_RIGHT:
- showRippleEffect(null);
- showFeedback(R.string.sandbox_mode_back_gesture_feedback_successful);
- break;
- case BACK_CANCELLED_FROM_LEFT:
- case BACK_CANCELLED_FROM_RIGHT:
- showFeedback(R.string.back_gesture_feedback_cancelled);
- break;
- case BACK_NOT_STARTED_TOO_FAR_FROM_EDGE:
- showFeedback(R.string.sandbox_mode_back_gesture_feedback_swipe_too_far_from_edge);
- break;
- }
- }
-
- @Override
- public void onNavBarGestureAttempted(NavBarGestureResult result, PointF finalVelocity) {
- switch (result) {
- case HOME_GESTURE_COMPLETED:
- animateFakeTaskViewHome(finalVelocity, () -> {
- showFeedback(R.string.sandbox_mode_home_gesture_feedback_successful);
- });
- break;
- case OVERVIEW_GESTURE_COMPLETED:
- fadeOutFakeTaskView(true, true, () -> {
- showFeedback(R.string.sandbox_mode_overview_gesture_feedback_successful);
- });
- break;
- case HOME_OR_OVERVIEW_NOT_STARTED_WRONG_SWIPE_DIRECTION:
- case HOME_OR_OVERVIEW_CANCELLED:
- case HOME_NOT_STARTED_TOO_FAR_FROM_EDGE:
- case OVERVIEW_NOT_STARTED_TOO_FAR_FROM_EDGE:
- showFeedback(R.string.home_gesture_feedback_swipe_too_far_from_edge);
- break;
- }
- }
-}
diff --git a/quickstep/src/com/android/quickstep/interaction/SandboxModeTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/SandboxModeTutorialFragment.java
deleted file mode 100644
index 7bd52f7..0000000
--- a/quickstep/src/com/android/quickstep/interaction/SandboxModeTutorialFragment.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.quickstep.interaction;
-
-import android.view.MotionEvent;
-import android.view.View;
-
-import androidx.annotation.NonNull;
-
-import com.android.launcher3.logging.StatsLogManager;
-import com.android.quickstep.interaction.TutorialController.TutorialType;
-
-/** Shows the general navigation gesture sandbox environment. */
-public class SandboxModeTutorialFragment extends TutorialFragment {
-
- public SandboxModeTutorialFragment(boolean fromTutorialMenu) {
- super(fromTutorialMenu);
- }
-
- @Override
- TutorialController createController(TutorialType type) {
- return new SandboxModeTutorialController(this, type);
- }
-
- @Override
- Class<? extends TutorialController> getControllerClass() {
- return SandboxModeTutorialController.class;
- }
-
- @Override
- public boolean onTouch(View view, MotionEvent motionEvent) {
- if (motionEvent.getAction() == MotionEvent.ACTION_DOWN && mTutorialController != null) {
- mTutorialController.setRippleHotspot(motionEvent.getX(), motionEvent.getY());
- }
- return super.onTouch(view, motionEvent);
- }
-
- @Override
- void logTutorialStepShown(@NonNull StatsLogManager statsLogManager) {
- // No-Op: tutorial step not currently shown to users
- }
-
- @Override
- void logTutorialStepCompleted(@NonNull StatsLogManager statsLogManager) {
- // No-Op: tutorial step not currently shown to users
- }
-}
diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialController.java b/quickstep/src/com/android/quickstep/interaction/TutorialController.java
index 6efdb07..d4ff457 100644
--- a/quickstep/src/com/android/quickstep/interaction/TutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/TutorialController.java
@@ -829,9 +829,6 @@
HOME_NAVIGATION,
HOME_NAVIGATION_COMPLETE,
OVERVIEW_NAVIGATION,
- OVERVIEW_NAVIGATION_COMPLETE,
- ASSISTANT,
- ASSISTANT_COMPLETE,
- SANDBOX_MODE
+ OVERVIEW_NAVIGATION_COMPLETE
}
}
diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
index 25de605..9f15e19 100644
--- a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
@@ -117,8 +117,6 @@
case OVERVIEW_NAVIGATION:
case OVERVIEW_NAVIGATION_COMPLETE:
return new OverviewGestureTutorialFragment(fromTutorialMenu);
- case SANDBOX_MODE:
- return new SandboxModeTutorialFragment(fromTutorialMenu);
default:
Log.e(LOG_TAG, "Failed to find an appropriate fragment for " + tutorialType.name());
}
diff --git a/quickstep/src/com/android/quickstep/util/SurfaceTransactionApplier.java b/quickstep/src/com/android/quickstep/util/SurfaceTransactionApplier.java
index 95473dc..bb028a7 100644
--- a/quickstep/src/com/android/quickstep/util/SurfaceTransactionApplier.java
+++ b/quickstep/src/com/android/quickstep/util/SurfaceTransactionApplier.java
@@ -22,13 +22,11 @@
import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
import android.view.View;
+import android.view.View.OnAttachStateChangeListener;
import android.view.ViewRootImpl;
import com.android.quickstep.RemoteAnimationTargets.ReleaseCheck;
-import java.util.function.Consumer;
-
-
/**
* Helper class to apply surface transactions in sync with RenderThread similar to
* android.view.SyncRtSurfaceTransactionApplier
@@ -39,22 +37,47 @@
private static final int MSG_UPDATE_SEQUENCE_NUMBER = 0;
- private final SurfaceControl mBarrierSurfaceControl;
- private final ViewRootImpl mTargetViewRootImpl;
private final Handler mApplyHandler;
+ private boolean mInitialized;
+ private SurfaceControl mBarrierSurfaceControl;
+ private ViewRootImpl mTargetViewRootImpl;
+
private int mLastSequenceNumber = 0;
/**
* @param targetView The view in the surface that acts as synchronization anchor.
*/
public SurfaceTransactionApplier(View targetView) {
- mTargetViewRootImpl = targetView.getViewRootImpl();
- mBarrierSurfaceControl = mTargetViewRootImpl.getSurfaceControl();
+ if (targetView.isAttachedToWindow()) {
+ initialize(targetView);
+ } else {
+ mInitialized = false;
+ targetView.addOnAttachStateChangeListener(new OnAttachStateChangeListener() {
+ @Override
+ public void onViewAttachedToWindow(View v) {
+ if (!mInitialized) {
+ targetView.removeOnAttachStateChangeListener(this);
+ initialize(targetView);
+ }
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(View v) {
+ // Do nothing
+ }
+ });
+ }
mApplyHandler = new Handler(this::onApplyMessage);
setCanRelease(true);
}
+ private void initialize(View view) {
+ mTargetViewRootImpl = view.getViewRootImpl();
+ mBarrierSurfaceControl = mTargetViewRootImpl.getSurfaceControl();
+ mInitialized = true;
+ }
+
protected boolean onApplyMessage(Message msg) {
if (msg.what == MSG_UPDATE_SEQUENCE_NUMBER) {
setCanRelease(msg.arg1 == mLastSequenceNumber);
@@ -70,6 +93,10 @@
* this method to avoid synchronization issues.
*/
public void scheduleApply(SurfaceTransaction params) {
+ if (!mInitialized) {
+ params.getTransaction().apply();
+ return;
+ }
View view = mTargetViewRootImpl.getView();
if (view == null) {
return;
@@ -93,33 +120,4 @@
// Make sure a frame gets scheduled.
view.invalidate();
}
-
- /**
- * Creates an instance of SurfaceTransactionApplier, deferring until the target view is
- * attached if necessary.
- */
- public static void create(
- final View targetView, final Consumer<SurfaceTransactionApplier> callback) {
- if (targetView == null) {
- // No target view, no applier
- callback.accept(null);
- } else if (targetView.isAttachedToWindow()) {
- // Already attached, we're good to go
- callback.accept(new SurfaceTransactionApplier(targetView));
- } else {
- // Haven't been attached before we can get the view root
- targetView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
- @Override
- public void onViewAttachedToWindow(View v) {
- targetView.removeOnAttachStateChangeListener(this);
- callback.accept(new SurfaceTransactionApplier(targetView));
- }
-
- @Override
- public void onViewDetachedFromWindow(View v) {
- // Do nothing
- }
- });
- }
- }
}
diff --git a/quickstep/src/com/android/quickstep/util/TaskRemovedDuringLaunchListener.java b/quickstep/src/com/android/quickstep/util/TaskRemovedDuringLaunchListener.java
new file mode 100644
index 0000000..c22e0bc
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/util/TaskRemovedDuringLaunchListener.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.quickstep.util;
+
+import static android.app.ActivityTaskManager.INVALID_TASK_ID;
+
+import android.app.Activity;
+
+import androidx.annotation.NonNull;
+
+import com.android.launcher3.util.ActivityLifecycleCallbacksAdapter;
+import com.android.quickstep.RecentsModel;
+
+/**
+ * This class tracks the failure of a task launch through the TaskView.launchTask() call, in an
+ * edge case in which starting a new task may initially succeed (startActivity returns true), but
+ * the launch ultimately fails if the activity finishes while it is resuming.
+ *
+ * There are two signals this class checks, the launcher lifecycle and the transition completion.
+ * If we hit either of those signals and the task is no longer valid, then the registered failure
+ * callback will be notified.
+ */
+public class TaskRemovedDuringLaunchListener implements ActivityLifecycleCallbacksAdapter {
+
+ private Activity mActivity;
+ private int mLaunchedTaskId = INVALID_TASK_ID;
+ private Runnable mTaskLaunchFailedCallback = null;
+
+ /**
+ * Registers a failure listener callback if it detects a scenario in which an app launch
+ * failed before the transition finished.
+ */
+ public void register(Activity activity, int launchedTaskId,
+ @NonNull Runnable taskLaunchFailedCallback) {
+ activity.registerActivityLifecycleCallbacks(this);
+ mActivity = activity;
+ mLaunchedTaskId = launchedTaskId;
+ mTaskLaunchFailedCallback = taskLaunchFailedCallback;
+ }
+
+ /**
+ * Unregisters the failure listener.
+ */
+ private void unregister() {
+ mActivity.unregisterActivityLifecycleCallbacks(this);
+ mActivity = null;
+ mLaunchedTaskId = INVALID_TASK_ID;
+ mTaskLaunchFailedCallback = null;
+ }
+
+ /**
+ * Called when the transition finishes.
+ */
+ public void onTransitionFinished() {
+ // The transition finished and Launcher was not stopped, check if the launch failed
+ checkTaskLaunchFailed();
+ }
+
+ @Override
+ public void onActivityStopped(Activity activity) {
+ // The normal task launch case, Launcher stops and updates its state correctly
+ unregister();
+ }
+
+ @Override
+ public void onActivityResumed(Activity activity) {
+ // The transition hasn't finished but Launcher was resumed, check if the launch failed
+ checkTaskLaunchFailed();
+ }
+
+ @Override
+ public void onActivityDestroyed(Activity activity) {
+ // If we somehow don't get any of the above signals, then just unregister this listener
+ unregister();
+ }
+
+ private void checkTaskLaunchFailed() {
+ if (mLaunchedTaskId != INVALID_TASK_ID) {
+ final int launchedTaskId = mLaunchedTaskId;
+ final Runnable taskLaunchFailedCallback = mTaskLaunchFailedCallback;
+ RecentsModel.INSTANCE.getNoCreate().isTaskRemoved(mLaunchedTaskId, (taskRemoved) -> {
+ if (taskRemoved) {
+ ActiveGestureLog.INSTANCE.addLog("Launch failed, task (id=" + launchedTaskId
+ + ") finished mid transition");
+ taskLaunchFailedCallback.run();
+ }
+ }, (task) -> true /* filter */);
+ unregister();
+ }
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/views/DesktopTaskView.java b/quickstep/src/com/android/quickstep/views/DesktopTaskView.java
index 379722b..1cfaf14 100644
--- a/quickstep/src/com/android/quickstep/views/DesktopTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/DesktopTaskView.java
@@ -321,7 +321,7 @@
}
@Override
- public void launchTask(@NonNull Consumer<Boolean> callback, boolean freezeTaskList) {
+ public void launchTask(@NonNull Consumer<Boolean> callback, boolean isQuickswitch) {
launchTasks();
callback.accept(true);
}
diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
index 5bfd035..c6c84bd 100644
--- a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
@@ -237,9 +237,9 @@
}
@Override
- public void launchTask(@NonNull Consumer<Boolean> callback, boolean freezeTaskList) {
+ public void launchTask(@NonNull Consumer<Boolean> callback, boolean isQuickswitch) {
getRecentsView().getSplitSelectController().launchTasks(mTask.key.id, mSecondaryTask.key.id,
- SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT, callback, freezeTaskList,
+ SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT, callback, isQuickswitch,
getSplitRatio());
}
diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
index 8ff0e9b..2008129 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -39,6 +39,7 @@
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.statehandlers.DepthController;
import com.android.launcher3.statehandlers.DesktopVisibilityController;
+import com.android.launcher3.statemanager.StateManager;
import com.android.launcher3.statemanager.StateManager.StateListener;
import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.PendingSplitSelectInfo;
@@ -79,9 +80,11 @@
}
@Override
- public void startHome() {
- mActivity.getStateManager().goToState(NORMAL);
- AbstractFloatingView.closeAllOpenViews(mActivity, mActivity.isStarted());
+ public void startHome(boolean animated) {
+ StateManager stateManager = mActivity.getStateManager();
+ animated &= stateManager.shouldAnimateStateChange();
+ stateManager.goToState(NORMAL, animated);
+ AbstractFloatingView.closeAllOpenViews(mActivity, animated);
}
@Override
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index f0afa69..ff5af28 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -2285,7 +2285,11 @@
}
}
- public abstract void startHome();
+ public void startHome() {
+ startHome(mActivity.isStarted());
+ }
+
+ public abstract void startHome(boolean animated);
public void reset() {
setCurrentTask(-1);
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 53660b5..796cd62 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -102,6 +102,7 @@
import com.android.quickstep.util.RecentsOrientedState;
import com.android.quickstep.util.SplitSelectStateController;
import com.android.quickstep.util.TaskCornerRadius;
+import com.android.quickstep.util.TaskRemovedDuringLaunchListener;
import com.android.quickstep.util.TransformParams;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.ThumbnailData;
@@ -815,23 +816,44 @@
* Starts the task associated with this view without any animation
*/
public void launchTask(@NonNull Consumer<Boolean> callback) {
- launchTask(callback, false /* freezeTaskList */);
+ launchTask(callback, false /* isQuickswitch */);
}
/**
* Starts the task associated with this view without any animation
*/
- public void launchTask(@NonNull Consumer<Boolean> callback, boolean freezeTaskList) {
+ public void launchTask(@NonNull Consumer<Boolean> callback, boolean isQuickswitch) {
if (mTask != null) {
TestLogging.recordEvent(
TestProtocol.SEQUENCE_MAIN, "startActivityFromRecentsAsync", mTask);
+ final TaskRemovedDuringLaunchListener
+ failureListener = new TaskRemovedDuringLaunchListener();
+ if (isQuickswitch) {
+ // We only listen for failures to launch in quickswitch because the during this
+ // gesture launcher is in the background state, vs other launches which are in
+ // the actual overview state
+ failureListener.register(mActivity, mTask.key.id, () -> {
+ notifyTaskLaunchFailed(TAG);
+ // Disable animations for now, as it is an edge case and the app usually covers
+ // launcher and also any state transition animation also gets clobbered by
+ // QuickstepTransitionManager.createWallpaperOpenAnimations when launcher
+ // shows again
+ getRecentsView().startHome(false /* animated */);
+ });
+ }
// Indicate success once the system has indicated that the transition has started
- ActivityOptions opts = makeCustomAnimation(getContext(), 0, 0,
- () -> callback.accept(true), MAIN_EXECUTOR.getHandler());
+ ActivityOptions opts = ActivityOptions.makeCustomTaskAnimation(getContext(), 0, 0,
+ MAIN_EXECUTOR.getHandler(),
+ elapsedRealTime -> {
+ callback.accept(true);
+ },
+ elapsedRealTime -> {
+ failureListener.onTransitionFinished();
+ });
opts.setLaunchDisplayId(
getDisplay() == null ? DEFAULT_DISPLAY : getDisplay().getDisplayId());
- if (freezeTaskList) {
+ if (isQuickswitch) {
opts.setFreezeRecentTasksReordering();
}
opts.setDisableStartingWindow(mSnapshotView.shouldShowSplashView());
diff --git a/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarBaseTestCase.kt b/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarBaseTestCase.kt
index 20466ad..2c16c15 100644
--- a/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarBaseTestCase.kt
+++ b/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarBaseTestCase.kt
@@ -16,8 +16,10 @@
package com.android.launcher3.taskbar
import com.android.launcher3.taskbar.allapps.TaskbarAllAppsController
+import com.android.launcher3.taskbar.bubbles.BubbleControllers
import com.android.launcher3.taskbar.overlay.TaskbarOverlayController
import com.android.systemui.shared.rotation.RotationButtonController
+import java.util.Optional
import org.junit.Before
import org.mockito.Mock
import org.mockito.MockitoAnnotations
@@ -54,6 +56,7 @@
@Mock lateinit var taskbarEduTooltipController: TaskbarEduTooltipController
@Mock lateinit var keyboardQuickSwitchController: KeyboardQuickSwitchController
@Mock lateinit var taskbarPinningController: TaskbarDividerPopupController
+ @Mock lateinit var optionalBubbleControllers: Optional<BubbleControllers>
lateinit var taskbarControllers: TaskbarControllers
@@ -94,6 +97,7 @@
taskbarEduTooltipController,
keyboardQuickSwitchController,
taskbarPinningController,
+ optionalBubbleControllers,
)
}
}
diff --git a/res/layout/widget_cell_content.xml b/res/layout/widget_cell_content.xml
index 3f61aaa..6db4fb5 100644
--- a/res/layout/widget_cell_content.xml
+++ b/res/layout/widget_cell_content.xml
@@ -24,6 +24,7 @@
android:layout_weight="1"
android:importantForAccessibility="noHideDescendants"
android:hapticFeedbackEnabled="false"
+ android:clipChildren="false"
android:layout_marginVertical="8dp">
<!-- The image of the widget. This view does not support padding. Any placement adjustment
should be done using margins. Width & height are set at runtime after scaling the
diff --git a/res/layout/widgets_bottom_sheet_content.xml b/res/layout/widgets_bottom_sheet_content.xml
index b76eef7..065c2ed 100644
--- a/res/layout/widgets_bottom_sheet_content.xml
+++ b/res/layout/widgets_bottom_sheet_content.xml
@@ -42,7 +42,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fadeScrollbars="false"
- android:layout_marginVertical="16dp">
+ android:layout_marginTop="16dp">
<include layout="@layout/widgets_table_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/src/com/android/launcher3/DropTargetHandler.kt b/src/com/android/launcher3/DropTargetHandler.kt
index 277f8b3..6560e16 100644
--- a/src/com/android/launcher3/DropTargetHandler.kt
+++ b/src/com/android/launcher3/DropTargetHandler.kt
@@ -6,7 +6,6 @@
import com.android.launcher3.SecondaryDropTarget.DeferredOnComplete
import com.android.launcher3.dragndrop.DragLayer
import com.android.launcher3.logging.StatsLogManager.LauncherEvent
-import com.android.launcher3.model.ModelWriter
import com.android.launcher3.model.data.ItemInfo
import com.android.launcher3.model.data.LauncherAppWidgetInfo
import com.android.launcher3.util.IntSet
@@ -22,8 +21,6 @@
class DropTargetHandler(launcher: Launcher) {
val mLauncher: Launcher = launcher
- val modelWriter: ModelWriter = mLauncher.modelWriter
-
fun onDropAnimationComplete() {
mLauncher.stateManager.goToState(LauncherState.NORMAL)
}
@@ -87,7 +84,7 @@
else mLauncher.workspace.currentPageScreenIds
val onUndoClicked = Runnable {
mLauncher.setPagesToBindSynchronously(pageIds)
- modelWriter.abortDelete()
+ mLauncher.modelWriter.abortDelete()
mLauncher.statsLogManager.logger().log(LauncherEvent.LAUNCHER_UNDO)
}
@@ -95,7 +92,7 @@
mLauncher,
R.string.item_removed,
R.string.undo,
- modelWriter::commitDelete,
+ mLauncher.modelWriter::commitDelete,
onUndoClicked
)
}
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 4764d72..29b0f08 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -1621,6 +1621,9 @@
return mModel;
}
+ /**
+ * Returns the ModelWriter writer, make sure to call the function every time you want to use it.
+ */
public ModelWriter getModelWriter() {
return mModelWriter;
}
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index fef6639..7f04860 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -253,7 +253,7 @@
"COLLECT_SEARCH_HISTORY", DISABLED, "Allow launcher to collect search history for log");
public static final BooleanFlag ENABLE_TWOLINE_ALLAPPS = getDebugFlag(270390937,
- "ENABLE_TWOLINE_ALLAPPS", DISABLED, "Enables two line label inside all apps.");
+ "ENABLE_TWOLINE_ALLAPPS", TEAMFOOD, "Enables two line label inside all apps.");
public static final BooleanFlag IME_STICKY_SNACKBAR_EDU = getDebugFlag(270391693,
"IME_STICKY_SNACKBAR_EDU", ENABLED, "Show sticky IME edu in AllApps");
diff --git a/src/com/android/launcher3/dragndrop/AddItemActivity.java b/src/com/android/launcher3/dragndrop/AddItemActivity.java
index 4906c1d..00f4285 100644
--- a/src/com/android/launcher3/dragndrop/AddItemActivity.java
+++ b/src/com/android/launcher3/dragndrop/AddItemActivity.java
@@ -304,7 +304,8 @@
mWidgetOptions = pendingInfo.getDefaultSizeOptions(this);
mWidgetCell.getWidgetView().setTag(pendingInfo);
- applyWidgetItemAsync(() -> new WidgetItem(widgetInfo, mIdp, mApp.getIconCache()));
+ applyWidgetItemAsync(() -> new WidgetItem(
+ widgetInfo, mIdp, mApp.getIconCache(), mApp.getContext()));
return WidgetsModel.newPendingItemInfo(this, widgetInfo.getComponent(),
widgetInfo.getUser());
}
diff --git a/src/com/android/launcher3/logging/StartupLatencyLogger.kt b/src/com/android/launcher3/logging/StartupLatencyLogger.kt
index 27b8c3b..93e9de5 100644
--- a/src/com/android/launcher3/logging/StartupLatencyLogger.kt
+++ b/src/com/android/launcher3/logging/StartupLatencyLogger.kt
@@ -21,14 +21,13 @@
const val UNSET_LONG = -1L
}
- @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
+ @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
val startTimeByEvent = SparseLongArray()
- @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
+ @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
val endTimeByEvent = SparseLongArray()
- @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
- var cardinality: Int = UNSET_INT
- @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
+ @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED) var cardinality: Int = UNSET_INT
+ @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
var workspaceLoadStartTime: Long = UNSET_LONG
private var isInTest = false
diff --git a/src/com/android/launcher3/model/WidgetItem.java b/src/com/android/launcher3/model/WidgetItem.java
index 7198d54..c99b889 100644
--- a/src/com/android/launcher3/model/WidgetItem.java
+++ b/src/com/android/launcher3/model/WidgetItem.java
@@ -3,6 +3,7 @@
import static com.android.launcher3.Utilities.ATLEAST_S;
import android.annotation.SuppressLint;
+import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.res.Resources;
@@ -25,13 +26,15 @@
public final ShortcutConfigActivityInfo activityInfo;
public final String label;
+ public final CharSequence description;
public final int spanX, spanY;
public WidgetItem(LauncherAppWidgetProviderInfo info,
- InvariantDeviceProfile idp, IconCache iconCache) {
+ InvariantDeviceProfile idp, IconCache iconCache, Context context) {
super(info.provider, info.getProfile());
label = iconCache.getTitleNoCache(info);
+ description = ATLEAST_S ? info.loadDescription(context) : null;
widgetInfo = info;
activityInfo = null;
@@ -43,6 +46,7 @@
super(info.getComponent(), info.getUser());
label = info.isPersistable() ? iconCache.getTitleNoCache(info) :
Utilities.trim(info.getLabel(pm));
+ description = null;
widgetInfo = null;
activityInfo = info;
spanX = spanY = 1;
diff --git a/src/com/android/launcher3/widget/PendingItemDragHelper.java b/src/com/android/launcher3/widget/PendingItemDragHelper.java
index 67d21f7..f269434 100644
--- a/src/com/android/launcher3/widget/PendingItemDragHelper.java
+++ b/src/com/android/launcher3/widget/PendingItemDragHelper.java
@@ -157,8 +157,15 @@
previewBounds.right -= padding;
}
if (mAppWidgetHostViewPreview != null) {
- previewWidth = mAppWidgetHostViewPreview.getMeasuredWidth();
- previewHeight = mAppWidgetHostViewPreview.getMeasuredHeight();
+ float previewScale = mAppWidgetHostViewPreview.getScaleX();
+ int widgetWidth = mAppWidgetHostViewPreview.getMeasuredWidth();
+ int widgetHeight = mAppWidgetHostViewPreview.getMeasuredHeight();
+ previewWidth = Math.round(widgetWidth * previewScale);
+ previewHeight = Math.round(widgetHeight * previewScale);
+
+ previewBounds.offset(
+ Math.round(widgetWidth * (previewScale - 1) / 2),
+ Math.round(widgetHeight * (previewScale - 1) / 2));
} else {
previewWidth = preview.getIntrinsicWidth();
previewHeight = preview.getIntrinsicHeight();
diff --git a/src/com/android/launcher3/widget/WidgetCell.java b/src/com/android/launcher3/widget/WidgetCell.java
index 80bc1a7..c30342a 100644
--- a/src/com/android/launcher3/widget/WidgetCell.java
+++ b/src/com/android/launcher3/widget/WidgetCell.java
@@ -16,18 +16,15 @@
package com.android.launcher3.widget;
-import static android.view.View.MeasureSpec.makeMeasureSpec;
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
-
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_WIDGETS_TRAY;
-import static com.android.launcher3.Utilities.ATLEAST_S;
-import static com.android.launcher3.util.MultiTranslateDelegate.INDEX_WIDGET_CENTERING;
+import static com.android.launcher3.widget.LauncherAppWidgetProviderInfo.fromProviderInfo;
+import static com.android.launcher3.widget.util.WidgetSizes.getWidgetItemSizePx;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.Process;
+import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Size;
@@ -47,7 +44,6 @@
import androidx.annotation.Nullable;
import com.android.launcher3.CheckLongPressHelper;
-import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.icons.FastBitmapDrawable;
@@ -55,7 +51,6 @@
import com.android.launcher3.icons.cache.HandlerRunnable;
import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.views.ActivityContext;
-import com.android.launcher3.widget.util.WidgetSizes;
import java.util.function.Consumer;
@@ -75,40 +70,8 @@
private static final int FADE_IN_DURATION_MS = 90;
- /** Widget cell width is calculated by multiplying this factor to grid cell width. */
- private static final float WIDTH_SCALE = 3f;
-
- /** Widget preview width is calculated by multiplying this factor to the widget cell width. */
- private static final float PREVIEW_SCALE = 0.8f;
-
/**
- * The maximum dimension that can be used as the size in
- * {@link android.view.View.MeasureSpec#makeMeasureSpec(int, int)}.
- *
- * <p>This is equal to (1 << MeasureSpec.MODE_SHIFT) - 1.
- */
- private static final int MAX_MEASURE_SPEC_DIMENSION = (1 << 30) - 1;
-
- /**
- * The target preview width, in pixels, of a widget or a shortcut.
- *
- * <p>The actual preview width may be smaller than or equal to this value subjected to scaling.
- */
- protected int mTargetPreviewWidth;
-
- /**
- * The target preview height, in pixels, of a widget or a shortcut.
- *
- * <p>The actual preview height may be smaller than or equal to this value subjected to scaling.
- */
- protected int mTargetPreviewHeight;
-
- protected int mPresetPreviewSize;
-
- private int mCellSize;
-
- /**
- * The scale of the preview container.
+ * The requested scale of the preview container. It can be lower than this as well.
*/
private float mPreviewContainerScale = 1f;
@@ -119,7 +82,8 @@
private TextView mWidgetDims;
private TextView mWidgetDescription;
- protected WidgetItem mItem;
+ private WidgetItem mItem;
+ private Size mWidgetSize;
private final DatabaseWidgetPreviewLoader mWidgetPreviewLoader;
@@ -150,18 +114,11 @@
mWidgetPreviewLoader = new DatabaseWidgetPreviewLoader(context);
mLongPressHelper = new CheckLongPressHelper(this);
mLongPressHelper.setLongPressTimeoutFactor(1);
+ mEnforcedCornerRadius = RoundedCornerEnforcement.computeEnforcedRadius(context);
+ mWidgetSize = new Size(0, 0);
- setContainerWidth();
- setWillNotDraw(false);
setClipToPadding(false);
setAccessibilityDelegate(mActivity.getAccessibilityDelegate());
- mEnforcedCornerRadius = RoundedCornerEnforcement.computeEnforcedRadius(context);
- }
-
- private void setContainerWidth() {
- mCellSize = (int) (mActivity.getDeviceProfile().allAppsIconSizePx * WIDTH_SCALE);
- mPresetPreviewSize = (int) (mCellSize * PREVIEW_SCALE);
- mTargetPreviewWidth = mTargetPreviewHeight = mPresetPreviewSize;
}
@Override
@@ -206,7 +163,6 @@
mWidgetDims.setText(null);
mWidgetDescription.setText(null);
mWidgetDescription.setVisibility(GONE);
- mTargetPreviewWidth = mTargetPreviewHeight = mPresetPreviewSize;
if (mActiveRequest != null) {
mActiveRequest.cancel();
@@ -218,7 +174,9 @@
}
mAppWidgetHostViewPreview = null;
mAppWidgetHostViewScale = 1f;
+ mPreviewContainerScale = 1f;
mItem = null;
+ mWidgetSize = new Size(0, 0);
}
public void setSourceContainer(int sourceContainer) {
@@ -248,17 +206,12 @@
*/
public void applyFromCellItem(WidgetItem item, float previewScale,
@NonNull Consumer<Bitmap> callback, @Nullable Bitmap cachedPreview) {
- // setPreviewSize
- DeviceProfile deviceProfile = mActivity.getDeviceProfile();
- Size widgetSize = WidgetSizes.getWidgetItemSizePx(getContext(), deviceProfile, item);
- mTargetPreviewWidth = widgetSize.getWidth();
- mTargetPreviewHeight = widgetSize.getHeight();
mPreviewContainerScale = previewScale;
- applyPreviewOnAppWidgetHostView(item);
-
Context context = getContext();
mItem = item;
+ mWidgetSize = getWidgetItemSizePx(getContext(), mActivity.getDeviceProfile(), mItem);
+
mWidgetName.setText(mItem.label);
mWidgetName.setContentDescription(
context.getString(R.string.widget_preview_context_description, mItem.label));
@@ -266,14 +219,11 @@
mItem.spanX, mItem.spanY));
mWidgetDims.setContentDescription(context.getString(
R.string.widget_accessible_dims_format, mItem.spanX, mItem.spanY));
- if (ATLEAST_S && mItem.widgetInfo != null) {
- CharSequence description = mItem.widgetInfo.loadDescription(context);
- if (description != null && description.length() > 0) {
- mWidgetDescription.setText(description);
- mWidgetDescription.setVisibility(VISIBLE);
- } else {
- mWidgetDescription.setVisibility(GONE);
- }
+ if (!TextUtils.isEmpty(mItem.description)) {
+ mWidgetDescription.setText(mItem.description);
+ mWidgetDescription.setVisibility(VISIBLE);
+ } else {
+ mWidgetDescription.setVisibility(GONE);
}
if (item.activityInfo != null) {
@@ -282,68 +232,31 @@
setTag(new PendingAddWidgetInfo(item.widgetInfo, mSourceContainer));
}
- ensurePreviewWithCallback(callback, cachedPreview);
- }
-
- private static class ScaledAppWidgetHostView extends LauncherAppWidgetHostView {
- private boolean mKeepOrigForDragging = true;
-
- ScaledAppWidgetHostView(Context context) {
- super(context);
- }
-
- /**
- * Set if the view will keep its original scale when dragged
- * @param isKeepOrig True if keep original scale when dragged, false otherwise
- */
- public void setKeepOrigForDragging(boolean isKeepOrig) {
- mKeepOrigForDragging = isKeepOrig;
- }
-
- /**
- * @return True if the view is set to preserve original scale when dragged, false otherwise
- */
- public boolean isKeepOrigForDragging() {
- return mKeepOrigForDragging;
- }
-
- @Override
- public void startDrag() {
- super.startDrag();
- if (!isKeepOrigForDragging()) {
- // restore to original scale when being dragged, if set to do so
- setScaleToFit(1.0f);
- }
- // When the drag start, translations need to be set to zero to center the view
- getTranslateDelegate().setTranslation(INDEX_WIDGET_CENTERING, 0f, 0f);
- }
- }
-
- private void applyPreviewOnAppWidgetHostView(WidgetItem item) {
if (mRemoteViewsPreview != null) {
- mAppWidgetHostViewPreview = createAppWidgetHostView(getContext());
+ mAppWidgetHostViewPreview = createAppWidgetHostView(context);
setAppWidgetHostViewPreview(mAppWidgetHostViewPreview, item.widgetInfo,
mRemoteViewsPreview);
- return;
+ } else if (item.hasPreviewLayout()) {
+ // If the context is a Launcher activity, DragView will show mAppWidgetHostViewPreview
+ // as a preview during drag & drop. And thus, we should use LauncherAppWidgetHostView,
+ // which supports applying local color extraction during drag & drop.
+ mAppWidgetHostViewPreview = isLauncherContext(context)
+ ? new LauncherAppWidgetHostView(context)
+ : createAppWidgetHostView(context);
+ LauncherAppWidgetProviderInfo providerInfo =
+ fromProviderInfo(context, item.widgetInfo.clone());
+ // A hack to force the initial layout to be the preview layout since there is no API for
+ // rendering a preview layout for work profile apps yet. For non-work profile layout, a
+ // proper solution is to use RemoteViews(PackageName, LayoutId).
+ providerInfo.initialLayout = item.widgetInfo.previewLayout;
+ setAppWidgetHostViewPreview(mAppWidgetHostViewPreview, providerInfo, null);
+ } else if (cachedPreview != null) {
+ applyPreview(cachedPreview);
+ } else {
+ if (mActiveRequest == null) {
+ mActiveRequest = mWidgetPreviewLoader.loadPreview(mItem, mWidgetSize, callback);
+ }
}
-
- if (!item.hasPreviewLayout()) return;
-
- Context context = getContext();
- // If the context is a Launcher activity, DragView will show mAppWidgetHostViewPreview as
- // a preview during drag & drop. And thus, we should use LauncherAppWidgetHostView, which
- // supports applying local color extraction during drag & drop.
- mAppWidgetHostViewPreview = isLauncherContext(context)
- ? new ScaledAppWidgetHostView(context)
- : createAppWidgetHostView(context);
- LauncherAppWidgetProviderInfo launcherAppWidgetProviderInfo =
- LauncherAppWidgetProviderInfo.fromProviderInfo(context, item.widgetInfo.clone());
- // A hack to force the initial layout to be the preview layout since there is no API for
- // rendering a preview layout for work profile apps yet. For non-work profile layout, a
- // proper solution is to use RemoteViews(PackageName, LayoutId).
- launcherAppWidgetProviderInfo.initialLayout = item.widgetInfo.previewLayout;
- setAppWidgetHostViewPreview(mAppWidgetHostViewPreview,
- launcherAppWidgetProviderInfo, /* remoteViews= */ null);
}
private void setAppWidgetHostViewPreview(
@@ -353,6 +266,43 @@
appWidgetHostViewPreview.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
appWidgetHostViewPreview.setAppWidget(/* appWidgetId= */ -1, providerInfo);
appWidgetHostViewPreview.updateAppWidget(remoteViews);
+ appWidgetHostViewPreview.setClipToPadding(false);
+ appWidgetHostViewPreview.setClipChildren(false);
+
+ FrameLayout.LayoutParams widgetHostLP = new FrameLayout.LayoutParams(
+ mWidgetSize.getWidth(), mWidgetSize.getHeight(), Gravity.CENTER);
+ mWidgetImageContainer.addView(appWidgetHostViewPreview, /* index= */ 0, widgetHostLP);
+ mWidgetImage.setVisibility(View.GONE);
+ applyPreview(null);
+
+ appWidgetHostViewPreview.addOnLayoutChangeListener(
+ (v, l, t, r, b, ol, ot, or, ob) ->
+ updateAppWidgetHostScale(appWidgetHostViewPreview));
+ }
+
+ private void updateAppWidgetHostScale(NavigableAppWidgetHostView view) {
+ // Scale the content such that all of the content is visible
+ int contentWidth = view.getWidth();
+ int contentHeight = view.getHeight();
+
+ if (view.getChildCount() == 1) {
+ View content = view.getChildAt(0);
+ // Take the content width based on the edge furthest from the center, so that when
+ // scaling the hostView, the farthest edge is still visible.
+ contentWidth = 2 * Math.max(contentWidth / 2 - content.getLeft(),
+ content.getRight() - contentWidth / 2);
+ contentHeight = 2 * Math.max(contentHeight / 2 - content.getTop(),
+ content.getBottom() - contentHeight / 2);
+ }
+
+ if (contentWidth <= 0 || contentHeight <= 0) {
+ mAppWidgetHostViewScale = 1;
+ } else {
+ float pWidth = mWidgetImageContainer.getWidth();
+ float pHeight = mWidgetImageContainer.getHeight();
+ mAppWidgetHostViewScale = Math.min(pWidth / contentWidth, pHeight / contentHeight);
+ }
+ view.setScaleToFit(mAppWidgetHostViewScale);
}
public WidgetImageView getWidgetView() {
@@ -372,17 +322,6 @@
if (bitmap != null) {
Drawable drawable = new RoundDrawableWrapper(
new FastBitmapDrawable(bitmap), mEnforcedCornerRadius);
-
- // Scale down the preview size if it's wider than the cell.
- float scale = 1f;
- if (mTargetPreviewWidth > 0) {
- float maxWidth = mTargetPreviewWidth;
- float previewWidth = drawable.getIntrinsicWidth() * mPreviewContainerScale;
- scale = Math.min(maxWidth / previewWidth, 1);
- }
- setContainerSize(
- Math.round(drawable.getIntrinsicWidth() * scale * mPreviewContainerScale),
- Math.round(drawable.getIntrinsicHeight() * scale * mPreviewContainerScale));
mWidgetImage.setDrawable(drawable);
mWidgetImage.setVisibility(View.VISIBLE);
if (mAppWidgetHostViewPreview != null) {
@@ -415,76 +354,6 @@
}
}
- private void setContainerSize(int width, int height) {
- LayoutParams layoutParams = (LayoutParams) mWidgetImageContainer.getLayoutParams();
- layoutParams.width = width;
- layoutParams.height = height;
- mWidgetImageContainer.setLayoutParams(layoutParams);
- }
-
- /**
- * Ensures that the preview is already loaded or being loaded. If the preview is not loaded,
- * it applies the provided cachedPreview. If that is null, it starts a loader and notifies the
- * callback on successful load.
- */
- private void ensurePreviewWithCallback(Consumer<Bitmap> callback,
- @Nullable Bitmap cachedPreview) {
- if (mAppWidgetHostViewPreview != null) {
- int containerWidth = (int) (mTargetPreviewWidth * mPreviewContainerScale);
- int containerHeight = (int) (mTargetPreviewHeight * mPreviewContainerScale);
- setContainerSize(containerWidth, containerHeight);
- boolean shouldMeasureAndScale = false;
- if (mAppWidgetHostViewPreview.getChildCount() == 1) {
- View widgetContent = mAppWidgetHostViewPreview.getChildAt(0);
- ViewGroup.LayoutParams layoutParams = widgetContent.getLayoutParams();
- // We only scale preview if both the width & height of the outermost view group are
- // not set to MATCH_PARENT.
- shouldMeasureAndScale =
- layoutParams.width != MATCH_PARENT && layoutParams.height != MATCH_PARENT;
- if (shouldMeasureAndScale) {
- setNoClip(mWidgetImageContainer);
- setNoClip(mAppWidgetHostViewPreview);
- mAppWidgetHostViewScale = measureAndComputeWidgetPreviewScale();
- }
- }
-
- FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
- mTargetPreviewWidth, mTargetPreviewHeight, Gravity.FILL);
- mAppWidgetHostViewPreview.setLayoutParams(params);
-
- if (!shouldMeasureAndScale
- && mAppWidgetHostViewPreview instanceof ScaledAppWidgetHostView) {
- // If the view is not measured & scaled, at least one side will match the grid size,
- // so it should be safe to restore the original scale once it is dragged.
- ScaledAppWidgetHostView tempView =
- (ScaledAppWidgetHostView) mAppWidgetHostViewPreview;
- tempView.setKeepOrigForDragging(false);
- tempView.setScaleToFit(mPreviewContainerScale);
- } else if (!shouldMeasureAndScale) {
- mAppWidgetHostViewPreview.setScaleToFit(mPreviewContainerScale);
- } else {
- mAppWidgetHostViewPreview.setScaleToFit(mAppWidgetHostViewScale);
- }
- mAppWidgetHostViewPreview.getTranslateDelegate().setTranslation(
- INDEX_WIDGET_CENTERING,
- -(params.width - (params.width * mPreviewContainerScale)) / 2.0f,
- -(params.height - (params.height * mPreviewContainerScale)) / 2.0f);
- mWidgetImageContainer.addView(mAppWidgetHostViewPreview, /* index= */ 0);
- mWidgetImage.setVisibility(View.GONE);
- applyPreview(null);
- return;
- }
- if (cachedPreview != null) {
- applyPreview(cachedPreview);
- return;
- }
- if (mActiveRequest != null) {
- return;
- }
- mActiveRequest = mWidgetPreviewLoader.loadPreview(
- mItem, new Size(mTargetPreviewWidth, mTargetPreviewHeight), callback);
- }
-
@Override
public boolean onTouchEvent(MotionEvent ev) {
super.onTouchEvent(ev);
@@ -522,61 +391,20 @@
info.removeAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK);
}
- private static void setNoClip(ViewGroup view) {
- view.setClipChildren(false);
- view.setClipToPadding(false);
- }
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ ViewGroup.LayoutParams containerLp = mWidgetImageContainer.getLayoutParams();
- private float measureAndComputeWidgetPreviewScale() {
- if (mAppWidgetHostViewPreview.getChildCount() != 1) {
- return 1f;
+ mAppWidgetHostViewScale = mPreviewContainerScale;
+ int maxWidth = MeasureSpec.getSize(widthMeasureSpec);
+ containerLp.width = Math.round(mWidgetSize.getWidth() * mAppWidgetHostViewScale);
+ if (containerLp.width > maxWidth) {
+ containerLp.width = maxWidth;
+ mAppWidgetHostViewScale = (float) containerLp.width / mWidgetSize.getWidth();
}
+ containerLp.height = Math.round(mWidgetSize.getHeight() * mAppWidgetHostViewScale);
+ // No need to call mWidgetImageContainer.setLayoutParams as we are in measure pass
- // Measure the largest possible width & height that the app widget wants to display.
- mAppWidgetHostViewPreview.measure(
- makeMeasureSpec(MAX_MEASURE_SPEC_DIMENSION, MeasureSpec.UNSPECIFIED),
- makeMeasureSpec(MAX_MEASURE_SPEC_DIMENSION, MeasureSpec.UNSPECIFIED));
- if (mRemoteViewsPreview != null) {
- // If RemoteViews contains multiple sizes, the best fit sized RemoteViews will be
- // selected in onLayout. To work out the right measurement, let's layout and then
- // measure again.
- mAppWidgetHostViewPreview.layout(
- /* left= */ 0,
- /* top= */ 0,
- /* right= */ mTargetPreviewWidth,
- /* bottom= */ mTargetPreviewHeight);
- mAppWidgetHostViewPreview.measure(
- makeMeasureSpec(mTargetPreviewWidth, MeasureSpec.UNSPECIFIED),
- makeMeasureSpec(mTargetPreviewHeight, MeasureSpec.UNSPECIFIED));
-
- }
- View widgetContent = mAppWidgetHostViewPreview.getChildAt(0);
- int appWidgetContentWidth = widgetContent.getMeasuredWidth();
- int appWidgetContentHeight = widgetContent.getMeasuredHeight();
- if (appWidgetContentWidth == 0 || appWidgetContentHeight == 0) {
- return 1f;
- }
-
- // If the width / height of the widget content is set to wrap content, overrides the width /
- // height with the measured dimension. This avoids incorrect measurement after scaling.
- FrameLayout.LayoutParams layoutParam =
- (FrameLayout.LayoutParams) widgetContent.getLayoutParams();
- if (layoutParam.width == WRAP_CONTENT) {
- layoutParam.width = widgetContent.getMeasuredWidth();
- }
- if (layoutParam.height == WRAP_CONTENT) {
- layoutParam.height = widgetContent.getMeasuredHeight();
- }
- widgetContent.setLayoutParams(layoutParam);
-
- int horizontalPadding = mAppWidgetHostViewPreview.getPaddingStart()
- + mAppWidgetHostViewPreview.getPaddingEnd();
- int verticalPadding = mAppWidgetHostViewPreview.getPaddingTop()
- + mAppWidgetHostViewPreview.getPaddingBottom();
- return Math.min(
- (mTargetPreviewWidth - horizontalPadding) * mPreviewContainerScale
- / appWidgetContentWidth,
- (mTargetPreviewHeight - verticalPadding) * mPreviewContainerScale
- / appWidgetContentHeight);
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
diff --git a/src/com/android/launcher3/widget/WidgetsBottomSheet.java b/src/com/android/launcher3/widget/WidgetsBottomSheet.java
index 23cdae9..846dafd 100644
--- a/src/com/android/launcher3/widget/WidgetsBottomSheet.java
+++ b/src/com/android/launcher3/widget/WidgetsBottomSheet.java
@@ -252,8 +252,11 @@
super.setInsets(insets);
int bottomPadding = Math.max(insets.bottom, mNavBarScrimHeight);
- mContent.setPadding(mContent.getPaddingStart(),
- mContent.getPaddingTop(), mContent.getPaddingEnd(),
+ View widgetsTable = findViewById(R.id.widgets_table);
+ widgetsTable.setPadding(
+ widgetsTable.getPaddingLeft(),
+ widgetsTable.getPaddingTop(),
+ widgetsTable.getPaddingRight(),
bottomPadding);
if (bottomPadding > 0) {
setupNavBarColor();
diff --git a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
index 1b743e8..2f16065 100644
--- a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
+++ b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
@@ -129,7 +129,7 @@
LauncherAppWidgetProviderInfo.fromProviderInfo(context, widgetInfo);
widgetsAndShortcuts.add(new WidgetItem(
- launcherWidgetInfo, idp, app.getIconCache()));
+ launcherWidgetInfo, idp, app.getIconCache(), app.getContext()));
updatedItems.add(launcherWidgetInfo);
}
@@ -200,7 +200,8 @@
app.getContext().getPackageManager()));
} else {
items.set(i, new WidgetItem(item.widgetInfo,
- app.getInvariantDeviceProfile(), app.getIconCache()));
+ app.getInvariantDeviceProfile(), app.getIconCache(),
+ app.getContext()));
}
}
}
diff --git a/tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java b/tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java
index 76492ba..8fc4481 100644
--- a/tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java
+++ b/tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java
@@ -147,7 +147,7 @@
widgetItems.add(new WidgetItem(
LauncherAppWidgetProviderInfo.fromProviderInfo(mContext, widgetInfo),
- mTestProfile, mIconCache));
+ mTestProfile, mIconCache, mContext));
}
return widgetItems;
}
diff --git a/tests/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinderTest.java b/tests/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinderTest.java
index e0101f5..60590e7 100644
--- a/tests/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinderTest.java
+++ b/tests/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinderTest.java
@@ -144,7 +144,7 @@
widgetItems.add(new WidgetItem(
LauncherAppWidgetProviderInfo.fromProviderInfo(mContext, widgetInfo),
- mTestProfile, mIconCache));
+ mTestProfile, mIconCache, mContext));
}
return widgetItems;
}
diff --git a/tests/src/com/android/launcher3/widget/picker/model/WidgetsListContentEntryTest.java b/tests/src/com/android/launcher3/widget/picker/model/WidgetsListContentEntryTest.java
index d8f1f14..7552619 100644
--- a/tests/src/com/android/launcher3/widget/picker/model/WidgetsListContentEntryTest.java
+++ b/tests/src/com/android/launcher3/widget/picker/model/WidgetsListContentEntryTest.java
@@ -26,6 +26,7 @@
import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName;
+import android.content.Context;
import android.os.UserHandle;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -249,12 +250,13 @@
String label = mWidgetsToLabels.get(componentName);
AppWidgetProviderInfo widgetInfo = createAppWidgetProviderInfo(componentName);
+ Context context = getApplicationContext();
LauncherAppWidgetProviderInfo launcherAppWidgetProviderInfo =
- LauncherAppWidgetProviderInfo.fromProviderInfo(getApplicationContext(), widgetInfo);
+ LauncherAppWidgetProviderInfo.fromProviderInfo(context, widgetInfo);
launcherAppWidgetProviderInfo.spanX = spanX;
launcherAppWidgetProviderInfo.spanY = spanY;
launcherAppWidgetProviderInfo.label = label;
- return new WidgetItem(launcherAppWidgetProviderInfo, mTestProfile, mIconCache);
+ return new WidgetItem(launcherAppWidgetProviderInfo, mTestProfile, mIconCache, context);
}
}
diff --git a/tests/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithmTest.java b/tests/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithmTest.java
index 0124f73..9c03ccf 100644
--- a/tests/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithmTest.java
+++ b/tests/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithmTest.java
@@ -202,7 +202,7 @@
WidgetItem widgetItem = new WidgetItem(
LauncherAppWidgetProviderInfo.fromProviderInfo(mContext, widgetInfo),
- mTestProfile, mIconCache);
+ mTestProfile, mIconCache, mContext);
widgetItems.add(widgetItem);
}
return widgetItems;
diff --git a/tests/src/com/android/launcher3/widget/picker/util/WidgetsTableUtilsTest.java b/tests/src/com/android/launcher3/widget/picker/util/WidgetsTableUtilsTest.java
index 834f851..2c5a396 100644
--- a/tests/src/com/android/launcher3/widget/picker/util/WidgetsTableUtilsTest.java
+++ b/tests/src/com/android/launcher3/widget/picker/util/WidgetsTableUtilsTest.java
@@ -218,19 +218,18 @@
new Point(2, 4), new Point(4, 4));
ArrayList<WidgetItem> widgetItems = new ArrayList<>();
- widgetSizes.stream().forEach(
- widgetSize -> {
- AppWidgetProviderInfo info = createAppWidgetProviderInfo(
- ComponentName.createRelative(
- TEST_PACKAGE,
- ".WidgetProvider_" + widgetSize.x + "x" + widgetSize.y));
- LauncherAppWidgetProviderInfo widgetInfo =
- LauncherAppWidgetProviderInfo.fromProviderInfo(mContext, info);
- widgetInfo.spanX = widgetSize.x;
- widgetInfo.spanY = widgetSize.y;
- widgetItems.add(new WidgetItem(widgetInfo, mTestInvariantProfile, mIconCache));
- }
- );
+ widgetSizes.stream().forEach(widgetSize -> {
+ AppWidgetProviderInfo info = createAppWidgetProviderInfo(
+ ComponentName.createRelative(
+ TEST_PACKAGE,
+ ".WidgetProvider_" + widgetSize.x + "x" + widgetSize.y));
+ LauncherAppWidgetProviderInfo widgetInfo =
+ LauncherAppWidgetProviderInfo.fromProviderInfo(mContext, info);
+ widgetInfo.spanX = widgetSize.x;
+ widgetInfo.spanY = widgetSize.y;
+ widgetItems.add(new WidgetItem(
+ widgetInfo, mTestInvariantProfile, mIconCache, mContext));
+ });
mWidget1x1 = widgetItems.get(0);
mWidget2x2 = widgetItems.get(1);
mWidget2x3 = widgetItems.get(2);
diff --git a/tests/tapl/com/android/launcher3/tapl/AppIcon.java b/tests/tapl/com/android/launcher3/tapl/AppIcon.java
index 2687b28..0a0cf07 100644
--- a/tests/tapl/com/android/launcher3/tapl/AppIcon.java
+++ b/tests/tapl/com/android/launcher3/tapl/AppIcon.java
@@ -37,7 +37,8 @@
}
static BySelector getAppIconSelector(String appName, LauncherInstrumentation launcher) {
- return By.clazz(TextView.class).text(appName).pkg(launcher.getLauncherPackageName());
+ return By.clazz(TextView.class).textContains(appName)
+ .pkg(launcher.getLauncherPackageName());
}
static BySelector getAnyAppIconSelector() {