Merge "Perform haptic feedback on nav button key press" into tm-qpr-dev
diff --git a/OWNERS b/OWNERS
index 7f98ea6..560b562 100644
--- a/OWNERS
+++ b/OWNERS
@@ -7,13 +7,6 @@
alexchau@google.com
andraskloczl@google.com
patmanning@google.com
-petrcermak@google.com
-pbdr@google.com
-kideckel@google.com
-stevenckng@google.com
-ydixit@google.com
-boadway@google.com
-alinazaidi@google.com
adamcohen@google.com
hyunyoungs@google.com
mrcasey@google.com
@@ -24,10 +17,8 @@
zakcohen@google.com
santie@google.com
vadimt@google.com
-mett@google.com
jonmiranda@google.com
pinyaoting@google.com
-sfufa@google.com
gwasserman@google.com
jamesoleary@google.com
joshtrask@google.com
@@ -37,8 +28,6 @@
tracyzhou@google.com
peanutbutter@google.com
xuqiu@google.com
-sreyasr@google.com
-thiruram@google.com
brianji@google.com
per-file FeatureFlags.java, globs = set noparent
diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
index eccdae1..13943a7 100644
--- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
@@ -191,7 +191,7 @@
isThreeButtonNav ? mStartContextualContainer : mEndContextualContainer,
mControllers.navButtonController, R.id.ime_switcher);
mPropertyHolders.add(new StatePropertyHolder(imeSwitcherButton,
- flags -> ((flags & MASK_IME_SWITCHER_VISIBLE) == MASK_IME_SWITCHER_VISIBLE)
+ flags -> ((flags & MASK_IME_SWITCHER_VISIBLE) != 0)
&& ((flags & FLAG_ROTATION_BUTTON_VISIBLE) == 0)));
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
index c522888..04fcc44 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
@@ -16,6 +16,7 @@
package com.android.launcher3.taskbar;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_ALL_APPS;
+import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_PREDICTION;
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT;
import android.animation.Animator;
@@ -435,7 +436,7 @@
if (tag instanceof ItemInfo) {
ItemInfo item = (ItemInfo) tag;
TaskbarViewController taskbarViewController = mControllers.taskbarViewController;
- if (item.container == CONTAINER_ALL_APPS) {
+ if (item.container == CONTAINER_ALL_APPS || item.container == CONTAINER_PREDICTION) {
// Since all apps closes when the drag starts, target the all apps button instead.
target = taskbarViewController.getAllAppsButtonView();
} else if (item.container >= 0) {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
index 2d7fe69..4d2f965 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
@@ -42,17 +42,10 @@
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_Y;
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 static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_TRANSLATE;
-import static com.android.launcher3.uioverrides.touchcontrollers.PortraitStatesTouchController.ALL_APPS_CONTENT_FADE_MAX_CLAMPING_THRESHOLD;
-import static com.android.launcher3.uioverrides.touchcontrollers.PortraitStatesTouchController.ALL_APPS_CONTENT_FADE_MIN_CLAMPING_THRESHOLD;
-import static com.android.launcher3.uioverrides.touchcontrollers.PortraitStatesTouchController.ALL_APPS_SCRIM_OPAQUE_THRESHOLD;
-import static com.android.launcher3.uioverrides.touchcontrollers.PortraitStatesTouchController.ALL_APPS_SCRIM_VISIBLE_THRESHOLD;
import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
-import static com.android.systemui.animation.Interpolators.EMPHASIZED_ACCELERATE;
-import static com.android.systemui.animation.Interpolators.EMPHASIZED_DECELERATE;
import android.animation.ValueAnimator;
@@ -60,8 +53,8 @@
import com.android.launcher3.Hotseat;
import com.android.launcher3.LauncherState;
import com.android.launcher3.Workspace;
-import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.states.StateAnimationConfig;
+import com.android.launcher3.touch.AllAppsSwipeController;
import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.DisplayController;
import com.android.quickstep.util.RecentsAtomicAnimationFactory;
@@ -182,23 +175,9 @@
}
config.duration = Math.max(config.duration, mHintToNormalDuration);
} else if (fromState == ALL_APPS && toState == NORMAL) {
- boolean isTablet = mActivity.getDeviceProfile().isTablet;
- config.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));
- config.setInterpolator(ANIM_SCRIM_FADE, Interpolators.clampToProgress(LINEAR,
- 1 - ALL_APPS_SCRIM_OPAQUE_THRESHOLD,
- 1 - ALL_APPS_SCRIM_VISIBLE_THRESHOLD));
- config.setInterpolator(ANIM_VERTICAL_PROGRESS, EMPHASIZED_ACCELERATE);
- if (!isTablet) {
- config.setInterpolator(ANIM_WORKSPACE_FADE, INSTANT);
- }
+ AllAppsSwipeController.applyAllAppsToNormalConfig(mActivity, config);
} else if (fromState == NORMAL && toState == ALL_APPS) {
- if (mActivity.getDeviceProfile().isTablet) {
- config.setInterpolator(ANIM_VERTICAL_PROGRESS, EMPHASIZED_DECELERATE);
- }
- // TODO(b/231682175): centralize this setup in AllAppsSwipeController
+ AllAppsSwipeController.applyNormalToAllAppsAnimConfig(mActivity, config);
}
}
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
index e56c90c..9efbc34 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
@@ -21,21 +21,8 @@
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
-import static com.android.launcher3.anim.Interpolators.FINAL_FRAME;
-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;
@@ -44,6 +31,7 @@
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.touch.AbstractStateChangeTouchController;
+import com.android.launcher3.touch.AllAppsSwipeController;
import com.android.launcher3.touch.SingleAxisSwipeDetector;
import com.android.launcher3.uioverrides.states.OverviewState;
import com.android.quickstep.SystemUiProxy;
@@ -58,53 +46,6 @@
private static final String TAG = "PortraitStatesTouchCtrl";
- /**
- * The progress at which all apps content will be fully visible.
- */
- public static final float ALL_APPS_CONTENT_FADE_MAX_CLAMPING_THRESHOLD = 0.8f;
-
- /**
- * Minimum clamping progress for fading in all apps content
- */
- public static final float ALL_APPS_CONTENT_FADE_MIN_CLAMPING_THRESHOLD = 0.5f;
-
- /**
- * Minimum clamping progress for fading in all apps scrim
- */
- public static final float ALL_APPS_SCRIM_VISIBLE_THRESHOLD = .1f;
-
- /**
- * Maximum clamping progress for opaque all apps scrim
- */
- 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) {
@@ -160,66 +101,15 @@
return fromState;
}
- private StateAnimationConfig getNormalToAllAppsAnimation() {
- StateAnimationConfig builder = new StateAnimationConfig();
- 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();
- 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;
- }
-
@Override
protected StateAnimationConfig getConfigForStates(
LauncherState fromState, LauncherState toState) {
- final StateAnimationConfig config;
+ final StateAnimationConfig config = new StateAnimationConfig();
+ config.userControlled = true;
if (fromState == NORMAL && toState == ALL_APPS) {
- config = getNormalToAllAppsAnimation();
+ AllAppsSwipeController.applyNormalToAllAppsAnimConfig(mLauncher, config);
} else if (fromState == ALL_APPS && toState == NORMAL) {
- config = getAllAppsToNormalAnimation();
- } else {
- config = new StateAnimationConfig();
+ AllAppsSwipeController.applyAllAppsToNormalConfig(mLauncher, config);
}
return config;
}
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index b3e2d91..0972e4e 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -166,11 +166,7 @@
if (mActivity != activity) {
return;
}
- if (mTaskAnimationManager != null) {
- mTaskAnimationManager.finishRunningRecentsAnimation(true);
- }
mRecentsView = null;
- mActivity.unregisterActivityLifecycleCallbacks(mLifecycleCallbacks);
mActivity = null;
}
};
@@ -865,6 +861,7 @@
TaskUtils.closeSystemWindowsAsync(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
if (mRecentsView != null) {
+ final View rv = mRecentsView;
mRecentsView.getViewTreeObserver().addOnDrawListener(new OnDrawListener() {
boolean mHandled = false;
@@ -880,8 +877,7 @@
InteractionJankMonitorWrapper.begin(mRecentsView,
InteractionJankMonitorWrapper.CUJ_APP_CLOSE_TO_HOME);
- mRecentsView.post(() ->
- mRecentsView.getViewTreeObserver().removeOnDrawListener(this));
+ rv.post(() -> rv.getViewTreeObserver().removeOnDrawListener(this));
}
});
}
@@ -1140,7 +1136,7 @@
mInputConsumerProxy.enable();
}
if (endTarget == HOME) {
- duration = mActivity.getDeviceProfile().isTaskbarPresent
+ duration = mActivity != null && mActivity.getDeviceProfile().isTaskbarPresent
? StaggeredWorkspaceAnim.DURATION_TASKBAR_MS
: StaggeredWorkspaceAnim.DURATION_MS;
// Early detach the nav bar once the endTarget is determined as HOME
@@ -1600,6 +1596,9 @@
private void reset() {
mStateCallback.setStateOnUiThread(STATE_HANDLER_INVALIDATED);
+ if (mActivity != null) {
+ mActivity.unregisterActivityLifecycleCallbacks(mLifecycleCallbacks);
+ }
}
/**
diff --git a/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java b/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java
index b83e26e..a3f7ae0 100644
--- a/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java
+++ b/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java
@@ -17,6 +17,7 @@
import android.content.Context;
import android.content.res.Resources;
+import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
@@ -31,6 +32,8 @@
*/
public class MotionPauseDetector {
+ private static final String TAG = "MotionPauseDetector";
+
// The percentage of the previous speed that determines whether this is a rapid deceleration.
// The bigger this number, the easier it is to trigger the first pause.
private static final float RAPID_DECELERATION_FACTOR = 0.6f;
@@ -85,7 +88,8 @@
mSpeedSomewhatFast = res.getDimension(R.dimen.motion_pause_detector_speed_somewhat_fast);
mSpeedFast = res.getDimension(R.dimen.motion_pause_detector_speed_fast);
mForcePauseTimeout = new Alarm();
- mForcePauseTimeout.setOnAlarmListener(alarm -> updatePaused(true /* isPaused */));
+ mForcePauseTimeout.setOnAlarmListener(alarm -> updatePaused(true /* isPaused */,
+ "Force pause timeout after " + alarm.getLastSetTimeout() + "ms" /* reason */));
mMakePauseHarderToTrigger = makePauseHarderToTrigger;
mVelocityProvider = new SystemVelocityProvider(axis);
}
@@ -102,7 +106,7 @@
*/
public void setDisallowPause(boolean disallowPause) {
mDisallowPause = disallowPause;
- updatePaused(mIsPaused);
+ updatePaused(mIsPaused, "Set disallowPause=" + disallowPause);
}
/**
@@ -134,21 +138,27 @@
float speed = Math.abs(velocity);
float previousSpeed = Math.abs(prevVelocity);
boolean isPaused;
+ String isPausedReason = "";
if (mIsPaused) {
// Continue to be paused until moving at a fast speed.
isPaused = speed < mSpeedFast || previousSpeed < mSpeedFast;
+ isPausedReason = "Was paused, but started moving at a fast speed";
} else {
if (velocity < 0 != prevVelocity < 0) {
// We're just changing directions, not necessarily stopping.
isPaused = false;
+ isPausedReason = "Velocity changed directions";
} else {
isPaused = speed < mSpeedVerySlow && previousSpeed < mSpeedVerySlow;
+ isPausedReason = "Pause requires back to back slow speeds";
if (!isPaused && !mHasEverBeenPaused) {
// We want to be more aggressive about detecting the first pause to ensure it
// feels as responsive as possible; getting two very slow speeds back to back
// takes too long, so also check for a rapid deceleration.
boolean isRapidDeceleration = speed < previousSpeed * RAPID_DECELERATION_FACTOR;
isPaused = isRapidDeceleration && speed < mSpeedSomewhatFast;
+ isPausedReason = "Didn't have back to back slow speeds, checking for rapid"
+ + " deceleration on first pause only";
}
if (mMakePauseHarderToTrigger) {
if (speed < mSpeedSlow) {
@@ -156,22 +166,27 @@
mSlowStartTime = time;
}
isPaused = time - mSlowStartTime >= HARDER_TRIGGER_TIMEOUT;
+ isPausedReason = "Maintained slow speed for sufficient duration when making"
+ + " pause harder to trigger";
} else {
mSlowStartTime = 0;
isPaused = false;
+ isPausedReason = "Intentionally making pause harder to trigger";
}
}
}
}
- updatePaused(isPaused);
+ updatePaused(isPaused, isPausedReason);
}
- private void updatePaused(boolean isPaused) {
+ private void updatePaused(boolean isPaused, String reason) {
if (mDisallowPause) {
+ reason = "Disallow pause; otherwise, would have been " + isPaused + " due to " + reason;
isPaused = false;
}
if (mIsPaused != isPaused) {
mIsPaused = isPaused;
+ Log.d(TAG, "onMotionPauseChanged, paused=" + mIsPaused + " reason=" + reason);
boolean isFirstDetectedPause = !mHasEverBeenPaused && mIsPaused;
if (mIsPaused) {
AccessibilityManagerCompat.sendPauseDetectedEventToTest(mContext);
diff --git a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
index 69cad69..1629bb7 100644
--- a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
@@ -52,6 +52,7 @@
import com.android.launcher3.Utilities;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.SystemUiController;
+import com.android.launcher3.util.SystemUiController.SystemUiControllerFlags;
import com.android.quickstep.TaskOverlayFactory.TaskOverlay;
import com.android.quickstep.views.TaskView.FullscreenDrawParams;
import com.android.systemui.shared.recents.model.Task;
@@ -247,6 +248,7 @@
}
+ @SystemUiControllerFlags
public int getSysUiStatusNavFlags() {
if (mThumbnailData != null) {
int flags = 0;
diff --git a/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java b/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java
index 6ec6269..401b967 100644
--- a/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java
+++ b/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java
@@ -16,8 +16,6 @@
package com.android.quickstep;
-import android.content.Intent;
-
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;
@@ -43,7 +41,7 @@
// b/143488140
mLauncher.goHome();
// Start an activity where the gestures start.
- startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR));
+ startTestActivity(2);
}
private void runTest(String... eventSequence) {
diff --git a/res/layout/widgets_list_row_header.xml b/res/layout/widgets_list_row_header.xml
index 3cdc2e8..35bea27 100644
--- a/res/layout/widgets_list_row_header.xml
+++ b/res/layout/widgets_list_row_header.xml
@@ -19,7 +19,6 @@
android:id="@+id/widgets_list_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingVertical="@dimen/widget_list_header_view_vertical_padding"
android:orientation="horizontal"
android:importantForAccessibility="yes"
android:focusable="true"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 847e4a8..2addf50 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -344,7 +344,7 @@
<string name="action_move">Move item</string>
<!-- Accessibility description to move item to empty cell. -->
- <string name="move_to_empty_cell">Move to row <xliff:g id="number" example="1">%1$s</xliff:g> column <xliff:g id="number" example="1">%2$s</xliff:g></string>
+ <string name="move_to_empty_cell_description">Move to row <xliff:g id="number" example="1">%1$s</xliff:g> column <xliff:g id="number" example="1">%2$s</xliff:g> in <xliff:g id="string" example="Home screen 2 of 4">%3$s</xliff:g></string>
<!-- Accessibility description to move item inside a folder. -->
<string name="move_to_position">Move to position <xliff:g id="number" example="1">%1$s</xliff:g></string>
diff --git a/src/com/android/launcher3/Alarm.java b/src/com/android/launcher3/Alarm.java
index d5b434c..e4aebf6 100644
--- a/src/com/android/launcher3/Alarm.java
+++ b/src/com/android/launcher3/Alarm.java
@@ -30,6 +30,7 @@
private Handler mHandler;
private OnAlarmListener mAlarmListener;
private boolean mAlarmPending = false;
+ private long mLastSetTimeout;
public Alarm() {
mHandler = new Handler();
@@ -46,6 +47,7 @@
mAlarmPending = true;
long oldTriggerTime = mAlarmTriggerTime;
mAlarmTriggerTime = currentTime + millisecondsInFuture;
+ mLastSetTimeout = millisecondsInFuture;
// If the previous alarm was set for a longer duration, cancel it.
if (mWaitingForCallback && oldTriggerTime > mAlarmTriggerTime) {
@@ -84,4 +86,9 @@
public boolean alarmPending() {
return mAlarmPending;
}
+
+ /** Returns the last value passed to {@link #setAlarm(long)} */
+ public long getLastSetTimeout() {
+ return mLastSetTimeout;
+ }
}
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index 300e7bf..52dfcd4 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -1202,13 +1202,14 @@
int row = cellY + 1;
int col = workspace.mIsRtl ? mCountX - cellX : cellX + 1;
int panelCount = workspace.getPanelCount();
+ int screenId = workspace.getIdForScreen(this);
+ int pageIndex = workspace.getPageIndexForScreenId(screenId);
if (panelCount > 1) {
// Increment the column if the target is on the right side of a two panel home
- int screenId = workspace.getIdForScreen(this);
- int pageIndex = workspace.getPageIndexForScreenId(screenId);
col += (pageIndex % panelCount) * mCountX;
}
- return getContext().getString(R.string.move_to_empty_cell, row, col);
+ return getContext().getString(R.string.move_to_empty_cell_description, row, col,
+ workspace.getPageDescription(pageIndex));
}
}
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 4903d77..c482ed5 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -3418,7 +3418,11 @@
return getPageDescription(page);
}
- private String getPageDescription(int page) {
+ /**
+ * @param page page index.
+ * @return Description of the page at the given page index.
+ */
+ public String getPageDescription(int page) {
int nScreens = getChildCount();
int extraScreenId = mScreenOrder.indexOf(EXTRA_EMPTY_SCREEN_ID);
if (extraScreenId >= 0 && nScreens > 1) {
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index a4a2085..e0f1b3d 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -23,7 +23,6 @@
import static com.android.launcher3.anim.PropertySetter.NO_ANIM_PROPERTY_SETTER;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PROGRESS;
-import static com.android.launcher3.util.SystemUiController.UI_STATE_ALLAPPS;
import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
@@ -37,7 +36,6 @@
import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
-import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatorListeners;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.anim.PropertySetter;
@@ -293,11 +291,6 @@
public void setupViews(ScrimView scrimView, ActivityAllAppsContainerView<Launcher> appsView) {
mScrimView = scrimView;
mAppsView = appsView;
- if (FeatureFlags.ENABLE_DEVICE_SEARCH.get() && Utilities.ATLEAST_R) {
- mLauncher.getSystemUiController().updateUiState(UI_STATE_ALLAPPS,
- View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
- | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
- }
mAppsView.setScrimView(scrimView);
mAppsViewAlpha = new MultiValueAlpha(mAppsView, APPS_VIEW_INDEX_COUNT);
mAppsViewAlpha.setUpdateVisibility(true);
diff --git a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
index 499e749..72a9b14 100644
--- a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
@@ -304,7 +304,8 @@
mTouchHandler.handleTouchEvent(ev, mFastScrollerOffset);
return true;
}
- if (isSearching()) {
+ if (isSearching()
+ && mActivityContext.getDragLayer().isEventOverView(getVisibleContainerView(), ev)) {
// if in search state, consume touch event.
return true;
}
diff --git a/src/com/android/launcher3/allapps/FloatingHeaderView.java b/src/com/android/launcher3/allapps/FloatingHeaderView.java
index 6ecbad2..02655b7 100644
--- a/src/com/android/launcher3/allapps/FloatingHeaderView.java
+++ b/src/com/android/launcher3/allapps/FloatingHeaderView.java
@@ -17,6 +17,7 @@
import android.animation.ValueAnimator;
import android.content.Context;
+import android.content.res.Configuration;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.ArrayMap;
@@ -84,7 +85,7 @@
// These two values are necessary to ensure that the header protection is drawn correctly.
private final int mHeaderTopAdjustment;
private final int mHeaderBottomAdjustment;
- private final boolean mHeaderProtectionSupported;
+ private boolean mHeaderProtectionSupported;
protected ViewGroup mTabLayout;
private AllAppsRecyclerView mMainRV;
@@ -122,9 +123,14 @@
mHeaderBottomAdjustment = context.getResources()
.getDimensionPixelSize(R.dimen.all_apps_header_bottom_adjustment);
mHeaderProtectionSupported = context.getResources().getBoolean(
- R.bool.config_header_protection_supported)
- // TODO(b/208599118) Support header protection for bottom sheet.
- && !ActivityContext.lookupContext(context).getDeviceProfile().isTablet;
+ R.bool.config_header_protection_supported);
+ }
+
+ @Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ mHeaderProtectionSupported = getContext().getResources().getBoolean(
+ R.bool.config_header_protection_supported);
}
@Override
diff --git a/src/com/android/launcher3/allapps/WorkProfileManager.java b/src/com/android/launcher3/allapps/WorkProfileManager.java
index 8443923..5edd431 100644
--- a/src/com/android/launcher3/allapps/WorkProfileManager.java
+++ b/src/com/android/launcher3/allapps/WorkProfileManager.java
@@ -155,7 +155,12 @@
mWorkModeSwitch.getResources().getDimensionPixelSize(R.dimen.qsb_widget_height);
}
if (!mAllApps.mActivityContext.getDeviceProfile().isGestureMode){
- workFabMarginBottom += mAllApps.mActivityContext.getDeviceProfile().getInsets().bottom;
+ if (mDeviceProfile.isTaskbarPresent){
+ workFabMarginBottom += mDeviceProfile.taskbarSize;
+ } else {
+ workFabMarginBottom +=
+ mAllApps.mActivityContext.getDeviceProfile().getInsets().bottom;
+ }
}
lp.bottomMargin = workFabMarginBottom;
int allAppsContainerWidth = mAllApps.getVisibleContainerView().getWidth();
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 38b5c65..da5c4c2 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -277,6 +277,10 @@
"ENABLE_DISMISS_PREDICTION_UNDO", false,
"Show an 'Undo' snackbar when users dismiss a predicted hotseat item");
+ public static final BooleanFlag ENABLE_CACHED_WIDGET = getDebugFlag(
+ "ENABLE_CACHED_WIDGET", true,
+ "Show previously cached widgets as opposed to deferred widget where available");
+
public static void initialize(Context context) {
synchronized (sDebugFlags) {
for (DebugFlag flag : sDebugFlags) {
diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java
index 3a030a8..b76e9d5 100644
--- a/src/com/android/launcher3/testing/TestProtocol.java
+++ b/src/com/android/launcher3/testing/TestProtocol.java
@@ -139,4 +139,9 @@
public static final String MISSING_PROMISE_ICON = "b/202985412";
public static final String BAD_STATE = "b/223498680";
public static final String TASKBAR_IN_APP_STATE = "b/227657604";
+
+ public static final String REQUEST_EMULATE_DISPLAY = "emulate-display";
+ public static final String REQUEST_STOP_EMULATE_DISPLAY = "stop-emulate-display";
+ public static final String REQUEST_IS_EMULATE_DISPLAY_RUNNING = "is-emulate-display-running";
+ public static final String REQUEST_EMULATE_PRINT_DEVICE = "emulate-print-device";
}
diff --git a/src/com/android/launcher3/touch/AllAppsSwipeController.java b/src/com/android/launcher3/touch/AllAppsSwipeController.java
index db43baa..37b76fb 100644
--- a/src/com/android/launcher3/touch/AllAppsSwipeController.java
+++ b/src/com/android/launcher3/touch/AllAppsSwipeController.java
@@ -47,48 +47,88 @@
*/
public class AllAppsSwipeController extends AbstractStateChangeTouchController {
- private static final float ALLAPPS_STAGGERED_FADE_THRESHOLD = 0.5f;
+ private static final float ALL_APPS_CONTENT_FADE_MAX_CLAMPING_THRESHOLD = 0.8f;
+ private static final float ALL_APPS_CONTENT_FADE_MIN_CLAMPING_THRESHOLD = 0.5f;
+ private static final float ALL_APPS_SCRIM_VISIBLE_THRESHOLD = 0.1f;
+ private static final float ALL_APPS_STAGGERED_FADE_THRESHOLD = 0.5f;
- // Custom timing for NORMAL -> ALL_APPS on phones only.
- 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;
+ public static final Interpolator ALL_APPS_SCRIM_RESPONDER =
+ Interpolators.clampToProgress(
+ LINEAR, ALL_APPS_SCRIM_VISIBLE_THRESHOLD, ALL_APPS_STAGGERED_FADE_THRESHOLD);
+ public static final Interpolator ALL_APPS_CLAMPING_RESPONDER =
+ Interpolators.clampToProgress(
+ LINEAR,
+ 1 - ALL_APPS_CONTENT_FADE_MAX_CLAMPING_THRESHOLD,
+ 1 - ALL_APPS_CONTENT_FADE_MIN_CLAMPING_THRESHOLD);
+
+ // ---- Custom interpolators for NORMAL -> ALL_APPS on phones only. ----
+
+ private static final float WORKSPACE_MOTION_START_ATOMIC = 0.1667f;
+ private static final float ALL_APPS_STATE_TRANSITION_ATOMIC = 0.305f;
+ private static final float ALL_APPS_STATE_TRANSITION_MANUAL = 0.4f;
+ private static final float ALL_APPS_FADE_END_ATOMIC = 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);
- public static final Interpolator ALLAPPS_STAGGERED_FADE_LATE_RESPONDER =
- Interpolators.clampToProgress(LINEAR, ALLAPPS_STAGGERED_FADE_THRESHOLD, 1f);
+ private static final Interpolator LINEAR_EARLY_MANUAL =
+ Interpolators.clampToProgress(LINEAR, 0f, ALL_APPS_STATE_TRANSITION_MANUAL);
+ private static final Interpolator STEP_TRANSITION_ATOMIC =
+ Interpolators.clampToProgress(FINAL_FRAME, 0f, ALL_APPS_STATE_TRANSITION_ATOMIC);
+ private static final Interpolator STEP_TRANSITION_MANUAL =
+ Interpolators.clampToProgress(FINAL_FRAME, 0f, ALL_APPS_STATE_TRANSITION_MANUAL);
- // 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 =
+ private static final Interpolator BLUR_ADJUSTED =
+ Interpolators.mapToProgress(LINEAR, 0f, ALL_APPS_FULL_DEPTH_PROGRESS);
+ public static final Interpolator BLUR_ATOMIC =
Interpolators.clampToProgress(
- Interpolators.mapToProgress(
- LINEAR, 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 =
+ BLUR_ADJUSTED, WORKSPACE_MOTION_START_ATOMIC, ALL_APPS_STATE_TRANSITION_ATOMIC);
+ public static final Interpolator BLUR_MANUAL =
+ Interpolators.clampToProgress(BLUR_ADJUSTED, 0f, ALL_APPS_STATE_TRANSITION_MANUAL);
+
+ public static final Interpolator WORKSPACE_FADE_ATOMIC = STEP_TRANSITION_ATOMIC;
+ public static final Interpolator WORKSPACE_FADE_MANUAL = STEP_TRANSITION_MANUAL;
+
+ public static final Interpolator WORKSPACE_SCALE_ATOMIC =
Interpolators.clampToProgress(
- EMPHASIZED_ACCELERATE, WORKSPACE_MOTION_START, 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 =
+ EMPHASIZED_ACCELERATE, WORKSPACE_MOTION_START_ATOMIC,
+ ALL_APPS_STATE_TRANSITION_ATOMIC);
+ public static final Interpolator WORKSPACE_SCALE_MANUAL = LINEAR_EARLY_MANUAL;
+
+ public static final Interpolator HOTSEAT_FADE_ATOMIC = STEP_TRANSITION_ATOMIC;
+ public static final Interpolator HOTSEAT_FADE_MANUAL = STEP_TRANSITION_MANUAL;
+
+ public static final Interpolator HOTSEAT_SCALE_ATOMIC = STEP_TRANSITION_ATOMIC;
+ public static final Interpolator HOTSEAT_SCALE_MANUAL = LINEAR_EARLY_MANUAL;
+
+ public static final Interpolator HOTSEAT_TRANSLATE_ATOMIC =
Interpolators.clampToProgress(
- EMPHASIZED_ACCELERATE, WORKSPACE_MOTION_START, ALL_APPS_STATE_TRANSITION);
- public static final Interpolator SCRIM_FADE =
+ EMPHASIZED_ACCELERATE, WORKSPACE_MOTION_START_ATOMIC,
+ ALL_APPS_STATE_TRANSITION_ATOMIC);
+ public static final Interpolator HOTSEAT_TRANSLATE_MANUAL = STEP_TRANSITION_MANUAL;
+
+ public static final Interpolator SCRIM_FADE_ATOMIC =
Interpolators.clampToProgress(
Interpolators.mapToProgress(LINEAR, 0f, 0.8f),
- WORKSPACE_MOTION_START, ALL_APPS_STATE_TRANSITION);
- public static final Interpolator ALL_APPS_FADE =
+ WORKSPACE_MOTION_START_ATOMIC, ALL_APPS_STATE_TRANSITION_ATOMIC);
+ public static final Interpolator SCRIM_FADE_MANUAL = LINEAR_EARLY_MANUAL;
+
+ public static final Interpolator ALL_APPS_FADE_ATOMIC =
Interpolators.clampToProgress(
- Interpolators.mapToProgress(DECELERATED_EASE, 0.2f, 1.0f),
- ALL_APPS_STATE_TRANSITION, ALL_APPS_FADE_END);
- public static final Interpolator ALL_APPS_VERTICAL_PROGRESS =
+ Interpolators.mapToProgress(DECELERATED_EASE, 0.2f, 1f),
+ ALL_APPS_STATE_TRANSITION_ATOMIC, ALL_APPS_FADE_END_ATOMIC);
+ public static final Interpolator ALL_APPS_FADE_MANUAL =
+ Interpolators.clampToProgress(LINEAR, ALL_APPS_STATE_TRANSITION_MANUAL, 1f);
+
+ public static final Interpolator ALL_APPS_VERTICAL_PROGRESS_ATOMIC =
Interpolators.clampToProgress(
- Interpolators.mapToProgress(EMPHASIZED_DECELERATE, 0.4f, 1.0f),
- ALL_APPS_STATE_TRANSITION, 1.0f);
+ Interpolators.mapToProgress(EMPHASIZED_DECELERATE, 0.4f, 1f),
+ ALL_APPS_STATE_TRANSITION_ATOMIC, 1f);
+ public static final Interpolator ALL_APPS_VERTICAL_PROGRESS_MANUAL =
+ Interpolators.clampToProgress(
+ Interpolators.mapToProgress(LINEAR, ALL_APPS_STATE_TRANSITION_MANUAL, 1f),
+ ALL_APPS_STATE_TRANSITION_MANUAL, 1f);
+
+ // --------
public AllAppsSwipeController(Launcher l) {
super(l, SingleAxisSwipeDetector.VERTICAL);
@@ -141,6 +181,7 @@
protected StateAnimationConfig getConfigForStates(LauncherState fromState,
LauncherState toState) {
StateAnimationConfig config = super.getConfigForStates(fromState, toState);
+ config.userControlled = true;
if (fromState == NORMAL && toState == ALL_APPS) {
applyNormalToAllAppsAnimConfig(mLauncher, config);
} else if (fromState == ALL_APPS && toState == NORMAL) {
@@ -150,36 +191,75 @@
}
/**
- * Applies Animation config values for transition from all apps to home
+ * Applies Animation config values for transition from all apps to home.
*/
public static void applyAllAppsToNormalConfig(Launcher launcher, StateAnimationConfig config) {
- boolean isTablet = launcher.getDeviceProfile().isTablet;
- config.setInterpolator(ANIM_SCRIM_FADE, ALLAPPS_STAGGERED_FADE_LATE_RESPONDER);
- config.setInterpolator(ANIM_ALL_APPS_FADE, isTablet
- ? FINAL_FRAME : ALLAPPS_STAGGERED_FADE_EARLY_RESPONDER);
- if (!isTablet) {
- config.setInterpolator(ANIM_WORKSPACE_FADE, INSTANT);
+ if (launcher.getDeviceProfile().isTablet) {
+ config.setInterpolator(ANIM_SCRIM_FADE,
+ Interpolators.reverse(ALL_APPS_SCRIM_RESPONDER));
+ config.setInterpolator(ANIM_ALL_APPS_FADE, FINAL_FRAME);
+ if (!config.userControlled) {
+ config.setInterpolator(ANIM_VERTICAL_PROGRESS, EMPHASIZED_ACCELERATE);
+ }
+ } else {
+ if (config.userControlled) {
+ config.setInterpolator(ANIM_DEPTH, Interpolators.reverse(BLUR_MANUAL));
+ config.setInterpolator(ANIM_WORKSPACE_FADE,
+ Interpolators.reverse(WORKSPACE_FADE_MANUAL));
+ config.setInterpolator(ANIM_WORKSPACE_SCALE,
+ Interpolators.reverse(WORKSPACE_SCALE_MANUAL));
+ config.setInterpolator(ANIM_HOTSEAT_FADE,
+ Interpolators.reverse(HOTSEAT_FADE_MANUAL));
+ config.setInterpolator(ANIM_HOTSEAT_SCALE,
+ Interpolators.reverse(HOTSEAT_SCALE_MANUAL));
+ config.setInterpolator(ANIM_HOTSEAT_TRANSLATE,
+ Interpolators.reverse(HOTSEAT_TRANSLATE_MANUAL));
+ config.setInterpolator(ANIM_SCRIM_FADE, Interpolators.reverse(SCRIM_FADE_MANUAL));
+ config.setInterpolator(ANIM_ALL_APPS_FADE,
+ Interpolators.reverse(ALL_APPS_FADE_MANUAL));
+ config.setInterpolator(ANIM_VERTICAL_PROGRESS,
+ Interpolators.reverse(ALL_APPS_VERTICAL_PROGRESS_MANUAL));
+ } else {
+ config.setInterpolator(ANIM_SCRIM_FADE,
+ Interpolators.reverse(ALL_APPS_SCRIM_RESPONDER));
+ config.setInterpolator(ANIM_ALL_APPS_FADE, ALL_APPS_CLAMPING_RESPONDER);
+ config.setInterpolator(ANIM_WORKSPACE_FADE, INSTANT);
+ config.setInterpolator(ANIM_VERTICAL_PROGRESS, EMPHASIZED_ACCELERATE);
+ }
}
}
/**
- * Applies Animation config values for transition from home to all apps
+ * Applies Animation config values for transition from home to all apps.
*/
- public static void applyNormalToAllAppsAnimConfig(Launcher launcher,
- StateAnimationConfig config) {
+ public static void applyNormalToAllAppsAnimConfig(
+ Launcher launcher, StateAnimationConfig config) {
if (launcher.getDeviceProfile().isTablet) {
- config.setInterpolator(ANIM_SCRIM_FADE, ALLAPPS_STAGGERED_FADE_EARLY_RESPONDER);
config.setInterpolator(ANIM_ALL_APPS_FADE, INSTANT);
+ config.setInterpolator(ANIM_SCRIM_FADE, ALL_APPS_SCRIM_RESPONDER);
+ if (!config.userControlled) {
+ config.setInterpolator(ANIM_VERTICAL_PROGRESS, EMPHASIZED_DECELERATE);
+ }
} 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);
- config.setInterpolator(ANIM_VERTICAL_PROGRESS, ALL_APPS_VERTICAL_PROGRESS);
+ config.setInterpolator(ANIM_DEPTH, config.userControlled ? BLUR_MANUAL : BLUR_ATOMIC);
+ config.setInterpolator(ANIM_WORKSPACE_FADE,
+ config.userControlled ? WORKSPACE_FADE_MANUAL : WORKSPACE_FADE_ATOMIC);
+ config.setInterpolator(ANIM_WORKSPACE_SCALE,
+ config.userControlled ? WORKSPACE_SCALE_MANUAL : WORKSPACE_SCALE_ATOMIC);
+ config.setInterpolator(ANIM_HOTSEAT_FADE,
+ config.userControlled ? HOTSEAT_FADE_MANUAL : HOTSEAT_FADE_ATOMIC);
+ config.setInterpolator(ANIM_HOTSEAT_SCALE,
+ config.userControlled ? HOTSEAT_SCALE_MANUAL : HOTSEAT_SCALE_ATOMIC);
+ config.setInterpolator(ANIM_HOTSEAT_TRANSLATE,
+ config.userControlled ? HOTSEAT_TRANSLATE_MANUAL : HOTSEAT_TRANSLATE_ATOMIC);
+ config.setInterpolator(ANIM_SCRIM_FADE,
+ config.userControlled ? SCRIM_FADE_MANUAL : SCRIM_FADE_ATOMIC);
+ config.setInterpolator(ANIM_ALL_APPS_FADE,
+ config.userControlled ? ALL_APPS_FADE_MANUAL : ALL_APPS_FADE_ATOMIC);
+ config.setInterpolator(ANIM_VERTICAL_PROGRESS,
+ config.userControlled
+ ? ALL_APPS_VERTICAL_PROGRESS_MANUAL
+ : ALL_APPS_VERTICAL_PROGRESS_ATOMIC);
}
}
}
diff --git a/src/com/android/launcher3/util/SystemUiController.java b/src/com/android/launcher3/util/SystemUiController.java
index 630df7e..6945983 100644
--- a/src/com/android/launcher3/util/SystemUiController.java
+++ b/src/com/android/launcher3/util/SystemUiController.java
@@ -19,6 +19,10 @@
import android.view.View;
import android.view.Window;
+import androidx.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
/**
@@ -31,15 +35,26 @@
public static final int UI_STATE_SCRIM_VIEW = 1;
public static final int UI_STATE_WIDGET_BOTTOM_SHEET = 2;
public static final int UI_STATE_FULLSCREEN_TASK = 3;
- public static final int UI_STATE_ALLAPPS = 4;
public static final int FLAG_LIGHT_NAV = 1 << 0;
public static final int FLAG_DARK_NAV = 1 << 1;
public static final int FLAG_LIGHT_STATUS = 1 << 2;
public static final int FLAG_DARK_STATUS = 1 << 3;
+ /**
+ * Security type based on WifiConfiguration.KeyMgmt
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(flag = true, value = {
+ FLAG_LIGHT_NAV,
+ FLAG_DARK_NAV,
+ FLAG_LIGHT_STATUS,
+ FLAG_DARK_STATUS,
+ })
+ public @interface SystemUiControllerFlags {}
+
private final Window mWindow;
- private final int[] mStates = new int[5];
+ private final int[] mStates = new int[4];
public SystemUiController(Window window) {
mWindow = window;
@@ -50,7 +65,7 @@
? (FLAG_LIGHT_NAV | FLAG_LIGHT_STATUS) : (FLAG_DARK_NAV | FLAG_DARK_STATUS));
}
- public void updateUiState(int uiState, int flags) {
+ public void updateUiState(int uiState, @SystemUiControllerFlags int flags) {
if (mStates[uiState] == flags) {
return;
}
diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetHost.java b/src/com/android/launcher3/widget/LauncherAppWidgetHost.java
index fe83f3f..98a960c 100644
--- a/src/com/android/launcher3/widget/LauncherAppWidgetHost.java
+++ b/src/com/android/launcher3/widget/LauncherAppWidgetHost.java
@@ -28,6 +28,7 @@
import android.os.Bundle;
import android.os.Handler;
import android.util.SparseArray;
+import android.widget.RemoteViews;
import android.widget.Toast;
import androidx.annotation.Nullable;
@@ -37,6 +38,7 @@
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.model.WidgetsModel;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.testing.TestLogging;
@@ -70,13 +72,14 @@
private final ArrayList<ProviderChangedListener> mProviderChangeListeners = new ArrayList<>();
private final SparseArray<LauncherAppWidgetHostView> mViews = new SparseArray<>();
private final SparseArray<PendingAppWidgetHostView> mPendingViews = new SparseArray<>();
+ private final SparseArray<LauncherAppWidgetHostView> mDeferredViews = new SparseArray<>();
+ private final SparseArray<RemoteViews> mCachedRemoteViews = new SparseArray<>();
private final Context mContext;
private int mFlags = FLAG_STATE_IS_NORMAL;
private IntConsumer mAppWidgetRemovedCallback = null;
-
public LauncherAppWidgetHost(Context context) {
this(context, null);
}
@@ -95,6 +98,11 @@
if (mPendingViews.get(appWidgetId) != null) {
view = mPendingViews.get(appWidgetId);
mPendingViews.remove(appWidgetId);
+ } else if (mDeferredViews.get(appWidgetId) != null) {
+ // In case the widget view is deferred, we will simply return the deferred view as
+ // opposed to instantiate a new instance of LauncherAppWidgetHostView since launcher
+ // already added the former to the workspace.
+ view = mDeferredViews.get(appWidgetId);
} else {
view = new LauncherAppWidgetHostView(context);
}
@@ -120,12 +128,25 @@
// widgets upon bind anyway. See issue 14255011 for more context.
}
- // We go in reverse order and inflate any deferred widget
+ // We go in reverse order and inflate any deferred or cached widget
for (int i = mViews.size() - 1; i >= 0; i--) {
LauncherAppWidgetHostView view = mViews.valueAt(i);
if (view instanceof DeferredAppWidgetHostView) {
view.reInflate();
}
+ if (FeatureFlags.ENABLE_CACHED_WIDGET.get()) {
+ final int appWidgetId = mViews.keyAt(i);
+ if (view == mDeferredViews.get(appWidgetId)) {
+ // If the widget view was deferred, we'll need to call super.createView here
+ // to make the binder call to system process to fetch cumulative updates to this
+ // widget, as well as setting up this view for future updates.
+ super.createView(view.mLauncher, appWidgetId, view.getAppWidgetInfo());
+ // At this point #onCreateView should have been called, which in turn returned
+ // the deferred view. There's no reason to keep the reference anymore, so we
+ // removed it here.
+ mDeferredViews.remove(appWidgetId);
+ }
+ }
}
}
@@ -221,10 +242,28 @@
CustomWidgetManager.INSTANCE.get(context).onViewCreated(lahv);
return lahv;
} else if ((mFlags & FLAG_LISTENING) == 0) {
- DeferredAppWidgetHostView view = new DeferredAppWidgetHostView(context);
- view.setAppWidget(appWidgetId, appWidget);
- mViews.put(appWidgetId, view);
- return view;
+ // Since the launcher hasn't started listening to widget updates, we can't simply call
+ // super.createView here because the later will make a binder call to retrieve
+ // RemoteViews from system process.
+ // TODO: have launcher always listens to widget updates in background so that this
+ // check can be removed altogether.
+ if (FeatureFlags.ENABLE_CACHED_WIDGET.get()
+ && mCachedRemoteViews.get(appWidgetId) != null) {
+ // We've found RemoteViews from cache for this widget, so we will instantiate a
+ // widget host view and populate it with the cached RemoteViews.
+ final LauncherAppWidgetHostView view = new LauncherAppWidgetHostView(context);
+ view.setAppWidget(appWidgetId, appWidget);
+ view.updateAppWidget(mCachedRemoteViews.get(appWidgetId));
+ mDeferredViews.put(appWidgetId, view);
+ mViews.put(appWidgetId, view);
+ return view;
+ } else {
+ // When cache misses, a placeholder for the widget will be returned instead.
+ DeferredAppWidgetHostView view = new DeferredAppWidgetHostView(context);
+ view.setAppWidget(appWidgetId, appWidget);
+ mViews.put(appWidgetId, view);
+ return view;
+ }
} else {
try {
return super.createView(context, appWidgetId, appWidget);
@@ -281,6 +320,16 @@
@Override
public void clearViews() {
super.clearViews();
+ if (FeatureFlags.ENABLE_CACHED_WIDGET.get()) {
+ // First, we clear any previously cached content from existing widgets
+ mCachedRemoteViews.clear();
+ // Then we proceed to cache the content from the widgets
+ for (int i = 0; i < mViews.size(); i++) {
+ final int appWidgetId = mViews.keyAt(i);
+ final LauncherAppWidgetHostView view = mViews.get(appWidgetId);
+ mCachedRemoteViews.put(appWidgetId, view.mLastRemoteViews);
+ }
+ }
mViews.clear();
}
diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
index 0865152..fc1e880 100644
--- a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
+++ b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
@@ -43,6 +43,7 @@
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
@@ -85,7 +86,7 @@
private Runnable mAutoAdvanceRunnable;
private long mDeferUpdatesUntilMillis = 0;
- private RemoteViews mDeferredRemoteViews;
+ RemoteViews mLastRemoteViews;
private boolean mHasDeferredColorChange = false;
private @Nullable SparseIntArray mDeferredColorChange = null;
@@ -150,11 +151,18 @@
TRACE_METHOD_NAME + getAppWidgetInfo().provider, getAppWidgetId());
mTrackingWidgetUpdate = false;
}
- if (isDeferringUpdates()) {
- mDeferredRemoteViews = remoteViews;
- return;
+ if (FeatureFlags.ENABLE_CACHED_WIDGET.get()) {
+ mLastRemoteViews = remoteViews;
+ if (isDeferringUpdates()) {
+ return;
+ }
+ } else {
+ if (isDeferringUpdates()) {
+ mLastRemoteViews = remoteViews;
+ return;
+ }
+ mLastRemoteViews = null;
}
- mDeferredRemoteViews = null;
super.updateAppWidget(remoteViews);
@@ -218,8 +226,7 @@
SparseIntArray deferredColors;
boolean hasDeferredColors;
mDeferUpdatesUntilMillis = 0;
- remoteViews = mDeferredRemoteViews;
- mDeferredRemoteViews = null;
+ remoteViews = mLastRemoteViews;
deferredColors = mDeferredColorChange;
hasDeferredColors = mHasDeferredColorChange;
mDeferredColorChange = null;
diff --git a/src/com/android/launcher3/widget/picker/WidgetsListDrawableFactory.java b/src/com/android/launcher3/widget/picker/WidgetsListDrawableFactory.java
index c61e3a4..984a274 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsListDrawableFactory.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsListDrawableFactory.java
@@ -27,6 +27,7 @@
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
+import android.graphics.drawable.InsetDrawable;
import android.graphics.drawable.RippleDrawable;
import android.graphics.drawable.StateListDrawable;
@@ -40,6 +41,8 @@
private final float mMiddleCornerRadius;
private final ColorStateList mSurfaceColor;
private final ColorStateList mRippleColor;
+ private final int mVerticalPadding;
+ private final int mHeaderMargin;
WidgetsListDrawableFactory(Context context) {
Resources res = context.getResources();
@@ -48,6 +51,9 @@
mSurfaceColor = context.getColorStateList(R.color.surface);
mRippleColor = ColorStateList.valueOf(
Themes.getAttrColor(context, android.R.attr.colorControlHighlight));
+ mVerticalPadding =
+ res.getDimensionPixelSize(R.dimen.widget_list_header_view_vertical_padding);
+ mHeaderMargin = res.getDimensionPixelSize(R.dimen.widget_list_entry_spacing);
}
/**
@@ -74,7 +80,10 @@
stateList.addState(
LAST.mStateSet,
createRoundedRectDrawable(mMiddleCornerRadius, mTopBottomCornerRadius));
- return new RippleDrawable(mRippleColor, /* content= */ stateList, /* mask= */ stateList);
+ RippleDrawable ripple =
+ new RippleDrawable(mRippleColor, /* content= */ stateList, /* mask= */ stateList);
+ ripple.setPadding(0, mVerticalPadding, 0, mVerticalPadding);
+ return new InsetDrawable(ripple, 0, mHeaderMargin, 0, 0);
}
/**
diff --git a/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java b/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java
index daa67a9..4c0e0d5 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java
@@ -16,18 +16,12 @@
package com.android.launcher3.widget.picker;
-import static com.android.launcher3.widget.picker.WidgetsListAdapter.VIEW_TYPE_WIDGETS_HEADER;
-import static com.android.launcher3.widget.picker.WidgetsListAdapter.VIEW_TYPE_WIDGETS_SEARCH_HEADER;
-
import android.content.Context;
import android.graphics.Point;
-import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.SparseIntArray;
import android.view.MotionEvent;
-import android.view.View;
-import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.OnItemTouchListener;
@@ -55,7 +49,6 @@
* VIEW_TYPE_WIDGETS_LIST is not visible on the screen.
*/
private final SparseIntArray mCachedSizes = new SparseIntArray();
- private final SpacingDecoration mSpacingDecoration;
public WidgetsRecyclerView(Context context) {
this(context, null);
@@ -70,9 +63,6 @@
super(context, attrs, defStyleAttr);
mScrollbarTop = getResources().getDimensionPixelSize(R.dimen.dynamic_grid_edge_margin);
addOnItemTouchListener(this);
-
- mSpacingDecoration = new SpacingDecoration(context);
- addItemDecoration(mSpacingDecoration);
}
@Override
@@ -183,7 +173,7 @@
@Override
protected int getItemsHeight(int untilIndex) {
// Initialize cache
- int childCount = getChildCount();
+ int childCount = Math.min(getChildCount(), getAdapter().getItemCount());
int startPosition;
if (childCount > 0
&& ((startPosition = getChildAdapterPosition(getChildAt(0))) != NO_POSITION)) {
@@ -200,7 +190,7 @@
int totalItemsHeight = 0;
for (int i = 0; i < untilIndex; i++) {
int type = mAdapter.getItemViewType(i);
- totalItemsHeight += mCachedSizes.get(type) + mSpacingDecoration.getSpacing(i, type);
+ totalItemsHeight += mCachedSizes.get(type);
}
return totalItemsHeight;
}
@@ -216,31 +206,4 @@
*/
int getHeaderViewHeight();
}
-
- private static class SpacingDecoration extends RecyclerView.ItemDecoration {
-
- private final int mSpacingBetweenEntries;
-
- SpacingDecoration(@NonNull Context context) {
- mSpacingBetweenEntries =
- context.getResources().getDimensionPixelSize(R.dimen.widget_list_entry_spacing);
- }
-
- @Override
- public void getItemOffsets(
- @NonNull Rect outRect,
- @NonNull View view,
- @NonNull RecyclerView parent,
- @NonNull RecyclerView.State state) {
- super.getItemOffsets(outRect, view, parent, state);
- int position = parent.getChildAdapterPosition(view);
- outRect.top += getSpacing(position, parent.getAdapter().getItemViewType(position));
- }
-
- public int getSpacing(int position, int type) {
- boolean isHeader = type == VIEW_TYPE_WIDGETS_SEARCH_HEADER
- || type == VIEW_TYPE_WIDGETS_HEADER;
- return position > 0 && isHeader ? mSpacingBetweenEntries : 0;
- }
- }
}
diff --git a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
index e00b569..ca39d2b 100644
--- a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
+++ b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
@@ -25,6 +25,7 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
import android.content.Intent;
import android.graphics.Point;
@@ -53,6 +54,7 @@
import com.android.launcher3.widget.picker.WidgetsRecyclerView;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -191,6 +193,17 @@
}
@Test
+ @PortraitLandscape
+ public void testAllAppsDeadzoneForTablet() throws Exception {
+ assumeTrue(mLauncher.isTablet());
+
+ mLauncher.getWorkspace().switchToAllApps().dismissByTappingOutsideForTablet(
+ true /* tapRight */);
+ mLauncher.getWorkspace().switchToAllApps().dismissByTappingOutsideForTablet(
+ false /* tapRight */);
+ }
+
+ @Test
@ScreenRecord // b/202433017
public void testWorkspace() throws Exception {
final Workspace workspace = mLauncher.getWorkspace();
@@ -376,6 +389,7 @@
@Test
@PortraitLandscape
@ScreenRecord
+ @Ignore // b/233075289
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.
@@ -521,6 +535,25 @@
}
}
+ @Test
+ @PortraitLandscape
+ public void testDragShortcutToWorkspaceCell() throws Exception {
+ Point[] targets = getCornersAndCenterPositions();
+
+ for (Point target : targets) {
+ final HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
+ allApps.freeze();
+ try {
+ allApps.getAppIcon(APP_NAME)
+ .openDeepShortcutMenu()
+ .getMenuItem(0)
+ .dragToWorkspace(target.x, target.y);
+ } finally {
+ allApps.unfreeze();
+ }
+ }
+ }
+
/**
* @return List of workspace grid coordinates. Those are not pixels. See {@link
* Workspace#getIconGridDimensions()}
diff --git a/tests/src/com/android/launcher3/util/rule/FailureWatcher.java b/tests/src/com/android/launcher3/util/rule/FailureWatcher.java
index 4c41d7e..0a0dfcb 100644
--- a/tests/src/com/android/launcher3/util/rule/FailureWatcher.java
+++ b/tests/src/com/android/launcher3/util/rule/FailureWatcher.java
@@ -32,7 +32,6 @@
public FailureWatcher(UiDevice device, LauncherInstrumentation launcher) {
mDevice = device;
mLauncher = launcher;
- Log.d("b/196820244", "FailureWatcher.ctor", new Exception());
}
@Override
@@ -48,10 +47,8 @@
public void evaluate() throws Throwable {
boolean success = false;
try {
- Log.d("b/196820244", "Before evaluate");
mDevice.executeShellCommand("cmd statusbar tracing start");
FailureWatcher.super.apply(base, description).evaluate();
- Log.d("b/196820244", "After evaluate");
success = true;
} finally {
// Save artifact for Launcher Winscope trace.
@@ -96,9 +93,7 @@
public static void onError(LauncherInstrumentation launcher, Description description,
Throwable e) {
final UiDevice device = launcher.getDevice();
- Log.d("b/196820244", "onError 1");
if (device == null) return;
- Log.d("b/196820244", "onError 2");
final File sceenshot = diagFile(description, "TestScreenshot", "png");
final File hierarchy = diagFile(description, "Hierarchy", "zip");
diff --git a/tests/tapl/com/android/launcher3/tapl/Folder.java b/tests/tapl/com/android/launcher3/tapl/Folder.java
index 26f0a8b..1352cc0 100644
--- a/tests/tapl/com/android/launcher3/tapl/Folder.java
+++ b/tests/tapl/com/android/launcher3/tapl/Folder.java
@@ -16,11 +16,6 @@
package com.android.launcher3.tapl;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.os.SystemClock;
-import android.view.MotionEvent;
-
import androidx.annotation.NonNull;
import androidx.test.uiautomator.UiObject2;
@@ -50,25 +45,15 @@
}
}
- private void touchOutsideFolder() {
- Rect containerBounds = mLauncher.getVisibleBounds(this.mContainer);
- final long downTime = SystemClock.uptimeMillis();
- Point containerLeftTopCorner = new Point(containerBounds.left - 1, containerBounds.top - 1);
- mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_DOWN,
- containerLeftTopCorner, LauncherInstrumentation.GestureScope.INSIDE);
- mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_UP,
- containerLeftTopCorner, LauncherInstrumentation.GestureScope.INSIDE);
- }
-
/**
- * CLose opened folder if possible. It throws assertion error if the folder is already closed.
+ * Close opened folder if possible. It throws assertion error if the folder is already closed.
*/
public Workspace close() {
try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"Want to close opened folder")) {
mLauncher.waitForLauncherObject(FOLDER_CONTENT_RES_ID);
- touchOutsideFolder();
+ mLauncher.touchOutsideContainer(this.mContainer, false /* tapRight */);
mLauncher.waitUntilLauncherObjectGone(FOLDER_CONTENT_RES_ID);
return mLauncher.getWorkspace();
}
diff --git a/tests/tapl/com/android/launcher3/tapl/HomeAllApps.java b/tests/tapl/com/android/launcher3/tapl/HomeAllApps.java
index c275f3b..7123de4 100644
--- a/tests/tapl/com/android/launcher3/tapl/HomeAllApps.java
+++ b/tests/tapl/com/android/launcher3/tapl/HomeAllApps.java
@@ -19,6 +19,7 @@
import androidx.test.uiautomator.UiObject2;
public class HomeAllApps extends AllApps {
+ private static final String BOTTOM_SHEET_RES_ID = "bottom_sheet_background";
HomeAllApps(LauncherInstrumentation launcher) {
super(launcher);
@@ -45,4 +46,23 @@
protected boolean hasSearchBox() {
return true;
}
+
+ /**
+ * Taps outside bottom sheet to dismiss and return to workspace. Available on tablets only.
+ * @param tapRight Tap on the right of bottom sheet if true, or left otherwise.
+ */
+ public Workspace dismissByTappingOutsideForTablet(boolean tapRight) {
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
+ LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+ "want to tap outside AllApps bottom sheet on the "
+ + (tapRight ? "right" : "left"))) {
+ final UiObject2 allAppsBottomSheet =
+ mLauncher.waitForLauncherObject(BOTTOM_SHEET_RES_ID);
+ mLauncher.touchOutsideContainer(allAppsBottomSheet, tapRight);
+ try (LauncherInstrumentation.Closable tapped = mLauncher.addContextLayer(
+ "tapped outside AllApps bottom sheet")) {
+ return mLauncher.getWorkspace();
+ }
+ }
+ }
}
diff --git a/tests/tapl/com/android/launcher3/tapl/HomeAppIcon.java b/tests/tapl/com/android/launcher3/tapl/HomeAppIcon.java
index 71d8ba9..7546504 100644
--- a/tests/tapl/com/android/launcher3/tapl/HomeAppIcon.java
+++ b/tests/tapl/com/android/launcher3/tapl/HomeAppIcon.java
@@ -22,8 +22,6 @@
import androidx.annotation.NonNull;
import androidx.test.uiautomator.UiObject2;
-import java.util.function.Supplier;
-
/**
* App icon on the workspace or all apps.
*/
@@ -102,38 +100,6 @@
}
}
- /**
- * Drag an object to the given cell in workspace. The target cell must be empty.
- *
- * @param cellX zero based column number, starting from the left of the screen.
- * @param cellY zero based row number, starting from the top of the screen.
- */
- public HomeAppIcon dragToWorkspace(int cellX, int cellY) {
- try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
- LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- String.format("want to drag the icon to cell(%d, %d)", cellX, cellY))
- ) {
- final Supplier<Point> dest = () -> Workspace.getCellCenter(mLauncher, cellX, cellY);
- Workspace.dragIconToWorkspace(
- mLauncher,
- /* launchable= */ this,
- dest,
- () -> addExpectedEventsForLongClick(),
- /*expectDropEvents= */ null);
- try (LauncherInstrumentation.Closable ignore = mLauncher.addContextLayer("dragged")) {
- WorkspaceAppIcon appIcon =
- (WorkspaceAppIcon) mLauncher.getWorkspace().getWorkspaceAppIcon(mAppName);
- mLauncher.assertTrue(
- String.format(
- "The %s icon should be in the cell (%d, %d).", mAppName, cellX,
- cellY),
- appIcon.isInCell(cellX, cellY));
- return appIcon;
- }
- }
- }
-
-
/** This method requires public access, however should not be called in tests. */
@Override
public Launchable getLaunchable() {
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 9d25b1b..ae7c46a 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -171,7 +171,7 @@
private static final String WIDGETS_RES_ID = "primary_widgets_list_view";
private static final String CONTEXT_MENU_RES_ID = "popup_container";
private static final String TASKBAR_RES_ID = "taskbar_view";
- public static final int WAIT_TIME_MS = 60000;
+ public static final int WAIT_TIME_MS = 30000;
private static final String SYSTEMUI_PACKAGE = "com.android.systemui";
private static final String ANDROID_PACKAGE = "android";
@@ -1831,4 +1831,26 @@
return ResourceUtils.getBoolByName(
"config_supportsRoundedCornersOnWindows", resources, false);
}
+
+ /**
+ * Taps outside container to dismiss.
+ * @param container container to be dismissed
+ * @param tapRight tap on the right of the container if true, or left otherwise
+ */
+ void touchOutsideContainer(UiObject2 container, boolean tapRight) {
+ try (LauncherInstrumentation.Closable c = addContextLayer(
+ "want to tap outside container on the " + (tapRight ? "right" : "left"))) {
+ Rect containerBounds = getVisibleBounds(container);
+ final long downTime = SystemClock.uptimeMillis();
+ final Point tapTarget = new Point(
+ tapRight
+ ? (containerBounds.right + getRealDisplaySize().x) / 2
+ : containerBounds.left / 2,
+ containerBounds.top + 1);
+ sendPointer(downTime, downTime, MotionEvent.ACTION_DOWN, tapTarget,
+ LauncherInstrumentation.GestureScope.INSIDE);
+ sendPointer(downTime, downTime, MotionEvent.ACTION_UP, tapTarget,
+ LauncherInstrumentation.GestureScope.INSIDE);
+ }
+ }
}
diff --git a/tests/tapl/com/android/launcher3/tapl/SearchResultFromQsb.java b/tests/tapl/com/android/launcher3/tapl/SearchResultFromQsb.java
index 82652c7..ddeeac2 100644
--- a/tests/tapl/com/android/launcher3/tapl/SearchResultFromQsb.java
+++ b/tests/tapl/com/android/launcher3/tapl/SearchResultFromQsb.java
@@ -26,6 +26,7 @@
public class SearchResultFromQsb {
// The input resource id in the search box.
private static final String INPUT_RES = "input";
+ private static final String BOTTOM_SHEET_RES_ID = "bottom_sheet_background";
private final LauncherInstrumentation mLauncher;
SearchResultFromQsb(LauncherInstrumentation launcher) {
@@ -47,4 +48,23 @@
UiObject2 icon = mLauncher.waitForLauncherObject(By.clazz(TextView.class).text(appName));
return new AllAppsAppIcon(mLauncher, icon);
}
+
+ /**
+ * Taps outside bottom sheet to dismiss and return to workspace. Available on tablets only.
+ * @param tapRight Tap on the right of bottom sheet if true, or left otherwise.
+ */
+ public Workspace dismissByTappingOutsideForTablet(boolean tapRight) {
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
+ LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+ "want to tap outside AllApps bottom sheet on the "
+ + (tapRight ? "right" : "left"))) {
+ final UiObject2 allAppsBottomSheet =
+ mLauncher.waitForLauncherObject(BOTTOM_SHEET_RES_ID);
+ mLauncher.touchOutsideContainer(allAppsBottomSheet, tapRight);
+ try (LauncherInstrumentation.Closable tapped = mLauncher.addContextLayer(
+ "tapped outside AllApps bottom sheet")) {
+ return mLauncher.getWorkspace();
+ }
+ }
+ }
}
diff --git a/tests/tapl/com/android/launcher3/tapl/Workspace.java b/tests/tapl/com/android/launcher3/tapl/Workspace.java
index e919740..42ba18c 100644
--- a/tests/tapl/com/android/launcher3/tapl/Workspace.java
+++ b/tests/tapl/com/android/launcher3/tapl/Workspace.java
@@ -228,10 +228,11 @@
private void dragIcon(UiObject2 workspace, HomeAppIcon homeAppIcon, int pageDelta) {
int pageWidth = mLauncher.getDevice().getDisplayWidth() / pagesPerScreen();
int targetX = (pageWidth / 2) + pageWidth * pageDelta;
+ int targetY = mLauncher.getVisibleBounds(workspace).centerY();
dragIconToWorkspace(
mLauncher,
homeAppIcon,
- new Point(targetX, mLauncher.getVisibleBounds(workspace).centerY()),
+ () -> new Point(targetX, targetY),
false,
false,
() -> mLauncher.expectEvent(
@@ -386,7 +387,7 @@
}
static void dragIconToWorkspace(LauncherInstrumentation launcher, Launchable launchable,
- Point dest, boolean startsActivity, boolean isWidgetShortcut,
+ Supplier<Point> dest, boolean startsActivity, boolean isWidgetShortcut,
Runnable expectLongClickEvents) {
Runnable expectDropEvents = null;
if (startsActivity || isWidgetShortcut) {
@@ -394,7 +395,7 @@
LauncherInstrumentation.EVENT_START);
}
dragIconToWorkspace(
- launcher, launchable, () -> dest, expectLongClickEvents, expectDropEvents);
+ launcher, launchable, dest, expectLongClickEvents, expectDropEvents);
}
/**
diff --git a/tests/tapl/com/android/launcher3/tapl/WorkspaceDragSource.java b/tests/tapl/com/android/launcher3/tapl/WorkspaceDragSource.java
index d8d4420..021cc98 100644
--- a/tests/tapl/com/android/launcher3/tapl/WorkspaceDragSource.java
+++ b/tests/tapl/com/android/launcher3/tapl/WorkspaceDragSource.java
@@ -17,6 +17,8 @@
import android.graphics.Point;
+import java.util.function.Supplier;
+
/** Launchable that can serve as a source for dragging and dropping to the workspace. */
interface WorkspaceDragSource {
@@ -36,7 +38,7 @@
Workspace.dragIconToWorkspace(
launcher,
launchable,
- new Point(
+ () -> new Point(
launchableCenter.x >= width
? launchableCenter.x - width / 2
: launchableCenter.x + width / 2,
@@ -47,6 +49,40 @@
}
}
+ /**
+ * Drag an object to the given cell in workspace. The target cell must be empty.
+ *
+ * @param cellX zero based column number, starting from the left of the screen.
+ * @param cellY zero based row number, starting from the top of the screen. *
+ */
+ default HomeAppIcon dragToWorkspace(int cellX, int cellY) {
+ Launchable launchable = getLaunchable();
+ final String iconName = launchable.getObject().getText();
+ LauncherInstrumentation launcher = launchable.mLauncher;
+ try (LauncherInstrumentation.Closable e = launcher.eventsCheck();
+ LauncherInstrumentation.Closable c = launcher.addContextLayer(
+ String.format("want to drag the icon to cell(%d, %d)", cellX, cellY))) {
+ final Supplier<Point> dest = () -> Workspace.getCellCenter(launcher, cellX, cellY);
+ Workspace.dragIconToWorkspace(
+ launcher,
+ launchable,
+ dest,
+ launchable::addExpectedEventsForLongClick,
+ /*expectDropEvents= */ null);
+
+ try (LauncherInstrumentation.Closable ignore = launcher.addContextLayer("dragged")) {
+ WorkspaceAppIcon appIcon =
+ (WorkspaceAppIcon) launcher.getWorkspace().getWorkspaceAppIcon(iconName);
+ launcher.assertTrue(
+ String.format(
+ "The %s icon should be in the cell (%d, %d).", iconName, cellX,
+ cellY),
+ appIcon.isInCell(cellX, cellY));
+ return appIcon;
+ }
+ }
+ }
+
/** This method requires public access, however should not be called in tests. */
Launchable getLaunchable();
}