summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--go/quickstep/src/com/android/quickstep/TouchInteractionService.java3
-rw-r--r--go/quickstep/src/com/android/quickstep/views/IconRecentsView.java17
-rw-r--r--iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java6
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java2
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java141
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityControllerHelper.java4
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java4
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/OtherActivityInputConsumer.java7
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java26
-rw-r--r--quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java18
-rw-r--r--quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java1
-rw-r--r--src/com/android/launcher3/LauncherAppState.java1
-rw-r--r--src/com/android/launcher3/LauncherStateManager.java9
-rw-r--r--src/com/android/launcher3/TestProtocol.java21
-rw-r--r--src/com/android/launcher3/WidgetPreviewLoader.java12
-rw-r--r--src/com/android/launcher3/anim/Interpolators.java1
-rw-r--r--src/com/android/launcher3/logging/LoggerUtils.java6
-rw-r--r--src/com/android/launcher3/touch/AbstractStateChangeTouchController.java5
-rw-r--r--src/com/android/launcher3/widget/WidgetsRecyclerView.java5
-rw-r--r--tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java56
20 files changed, 280 insertions, 65 deletions
diff --git a/go/quickstep/src/com/android/quickstep/TouchInteractionService.java b/go/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 89a845426..80e1325f6 100644
--- a/go/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/go/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -30,7 +30,6 @@ import android.view.MotionEvent;
import com.android.systemui.shared.recents.IOverviewProxy;
import com.android.systemui.shared.recents.ISystemUiProxy;
-import com.android.systemui.shared.system.NavigationBarCompat.HitTarget;
/**
* Service connected by system-UI for handling touch interaction.
@@ -38,8 +37,6 @@ import com.android.systemui.shared.system.NavigationBarCompat.HitTarget;
@TargetApi(Build.VERSION_CODES.O)
public class TouchInteractionService extends Service {
- public static final int EDGE_NAV_BAR = 1 << 8;
-
private static final String TAG = "TouchInteractionService";
private final IBinder mMyBinder = new IOverviewProxy.Stub() {
diff --git a/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java b/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java
index 8976c4474..5bb4c5aaa 100644
--- a/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java
+++ b/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java
@@ -89,6 +89,7 @@ public final class IconRecentsView extends FrameLayout {
private RecyclerView mTaskRecyclerView;
private View mEmptyView;
private View mContentView;
+ private View mClearAllView;
private boolean mTransitionedFromApp;
public IconRecentsView(Context context, AttributeSet attrs) {
@@ -125,10 +126,20 @@ public final class IconRecentsView extends FrameLayout {
updateContentViewVisibility();
}
});
+ mClearAllView = findViewById(R.id.clear_all_button);
+ mClearAllView.setOnClickListener(v -> animateClearAllTasks());
+ }
+ }
+
- View clearAllView = findViewById(R.id.clear_all_button);
- clearAllView.setOnClickListener(v -> animateClearAllTasks());
+ @Override
+ public void setEnabled(boolean enabled) {
+ super.setEnabled(enabled);
+ TaskItemView[] itemViews = getTaskViews();
+ for (TaskItemView itemView : itemViews) {
+ itemView.setEnabled(enabled);
}
+ mClearAllView.setEnabled(enabled);
}
/**
@@ -204,6 +215,7 @@ public final class IconRecentsView extends FrameLayout {
* Clear all tasks and animate out.
*/
private void animateClearAllTasks() {
+ setEnabled(false);
TaskItemView[] itemViews = getTaskViews();
AnimatorSet clearAnim = new AnimatorSet();
@@ -249,6 +261,7 @@ public final class IconRecentsView extends FrameLayout {
itemView.setTranslationX(0);
itemView.setAlpha(1.0f);
}
+ setEnabled(true);
mContentView.setVisibility(GONE);
mTaskActionController.clearAllTasks();
}
diff --git a/iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java b/iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java
index 96b0a9e25..ab4b64cbf 100644
--- a/iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java
+++ b/iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java
@@ -61,6 +61,7 @@ public class BaseIconFactory implements AutoCloseable {
mCanvas = new Canvas();
mCanvas.setDrawFilter(new PaintFlagsDrawFilter(DITHER_FLAG, FILTER_BITMAP_FLAG));
+ clear();
}
protected void clear() {
@@ -114,11 +115,6 @@ public class BaseIconFactory implements AutoCloseable {
}
public BitmapInfo createBadgedIconBitmap(Drawable icon, UserHandle user,
- boolean shrinkNonAdaptiveIcons, boolean isInstantApp) {
- return createBadgedIconBitmap(icon, user, shrinkNonAdaptiveIcons, isInstantApp, null);
- }
-
- public BitmapInfo createBadgedIconBitmap(Drawable icon, UserHandle user,
int iconAppTargetSdk) {
return createBadgedIconBitmap(icon, user, iconAppTargetSdk, false);
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java
index 36014a9b5..f507d0f9d 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java
@@ -30,6 +30,7 @@ import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.uioverrides.touchcontrollers.FlingAndHoldTouchController;
import com.android.launcher3.uioverrides.touchcontrollers.LandscapeEdgeSwipeController;
+import com.android.launcher3.uioverrides.touchcontrollers.NavBarToHomeTouchController;
import com.android.launcher3.uioverrides.touchcontrollers.OverviewToAllAppsTouchController;
import com.android.launcher3.uioverrides.touchcontrollers.PortraitStatesTouchController;
import com.android.launcher3.uioverrides.touchcontrollers.StatusBarTouchController;
@@ -64,6 +65,7 @@ public abstract class RecentsUiFactory {
list.add(launcher.getDragController());
if (mode == Mode.NO_BUTTON) {
list.add(new QuickSwitchTouchController(launcher));
+ list.add(new NavBarToHomeTouchController(launcher));
list.add(new FlingAndHoldTouchController(launcher));
} else {
if (launcher.getDeviceProfile().isVerticalBarLayout()) {
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
new file mode 100644
index 000000000..673beff85
--- /dev/null
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.uioverrides.touchcontrollers;
+
+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.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS;
+import static com.android.launcher3.anim.Interpolators.DEACCEL_3;
+
+import android.animation.Animator;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.animation.Interpolator;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherState;
+import com.android.launcher3.LauncherStateManager.AnimationConfig;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.allapps.AllAppsTransitionController;
+import com.android.launcher3.anim.AnimatorPlaybackController;
+import com.android.launcher3.anim.AnimatorSetBuilder;
+import com.android.launcher3.anim.Interpolators;
+import com.android.launcher3.touch.AbstractStateChangeTouchController;
+import com.android.launcher3.touch.SwipeDetector;
+import com.android.launcher3.userevent.nano.LauncherLogProto;
+import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
+import com.android.quickstep.views.RecentsView;
+
+/**
+ * Handles swiping up on the nav bar to go home from overview or all apps.
+ */
+public class NavBarToHomeTouchController extends AbstractStateChangeTouchController {
+
+ private static final Interpolator PULLBACK_INTERPOLATOR = DEACCEL_3;
+
+ public NavBarToHomeTouchController(Launcher launcher) {
+ super(launcher, SwipeDetector.VERTICAL);
+ }
+
+ @Override
+ protected boolean canInterceptTouch(MotionEvent ev) {
+ boolean cameFromNavBar = (ev.getEdgeFlags() & Utilities.EDGE_NAV_BAR) != 0;
+ return cameFromNavBar && (mLauncher.isInState(OVERVIEW) || mLauncher.isInState(ALL_APPS));
+ }
+
+ @Override
+ protected LauncherState getTargetState(LauncherState fromState, boolean isDragTowardPositive) {
+ return isDragTowardPositive ? NORMAL : fromState;
+ }
+
+ @Override
+ protected float initCurrentAnimation(int animComponents) {
+ long accuracy = (long) (getShiftRange() * 2);
+ final AnimatorSet anim;
+ if (mFromState == OVERVIEW) {
+ anim = new AnimatorSet();
+ RecentsView recentsView = mLauncher.getOverviewPanel();
+ float pullbackDistance = recentsView.getPaddingStart() / 2;
+ if (!recentsView.isRtl()) {
+ pullbackDistance = -pullbackDistance;
+ }
+ anim.play(ObjectAnimator.ofFloat(recentsView, View.TRANSLATION_X, pullbackDistance));
+ anim.setInterpolator(PULLBACK_INTERPOLATOR);
+ } else { // if (mFromState == ALL_APPS)
+ AnimatorSetBuilder builder = new AnimatorSetBuilder();
+ AllAppsTransitionController allAppsController = mLauncher.getAllAppsController();
+ final float pullbackDistance = mLauncher.getDeviceProfile().allAppsIconSizePx / 2;
+ Animator allAppsProgress = ObjectAnimator.ofFloat(allAppsController, ALL_APPS_PROGRESS,
+ -pullbackDistance / allAppsController.getShiftRange());
+ allAppsProgress.setInterpolator(PULLBACK_INTERPOLATOR);
+ builder.play(allAppsProgress);
+ // Slightly fade out all apps content to further distinguish from scrolling.
+ builder.setInterpolator(AnimatorSetBuilder.ANIM_ALL_APPS_FADE, Interpolators
+ .mapToProgress(PULLBACK_INTERPOLATOR, 0, 0.5f));
+ AnimationConfig config = new AnimationConfig();
+ config.duration = accuracy;
+ allAppsController.setAlphas(mToState.getVisibleElements(mLauncher), config, builder);
+ anim = builder.build();
+ }
+ anim.setDuration(accuracy);
+ mCurrentAnimation = AnimatorPlaybackController.wrap(anim, accuracy, this::clearState);
+ return -1 / getShiftRange();
+ }
+
+ @Override
+ public void onDragStart(boolean start) {
+ super.onDragStart(start);
+ mStartContainerType = LauncherLogProto.ContainerType.NAVBAR;
+ }
+
+ @Override
+ public void onDragEnd(float velocity, boolean fling) {
+ final int logAction = fling ? Touch.FLING : Touch.SWIPE;
+ float interpolatedProgress = PULLBACK_INTERPOLATOR.getInterpolation(
+ mCurrentAnimation.getProgressFraction());
+ if (interpolatedProgress >= SUCCESS_TRANSITION_PROGRESS || velocity < 0 && fling) {
+ mLauncher.getStateManager().goToState(mToState, true,
+ () -> onSwipeInteractionCompleted(mToState, logAction));
+ } else {
+ // Quickly return to the state we came from (we didn't move far).
+ AnimatorPlaybackController anim = mLauncher.getStateManager()
+ .createAnimationToNewWorkspace(mFromState, 80);
+ anim.setEndAction(() -> onSwipeInteractionCompleted(mFromState, logAction));
+ anim.start();
+ }
+ mCurrentAnimation.dispatchOnCancel();
+ }
+
+ @Override
+ protected int getDirectionForLog() {
+ return LauncherLogProto.Action.Direction.UP;
+ }
+
+ @Override
+ protected boolean goingBetweenNormalAndOverview(LauncherState fromState,
+ LauncherState toState) {
+ // We don't want to create an atomic animation to/from overview.
+ return false;
+ }
+
+ @Override
+ protected int getLogContainerTypeForNormalState() {
+ return LauncherLogProto.ContainerType.NAVBAR;
+ }
+}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityControllerHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityControllerHelper.java
index ef46b3b0d..73fcf78b8 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityControllerHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityControllerHelper.java
@@ -16,6 +16,7 @@
package com.android.quickstep;
import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
import static com.android.quickstep.views.RecentsView.CONTENT_ALPHA;
import android.animation.Animator;
@@ -59,7 +60,8 @@ public final class FallbackActivityControllerHelper implements
@Override
public int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context, Rect outRect) {
LayoutUtils.calculateFallbackTaskSize(context, dp, outRect);
- if (dp.isVerticalBarLayout()) {
+ if (dp.isVerticalBarLayout()
+ && SysUINavigationMode.INSTANCE.get(context).getMode() != NO_BUTTON) {
Rect targetInsets = dp.getInsets();
int hotseatInset = dp.isSeascape() ? targetInsets.left : targetInsets.right;
return dp.hotseatBarSizePx + hotseatInset;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
index 69f3338e1..df2b687b2 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
@@ -24,6 +24,7 @@ import static com.android.launcher3.allapps.AllAppsTransitionController.SPRING_D
import static com.android.launcher3.allapps.AllAppsTransitionController.SPRING_STIFFNESS;
import static com.android.launcher3.anim.Interpolators.DEACCEL_3;
import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -74,7 +75,8 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe
@Override
public int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context, Rect outRect) {
LayoutUtils.calculateLauncherTaskSize(context, dp, outRect);
- if (dp.isVerticalBarLayout()) {
+ if (dp.isVerticalBarLayout()
+ && SysUINavigationMode.INSTANCE.get(context).getMode() != NO_BUTTON) {
Rect targetInsets = dp.getInsets();
int hotseatInset = dp.isSeascape() ? targetInsets.left : targetInsets.right;
return dp.hotseatBarSizePx + hotseatInset;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/OtherActivityInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/OtherActivityInputConsumer.java
index c8dcf8068..63c2e5dd4 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/OtherActivityInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/OtherActivityInputConsumer.java
@@ -24,6 +24,7 @@ import static android.view.MotionEvent.INVALID_POINTER_ID;
import static com.android.launcher3.util.RaceConditionTracker.ENTER;
import static com.android.launcher3.util.RaceConditionTracker.EXIT;
import static com.android.launcher3.Utilities.EDGE_NAV_BAR;
+import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
import static com.android.quickstep.TouchInteractionService.TOUCH_INTERACTION_LOG;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
@@ -284,11 +285,13 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
}
private boolean isNavBarOnRight() {
- return mDisplayRotation == Surface.ROTATION_90 && mStableInsets.right > 0;
+ return SysUINavigationMode.INSTANCE.get(getBaseContext()).getMode() != NO_BUTTON
+ && mDisplayRotation == Surface.ROTATION_90 && mStableInsets.right > 0;
}
private boolean isNavBarOnLeft() {
- return mDisplayRotation == Surface.ROTATION_270 && mStableInsets.left > 0;
+ return SysUINavigationMode.INSTANCE.get(getBaseContext()).getMode() != NO_BUTTON
+ && mDisplayRotation == Surface.ROTATION_270 && mStableInsets.left > 0;
}
private void startTouchTrackingForWindowAnimation(long touchTimeMs) {
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
index 10180f586..b1db78083 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -203,6 +203,11 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
private static final long SHELF_ANIM_DURATION = 120;
+ /**
+ * Used as the page index for logging when we return to the last task at the end of the gesture.
+ */
+ private static final int LOG_NO_OP_PAGE_INDEX = -1;
+
private final ClipAnimationHelper mClipAnimationHelper;
private final ClipAnimationHelper.TransformParams mTransformParams;
@@ -245,6 +250,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
private boolean mPassedOverviewThreshold;
private boolean mGestureStarted;
private int mLogAction = Touch.SWIPE;
+ private int mLogDirection = Direction.UP;
private final RecentsAnimationWrapper mRecentsAnimationWrapper;
@@ -692,6 +698,12 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
setStateOnUiThread(STATE_GESTURE_COMPLETED);
mLogAction = isFling ? Touch.FLING : Touch.SWIPE;
+ boolean isVelocityVertical = Math.abs(velocity.y) > Math.abs(velocity.x);
+ if (isVelocityVertical) {
+ mLogDirection = velocity.y < 0 ? Direction.UP : Direction.DOWN;
+ } else {
+ mLogDirection = velocity.x < 0 ? Direction.LEFT : Direction.RIGHT;
+ }
handleNormalGestureEnd(endVelocity, isFling, velocity);
}
@@ -824,19 +836,15 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
// We probably never received an animation controller, skip logging.
return;
}
- boolean toLauncher = endTarget.isLauncher;
- final int direction;
- if (dp.isVerticalBarLayout()) {
- direction = (dp.isSeascape() ^ toLauncher) ? Direction.LEFT : Direction.RIGHT;
- } else {
- direction = toLauncher ? Direction.UP : Direction.DOWN;
- }
+ int pageIndex = endTarget == LAST_TASK
+ ? LOG_NO_OP_PAGE_INDEX
+ : mRecentsView.getNextPage();
UserEventDispatcher.newInstance(mContext).logStateChangeAction(
- mLogAction, direction,
+ mLogAction, mLogDirection,
ContainerType.NAVBAR, ContainerType.APP,
endTarget.containerType,
- 0);
+ pageIndex);
}
/** Animates to the given progress, where 0 is the current app and 1 is overview. */
diff --git a/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java b/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java
index 8633b21a1..f5ac9c94e 100644
--- a/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java
+++ b/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java
@@ -17,7 +17,6 @@
package com.android.quickstep;
import static androidx.test.InstrumentationRegistry.getInstrumentation;
-
import static com.android.quickstep.NavigationModeSwitchRule.Mode.ALL;
import static com.android.quickstep.NavigationModeSwitchRule.Mode.THREE_BUTTON;
import static com.android.quickstep.NavigationModeSwitchRule.Mode.TWO_BUTTON;
@@ -27,22 +26,17 @@ import static com.android.systemui.shared.system.QuickStepContract.NAV_BAR_MODE_
import android.content.Context;
import android.util.Log;
-
import androidx.test.uiautomator.UiDevice;
-
import com.android.launcher3.tapl.LauncherInstrumentation;
import com.android.launcher3.tapl.TestHelpers;
-import com.android.systemui.shared.system.QuickStepContract;
-
-import org.junit.Assert;
-import org.junit.rules.TestRule;
-import org.junit.runner.Description;
-import org.junit.runners.model.Statement;
-
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
+import org.junit.Assert;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
/**
* Test rule that allows executing a test with Quickstep on and then Quickstep off.
@@ -78,9 +72,9 @@ public class NavigationModeSwitchRule implements TestRule {
@Override
public void evaluate() throws Throwable {
final Context context = getInstrumentation().getContext();
- final String prevOverlayPkg = QuickStepContract.isGesturalMode(context)
+ final String prevOverlayPkg = LauncherInstrumentation.isGesturalMode(context)
? NAV_BAR_MODE_GESTURAL_OVERLAY
- : QuickStepContract.isSwipeUpMode(context)
+ : LauncherInstrumentation.isSwipeUpMode(context)
? NAV_BAR_MODE_2BUTTON_OVERLAY
: NAV_BAR_MODE_3BUTTON_OVERLAY;
final LauncherInstrumentation.NavigationModel originalMode =
diff --git a/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java b/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java
index 554aef4b7..dc83e8763 100644
--- a/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java
+++ b/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java
@@ -96,6 +96,7 @@ public class StartLauncherViaGestureTests extends AbstractQuickStepTest {
}
@Test
+ @Ignore // b/129723135
@NavigationModeSwitch
public void testStressSwipeToOverview() {
for (int i = 0; i < STRESS_REPEAT_COUNT; ++i) {
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 7bb60714f..dc275161d 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -131,6 +131,7 @@ public class LauncherAppState {
if ((changeFlags & CHANGE_FLAG_ICON_PARAMS) != 0) {
LauncherIcons.clearPool();
mIconCache.updateIconParams(idp.fillResIconDpi, idp.iconBitmapSize);
+ mWidgetCache.refresh();
}
mModel.forceReload();
diff --git a/src/com/android/launcher3/LauncherStateManager.java b/src/com/android/launcher3/LauncherStateManager.java
index 5f7538b40..5b654d8f3 100644
--- a/src/com/android/launcher3/LauncherStateManager.java
+++ b/src/com/android/launcher3/LauncherStateManager.java
@@ -17,6 +17,7 @@
package com.android.launcher3;
import static android.view.View.VISIBLE;
+
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.LauncherState.OVERVIEW_PEEK;
@@ -29,7 +30,6 @@ import static com.android.launcher3.anim.Interpolators.ACCEL;
import static com.android.launcher3.anim.Interpolators.DEACCEL;
import static com.android.launcher3.anim.Interpolators.DEACCEL_1_7;
import static com.android.launcher3.anim.Interpolators.INSTANT;
-import static com.android.launcher3.anim.Interpolators.NEVER;
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2;
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_7;
import static com.android.launcher3.anim.Interpolators.clampToProgress;
@@ -41,6 +41,8 @@ import android.animation.AnimatorSet;
import android.os.Handler;
import android.os.Looper;
+import androidx.annotation.IntDef;
+
import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.AnimatorSetBuilder;
@@ -52,8 +54,6 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
-import androidx.annotation.IntDef;
-
/**
* TODO: figure out what kind of tests we can write for this
*
@@ -326,7 +326,8 @@ public class LauncherStateManager {
} else if (fromState == NORMAL && toState == OVERVIEW_PEEK) {
builder.setInterpolator(ANIM_OVERVIEW_FADE, INSTANT);
} else if (fromState == OVERVIEW_PEEK && toState == NORMAL) {
- builder.setInterpolator(ANIM_OVERVIEW_FADE, NEVER);
+ // Keep fully visible until the very end (when overview is offscreen) to make invisible.
+ builder.setInterpolator(ANIM_OVERVIEW_FADE, t -> t < 1 ? 0 : 1);
}
}
diff --git a/src/com/android/launcher3/TestProtocol.java b/src/com/android/launcher3/TestProtocol.java
index 49a736eed..7d3715ef1 100644
--- a/src/com/android/launcher3/TestProtocol.java
+++ b/src/com/android/launcher3/TestProtocol.java
@@ -33,6 +33,27 @@ public final class TestProtocol {
public static final int ALL_APPS_STATE_ORDINAL = 5;
public static final int BACKGROUND_APP_STATE_ORDINAL = 6;
+ public static String stateOrdinalToString(int ordinal) {
+ switch (ordinal) {
+ case NORMAL_STATE_ORDINAL:
+ return "Normal";
+ case SPRING_LOADED_STATE_ORDINAL:
+ return "SpringLoaded";
+ case OVERVIEW_STATE_ORDINAL:
+ return "Overview";
+ case OVERVIEW_PEEK_STATE_ORDINAL:
+ return "OverviewPeek";
+ case QUICK_SWITCH_STATE_ORDINAL:
+ return "QuickSwitch";
+ case ALL_APPS_STATE_ORDINAL:
+ return "AllApps";
+ case BACKGROUND_APP_STATE_ORDINAL:
+ return "Background";
+ default:
+ return null;
+ }
+ }
+
public static final String TEST_INFO_RESPONSE_FIELD = "response";
public static final String REQUEST_HOME_TO_OVERVIEW_SWIPE_HEIGHT =
"home-to-overview-swipe-height";
diff --git a/src/com/android/launcher3/WidgetPreviewLoader.java b/src/com/android/launcher3/WidgetPreviewLoader.java
index 050849cc2..6d1bc1a9c 100644
--- a/src/com/android/launcher3/WidgetPreviewLoader.java
+++ b/src/com/android/launcher3/WidgetPreviewLoader.java
@@ -24,6 +24,7 @@ import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.CancellationSignal;
import android.os.Handler;
+import android.os.Process;
import android.os.UserHandle;
import android.util.Log;
import android.util.LongSparseArray;
@@ -73,7 +74,6 @@ public class WidgetPreviewLoader {
private final Context mContext;
private final IconCache mIconCache;
private final UserManagerCompat mUserManager;
- private final AppWidgetManagerCompat mWidgetManager;
private final CacheDb mDb;
private final MainThreadExecutor mMainThreadExecutor = new MainThreadExecutor();
@@ -82,7 +82,6 @@ public class WidgetPreviewLoader {
public WidgetPreviewLoader(Context context, IconCache iconCache) {
mContext = context;
mIconCache = iconCache;
- mWidgetManager = AppWidgetManagerCompat.getInstance(context);
mUserManager = UserManagerCompat.getInstance(context);
mDb = new CacheDb(context);
mWorkerHandler = new Handler(LauncherModel.getWorkerLooper());
@@ -107,6 +106,10 @@ public class WidgetPreviewLoader {
return signal;
}
+ public void refresh() {
+ mDb.clear();
+
+ }
/**
* The DB holds the generated previews for various components. Previews can also have different
* sizes (landscape vs portrait).
@@ -474,8 +477,9 @@ public class WidgetPreviewLoader {
RectF boxRect = drawBoxWithShadow(c, size, size);
LauncherIcons li = LauncherIcons.obtain(mContext);
- Bitmap icon = li.createScaledBitmapWithoutShadow(
- mutateOnMainThread(info.getFullResIcon(mIconCache)), 0);
+ Bitmap icon = li.createBadgedIconBitmap(
+ mutateOnMainThread(info.getFullResIcon(mIconCache)),
+ Process.myUserHandle(), 0).icon;
li.recycle();
Rect src = new Rect(0, 0, icon.getWidth(), icon.getHeight());
diff --git a/src/com/android/launcher3/anim/Interpolators.java b/src/com/android/launcher3/anim/Interpolators.java
index 217b6db2c..b169cb80b 100644
--- a/src/com/android/launcher3/anim/Interpolators.java
+++ b/src/com/android/launcher3/anim/Interpolators.java
@@ -58,7 +58,6 @@ public class Interpolators {
public static final Interpolator EXAGGERATED_EASE;
public static final Interpolator INSTANT = t -> 1;
- public static final Interpolator NEVER = t -> 0;
private static final int MIN_SETTLE_DURATION = 200;
private static final float OVERSHOOT_FACTOR = 0.9f;
diff --git a/src/com/android/launcher3/logging/LoggerUtils.java b/src/com/android/launcher3/logging/LoggerUtils.java
index 4ef86265f..d208077d5 100644
--- a/src/com/android/launcher3/logging/LoggerUtils.java
+++ b/src/com/android/launcher3/logging/LoggerUtils.java
@@ -15,7 +15,8 @@
*/
package com.android.launcher3.logging;
-import android.content.Context;
+import static com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType.NAVBAR;
+
import android.util.ArrayMap;
import android.util.SparseArray;
import android.view.View;
@@ -97,7 +98,8 @@ public class LoggerUtils {
case Target.Type.CONTAINER:
str = getFieldName(t.containerType, ContainerType.class);
if (t.containerType == ContainerType.WORKSPACE ||
- t.containerType == ContainerType.HOTSEAT) {
+ t.containerType == ContainerType.HOTSEAT ||
+ t.containerType == NAVBAR) {
str += " id=" + t.pageIndex;
} else if (t.containerType == ContainerType.FOLDER) {
str += " grid(" + t.gridX + "," + t.gridY+ ")";
diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
index c403e76ee..0274de35c 100644
--- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
+++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
@@ -224,7 +224,8 @@ public abstract class AbstractStateChangeTouchController
return true;
}
- private boolean goingBetweenNormalAndOverview(LauncherState fromState, LauncherState toState) {
+ protected boolean goingBetweenNormalAndOverview(LauncherState fromState,
+ LauncherState toState) {
return (fromState == NORMAL || fromState == OVERVIEW)
&& (toState == NORMAL || toState == OVERVIEW)
&& mPendingAnimation == null;
@@ -242,7 +243,7 @@ public abstract class AbstractStateChangeTouchController
mStartContainerType = LauncherLogProto.ContainerType.ALLAPPS;
} else if (mStartState == NORMAL) {
mStartContainerType = getLogContainerTypeForNormalState();
- } else if (mStartState == OVERVIEW){
+ } else if (mStartState == OVERVIEW){
mStartContainerType = LauncherLogProto.ContainerType.TASKSWITCHER;
}
if (mCurrentAnimation == null) {
diff --git a/src/com/android/launcher3/widget/WidgetsRecyclerView.java b/src/com/android/launcher3/widget/WidgetsRecyclerView.java
index 641183a01..c15557beb 100644
--- a/src/com/android/launcher3/widget/WidgetsRecyclerView.java
+++ b/src/com/android/launcher3/widget/WidgetsRecyclerView.java
@@ -56,11 +56,6 @@ public class WidgetsRecyclerView extends BaseRecyclerView implements OnItemTouch
addOnItemTouchListener(this);
}
- public WidgetsRecyclerView(Context context, AttributeSet attrs, int defStyleAttr,
- int defStyleRes) {
- this(context, attrs, defStyleAttr);
- }
-
@Override
protected void onFinishInflate() {
super.onFinishInflate();
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 00257a5d1..a4b417192 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -16,27 +16,26 @@
package com.android.launcher3.tapl;
-import static com.android.launcher3.TestProtocol.BACKGROUND_APP_STATE_ORDINAL;
-
import android.app.ActivityManager;
import android.app.Instrumentation;
import android.app.UiAutomation;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.content.res.Resources;
import android.graphics.Point;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcelable;
import android.os.SystemClock;
+import android.text.TextUtils;
import android.util.Log;
import android.view.InputDevice;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.ViewConfiguration;
import android.view.accessibility.AccessibilityEvent;
-
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.test.uiautomator.By;
@@ -45,18 +44,15 @@ import androidx.test.uiautomator.Configurator;
import androidx.test.uiautomator.UiDevice;
import androidx.test.uiautomator.UiObject2;
import androidx.test.uiautomator.Until;
-
import com.android.launcher3.TestProtocol;
import com.android.systemui.shared.system.QuickStepContract;
-
-import org.junit.Assert;
-
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeoutException;
+import org.junit.Assert;
/**
* The main tapl object. The only object that can be explicitly constructed by the using code. It
@@ -65,6 +61,8 @@ import java.util.concurrent.TimeoutException;
public final class LauncherInstrumentation {
private static final String TAG = "Tapl";
+ private static final String NAV_BAR_INTERACTION_MODE_RES_NAME =
+ "config_navBarInteractionMode";
private static final int ZERO_BUTTON_STEPS_FROM_BACKGROUND_TO_HOME = 20;
// Types for launcher containers that the user is interacting with. "Background" is a
@@ -171,11 +169,11 @@ public final class LauncherInstrumentation {
// Workaround, use constructed context because both the instrumentation context and the
// app context are not constructed with resources that take overlays into account
final Context ctx = baseContext.createPackageContext("android", 0);
- if (QuickStepContract.isGesturalMode(ctx)) {
+ if (isGesturalMode(ctx)) {
return NavigationModel.ZERO_BUTTON;
- } else if (QuickStepContract.isSwipeUpMode(ctx)) {
+ } else if (isSwipeUpMode(ctx)) {
return NavigationModel.TWO_BUTTON;
- } else if (QuickStepContract.isLegacyMode(ctx)) {
+ } else if (isLegacyMode(ctx)) {
return NavigationModel.THREE_BUTTON;
} else {
fail("Can't detect navigation mode");
@@ -225,6 +223,12 @@ public final class LauncherInstrumentation {
}
}
+ private void assertEquals(String message, String expected, String actual) {
+ if (!TextUtils.equals(expected, actual)) {
+ fail(message + " expected: '" + expected + "' but was: '" + actual + "'");
+ }
+ }
+
void assertNotEquals(String message, int unexpected, int actual) {
if (unexpected == actual) {
failEquals(message, actual);
@@ -539,8 +543,9 @@ public final class LauncherInstrumentation {
event -> TestProtocol.SWITCHED_TO_STATE_MESSAGE.equals(event.getClassName()),
"Swipe failed to receive an event for the swipe end: " + startX + ", " + startY
+ ", " + endX + ", " + endY);
- assertEquals("Swipe switched launcher to a wrong state",
- expectedState, parcel.getInt(TestProtocol.STATE_FIELD));
+ assertEquals("Swipe switched launcher to a wrong state;",
+ TestProtocol.stateOrdinalToString(expectedState),
+ TestProtocol.stateOrdinalToString(parcel.getInt(TestProtocol.STATE_FIELD)));
}
void waitForIdle() {
@@ -595,6 +600,33 @@ public final class LauncherInstrumentation {
}
}
+ public static boolean isGesturalMode(Context context) {
+ return QuickStepContract.isGesturalMode(
+ getSystemIntegerRes(context, NAV_BAR_INTERACTION_MODE_RES_NAME));
+ }
+
+ public static boolean isSwipeUpMode(Context context) {
+ return QuickStepContract.isSwipeUpMode(
+ getSystemIntegerRes(context, NAV_BAR_INTERACTION_MODE_RES_NAME));
+ }
+
+ public static boolean isLegacyMode(Context context) {
+ return QuickStepContract.isLegacyMode(
+ getSystemIntegerRes(context, NAV_BAR_INTERACTION_MODE_RES_NAME));
+ }
+
+ private static int getSystemIntegerRes(Context context, String resName) {
+ Resources res = context.getResources();
+ int resId = res.getIdentifier(resName, "integer", "android");
+
+ if (resId != 0) {
+ return res.getInteger(resId);
+ } else {
+ Log.e(TAG, "Failed to get system resource ID. Incompatible framework version?");
+ return -1;
+ }
+ }
+
static void sleep(int duration) {
try {
Thread.sleep(duration);