Merge "Import translations. DO NOT MERGE ANYWHERE" into tm-dev
diff --git a/go/res/xml/device_profiles.xml b/go/res/xml/device_profiles.xml
index 0c7eba3..7c3a160 100644
--- a/go/res/xml/device_profiles.xml
+++ b/go/res/xml/device_profiles.xml
@@ -33,6 +33,8 @@
launcher:minHeightDps="491.33"
launcher:iconImageSize="60"
launcher:iconTextSize="14.0"
+ launcher:allAppsBorderSpace="16"
+ launcher:allAppsCellHeight="104"
launcher:canBeDefault="true" />
</grid-option>
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
index 9870a2e..21d7af9 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
@@ -16,10 +16,11 @@
package com.android.launcher3.taskbar
import android.graphics.Insets
+import android.graphics.Region
+import android.view.InsetsState.ITYPE_BOTTOM_MANDATORY_GESTURES
import android.view.WindowManager
import com.android.launcher3.AbstractFloatingView
import com.android.launcher3.AbstractFloatingView.TYPE_TASKBAR_ALL_APPS
-import com.android.launcher3.R
import com.android.launcher3.anim.AlphaUpdateListener
import com.android.launcher3.taskbar.TaskbarControllers.LoggableTaskbarController
import com.android.quickstep.KtR
@@ -36,6 +37,7 @@
/** The bottom insets taskbar provides to the IME when IME is visible. */
val taskbarHeightForIme: Int = context.resources.getDimensionPixelSize(
KtR.dimen.taskbar_ime_size)
+ private val contentRegion: Region = Region()
// Initialized in init.
private lateinit var controllers: TaskbarControllers
@@ -50,7 +52,8 @@
windowLayoutParams,
intArrayOf(
ITYPE_EXTRA_NAVIGATION_BAR,
- ITYPE_BOTTOM_TAPPABLE_ELEMENT
+ ITYPE_BOTTOM_TAPPABLE_ELEMENT,
+ ITYPE_BOTTOM_MANDATORY_GESTURES
)
)
@@ -67,14 +70,20 @@
fun onTaskbarWindowHeightOrInsetsChanged() {
var reducingSize = getReducingInsetsForTaskbarInsetsHeight(
controllers.taskbarStashController.contentHeightToReportToApps)
+
+ contentRegion.set(0, reducingSize.top,
+ context.dragLayer.width, windowLayoutParams.height)
windowLayoutParams.providedInternalInsets[ITYPE_EXTRA_NAVIGATION_BAR] = reducingSize
+ windowLayoutParams.providedInternalInsets[ITYPE_BOTTOM_MANDATORY_GESTURES] = reducingSize
reducingSize = getReducingInsetsForTaskbarInsetsHeight(
controllers.taskbarStashController.tappableHeightToReportToApps)
windowLayoutParams.providedInternalInsets[ITYPE_BOTTOM_TAPPABLE_ELEMENT] = reducingSize
+ windowLayoutParams.providedInternalInsets[ITYPE_BOTTOM_MANDATORY_GESTURES] = reducingSize
reducingSize = getReducingInsetsForTaskbarInsetsHeight(taskbarHeightForIme)
windowLayoutParams.providedInternalImeInsets[ITYPE_EXTRA_NAVIGATION_BAR] = reducingSize
windowLayoutParams.providedInternalImeInsets[ITYPE_BOTTOM_TAPPABLE_ELEMENT] = reducingSize
+ windowLayoutParams.providedInternalImeInsets[ITYPE_BOTTOM_MANDATORY_GESTURES] = reducingSize
}
/**
@@ -121,7 +130,8 @@
if (context.isTaskbarWindowFullscreen) {
InsetsInfo.TOUCHABLE_INSETS_FRAME
} else {
- InsetsInfo.TOUCHABLE_INSETS_CONTENT
+ insetsInfo.touchableRegion.set(contentRegion)
+ InsetsInfo.TOUCHABLE_INSETS_REGION
}
)
insetsIsTouchableRegion = false
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
index 3b1f119..a74774c 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
@@ -31,6 +31,8 @@
*/
public class AllAppsState extends LauncherState {
+ private static final float WORKSPACE_SCALE_FACTOR = 0.97f;
+
private static final int STATE_FLAGS =
FLAG_WORKSPACE_INACCESSIBLE | FLAG_CLOSE_POPUPS | FLAG_HOTSEAT_INACCESSIBLE;
@@ -58,7 +60,7 @@
@Override
public ScaleAndTranslation getWorkspaceScaleAndTranslation(Launcher launcher) {
- return new ScaleAndTranslation(0.97f, NO_OFFSET, NO_OFFSET);
+ return new ScaleAndTranslation(WORKSPACE_SCALE_FACTOR, NO_OFFSET, NO_OFFSET);
}
@Override
@@ -69,7 +71,7 @@
ScaleAndTranslation overviewScaleAndTranslation = LauncherState.OVERVIEW
.getWorkspaceScaleAndTranslation(launcher);
return new ScaleAndTranslation(
- NO_SCALE,
+ WORKSPACE_SCALE_FACTOR,
overviewScaleAndTranslation.translationX,
overviewScaleAndTranslation.translationY);
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
index dbee9c1..e56c90c 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
@@ -25,9 +25,17 @@
import static com.android.launcher3.anim.Interpolators.INSTANT;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
+import static com.android.launcher3.states.StateAnimationConfig.ANIM_DEPTH;
+import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_FADE;
+import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_SCALE;
+import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_TRANSLATE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_SCRIM_FADE;
+import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PROGRESS;
+import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_FADE;
+import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_SCALE;
import android.view.MotionEvent;
+import android.view.animation.Interpolator;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
@@ -70,6 +78,33 @@
*/
public static final float ALL_APPS_SCRIM_OPAQUE_THRESHOLD = .5f;
+ // Custom timing for NORMAL -> ALL_APPS on phones only.
+ private static final float ALL_APPS_STATE_TRANSITION = 0.4f;
+ private static final float ALL_APPS_FULL_DEPTH_PROGRESS = 0.5f;
+
+ // Custom interpolators for NORMAL -> ALL_APPS on phones only.
+ private static final Interpolator LINEAR_EARLY =
+ Interpolators.clampToProgress(LINEAR, 0f, ALL_APPS_STATE_TRANSITION);
+ private static final Interpolator STEP_TRANSITION =
+ Interpolators.clampToProgress(FINAL_FRAME, 0f, ALL_APPS_STATE_TRANSITION);
+ // The blur to and from All Apps is set to be complete when the interpolator is at 0.5.
+ public static final Interpolator BLUR =
+ Interpolators.clampToProgress(
+ Interpolators.mapToProgress(LINEAR, 0f, ALL_APPS_FULL_DEPTH_PROGRESS),
+ 0f, ALL_APPS_STATE_TRANSITION);
+ public static final Interpolator WORKSPACE_FADE = STEP_TRANSITION;
+ public static final Interpolator WORKSPACE_SCALE = LINEAR_EARLY;
+ public static final Interpolator HOTSEAT_FADE = STEP_TRANSITION;
+ public static final Interpolator HOTSEAT_SCALE = LINEAR_EARLY;
+ public static final Interpolator HOTSEAT_TRANSLATE = STEP_TRANSITION;
+ public static final Interpolator SCRIM_FADE = LINEAR_EARLY;
+ public static final Interpolator ALL_APPS_FADE =
+ Interpolators.clampToProgress(LINEAR, ALL_APPS_STATE_TRANSITION, 1f);
+ public static final Interpolator ALL_APPS_VERTICAL_PROGRESS =
+ Interpolators.clampToProgress(
+ Interpolators.mapToProgress(LINEAR, ALL_APPS_STATE_TRANSITION, 1f),
+ ALL_APPS_STATE_TRANSITION, 1f);
+
private final PortraitOverviewStateTouchHelper mOverviewPortraitStateTouchHelper;
public PortraitStatesTouchController(Launcher l) {
@@ -127,29 +162,51 @@
private StateAnimationConfig getNormalToAllAppsAnimation() {
StateAnimationConfig builder = new StateAnimationConfig();
- boolean isTablet = mLauncher.getDeviceProfile().isTablet;
- builder.setInterpolator(ANIM_ALL_APPS_FADE, isTablet
- ? INSTANT
- : Interpolators.clampToProgress(LINEAR,
- ALL_APPS_CONTENT_FADE_MIN_CLAMPING_THRESHOLD,
- ALL_APPS_CONTENT_FADE_MAX_CLAMPING_THRESHOLD));
- builder.setInterpolator(ANIM_SCRIM_FADE, Interpolators.clampToProgress(LINEAR,
- ALL_APPS_SCRIM_VISIBLE_THRESHOLD,
- ALL_APPS_SCRIM_OPAQUE_THRESHOLD));
+ if (mLauncher.getDeviceProfile().isTablet) {
+ builder.setInterpolator(ANIM_ALL_APPS_FADE, INSTANT);
+ builder.setInterpolator(ANIM_SCRIM_FADE,
+ Interpolators.clampToProgress(LINEAR,
+ ALL_APPS_SCRIM_VISIBLE_THRESHOLD,
+ ALL_APPS_SCRIM_OPAQUE_THRESHOLD));
+ } else {
+ // TODO(b/231682175): centralize this setup in AllAppsSwipeController.
+ builder.setInterpolator(ANIM_DEPTH, BLUR);
+ builder.setInterpolator(ANIM_WORKSPACE_FADE, WORKSPACE_FADE);
+ builder.setInterpolator(ANIM_WORKSPACE_SCALE, WORKSPACE_SCALE);
+ builder.setInterpolator(ANIM_HOTSEAT_FADE, HOTSEAT_FADE);
+ builder.setInterpolator(ANIM_HOTSEAT_SCALE, HOTSEAT_SCALE);
+ builder.setInterpolator(ANIM_HOTSEAT_TRANSLATE, HOTSEAT_TRANSLATE);
+ builder.setInterpolator(ANIM_SCRIM_FADE, SCRIM_FADE);
+ builder.setInterpolator(ANIM_ALL_APPS_FADE, ALL_APPS_FADE);
+ builder.setInterpolator(ANIM_VERTICAL_PROGRESS, ALL_APPS_VERTICAL_PROGRESS);
+ }
return builder;
}
private StateAnimationConfig getAllAppsToNormalAnimation() {
StateAnimationConfig builder = new StateAnimationConfig();
- boolean isTablet = mLauncher.getDeviceProfile().isTablet;
- builder.setInterpolator(ANIM_ALL_APPS_FADE, isTablet
- ? FINAL_FRAME
- : Interpolators.clampToProgress(LINEAR,
- 1 - ALL_APPS_CONTENT_FADE_MAX_CLAMPING_THRESHOLD,
- 1 - ALL_APPS_CONTENT_FADE_MIN_CLAMPING_THRESHOLD));
- builder.setInterpolator(ANIM_SCRIM_FADE, Interpolators.clampToProgress(LINEAR,
- 1 - ALL_APPS_SCRIM_OPAQUE_THRESHOLD,
- 1 - ALL_APPS_SCRIM_VISIBLE_THRESHOLD));
+ if (mLauncher.getDeviceProfile().isTablet) {
+ builder.setInterpolator(ANIM_ALL_APPS_FADE, FINAL_FRAME);
+ builder.setInterpolator(ANIM_SCRIM_FADE,
+ Interpolators.clampToProgress(LINEAR,
+ 1 - ALL_APPS_SCRIM_OPAQUE_THRESHOLD,
+ 1 - ALL_APPS_SCRIM_VISIBLE_THRESHOLD));
+ } else {
+ // These interpolators are the reverse of the ones used above, so swiping out of All
+ // Apps feels the same as swiping into it.
+ // TODO(b/231682175): centralize this setup in AllAppsSwipeController.
+ builder.setInterpolator(ANIM_DEPTH, Interpolators.reverse(BLUR));
+ builder.setInterpolator(ANIM_WORKSPACE_FADE, Interpolators.reverse(WORKSPACE_FADE));
+ builder.setInterpolator(ANIM_WORKSPACE_SCALE, Interpolators.reverse(WORKSPACE_SCALE));
+ builder.setInterpolator(ANIM_HOTSEAT_FADE, Interpolators.reverse(HOTSEAT_FADE));
+ builder.setInterpolator(ANIM_HOTSEAT_SCALE, Interpolators.reverse(HOTSEAT_SCALE));
+ builder.setInterpolator(ANIM_HOTSEAT_TRANSLATE,
+ Interpolators.reverse(HOTSEAT_TRANSLATE));
+ builder.setInterpolator(ANIM_SCRIM_FADE, Interpolators.reverse(SCRIM_FADE));
+ builder.setInterpolator(ANIM_ALL_APPS_FADE, Interpolators.reverse(ALL_APPS_FADE));
+ builder.setInterpolator(ANIM_VERTICAL_PROGRESS,
+ Interpolators.reverse(ALL_APPS_VERTICAL_PROGRESS));
+ }
return builder;
}
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 1b1cb85..21728ad 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -1032,19 +1032,19 @@
return RECENTS;
}
final GestureEndTarget endTarget;
- final boolean canGoToNewTask;
+ final boolean goingToNewTask;
if (mRecentsView != null) {
if (!hasTargets()) {
// If there are no running tasks, then we can assume that this is a continuation of
// the last gesture, but after the recents animation has finished
- canGoToNewTask = true;
+ goingToNewTask = true;
} else {
final int runningTaskIndex = mRecentsView.getRunningTaskIndex();
final int taskToLaunch = mRecentsView.getNextPage();
- canGoToNewTask = runningTaskIndex >= 0 && taskToLaunch != runningTaskIndex;
+ goingToNewTask = runningTaskIndex >= 0 && taskToLaunch != runningTaskIndex;
}
} else {
- canGoToNewTask = false;
+ goingToNewTask = false;
}
final boolean reachedOverviewThreshold = mCurrentShift.value >= MIN_PROGRESS_FOR_OVERVIEW;
final boolean isFlingX = Math.abs(velocity.x) > mContext.getResources()
@@ -1053,13 +1053,13 @@
if (isCancel) {
endTarget = LAST_TASK;
} else if (mDeviceState.isFullyGesturalNavMode()) {
- if (canGoToNewTask && isFlingX) {
+ if (goingToNewTask && isFlingX) {
// Flinging towards new task takes precedence over mIsMotionPaused (which only
// checks y-velocity).
endTarget = NEW_TASK;
} else if (mIsMotionPaused) {
endTarget = RECENTS;
- } else if (canGoToNewTask) {
+ } else if (goingToNewTask) {
endTarget = NEW_TASK;
} else {
endTarget = !reachedOverviewThreshold ? LAST_TASK : HOME;
@@ -1067,22 +1067,26 @@
} else {
endTarget = reachedOverviewThreshold && mGestureStarted
? RECENTS
- : canGoToNewTask
+ : goingToNewTask
? NEW_TASK
: LAST_TASK;
}
} else {
// If swiping at a diagonal, base end target on the faster velocity.
boolean isSwipeUp = endVelocity < 0;
- boolean willGoToNewTask =
- canGoToNewTask && Math.abs(velocity.x) > Math.abs(endVelocity);
+ boolean willGoToNewTaskOnSwipeUp =
+ goingToNewTask && Math.abs(velocity.x) > Math.abs(endVelocity);
- if (mDeviceState.isFullyGesturalNavMode() && isSwipeUp) {
- endTarget = willGoToNewTask ? NEW_TASK : HOME;
+ if (mDeviceState.isFullyGesturalNavMode() && isSwipeUp && !willGoToNewTaskOnSwipeUp) {
+ endTarget = HOME;
+ } else if (mDeviceState.isFullyGesturalNavMode() && isSwipeUp) {
+ // If swiping at a diagonal, base end target on the faster velocity.
+ endTarget = NEW_TASK;
} else if (isSwipeUp) {
- endTarget = (!reachedOverviewThreshold && willGoToNewTask) ? NEW_TASK : RECENTS;
+ endTarget = !reachedOverviewThreshold && willGoToNewTaskOnSwipeUp
+ ? NEW_TASK : RECENTS;
} else {
- endTarget = willGoToNewTask ? NEW_TASK : LAST_TASK; // Swipe is downward.
+ endTarget = goingToNewTask ? NEW_TASK : LAST_TASK;
}
}
@@ -1167,8 +1171,6 @@
duration = Math.max(duration, mRecentsView.getScroller().getDuration());
}
}
- } else if (endTarget == LAST_TASK && mRecentsView != null) {
- mRecentsView.snapToPage(mRecentsView.getCurrentPage(), Math.toIntExact(duration));
}
// Let RecentsView handle the scrolling to the task, which we launch in startNewTask()
diff --git a/quickstep/src/com/android/quickstep/TopTaskTracker.java b/quickstep/src/com/android/quickstep/TopTaskTracker.java
index 80bc329..39c5f2a 100644
--- a/quickstep/src/com/android/quickstep/TopTaskTracker.java
+++ b/quickstep/src/com/android/quickstep/TopTaskTracker.java
@@ -25,6 +25,7 @@
import android.app.ActivityManager.RunningTaskInfo;
import android.content.Context;
+import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
import com.android.launcher3.util.MainThreadInitializedObject;
@@ -183,30 +184,31 @@
*/
public static class CachedTaskInfo {
+ @Nullable
private final RunningTaskInfo mTopTask;
private final List<RunningTaskInfo> mAllCachedTasks;
CachedTaskInfo(List<RunningTaskInfo> allCachedTasks) {
mAllCachedTasks = allCachedTasks;
- mTopTask = allCachedTasks.get(0);
+ mTopTask = allCachedTasks.isEmpty() ? null : allCachedTasks.get(0);
}
public int getTaskId() {
- return mTopTask.taskId;
+ return mTopTask == null ? -1 : mTopTask.taskId;
}
/**
* Returns true if the root of the task chooser activity
*/
public boolean isRootChooseActivity() {
- return ACTION_CHOOSER.equals(mTopTask.baseIntent.getAction());
+ return mTopTask != null && ACTION_CHOOSER.equals(mTopTask.baseIntent.getAction());
}
/**
* Returns true if the given task holds an Assistant activity that is excluded from recents
*/
public boolean isExcludedAssistant() {
- return mTopTask.configuration.windowConfiguration
+ return mTopTask != null && mTopTask.configuration.windowConfiguration
.getActivityType() == ACTIVITY_TYPE_ASSISTANT
&& (mTopTask.baseIntent.getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) != 0;
}
@@ -215,7 +217,7 @@
* Returns true if this represents the HOME task
*/
public boolean isHomeTask() {
- return mTopTask.configuration.windowConfiguration
+ return mTopTask != null && mTopTask.configuration.windowConfiguration
.getActivityType() == ACTIVITY_TYPE_HOME;
}
@@ -224,7 +226,8 @@
* is loaded by the model
*/
public Task[] getPlaceholderTasks() {
- return new Task[] {Task.from(new TaskKey(mTopTask), mTopTask, false)};
+ return mTopTask == null ? new Task[0]
+ : new Task[] {Task.from(new TaskKey(mTopTask), mTopTask, false)};
}
/**
@@ -232,6 +235,9 @@
* placeholder until the true object is loaded by the model
*/
public Task[] getPlaceholderTasks(int[] taskIds) {
+ if (mTopTask == null) {
+ return new Task[0];
+ }
Task[] result = new Task[taskIds.length];
for (int i = 0; i < taskIds.length; i++) {
final int index = i;
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
index 3e68c7f..ab3201a 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -56,6 +56,7 @@
public class FallbackRecentsView extends RecentsView<RecentsActivity, RecentsState>
implements StateListener<RecentsState> {
+ @Nullable
private Task mHomeTask;
public FallbackRecentsView(Context context, AttributeSet attrs) {
@@ -89,7 +90,7 @@
RotationTouchHelper rotationTouchHelper) {
// TODO(b/195607777) General fallback love, but this might be correct
// Home task should be defined as the front-most task info I think?
- mHomeTask = homeTask[0];
+ mHomeTask = homeTask.length > 0 ? homeTask[0] : null;
onGestureAnimationStart(homeTask, rotationTouchHelper);
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index b634518..2360396 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -2257,6 +2257,9 @@
* is called. Also scrolls the view to this task.
*/
private void showCurrentTask(Task[] runningTasks) {
+ if (runningTasks.length == 0) {
+ return;
+ }
int runningTaskViewId = -1;
boolean needGroupTaskView = runningTasks.length > 1;
if (shouldAddStubTaskView(runningTasks)) {
diff --git a/src/com/android/launcher3/DeleteDropTarget.java b/src/com/android/launcher3/DeleteDropTarget.java
index 477964a..371bb80 100644
--- a/src/com/android/launcher3/DeleteDropTarget.java
+++ b/src/com/android/launcher3/DeleteDropTarget.java
@@ -160,7 +160,7 @@
// Remove the item from launcher and the db, we can ignore the containerInfo in this call
// because we already remove the drag view from the folder (if the drag originated from
// a folder) in Folder.beginDrag()
- mLauncher.removeItem(view, item, true /* deleteFromDb */);
+ mLauncher.removeItem(view, item, true /* deleteFromDb */, "removed by accessibility drop");
mLauncher.getWorkspace().stripEmptyScreens();
mLauncher.getDragLayer()
.announceForAccessibility(getContext().getString(R.string.item_removed));
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 135b88d..31c1eff 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -1956,6 +1956,19 @@
* @param deleteFromDb whether or not to delete this item from the db.
*/
public boolean removeItem(View v, final ItemInfo itemInfo, boolean deleteFromDb) {
+ return removeItem(v, itemInfo, deleteFromDb, null);
+ }
+
+ /**
+ * Unbinds the view for the specified item, and removes the item and all its children.
+ *
+ * @param v the view being removed.
+ * @param itemInfo the {@link ItemInfo} for this view.
+ * @param deleteFromDb whether or not to delete this item from the db.
+ * @param reason the resaon for removal.
+ */
+ public boolean removeItem(View v, final ItemInfo itemInfo, boolean deleteFromDb,
+ @Nullable final String reason) {
if (itemInfo instanceof WorkspaceItemInfo) {
// Remove the shortcut from the folder before removing it from launcher
View folderIcon = mWorkspace.getHomescreenIconByItemId(itemInfo.container);
@@ -1965,7 +1978,7 @@
mWorkspace.removeWorkspaceItem(v);
}
if (deleteFromDb) {
- getModelWriter().deleteItemFromDatabase(itemInfo);
+ getModelWriter().deleteItemFromDatabase(itemInfo, reason);
}
} else if (itemInfo instanceof FolderInfo) {
final FolderInfo folderInfo = (FolderInfo) itemInfo;
@@ -1980,7 +1993,7 @@
final LauncherAppWidgetInfo widgetInfo = (LauncherAppWidgetInfo) itemInfo;
mWorkspace.removeWorkspaceItem(v);
if (deleteFromDb) {
- getModelWriter().deleteWidgetInfo(widgetInfo, getAppWidgetHost());
+ getModelWriter().deleteWidgetInfo(widgetInfo, getAppWidgetHost(), reason);
}
} else {
return false;
@@ -2032,13 +2045,16 @@
// Note: There should be at most one log per method call. This is enforced implicitly
// by using if-else statements.
AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(this);
- if (topView != null && topView.onBackPressed()) {
- // Handled by the floating view.
- } else {
- mStateManager.getState().onBackPressed(this);
+ if (topView == null || !topView.onBackPressed()) {
+ // Not handled by the floating view.
+ onStateBack();
}
}
+ protected void onStateBack() {
+ mStateManager.getState().onBackPressed(this);
+ }
+
protected void onScreenOff() {
// Reset AllApps to its initial state only if we are not in the middle of
// processing a multi-step drop
@@ -2399,8 +2415,7 @@
if (FeatureFlags.IS_STUDIO_BUILD) {
throw (new RuntimeException(desc));
} else {
- Log.d(TAG, desc);
- getModelWriter().deleteItemFromDatabase(item);
+ getModelWriter().deleteItemFromDatabase(item, desc);
if (TestProtocol.sDebugTracing) {
Log.d(TestProtocol.MISSING_PROMISE_ICON,
TAG + "bindItems failed for item=" + item);
@@ -2480,7 +2495,8 @@
if (item.hasOptionFlag(LauncherAppWidgetInfo.OPTION_SEARCH_WIDGET)) {
item.providerName = QsbContainerView.getSearchComponentName(this);
if (item.providerName == null) {
- getModelWriter().deleteItemFromDatabase(item);
+ getModelWriter().deleteItemFromDatabase(item,
+ "search widget removed because search component cannot be found");
return null;
}
}
@@ -2531,10 +2547,10 @@
if (!item.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY)
&& (item.restoreStatus != LauncherAppWidgetInfo.RESTORE_COMPLETED)) {
if (appWidgetInfo == null) {
- FileLog.d(TAG, "Removing restored widget: id=" + item.appWidgetId
+ getModelWriter().deleteItemFromDatabase(item,
+ "Removing restored widget: id=" + item.appWidgetId
+ " belongs to component " + item.providerName + " user " + item.user
+ ", as the provider is null and " + removalReason);
- getModelWriter().deleteItemFromDatabase(item);
return null;
}
@@ -2604,7 +2620,7 @@
// Verify that we own the widget
if (appWidgetInfo == null) {
FileLog.e(TAG, "Removing invalid widget: id=" + item.appWidgetId);
- getModelWriter().deleteWidgetInfo(item, getAppWidgetHost());
+ getModelWriter().deleteWidgetInfo(item, getAppWidgetHost(), removalReason);
return null;
}
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index 5c5c101..de0d300 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -477,7 +477,9 @@
}
if (!removedIds.isEmpty()) {
- deleteAndBindComponentsRemoved(ItemInfoMatcher.ofItemIds(removedIds));
+ deleteAndBindComponentsRemoved(
+ ItemInfoMatcher.ofItemIds(removedIds),
+ "removed because install session failed");
}
}
});
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 6c091f0..93f3d9f 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -3068,7 +3068,8 @@
if (info instanceof LauncherAppWidgetInfo) {
LauncherAppWidgetInfo appWidgetInfo = (LauncherAppWidgetInfo) info;
if (appWidgetInfo.appWidgetId == appWidgetId) {
- mLauncher.removeItem(view, appWidgetInfo, true);
+ mLauncher.removeItem(view, appWidgetInfo, true,
+ "widget is removed in response to widget remove broadcast");
return true;
}
}
@@ -3318,8 +3319,9 @@
*
* @param matcher the matcher generated by the caller.
*/
- public void persistRemoveItemsByMatcher(Predicate<ItemInfo> matcher) {
- mLauncher.getModelWriter().deleteItemsFromDatabase(matcher);
+ public void persistRemoveItemsByMatcher(Predicate<ItemInfo> matcher,
+ @Nullable final String reason) {
+ mLauncher.getModelWriter().deleteItemsFromDatabase(matcher, reason);
removeItemsByMatcher(matcher);
}
diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
index 096e2c8..88e7fc0 100644
--- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
@@ -15,9 +15,7 @@
*/
package com.android.launcher3.allapps;
-import static android.view.View.MeasureSpec.EXACTLY;
import static android.view.View.MeasureSpec.UNSPECIFIED;
-import static android.view.View.MeasureSpec.makeMeasureSpec;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_SCROLLED;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_VERTICAL_SWIPE_BEGIN;
@@ -47,7 +45,6 @@
import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.views.RecyclerViewFastScroller;
-import java.util.ArrayList;
import java.util.List;
/**
@@ -97,8 +94,6 @@
private AllAppsBackgroundDrawable mEmptySearchBackground;
private int mEmptySearchBackgroundTopOffset;
- private ArrayList<View> mAutoSizedOverlays = new ArrayList<>();
-
public AllAppsRecyclerView(Context context) {
this(context, null);
}
@@ -172,30 +167,6 @@
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
updateEmptySearchBackgroundBounds();
updatePoolSize();
- for (int i = 0; i < mAutoSizedOverlays.size(); i++) {
- View overlay = mAutoSizedOverlays.get(i);
- overlay.measure(makeMeasureSpec(w, EXACTLY), makeMeasureSpec(w, EXACTLY));
- overlay.layout(0, 0, w, h);
- }
- }
-
- /**
- * Adds an overlay that automatically rescales with the recyclerview.
- */
- public void addAutoSizedOverlay(View overlay) {
- mAutoSizedOverlays.add(overlay);
- getOverlay().add(overlay);
- onSizeChanged(getWidth(), getHeight(), getWidth(), getHeight());
- }
-
- /**
- * Clears auto scaling overlay views added by #addAutoSizedOverlay
- */
- public void clearAutoSizedOverlays() {
- for (View v : mAutoSizedOverlays) {
- getOverlay().remove(v);
- }
- mAutoSizedOverlays.clear();
}
public void onSearchResultsChanged() {
diff --git a/src/com/android/launcher3/anim/Interpolators.java b/src/com/android/launcher3/anim/Interpolators.java
index c38cf9a..0a77aa7 100644
--- a/src/com/android/launcher3/anim/Interpolators.java
+++ b/src/com/android/launcher3/anim/Interpolators.java
@@ -208,4 +208,14 @@
float upperBound) {
return t -> Utilities.mapRange(interpolator.getInterpolation(t), lowerBound, upperBound);
}
+
+ /**
+ * Returns the reverse of the provided interpolator, following the formula: g(x) = 1 - f(1 - x).
+ * In practice, this means that if f is an interpolator used to model a value animating between
+ * m and n, g is the interpolator to use to obtain the specular behavior when animating from n
+ * to m.
+ */
+ public static Interpolator reverse(Interpolator interpolator) {
+ return t -> 1 - interpolator.getInterpolation(1 - t);
+ }
}
diff --git a/src/com/android/launcher3/folder/LauncherDelegate.java b/src/com/android/launcher3/folder/LauncherDelegate.java
index c5b3913..1f0a011 100644
--- a/src/com/android/launcher3/folder/LauncherDelegate.java
+++ b/src/com/android/launcher3/folder/LauncherDelegate.java
@@ -100,7 +100,8 @@
}
// Remove the folder
- mLauncher.removeItem(folder.mFolderIcon, info, true /* deleteFromDb */);
+ mLauncher.removeItem(folder.mFolderIcon, info, true /* deleteFromDb */,
+ "folder removed because there's only 1 item in it");
if (folder.mFolderIcon instanceof DropTarget) {
folder.mDragController.removeDropTarget((DropTarget) folder.mFolderIcon);
}
diff --git a/src/com/android/launcher3/model/BaseModelUpdateTask.java b/src/com/android/launcher3/model/BaseModelUpdateTask.java
index 832c1dd..2a6a691 100644
--- a/src/com/android/launcher3/model/BaseModelUpdateTask.java
+++ b/src/com/android/launcher3/model/BaseModelUpdateTask.java
@@ -17,6 +17,8 @@
import android.util.Log;
+import androidx.annotation.Nullable;
+
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherModel;
import com.android.launcher3.LauncherModel.CallbackTask;
@@ -128,8 +130,9 @@
scheduleCallbackTask(c -> c.bindAllWidgets(widgets));
}
- public void deleteAndBindComponentsRemoved(final Predicate<ItemInfo> matcher) {
- getModelWriter().deleteItemsFromDatabase(matcher);
+ public void deleteAndBindComponentsRemoved(final Predicate<ItemInfo> matcher,
+ @Nullable final String reason) {
+ getModelWriter().deleteItemsFromDatabase(matcher, reason);
// Call the components-removed callback
scheduleCallbackTask(c -> c.bindWorkspaceComponentsRemoved(matcher));
diff --git a/src/com/android/launcher3/model/ModelWriter.java b/src/com/android/launcher3/model/ModelWriter.java
index 015abe9..0a68d4a 100644
--- a/src/com/android/launcher3/model/ModelWriter.java
+++ b/src/com/android/launcher3/model/ModelWriter.java
@@ -23,8 +23,10 @@
import android.content.ContentValues;
import android.content.Context;
import android.net.Uri;
+import android.text.TextUtils;
import android.util.Log;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.launcher3.LauncherAppState;
@@ -272,27 +274,30 @@
/**
* Removes the specified item from the database
*/
- public void deleteItemFromDatabase(ItemInfo item) {
- deleteItemsFromDatabase(Arrays.asList(item));
+ public void deleteItemFromDatabase(ItemInfo item, @Nullable final String reason) {
+ deleteItemsFromDatabase(Arrays.asList(item), reason);
}
/**
* Removes all the items from the database matching {@param matcher}.
*/
- public void deleteItemsFromDatabase(Predicate<ItemInfo> matcher) {
+ public void deleteItemsFromDatabase(@NonNull final Predicate<ItemInfo> matcher,
+ @Nullable final String reason) {
deleteItemsFromDatabase(StreamSupport.stream(mBgDataModel.itemsIdMap.spliterator(), false)
- .filter(matcher).collect(Collectors.toList()));
+ .filter(matcher).collect(Collectors.toList()), reason);
}
/**
* Removes the specified items from the database
*/
- public void deleteItemsFromDatabase(final Collection<? extends ItemInfo> items) {
+ public void deleteItemsFromDatabase(final Collection<? extends ItemInfo> items,
+ @Nullable final String reason) {
ModelVerifier verifier = new ModelVerifier();
FileLog.d(TAG, "removing items from db " + items.stream().map(
(item) -> item.getTargetComponent() == null ? ""
: item.getTargetComponent().getPackageName()).collect(
- Collectors.joining(",")));
+ Collectors.joining(","))
+ + ". Reason: [" + (TextUtils.isEmpty(reason) ? "unknown" : reason) + "]");
notifyDelete(items);
enqueueDeleteRunnable(() -> {
for (ItemInfo item : items) {
@@ -328,14 +333,15 @@
/**
* Deletes the widget info and the widget id.
*/
- public void deleteWidgetInfo(final LauncherAppWidgetInfo info, LauncherAppWidgetHost host) {
+ public void deleteWidgetInfo(final LauncherAppWidgetInfo info, LauncherAppWidgetHost host,
+ @Nullable final String reason) {
notifyDelete(Collections.singleton(info));
if (host != null && !info.isCustomWidget() && info.isWidgetIdAllocated()) {
// Deleting an app widget ID is a void call but writes to disk before returning
// to the caller...
enqueueDeleteRunnable(() -> host.deleteAppWidgetId(info.appWidgetId));
}
- deleteItemFromDatabase(info);
+ deleteItemFromDatabase(info, reason);
}
private void notifyDelete(Collection<? extends ItemInfo> items) {
diff --git a/src/com/android/launcher3/model/PackageUpdatedTask.java b/src/com/android/launcher3/model/PackageUpdatedTask.java
index 239dd45..489bc38 100644
--- a/src/com/android/launcher3/model/PackageUpdatedTask.java
+++ b/src/com/android/launcher3/model/PackageUpdatedTask.java
@@ -311,7 +311,9 @@
bindUpdatedWorkspaceItems(updatedWorkspaceItems);
if (!removedShortcuts.isEmpty()) {
- deleteAndBindComponentsRemoved(ItemInfoMatcher.ofItemIds(removedShortcuts));
+ deleteAndBindComponentsRemoved(
+ ItemInfoMatcher.ofItemIds(removedShortcuts),
+ "removed because the target component is invalid");
}
if (!widgets.isEmpty()) {
@@ -340,7 +342,8 @@
Predicate<ItemInfo> removeMatch = ItemInfoMatcher.ofPackages(removedPackages, mUser)
.or(ItemInfoMatcher.ofComponents(removedComponents, mUser))
.and(ItemInfoMatcher.ofItemIds(forceKeepShortcuts).negate());
- deleteAndBindComponentsRemoved(removeMatch);
+ deleteAndBindComponentsRemoved(removeMatch,
+ "removed because the corresponding package or component is removed");
// Remove any queued items from the install queue
ItemInstallQueue.INSTANCE.get(context)
diff --git a/src/com/android/launcher3/model/ShortcutsChangedTask.java b/src/com/android/launcher3/model/ShortcutsChangedTask.java
index 4296d32..1026e0b 100644
--- a/src/com/android/launcher3/model/ShortcutsChangedTask.java
+++ b/src/com/android/launcher3/model/ShortcutsChangedTask.java
@@ -108,7 +108,8 @@
deleteAndBindComponentsRemoved(ItemInfoMatcher.ofShortcutKeys(
nonPinnedIds.stream()
.map(id -> new ShortcutKey(mPackageName, mUser, id))
- .collect(Collectors.toSet())));
+ .collect(Collectors.toSet())),
+ "removed because the shortcut is no longer available in shortcut service");
}
}
diff --git a/src/com/android/launcher3/model/UserLockStateChangedTask.java b/src/com/android/launcher3/model/UserLockStateChangedTask.java
index 5048e13..1565b19 100644
--- a/src/com/android/launcher3/model/UserLockStateChangedTask.java
+++ b/src/com/android/launcher3/model/UserLockStateChangedTask.java
@@ -96,7 +96,9 @@
}
bindUpdatedWorkspaceItems(updatedWorkspaceItemInfos);
if (!removedKeys.isEmpty()) {
- deleteAndBindComponentsRemoved(ItemInfoMatcher.ofShortcutKeys(removedKeys));
+ deleteAndBindComponentsRemoved(ItemInfoMatcher.ofShortcutKeys(removedKeys),
+ "removed during unlock because it's no longer available"
+ + " (possibly due to clear data)");
}
// Remove shortcut id map for that user
diff --git a/src/com/android/launcher3/touch/AllAppsSwipeController.java b/src/com/android/launcher3/touch/AllAppsSwipeController.java
index 9d7fd9a..787d9ea 100644
--- a/src/com/android/launcher3/touch/AllAppsSwipeController.java
+++ b/src/com/android/launcher3/touch/AllAppsSwipeController.java
@@ -26,9 +26,11 @@
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_DEPTH;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_FADE;
+import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_SCALE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_TRANSLATE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_SCRIM_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PROGRESS;
+import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_SCALE;
import android.view.MotionEvent;
@@ -51,6 +53,7 @@
private static final float WORKSPACE_MOTION_START = 0.1667f;
private static final float ALL_APPS_STATE_TRANSITION = 0.305f;
private static final float ALL_APPS_FADE_END = 0.4717f;
+ private static final float ALL_APPS_FULL_DEPTH_PROGRESS = 0.5f;
public static final Interpolator ALLAPPS_STAGGERED_FADE_EARLY_RESPONDER =
Interpolators.clampToProgress(LINEAR, 0, ALLAPPS_STAGGERED_FADE_THRESHOLD);
@@ -58,14 +61,19 @@
Interpolators.clampToProgress(LINEAR, ALLAPPS_STAGGERED_FADE_THRESHOLD, 1f);
// Custom interpolators for NORMAL -> ALL_APPS on phones only.
+ // The blur to All Apps is set to be complete when the interpolator is at 0.5.
public static final Interpolator BLUR =
Interpolators.clampToProgress(
- EMPHASIZED_DECELERATE, WORKSPACE_MOTION_START, ALL_APPS_STATE_TRANSITION);
+ Interpolators.mapToProgress(
+ EMPHASIZED_DECELERATE, 0f, ALL_APPS_FULL_DEPTH_PROGRESS),
+ WORKSPACE_MOTION_START, ALL_APPS_STATE_TRANSITION);
+ public static final Interpolator WORKSPACE_FADE =
+ Interpolators.clampToProgress(FINAL_FRAME, 0f, ALL_APPS_STATE_TRANSITION);
public static final Interpolator WORKSPACE_SCALE =
Interpolators.clampToProgress(
EMPHASIZED_DECELERATE, WORKSPACE_MOTION_START, ALL_APPS_STATE_TRANSITION);
- public static final Interpolator HOTSEAT_FADE =
- Interpolators.clampToProgress(FINAL_FRAME, 0f, ALL_APPS_STATE_TRANSITION);
+ public static final Interpolator HOTSEAT_FADE = WORKSPACE_FADE;
+ public static final Interpolator HOTSEAT_SCALE = HOTSEAT_FADE;
public static final Interpolator HOTSEAT_TRANSLATE =
Interpolators.clampToProgress(
EMPHASIZED_ACCELERATE, WORKSPACE_MOTION_START, ALL_APPS_STATE_TRANSITION);
@@ -161,8 +169,10 @@
config.setInterpolator(ANIM_ALL_APPS_FADE, INSTANT);
} else {
config.setInterpolator(ANIM_DEPTH, BLUR);
+ config.setInterpolator(ANIM_WORKSPACE_FADE, WORKSPACE_FADE);
config.setInterpolator(ANIM_WORKSPACE_SCALE, WORKSPACE_SCALE);
config.setInterpolator(ANIM_HOTSEAT_FADE, HOTSEAT_FADE);
+ config.setInterpolator(ANIM_HOTSEAT_SCALE, HOTSEAT_SCALE);
config.setInterpolator(ANIM_HOTSEAT_TRANSLATE, HOTSEAT_TRANSLATE);
config.setInterpolator(ANIM_SCRIM_FADE, SCRIM_FADE);
config.setInterpolator(ANIM_ALL_APPS_FADE, ALL_APPS_FADE);
diff --git a/src/com/android/launcher3/touch/ItemClickHandler.java b/src/com/android/launcher3/touch/ItemClickHandler.java
index c4d2bc4..e95a787 100644
--- a/src/com/android/launcher3/touch/ItemClickHandler.java
+++ b/src/com/android/launcher3/touch/ItemClickHandler.java
@@ -176,7 +176,8 @@
.setNeutralButton(R.string.abandoned_clean_this,
(d, i) -> launcher.getWorkspace()
.persistRemoveItemsByMatcher(ItemInfoMatcher.ofPackages(
- Collections.singleton(packageName), user)))
+ Collections.singleton(packageName), user),
+ "user explicitly removes the promise app icon"))
.create().show();
}
@@ -259,7 +260,8 @@
// Remove the icon if launcher is successfully initialized
launcher.getWorkspace().persistRemoveItemsByMatcher(ItemInfoMatcher
.ofShortcutKeys(Collections.singleton(ShortcutKey
- .fromItemInfo(shortcut))));
+ .fromItemInfo(shortcut))),
+ "user explicitly removes disabled shortcut");
})
.create()
.show();
diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java
index 4c001fd..f553fb4 100644
--- a/src/com/android/launcher3/views/BaseDragLayer.java
+++ b/src/com/android/launcher3/views/BaseDragLayer.java
@@ -40,6 +40,7 @@
import android.widget.FrameLayout;
import com.android.launcher3.AbstractFloatingView;
+import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InsettableFrameLayout;
import com.android.launcher3.Utilities;
import com.android.launcher3.util.MultiValueAlpha;
@@ -553,8 +554,14 @@
public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) {
if (Utilities.ATLEAST_Q) {
Insets gestureInsets = insets.getMandatorySystemGestureInsets();
+ int gestureInsetBottom = gestureInsets.bottom;
+ DeviceProfile dp = mActivity.getDeviceProfile();
+ if (dp.isTaskbarPresent) {
+ // Ignore taskbar gesture insets to avoid interfering with TouchControllers.
+ gestureInsetBottom = Math.max(0, gestureInsetBottom - dp.taskbarSize);
+ }
mSystemGestureRegion.set(gestureInsets.left, gestureInsets.top,
- gestureInsets.right, gestureInsets.bottom);
+ gestureInsets.right, gestureInsetBottom);
}
return super.dispatchApplyWindowInsets(insets);
}
diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
index 53c772f..0865152 100644
--- a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
+++ b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
@@ -457,7 +457,8 @@
}
// Remove and rebind the current widget (which was inflated in the wrong
// orientation), but don't delete it from the database
- mLauncher.removeItem(this, info, false /* deleteFromDb */);
+ mLauncher.removeItem(this, info, false /* deleteFromDb */,
+ "widget removed because of configuration change");
mLauncher.bindAppWidget(info);
}
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/states/AllAppsState.java b/src_ui_overrides/com/android/launcher3/uioverrides/states/AllAppsState.java
index ec921e8..bf35dd8 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/states/AllAppsState.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/states/AllAppsState.java
@@ -32,6 +32,7 @@
public class AllAppsState extends LauncherState {
private static final float PARALLAX_COEFFICIENT = .125f;
+ private static final float WORKSPACE_SCALE_FACTOR = 0.97f;
private static final int STATE_FLAGS = FLAG_WORKSPACE_INACCESSIBLE;
@@ -59,7 +60,7 @@
@Override
public ScaleAndTranslation getWorkspaceScaleAndTranslation(Launcher launcher) {
- return new ScaleAndTranslation(0.97f, NO_OFFSET, NO_OFFSET);
+ return new ScaleAndTranslation(WORKSPACE_SCALE_FACTOR, NO_OFFSET, NO_OFFSET);
}
@Override
@@ -70,7 +71,7 @@
ScaleAndTranslation overviewScaleAndTranslation = LauncherState.OVERVIEW
.getWorkspaceScaleAndTranslation(launcher);
return new ScaleAndTranslation(
- NO_SCALE,
+ WORKSPACE_SCALE_FACTOR,
overviewScaleAndTranslation.translationX,
overviewScaleAndTranslation.translationY);
}
diff --git a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
index a3b05f6..8a97c6b 100644
--- a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
+++ b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
@@ -48,7 +48,6 @@
import com.android.launcher3.tapl.Widgets;
import com.android.launcher3.tapl.Workspace;
import com.android.launcher3.util.TestUtil;
-import com.android.launcher3.util.rule.ScreenRecordRule;
import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
import com.android.launcher3.widget.picker.WidgetsFullSheet;
import com.android.launcher3.widget.picker.WidgetsRecyclerView;
@@ -70,9 +69,6 @@
private static final String STORE_APP_NAME = "Play Store";
private static final String GMAIL_APP_NAME = "Gmail";
- @Rule
- public ScreenRecordRule mScreenRecordRule = new ScreenRecordRule();
-
@Before
public void setUp() throws Exception {
super.setUp();
@@ -380,7 +376,6 @@
@Test
@PortraitLandscape
- @ScreenRecord
public void testDragToFolder() {
// TODO: add the use case to drag an icon to an existing folder. Currently it either fails
// on tablets or phones due to difference in resolution.
@@ -397,6 +392,15 @@
workspace.tryGetWorkspaceAppIcon(STORE_APP_NAME));
assertNull(GMAIL_APP_NAME + " should be moved to a folder.",
workspace.tryGetWorkspaceAppIcon(GMAIL_APP_NAME));
+
+ final HomeAppIcon mapIcon = createShortcutInCenterIfNotExist(MAPS_APP_NAME);
+ folderIcon = mapIcon.dragToIcon(folderIcon);
+ folder = folderIcon.open();
+ folder.getAppIcon(MAPS_APP_NAME);
+ workspace = folder.close();
+
+ assertNull(MAPS_APP_NAME + " should be moved to a folder.",
+ workspace.tryGetWorkspaceAppIcon(MAPS_APP_NAME));
}
@Test
diff --git a/tests/tapl/com/android/launcher3/tapl/Workspace.java b/tests/tapl/com/android/launcher3/tapl/Workspace.java
index 954af3d..eb7f05b 100644
--- a/tests/tapl/com/android/launcher3/tapl/Workspace.java
+++ b/tests/tapl/com/android/launcher3/tapl/Workspace.java
@@ -394,6 +394,7 @@
launcher,
launchable,
destSupplier,
+ /* isDecelerating= */ false,
() -> launcher.expectEvent(TestProtocol.SEQUENCE_MAIN, LONG_CLICK_EVENT),
/* expectDropEvents= */ null);
}
@@ -404,6 +405,17 @@
Supplier<Point> dest,
Runnable expectLongClickEvents,
@Nullable Runnable expectDropEvents) {
+ dragIconToWorkspace(launcher, launchable, dest, /* isDecelerating */ true,
+ expectLongClickEvents, expectDropEvents);
+ }
+
+ static void dragIconToWorkspace(
+ LauncherInstrumentation launcher,
+ Launchable launchable,
+ Supplier<Point> dest,
+ boolean isDecelerating,
+ Runnable expectLongClickEvents,
+ @Nullable Runnable expectDropEvents) {
try (LauncherInstrumentation.Closable ignored = launcher.addContextLayer(
"want to drag icon to workspace")) {
final long downTime = SystemClock.uptimeMillis();
@@ -430,7 +442,7 @@
// targetDest.x is now between 0 and displayX so we found the target page,
// we just have to put move the icon to the destination and drop it
- launcher.movePointer(dragStart, targetDest, DEFAULT_DRAG_STEPS, true,
+ launcher.movePointer(dragStart, targetDest, DEFAULT_DRAG_STEPS, isDecelerating,
downTime, SystemClock.uptimeMillis(), false,
LauncherInstrumentation.GestureScope.INSIDE);
dropDraggedIcon(launcher, targetDest, downTime, expectDropEvents);