summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java6
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java9
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java3
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java8
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java3
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityControllerHelper.java30
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java5
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java9
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java40
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java48
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java32
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java69
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/InputConsumer.java3
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java28
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java8
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewWithoutFocusInputConsumer.java151
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/util/NavBarPosition.java55
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java22
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java21
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java55
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskMenuView.java3
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java31
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java15
-rw-r--r--quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java2
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/UiFactory.java13
-rw-r--r--quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java11
-rw-r--r--src/com/android/launcher3/Launcher.java5
-rw-r--r--src/com/android/launcher3/LauncherState.java3
-rw-r--r--src/com/android/launcher3/Workspace.java4
-rw-r--r--src/com/android/launcher3/WorkspaceStateTransitionAnimation.java5
-rw-r--r--src/com/android/launcher3/states/RotationHelper.java9
-rw-r--r--src/com/android/launcher3/testing/TestProtocol.java1
-rw-r--r--src/com/android/launcher3/util/TraceHelper.java7
-rw-r--r--src/com/android/launcher3/views/FloatingIconView.java10
-rw-r--r--src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java3
-rw-r--r--tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java59
-rw-r--r--tests/src/com/android/launcher3/util/rule/FailureWatcher.java59
-rw-r--r--tests/tapl/com/android/launcher3/tapl/Background.java2
38 files changed, 658 insertions, 189 deletions
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
index 1042c60b8..eac4dce18 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
@@ -121,12 +121,16 @@ public final class LauncherAppTransitionManagerImpl extends QuickstepAppTransiti
alpha.setDuration(CONTENT_ALPHA_DURATION);
alpha.setInterpolator(LINEAR);
anim.play(alpha);
+ overview.setFreezeViewVisibility(true);
ObjectAnimator transY = ObjectAnimator.ofFloat(overview, View.TRANSLATION_Y, trans);
transY.setInterpolator(AGGRESSIVE_EASE);
transY.setDuration(CONTENT_TRANSLATION_DURATION);
anim.play(transY);
- return mLauncher.getStateManager()::reapplyState;
+ return () -> {
+ overview.setFreezeViewVisibility(false);
+ mLauncher.getStateManager().reapplyState();
+ };
}
}
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 336cdc93f..d84362c9f 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
@@ -205,15 +205,6 @@ public abstract class RecentsUiFactory {
}
/**
- * Clean-up logic that occurs when recents is no longer in use/visible.
- *
- * @param launcher the launcher activity
- */
- public static void resetOverview(Launcher launcher) {
- launcher.<RecentsView>getOverviewPanel().reset();
- }
-
- /**
* Recents logic that triggers when launcher state changes or launcher activity stops/resumes.
*
* @param launcher the launcher activity
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
index 8436fe5f9..f1d6450a5 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
@@ -21,7 +21,6 @@ import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.Launcher;
import com.android.launcher3.allapps.AllAppsTransitionController;
import com.android.launcher3.userevent.nano.LauncherLogProto;
-import com.android.quickstep.util.ClipAnimationHelper;
import com.android.quickstep.util.LayoutUtils;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
@@ -45,8 +44,6 @@ public class BackgroundAppState extends OverviewState {
@Override
public void onStateEnabled(Launcher launcher) {
- RecentsView rv = launcher.getOverviewPanel();
- rv.setOverviewStateEnabled(true);
AbstractFloatingView.closeAllOpenViews(launcher, false);
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java
index cda03dcde..9a99c1552 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java
@@ -86,18 +86,10 @@ public class OverviewState extends LauncherState {
@Override
public void onStateEnabled(Launcher launcher) {
- RecentsView rv = launcher.getOverviewPanel();
- rv.setOverviewStateEnabled(true);
AbstractFloatingView.closeAllOpenViews(launcher);
}
@Override
- public void onStateDisabled(Launcher launcher) {
- RecentsView rv = launcher.getOverviewPanel();
- rv.setOverviewStateEnabled(false);
- }
-
- @Override
public void onStateTransitionEnd(Launcher launcher) {
launcher.getRotationHelper().setCurrentStateRequest(REQUEST_ROTATE);
DiscoveryBounce.showForOverviewIfNeeded(launcher);
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
index a6c444561..d66af1ae2 100644
--- 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
@@ -98,9 +98,6 @@ public class NavBarToHomeTouchController implements TouchController, SwipeDetect
if (mStartState == OVERVIEW || mStartState == ALL_APPS) {
return true;
}
- if (!mLauncher.hasWindowFocus()) {
- return true;
- }
if (AbstractFloatingView.getTopOpenView(mLauncher) != null) {
return true;
}
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 dc58a4efc..2c42fd63a 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityControllerHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityControllerHelper.java
@@ -17,6 +17,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.fallback.FallbackRecentsView.ZOOM_PROGRESS;
import static com.android.quickstep.views.RecentsView.CONTENT_ALPHA;
import android.animation.Animator;
@@ -33,6 +34,7 @@ import com.android.launcher3.DeviceProfile;
import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.userevent.nano.LauncherLogProto;
+import com.android.quickstep.fallback.FallbackRecentsView;
import com.android.quickstep.util.LayoutUtils;
import com.android.quickstep.util.RemoteAnimationTargetSet;
import com.android.quickstep.views.RecentsView;
@@ -120,11 +122,14 @@ public final class FallbackActivityControllerHelper implements
return (transitionLength) -> { };
}
- RecentsView rv = activity.getOverviewPanel();
+ FallbackRecentsView rv = activity.getOverviewPanel();
rv.setContentAlpha(0);
rv.getClearAllButton().setVisibilityAlpha(0);
rv.setDisallowScrollToClearAll(true);
+ boolean fromState = !animateActivity;
+ rv.setInOverviewState(fromState);
+
return new AnimationFactory() {
boolean isAnimatingToRecents = false;
@@ -141,15 +146,28 @@ public final class FallbackActivityControllerHelper implements
@Override
public void createActivityController(long transitionLength) {
- if (!isAnimatingToRecents) {
- return;
+ AnimatorSet animatorSet = new AnimatorSet();
+ if (isAnimatingToRecents) {
+ ObjectAnimator anim = ObjectAnimator.ofFloat(rv, CONTENT_ALPHA, 0, 1);
+ anim.setDuration(transitionLength).setInterpolator(LINEAR);
+ animatorSet.play(anim);
}
- ObjectAnimator anim = ObjectAnimator.ofFloat(rv, CONTENT_ALPHA, 0, 1);
+ ObjectAnimator anim = ObjectAnimator.ofFloat(rv, ZOOM_PROGRESS, 1, 0);
anim.setDuration(transitionLength).setInterpolator(LINEAR);
- AnimatorSet animatorSet = new AnimatorSet();
animatorSet.play(anim);
- callback.accept(AnimatorPlaybackController.wrap(animatorSet, transitionLength));
+
+ AnimatorPlaybackController controller =
+ AnimatorPlaybackController.wrap(animatorSet, transitionLength);
+
+ // Since we are changing the start position of the UI, reapply the state, at the end
+ controller.setEndAction(() -> {
+ boolean endState = true;
+ rv.setInOverviewState(controller.getInterpolatedProgress() > 0.5 ?
+ endState : fromState);
+ });
+
+ callback.accept(controller);
}
};
}
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 d0a41f3b5..1b82bcb57 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
@@ -36,6 +36,7 @@ import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region;
import android.os.UserHandle;
+import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Interpolator;
@@ -53,6 +54,7 @@ import com.android.launcher3.allapps.DiscoveryBounce;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.SpringObjectAnimator;
import com.android.launcher3.compat.AccessibilityManagerCompat;
+import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.views.FloatingIconView;
import com.android.quickstep.SysUINavigationMode.Mode;
@@ -174,6 +176,9 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe
@Override
public AnimationFactory prepareRecentsUI(Launcher activity, boolean activityVisible,
boolean animateActivity, Consumer<AnimatorPlaybackController> callback) {
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "prepareRecentsUI");
+ }
final LauncherState startState = activity.getStateManager().getState();
LauncherState resetState = startState;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java
index 5decc3ed6..32a92618a 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java
@@ -125,7 +125,14 @@ public final class RecentsActivity extends BaseRecentsActivity {
@Override
public void onCreateAnimation(RemoteAnimationTargetCompat[] targetCompats,
AnimationResult result) {
- result.setAnimation(composeRecentsLaunchAnimator(taskView, targetCompats));
+ AnimatorSet anim = composeRecentsLaunchAnimator(taskView, targetCompats);
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mFallbackRecentsView.resetViewUI();
+ }
+ });
+ result.setAnimation(anim);
}
};
return ActivityOptionsCompat.makeRemoteAnimation(new RemoteAnimationAdapterCompat(
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java
index 84af109a3..5104fb880 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java
@@ -36,8 +36,6 @@ import java.util.List;
*/
public class TaskOverlayFactory implements ResourceBasedOverride {
- public static final String AIAI_PACKAGE = "com.google.android.as";
-
/** Note that these will be shown in order from top to bottom, if available for the task. */
private static final TaskSystemShortcut[] MENU_OPTIONS = new TaskSystemShortcut[]{
new TaskSystemShortcut.AppInfo(),
@@ -51,29 +49,33 @@ public class TaskOverlayFactory implements ResourceBasedOverride {
new MainThreadInitializedObject<>(c -> Overrides.getObject(TaskOverlayFactory.class,
c, R.string.task_overlay_factory_class));
+ public List<TaskSystemShortcut> getEnabledShortcuts(TaskView taskView) {
+ final ArrayList<TaskSystemShortcut> shortcuts = new ArrayList<>();
+ final BaseDraggingActivity activity = BaseActivity.fromContext(taskView.getContext());
+ for (TaskSystemShortcut menuOption : MENU_OPTIONS) {
+ View.OnClickListener onClickListener =
+ menuOption.getOnClickListener(activity, taskView);
+ if (onClickListener != null) {
+ shortcuts.add(menuOption);
+ }
+ }
+ return shortcuts;
+ }
+
public TaskOverlay createOverlay(View thumbnailView) {
return new TaskOverlay();
}
public static class TaskOverlay {
- public void setTaskInfo(Task task, ThumbnailData thumbnail, Matrix matrix) {
- }
-
- public void reset() {
- }
+ /**
+ * Called when the current task is interactive for the user
+ */
+ public void initOverlay(Task task, ThumbnailData thumbnail, Matrix matrix) { }
- public List<TaskSystemShortcut> getEnabledShortcuts(TaskView taskView) {
- final ArrayList<TaskSystemShortcut> shortcuts = new ArrayList<>();
- final BaseDraggingActivity activity = BaseActivity.fromContext(taskView.getContext());
- for (TaskSystemShortcut menuOption : MENU_OPTIONS) {
- View.OnClickListener onClickListener =
- menuOption.getOnClickListener(activity, taskView);
- if (onClickListener != null) {
- shortcuts.add(menuOption);
- }
- }
- return shortcuts;
- }
+ /**
+ * Called when the overlay is no longer used.
+ */
+ public void reset() { }
}
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
index 294a997f3..dc354404a 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
@@ -27,6 +27,8 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_N
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED;
import android.annotation.TargetApi;
import android.app.ActivityManager;
@@ -60,6 +62,7 @@ import android.view.WindowManager;
import androidx.annotation.BinderThread;
+import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.MainThreadExecutor;
import com.android.launcher3.R;
import com.android.launcher3.ResourceUtils;
@@ -77,6 +80,7 @@ import com.android.quickstep.inputconsumers.DeviceLockedInputConsumer;
import com.android.quickstep.inputconsumers.InputConsumer;
import com.android.quickstep.inputconsumers.OtherActivityInputConsumer;
import com.android.quickstep.inputconsumers.OverviewInputConsumer;
+import com.android.quickstep.inputconsumers.OverviewWithoutFocusInputConsumer;
import com.android.quickstep.inputconsumers.ScreenPinnedInputConsumer;
import com.android.systemui.shared.recents.IOverviewProxy;
import com.android.systemui.shared.recents.ISystemUiProxy;
@@ -543,9 +547,11 @@ public class TouchInteractionService extends Service implements
if (!useSharedState) {
mSwipeSharedState.clearAllState();
}
- if (mKM.isDeviceLocked()) {
+ if ((mSystemUiStateFlags & SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED) != 0
+ || mKM.isDeviceLocked()) {
// This handles apps launched in direct boot mode (e.g. dialer) as well as apps launched
- // while device is locked even after exiting direct boot mode (e.g. camera).
+ // while device is locked after exiting direct boot mode (e.g. camera), or if the
+ // app is showing over the lockscreen (even if not locked)
return createDeviceLockedInputConsumer(runningTaskInfo);
}
@@ -562,10 +568,9 @@ public class TouchInteractionService extends Service implements
info.id = mSwipeSharedState.nextRunningTaskId;
return createOtherActivityInputConsumer(event, info);
} else if (mSwipeSharedState.goingToLauncher || activityControl.isResumed()) {
- return OverviewInputConsumer.newInstance(activityControl, mInputMonitorCompat, false);
- } else if (ENABLE_QUICKSTEP_LIVE_TILE.get() &&
- activityControl.isInLiveTileMode()) {
- return OverviewInputConsumer.newInstance(activityControl, mInputMonitorCompat, false);
+ return createOverviewInputConsumer(event);
+ } else if (ENABLE_QUICKSTEP_LIVE_TILE.get() && activityControl.isInLiveTileMode()) {
+ return createOverviewInputConsumer(event);
} else if (mGestureBlockingActivity != null && runningTaskInfo != null
&& mGestureBlockingActivity.equals(runningTaskInfo.topActivity)) {
return InputConsumer.NO_OP;
@@ -574,20 +579,24 @@ public class TouchInteractionService extends Service implements
}
}
+ private boolean disableHorizontalSwipe(MotionEvent event) {
+ // mExclusionRegion can change on binder thread, use a local instance here.
+ Region exclusionRegion = mExclusionRegion;
+ return mMode == Mode.NO_BUTTON && exclusionRegion != null
+ && exclusionRegion.contains((int) event.getX(), (int) event.getY());
+ }
+
private OtherActivityInputConsumer createOtherActivityInputConsumer(MotionEvent event,
RunningTaskInfo runningTaskInfo) {
final ActivityControlHelper activityControl =
mOverviewComponentObserver.getActivityControlHelper();
boolean shouldDefer = activityControl.deferStartingActivity(mActiveNavBarRegion, event);
- // mExclusionRegion can change on binder thread, use a local instance here.
- Region exclusionRegion = mExclusionRegion;
- boolean disableHorizontalSwipe = mMode == Mode.NO_BUTTON && exclusionRegion != null
- && exclusionRegion.contains((int) event.getX(), (int) event.getY());
return new OtherActivityInputConsumer(this, runningTaskInfo, mRecentsModel,
mOverviewComponentObserver.getOverviewIntent(), activityControl,
shouldDefer, mOverviewCallbacks, mInputConsumer, this::onConsumerInactive,
- mSwipeSharedState, mInputMonitorCompat, mSwipeTouchRegion, disableHorizontalSwipe);
+ mSwipeSharedState, mInputMonitorCompat, mSwipeTouchRegion,
+ disableHorizontalSwipe(event));
}
private InputConsumer createDeviceLockedInputConsumer(RunningTaskInfo taskInfo) {
@@ -599,6 +608,23 @@ public class TouchInteractionService extends Service implements
}
}
+ public InputConsumer createOverviewInputConsumer(MotionEvent event) {
+ final ActivityControlHelper activityControl =
+ mOverviewComponentObserver.getActivityControlHelper();
+ BaseDraggingActivity activity = activityControl.getCreatedActivity();
+ if (activity == null) {
+ return InputConsumer.NO_OP;
+ }
+
+ if (activity.getRootView().hasWindowFocus()) {
+ return new OverviewInputConsumer(activity, mInputMonitorCompat,
+ false /* startingInActivityBounds */);
+ } else {
+ return new OverviewWithoutFocusInputConsumer(this, mInputMonitorCompat,
+ disableHorizontalSwipe(event));
+ }
+ }
+
/**
* To be called by the consumer when it's no longer active.
*/
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 87b732664..c7841d98e 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -59,6 +59,7 @@ import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.os.SystemClock;
+import android.util.Log;
import android.view.HapticFeedbackConstants;
import android.view.MotionEvent;
import android.view.View;
@@ -83,6 +84,7 @@ import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.graphics.RotationMode;
import com.android.launcher3.logging.UserEventDispatcher;
+import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
@@ -267,6 +269,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
private MultiStateCallback mStateCallback;
// Used to control launcher components throughout the swipe gesture.
private AnimatorPlaybackController mLauncherTransitionController;
+ private boolean mHasLauncherTransitionControllerStarted;
private T mActivity;
private RecentsView mRecentsView;
@@ -457,17 +460,32 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
}
private void onLauncherStart(final T activity) {
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "onLauncherStart");
+ }
if (mActivity != activity) {
return;
}
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "onLauncherStart 1");
+ }
if (mStateCallback.hasStates(STATE_HANDLER_INVALIDATED)) {
return;
}
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "onLauncherStart 2");
+ }
// If we've already ended the gesture and are going home, don't prepare recents UI,
// as that will set the state as BACKGROUND_APP, overriding the animation to NORMAL.
if (mGestureEndTarget != HOME) {
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "onLauncherStart 3");
+ }
Runnable initAnimFactory = () -> {
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "onLauncherStart 4");
+ }
mAnimationFactory = mActivityControlHelper.prepareRecentsUI(mActivity,
mWasLauncherAlreadyVisible, true,
this::onAnimatorPlaybackControllerCreated);
@@ -477,8 +495,14 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
// Launcher is visible, but might be about to stop. Thus, if we prepare recents
// now, it might get overridden by moveToRestState() in onStop(). To avoid this,
// wait until the next gesture (and possibly launcher) starts.
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "onLauncherStart 5");
+ }
mStateCallback.addCallback(STATE_GESTURE_STARTED, initAnimFactory);
} else {
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "onLauncherStart 6");
+ }
initAnimFactory.run();
}
}
@@ -647,8 +671,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
}
private void buildAnimationController() {
- if (mGestureEndTarget == HOME || (mLauncherTransitionController != null
- && mLauncherTransitionController.getAnimationPlayer().isStarted())) {
+ if (mGestureEndTarget == HOME || mHasLauncherTransitionControllerStarted) {
// We don't want a new mLauncherTransitionController if mGestureEndTarget == HOME (it
// has its own animation) or if we're already animating the current controller.
return;
@@ -858,7 +881,9 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
setTargetAlphaProvider(WindowTransformSwipeHandler::getHiddenTargetAlpha);
}
- return OverviewInputConsumer.newInstance(mActivityControlHelper, null, true);
+ BaseDraggingActivity activity = mActivityControlHelper.getCreatedActivity();
+ return activity == null
+ ? InputConsumer.NO_OP : new OverviewInputConsumer(activity, null, true);
}
private void endRunningWindowAnim() {
@@ -1122,6 +1147,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
}
mLauncherTransitionController.getAnimationPlayer().start();
}
+ mHasLauncherTransitionControllerStarted = true;
}
/**
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java
index e254e240a..c28761804 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -15,19 +15,45 @@
*/
package com.android.quickstep.fallback;
+import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
+
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.util.AttributeSet;
+import android.util.FloatProperty;
import android.view.View;
import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.LauncherState.ScaleAndTranslation;
+import com.android.launcher3.Utilities;
import com.android.quickstep.RecentsActivity;
import com.android.quickstep.util.LayoutUtils;
import com.android.quickstep.views.RecentsView;
+import com.android.quickstep.views.TaskView;
public class FallbackRecentsView extends RecentsView<RecentsActivity> {
+ public static final FloatProperty<FallbackRecentsView> ZOOM_PROGRESS =
+ new FloatProperty<FallbackRecentsView> ("zoomInProgress") {
+
+ @Override
+ public void setValue(FallbackRecentsView view, float value) {
+ view.setZoomProgress(value);
+ }
+
+ @Override
+ public Float get(FallbackRecentsView view) {
+ return view.mZoomInProgress;
+ }
+ };
+
+ private float mZoomInProgress = 0;
+ private boolean mInOverviewState = true;
+
+ private float mZoomScale = 1f;
+ private float mZoomTranslationY = 0f;
+
public FallbackRecentsView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
@@ -35,6 +61,7 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity> {
public FallbackRecentsView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setOverviewStateEnabled(true);
+ setOverlayEnabled(true);
}
@Override
@@ -70,4 +97,46 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity> {
// Just use the activity task size for multi-window as well.
return false;
}
+
+ public void resetViewUI() {
+ setZoomProgress(0);
+ resetTaskVisuals();
+ }
+
+ public void setInOverviewState(boolean inOverviewState) {
+ if (mInOverviewState != inOverviewState) {
+ mInOverviewState = inOverviewState;
+ if (mInOverviewState) {
+ resetTaskVisuals();
+ } else {
+ setZoomProgress(1);
+ }
+ }
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
+
+ if (getTaskViewCount() == 0) {
+ mZoomScale = 1f;
+ mZoomTranslationY = 0f;
+ } else {
+ TaskView dummyTask = getTaskViewAt(0);
+ ScaleAndTranslation sat = getTempClipAnimationHelper()
+ .updateForFullscreenOverview(dummyTask)
+ .getScaleAndTranslation();
+ mZoomScale = sat.scale;
+ mZoomTranslationY = sat.translationY;
+ }
+
+ setZoomProgress(mZoomInProgress);
+ }
+
+ public void setZoomProgress(float progress) {
+ mZoomInProgress = progress;
+ SCALE_PROPERTY.set(this, Utilities.mapRange(mZoomInProgress, 1, mZoomScale));
+ TRANSLATION_Y.set(this, Utilities.mapRange(mZoomInProgress, 0, mZoomTranslationY));
+ FULLSCREEN_PROGRESS.set(this, mZoomInProgress);
+ }
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/InputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/InputConsumer.java
index 6e7cb8fca..489eb278f 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/InputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/InputConsumer.java
@@ -31,6 +31,7 @@ public interface InputConsumer {
int TYPE_DEVICE_LOCKED = 1 << 4;
int TYPE_ACCESSIBILITY = 1 << 5;
int TYPE_SCREEN_PINNED = 1 << 6;
+ int TYPE_OVERVIEW_WITHOUT_FOCUS = 1 << 7;
InputConsumer NO_OP = () -> TYPE_NO_OP;
@@ -78,6 +79,8 @@ public interface InputConsumer {
return "ACCESSIBILITY";
case TYPE_SCREEN_PINNED:
return "SCREEN_PINNED";
+ case TYPE_OVERVIEW_WITHOUT_FOCUS:
+ return "TYPE_OVERVIEW_WITHOUT_FOCUS";
default:
return "NO_OP";
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
index 0ed4c99a6..69b25db8f 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
@@ -28,7 +28,6 @@ import static com.android.launcher3.uioverrides.RecentsUiFactory.ROTATION_LANDSC
import static com.android.launcher3.uioverrides.RecentsUiFactory.ROTATION_SEASCAPE;
import static com.android.launcher3.util.RaceConditionTracker.ENTER;
import static com.android.launcher3.util.RaceConditionTracker.EXIT;
-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;
@@ -43,10 +42,8 @@ import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.view.MotionEvent;
-import android.view.Surface;
import android.view.VelocityTracker;
import android.view.ViewConfiguration;
-import android.view.WindowManager;
import androidx.annotation.UiThread;
@@ -65,6 +62,7 @@ import com.android.quickstep.WindowTransformSwipeHandler;
import com.android.quickstep.WindowTransformSwipeHandler.GestureEndTarget;
import com.android.quickstep.util.CachedEventDispatcher;
import com.android.quickstep.util.MotionPauseDetector;
+import com.android.quickstep.util.NavBarPosition;
import com.android.quickstep.util.RecentsAnimationListenerSet;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.BackgroundExecutor;
@@ -95,7 +93,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
private final SysUINavigationMode.Mode mMode;
private final RectF mSwipeTouchRegion;
- private final int mDisplayRotation;
+ private final NavBarPosition mNavBarPosition;
private final Consumer<OtherActivityInputConsumer> mOnCompleteCallback;
private final MotionPauseDetector mMotionPauseDetector;
@@ -157,7 +155,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
mInputConsumer = inputConsumer;
mSwipeSharedState = swipeSharedState;
- mDisplayRotation = getSystemService(WindowManager.class).getDefaultDisplay().getRotation();
+ mNavBarPosition = new NavBarPosition(base);
mDragSlop = QuickStepContract.getQuickStepDragSlopPx();
float slop = QuickStepContract.getQuickStepTouchSlopPx();
mSquaredTouchSlop = slop * slop;
@@ -188,9 +186,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
if (mPassedDragSlop && mInteractionHandler != null
&& !mRecentsViewDispatcher.hasConsumer()) {
mRecentsViewDispatcher.setConsumer(mInteractionHandler.getRecentsViewDispatcher(
- isNavBarOnLeft()
- ? ROTATION_SEASCAPE
- : (isNavBarOnRight() ? ROTATION_LANDSCAPE : RotationMode.NORMAL)));
+ mNavBarPosition.getRotationMode()));
}
int edgeFlags = ev.getEdgeFlags();
ev.setEdgeFlags(edgeFlags | EDGE_NAV_BAR);
@@ -329,14 +325,6 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
mInteractionHandler.onGestureStarted();
}
- private boolean isNavBarOnRight() {
- return mMode != NO_BUTTON && mDisplayRotation == Surface.ROTATION_90;
- }
-
- private boolean isNavBarOnLeft() {
- return mMode != NO_BUTTON && mDisplayRotation == Surface.ROTATION_270;
- }
-
private void startTouchTrackingForWindowAnimation(long touchTimeMs) {
TOUCH_INTERACTION_LOG.addLog("startRecentsAnimation");
@@ -382,8 +370,8 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
ViewConfiguration.get(this).getScaledMaximumFlingVelocity());
float velocityX = mVelocityTracker.getXVelocity(mActivePointerId);
float velocityY = mVelocityTracker.getYVelocity(mActivePointerId);
- float velocity = isNavBarOnRight() ? velocityX
- : isNavBarOnLeft() ? -velocityX
+ float velocity = mNavBarPosition.isRightEdge() ? velocityX
+ : mNavBarPosition.isLeftEdge() ? -velocityX
: velocityY;
mInteractionHandler.updateDisplacement(getDisplacement(ev) - mStartDisplacement);
@@ -444,9 +432,9 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
}
private float getDisplacement(MotionEvent ev) {
- if (isNavBarOnRight()) {
+ if (mNavBarPosition.isRightEdge()) {
return ev.getX() - mDownPos.x;
- } else if (isNavBarOnLeft()) {
+ } else if (mNavBarPosition.isLeftEdge()) {
return mDownPos.x - ev.getX();
} else {
return ev.getY() - mDownPos.y;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
index bab3c71c6..4851e67e9 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
@@ -51,7 +51,7 @@ public class OverviewInputConsumer<T extends BaseDraggingActivity>
private final boolean mStartingInActivityBounds;
private boolean mTargetHandledTouch;
- OverviewInputConsumer(T activity, @Nullable InputMonitorCompat inputMonitor,
+ public OverviewInputConsumer(T activity, @Nullable InputMonitorCompat inputMonitor,
boolean startingInActivityBounds) {
mActivity = activity;
mInputMonitor = inputMonitor;
@@ -115,12 +115,12 @@ public class OverviewInputConsumer<T extends BaseDraggingActivity>
}
}
- public static InputConsumer newInstance(ActivityControlHelper activityHelper,
- @Nullable InputMonitorCompat inputMonitor, boolean startingInActivityBounds) {
+ public static InputConsumer newInstanceWithinActivityBounds(
+ ActivityControlHelper activityHelper) {
BaseDraggingActivity activity = activityHelper.getCreatedActivity();
if (activity == null) {
return InputConsumer.NO_OP;
}
- return new OverviewInputConsumer(activity, inputMonitor, startingInActivityBounds);
+ return new OverviewInputConsumer(activity, null, true);
}
} \ No newline at end of file
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewWithoutFocusInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewWithoutFocusInputConsumer.java
new file mode 100644
index 000000000..425b8b6b0
--- /dev/null
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewWithoutFocusInputConsumer.java
@@ -0,0 +1,151 @@
+/*
+ * 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.quickstep.inputconsumers;
+
+import static android.view.MotionEvent.ACTION_CANCEL;
+import static android.view.MotionEvent.ACTION_DOWN;
+import static android.view.MotionEvent.ACTION_MOVE;
+import static android.view.MotionEvent.ACTION_UP;
+
+import static com.android.launcher3.Utilities.squaredHypot;
+import static com.android.quickstep.TouchInteractionService.TOUCH_INTERACTION_LOG;
+import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
+
+import android.content.Context;
+import android.graphics.PointF;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.ViewConfiguration;
+
+import com.android.launcher3.Utilities;
+import com.android.quickstep.OverviewCallbacks;
+import com.android.quickstep.util.NavBarPosition;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.InputMonitorCompat;
+
+public class OverviewWithoutFocusInputConsumer implements InputConsumer {
+
+ private final InputMonitorCompat mInputMonitor;
+ private final boolean mDisableHorizontalSwipe;
+ private final PointF mDownPos = new PointF();
+ private final float mSquaredTouchSlop;
+ private final Context mContext;
+ private final NavBarPosition mNavBarPosition;
+
+ private boolean mInterceptedTouch;
+ private VelocityTracker mVelocityTracker;
+
+
+ public OverviewWithoutFocusInputConsumer(Context context, InputMonitorCompat inputMonitor,
+ boolean disableHorizontalSwipe) {
+ mInputMonitor = inputMonitor;
+ mDisableHorizontalSwipe = disableHorizontalSwipe;
+ mContext = context;
+ mSquaredTouchSlop = Utilities.squaredTouchSlop(context);
+ mNavBarPosition = new NavBarPosition(context);
+
+ mVelocityTracker = VelocityTracker.obtain();
+ }
+
+ @Override
+ public int getType() {
+ return TYPE_OVERVIEW_WITHOUT_FOCUS;
+ }
+
+ @Override
+ public boolean allowInterceptByParent() {
+ return !mInterceptedTouch;
+ }
+
+ private void endTouchTracking() {
+ if (mVelocityTracker != null) {
+ mVelocityTracker.recycle();
+ mVelocityTracker = null;
+ }
+ }
+
+ @Override
+ public void onMotionEvent(MotionEvent ev) {
+ if (mVelocityTracker == null) {
+ return;
+ }
+
+ mVelocityTracker.addMovement(ev);
+ switch (ev.getActionMasked()) {
+ case ACTION_DOWN: {
+ mDownPos.set(ev.getX(), ev.getY());
+ break;
+ }
+ case ACTION_MOVE: {
+ if (!mInterceptedTouch) {
+ float displacementX = ev.getX() - mDownPos.x;
+ float displacementY = ev.getY() - mDownPos.y;
+ if (squaredHypot(displacementX, displacementY) >= mSquaredTouchSlop) {
+ if (mDisableHorizontalSwipe
+ && Math.abs(displacementX) > Math.abs(displacementY)) {
+ // Horizontal gesture is not allowed in this region
+ endTouchTracking();
+ break;
+ }
+
+ mInterceptedTouch = true;
+
+ if (mInputMonitor != null) {
+ mInputMonitor.pilferPointers();
+ }
+ }
+ }
+ break;
+ }
+
+ case ACTION_CANCEL:
+ endTouchTracking();
+ break;
+
+ case ACTION_UP: {
+ finishTouchTracking(ev);
+ endTouchTracking();
+ break;
+ }
+ }
+ }
+
+ private void finishTouchTracking(MotionEvent ev) {
+ mVelocityTracker.computeCurrentVelocity(100);
+ float velocityX = mVelocityTracker.getXVelocity();
+ float velocityY = mVelocityTracker.getYVelocity();
+ float velocity = mNavBarPosition.isRightEdge()
+ ? -velocityX : (mNavBarPosition.isLeftEdge() ? velocityX : -velocityY);
+
+ final boolean triggerQuickstep;
+ if (Math.abs(velocity) >= ViewConfiguration.get(mContext).getScaledMinimumFlingVelocity()) {
+ triggerQuickstep = velocity > 0;
+ } else {
+ float displacementX = mDisableHorizontalSwipe ? 0 : (ev.getX() - mDownPos.x);
+ float displacementY = ev.getY() - mDownPos.y;
+ triggerQuickstep = squaredHypot(displacementX, displacementY) >= mSquaredTouchSlop;
+ }
+
+ if (triggerQuickstep) {
+ OverviewCallbacks.get(mContext).closeAllWindows();
+ ActivityManagerWrapper.getInstance()
+ .closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
+ TOUCH_INTERACTION_LOG.addLog("startQuickstep");
+ } else {
+ // ignore
+ }
+ }
+}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/NavBarPosition.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/NavBarPosition.java
new file mode 100644
index 000000000..3ce341d8c
--- /dev/null
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/NavBarPosition.java
@@ -0,0 +1,55 @@
+/*
+ * 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.quickstep.util;
+
+import static com.android.launcher3.uioverrides.RecentsUiFactory.ROTATION_LANDSCAPE;
+import static com.android.launcher3.uioverrides.RecentsUiFactory.ROTATION_SEASCAPE;
+import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
+
+import android.content.Context;
+import android.view.Surface;
+import android.view.WindowManager;
+
+import com.android.launcher3.graphics.RotationMode;
+import com.android.quickstep.SysUINavigationMode;
+
+/**
+ * Utility class to check nav bar position
+ */
+public class NavBarPosition {
+
+ private final SysUINavigationMode.Mode mMode;
+ private final int mDisplayRotation;
+
+ public NavBarPosition(Context context) {
+ mMode = SysUINavigationMode.getMode(context);
+ mDisplayRotation = context.getSystemService(WindowManager.class)
+ .getDefaultDisplay().getRotation();
+ }
+
+ public boolean isRightEdge() {
+ return mMode != NO_BUTTON && mDisplayRotation == Surface.ROTATION_90;
+ }
+
+ public boolean isLeftEdge() {
+ return mMode != NO_BUTTON && mDisplayRotation == Surface.ROTATION_270;
+ }
+
+ public RotationMode getRotationMode() {
+ return isLeftEdge() ? ROTATION_SEASCAPE
+ : (isRightEdge() ? ROTATION_LANDSCAPE : RotationMode.NORMAL);
+ }
+}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java
index 837c2dc93..9eda2f9d4 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java
@@ -28,13 +28,20 @@ import com.android.launcher3.CellLayout;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAnimUtils.ViewProgressProperty;
+import com.android.launcher3.LauncherState;
+import com.android.launcher3.LauncherStateManager;
+import com.android.launcher3.LauncherStateManager.AnimationConfig;
import com.android.launcher3.R;
import com.android.launcher3.ShortcutAndWidgetContainer;
+import com.android.launcher3.anim.AnimatorSetBuilder;
+import com.android.launcher3.anim.PropertySetter;
import com.android.launcher3.anim.SpringObjectAnimator;
import java.util.ArrayList;
import java.util.List;
+import static com.android.launcher3.LauncherState.BACKGROUND_APP;
+import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.anim.Interpolators.LINEAR;
/**
@@ -56,7 +63,7 @@ public class StaggeredWorkspaceAnim {
private final float mSpringTransY;
private final View mViewToIgnore;
- private final List<ValueAnimator> mAnimators = new ArrayList<>();
+ private final List<Animator> mAnimators = new ArrayList<>();
/**
* @param floatingViewOriginalView The FloatingIconView's original view.
@@ -104,6 +111,9 @@ public class StaggeredWorkspaceAnim {
View qsb = launcher.findViewById(R.id.search_container_all_apps);
addStaggeredAnimationForView(qsb, grid.inv.numRows + 2, totalRows);
}
+
+ addWorkspaceScrimAnimationForState(launcher, BACKGROUND_APP, 0);
+ addWorkspaceScrimAnimationForState(launcher, NORMAL, ALPHA_DURATION_MS);
}
/**
@@ -150,4 +160,14 @@ public class StaggeredWorkspaceAnim {
alpha.setStartDelay(startDelay);
mAnimators.add(alpha);
}
+
+ private void addWorkspaceScrimAnimationForState(Launcher launcher, LauncherState state,
+ long duration) {
+ AnimatorSetBuilder scrimAnimBuilder = new AnimatorSetBuilder();
+ AnimationConfig scrimAnimConfig = new AnimationConfig();
+ scrimAnimConfig.duration = duration;
+ PropertySetter scrimPropertySetter = scrimAnimConfig.getPropertySetter(scrimAnimBuilder);
+ launcher.getWorkspace().getStateTransitionAnimation().setScrim(scrimPropertySetter, state);
+ mAnimators.add(scrimAnimBuilder.build());
+ }
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
index 3b23bd109..5b2e27e53 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -20,6 +20,7 @@ import static com.android.launcher3.LauncherState.ALL_APPS_HEADER_EXTRA;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.LauncherState.RECENTS_CLEAR_ALL_BUTTON;
+import static com.android.launcher3.LauncherState.SPRING_LOADED;
import static com.android.launcher3.QuickstepAppTransitionManagerImpl.ALL_APPS_PROGRESS_OFF_SCREEN;
import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS;
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
@@ -37,6 +38,7 @@ import android.view.View;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
+import com.android.launcher3.LauncherStateManager.StateListener;
import com.android.launcher3.R;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.appprediction.PredictionUiStateManager;
@@ -51,7 +53,7 @@ import com.android.quickstep.util.LayoutUtils;
* {@link RecentsView} used in Launcher activity
*/
@TargetApi(Build.VERSION_CODES.O)
-public class LauncherRecentsView extends RecentsView<Launcher> {
+public class LauncherRecentsView extends RecentsView<Launcher> implements StateListener {
private final TransformParams mTransformParams = new TransformParams();
@@ -66,6 +68,7 @@ public class LauncherRecentsView extends RecentsView<Launcher> {
public LauncherRecentsView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setContentAlpha(0);
+ mActivity.getStateManager().addStateListener(this);
}
@Override
@@ -222,6 +225,22 @@ public class LauncherRecentsView extends RecentsView<Launcher> {
}
@Override
+ public void onStateTransitionStart(LauncherState toState) {
+ setOverviewStateEnabled(toState.overviewUi);
+ setFreezeViewVisibility(true);
+ }
+
+ @Override
+ public void onStateTransitionComplete(LauncherState finalState) {
+ if (finalState == NORMAL || finalState == SPRING_LOADED) {
+ // Clean-up logic that occurs when recents is no longer in use/visible.
+ reset();
+ }
+ setOverlayEnabled(finalState == OVERVIEW);
+ setFreezeViewVisibility(false);
+ }
+
+ @Override
public void setOverviewStateEnabled(boolean enabled) {
super.setOverviewStateEnabled(enabled);
if (enabled) {
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
index 1e1007e68..e38a315f8 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
@@ -72,6 +72,9 @@ import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.ListView;
+import androidx.annotation.Nullable;
+import androidx.dynamicanimation.animation.SpringForce;
+
import com.android.launcher3.BaseActivity;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Insettable;
@@ -111,9 +114,6 @@ import com.android.systemui.shared.system.TaskStackChangeListener;
import java.util.ArrayList;
import java.util.function.Consumer;
-import androidx.annotation.Nullable;
-import androidx.dynamicanimation.animation.SpringForce;
-
/**
* A list of recent tasks.
*/
@@ -168,8 +168,6 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
// The threshold at which we update the SystemUI flags when animating from the task into the app
public static final float UPDATE_SYSUI_FLAGS_THRESHOLD = 0.85f;
- private static final float[] sTempFloatArray = new float[3];
-
protected final T mActivity;
private final float mFastFlingVelocity;
private final RecentsModel mModel;
@@ -189,6 +187,8 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
private boolean mDwbToastShown;
private boolean mDisallowScrollToClearAll;
+ private boolean mOverlayEnabled;
+ private boolean mFreezeViewVisibility;
/**
* TODO: Call reloadIdNeeded in onTaskStackChanged.
@@ -428,11 +428,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
// Clear the task data for the removed child if it was visible
if (child != mClearAllButton) {
TaskView taskView = (TaskView) child;
- Task task = taskView.getTask();
- if (mHasVisibleTaskData.get(task.key.id)) {
- mHasVisibleTaskData.delete(task.key.id);
- taskView.onTaskListVisibilityChanged(false /* visible */);
- }
+ mHasVisibleTaskData.delete(taskView.getTask().key.id);
mTaskViewPool.recycle(taskView);
}
}
@@ -455,7 +451,6 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
public void setOverviewStateEnabled(boolean enabled) {
mOverviewStateEnabled = enabled;
updateTaskStackListenerState();
- if (!enabled) mDwbToastShown = false;
}
public void onDigitalWellbeingToastShown() {
@@ -582,6 +577,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
}
resetTaskVisuals();
onTaskStackUpdated();
+ updateEnabledOverlays();
}
public int getTaskViewCount() {
@@ -780,6 +776,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
unloadVisibleTaskData();
setCurrentPage(0);
+ mDwbToastShown = false;
}
public @Nullable TaskView getRunningTaskView() {
@@ -1306,7 +1303,25 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
mEmptyMessagePaint.setAlpha(alphaInt);
mEmptyIcon.setAlpha(alphaInt);
- setVisibility(alpha > 0 ? VISIBLE : GONE);
+ if (alpha > 0) {
+ setVisibility(VISIBLE);
+ } else if (!mFreezeViewVisibility) {
+ setVisibility(GONE);
+ }
+ }
+
+ /**
+ * Freezes the view visibility change. When frozen, the view will not change its visibility
+ * to gone due to alpha changes.
+ */
+ public void setFreezeViewVisibility(boolean freezeViewVisibility) {
+ if (mFreezeViewVisibility != freezeViewVisibility) {
+ mFreezeViewVisibility = freezeViewVisibility;
+
+ if (!mFreezeViewVisibility) {
+ setVisibility(mContentAlpha > 0 ? VISIBLE : GONE);
+ }
+ }
}
@Override
@@ -1545,6 +1560,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
protected void notifyPageSwitchListener(int prevPage) {
super.notifyPageSwitchListener(prevPage);
loadVisibleTaskData();
+ updateEnabledOverlays();
}
@Override
@@ -1685,4 +1701,19 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
public ClipAnimationHelper getTempClipAnimationHelper() {
return mTempClipAnimationHelper;
}
+
+ private void updateEnabledOverlays() {
+ int overlayEnabledPage = mOverlayEnabled ? getNextPage() : -1;
+ int taskCount = getTaskViewCount();
+ for (int i = 0; i < taskCount; i++) {
+ ((TaskView) getChildAt(i)).setOverlayEnabled(i == overlayEnabledPage);
+ }
+ }
+
+ public void setOverlayEnabled(boolean overlayEnabled) {
+ if (mOverlayEnabled != overlayEnabled) {
+ mOverlayEnabled = overlayEnabled;
+ updateEnabledOverlays();
+ }
+ }
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskMenuView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskMenuView.java
index c47e943be..c1f6b82ec 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskMenuView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskMenuView.java
@@ -42,6 +42,7 @@ import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.anim.RoundedRectRevealOutlineProvider;
import com.android.launcher3.util.Themes;
import com.android.launcher3.views.BaseDragLayer;
+import com.android.quickstep.TaskOverlayFactory;
import com.android.quickstep.TaskSystemShortcut;
import com.android.quickstep.TaskUtils;
import com.android.quickstep.views.IconView.OnScaleUpdateListener;
@@ -196,7 +197,7 @@ public class TaskMenuView extends AbstractFloatingView {
final BaseDraggingActivity activity = BaseDraggingActivity.fromContext(getContext());
final List<TaskSystemShortcut> shortcuts =
- taskView.getTaskOverlay().getEnabledShortcuts(taskView);
+ TaskOverlayFactory.INSTANCE.get(getContext()).getEnabledShortcuts(taskView);
final int count = shortcuts.size();
for (int i = 0; i < count; ++i) {
final TaskSystemShortcut menuOption = shortcuts.get(i);
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java
index df5831b08..8b8240d0a 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java
@@ -98,6 +98,9 @@ public class TaskThumbnailView extends View {
private float mDimAlphaMultiplier = 1f;
private float mSaturation = 1f;
+ private boolean mOverlayEnabled;
+ private boolean mRotated;
+
public TaskThumbnailView(Context context) {
this(context, null);
}
@@ -192,10 +195,6 @@ public class TaskThumbnailView extends View {
return 0;
}
- public TaskOverlay getTaskOverlay() {
- return mOverlay;
- }
-
@Override
protected void onDraw(Canvas canvas) {
RectF currentDrawnInsets = mFullscreenParams.mCurrentDrawnInsets;
@@ -257,6 +256,22 @@ public class TaskThumbnailView extends View {
return (TaskView) getParent();
}
+ public void setOverlayEnabled(boolean overlayEnabled) {
+ if (mOverlayEnabled != overlayEnabled) {
+ mOverlayEnabled = overlayEnabled;
+ updateOverlay();
+ }
+ }
+
+ private void updateOverlay() {
+ // The overlay doesn't really work when the screenshot is rotated, so don't add it.
+ if (mOverlayEnabled && !mRotated && mBitmapShader != null && mThumbnailData != null) {
+ mOverlay.initOverlay(mTask, mThumbnailData, mMatrix);
+ } else {
+ mOverlay.reset();
+ }
+ }
+
private void updateThumbnailPaintFilter() {
int mul = (int) ((1 - mDimAlpha * mDimAlphaMultiplier) * 255);
ColorFilter filter = getColorFilter(mul, mIsDarkTextTheme, mSaturation);
@@ -351,12 +366,8 @@ public class TaskThumbnailView extends View {
mPaint.setShader(mBitmapShader);
}
- if (isRotated) {
- // The overlay doesn't really work when the screenshot is rotated, so don't add it.
- mOverlay.reset();
- } else {
- mOverlay.setTaskInfo(mTask, mThumbnailData, mMatrix);
- }
+ mRotated = isRotated;
+ updateOverlay();
invalidate();
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
index f8d454f34..bf3e91ff6 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
@@ -39,7 +39,6 @@ import android.os.Handler;
import android.util.AttributeSet;
import android.util.FloatProperty;
import android.util.Log;
-import android.util.Property;
import android.view.View;
import android.view.ViewOutlineProvider;
import android.view.accessibility.AccessibilityNodeInfo;
@@ -253,10 +252,6 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
return mIconView;
}
- public TaskOverlayFactory.TaskOverlay getTaskOverlay() {
- return mSnapshotView.getTaskOverlay();
- }
-
public AnimatorPlaybackController createLaunchAnimationForRunningTask() {
final PendingAnimation pendingAnimation =
getRecentsView().createTaskLauncherAnimation(this, RECENTS_LAUNCH_DURATION);
@@ -488,6 +483,8 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
// Clear any references to the thumbnail (it will be re-read either from the cache or the
// system on next bind)
mSnapshotView.setThumbnail(mTask, null);
+ setOverlayEnabled(false);
+ onTaskListVisibilityChanged(false);
if (mTask != null) {
mTask.thumbnail = null;
}
@@ -608,7 +605,7 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
final Context context = getContext();
final List<TaskSystemShortcut> shortcuts =
- mSnapshotView.getTaskOverlay().getEnabledShortcuts(this);
+ TaskOverlayFactory.INSTANCE.get(getContext()).getEnabledShortcuts(this);
final int count = shortcuts.size();
for (int i = 0; i < count; ++i) {
final TaskSystemShortcut menuOption = shortcuts.get(i);
@@ -647,7 +644,7 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
}
final List<TaskSystemShortcut> shortcuts =
- mSnapshotView.getTaskOverlay().getEnabledShortcuts(this);
+ TaskOverlayFactory.INSTANCE.get(getContext()).getEnabledShortcuts(this);
final int count = shortcuts.size();
for (int i = 0; i < count; ++i) {
final TaskSystemShortcut menuOption = shortcuts.get(i);
@@ -733,6 +730,10 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
return mShowScreenshot;
}
+ public void setOverlayEnabled(boolean overlayEnabled) {
+ mSnapshotView.setOverlayEnabled(overlayEnabled);
+ }
+
/**
* We update and subsequently draw these in {@link #setFullscreenProgress(float)}.
*/
diff --git a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
index dcf2e3c15..46161cbc8 100644
--- a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
@@ -108,7 +108,7 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans
// Use a shorter duration for x or y translation to create a curve effect
private static final long APP_LAUNCH_CURVED_DURATION = 250;
private static final long APP_LAUNCH_ALPHA_DURATION = 50;
- private static final long APP_LAUNCH_ALPHA_START_DELAY = 50;
+ private static final long APP_LAUNCH_ALPHA_START_DELAY = 25;
// We scale the durations for the downward app launch animations (minus the scale animation).
private static final float APP_LAUNCH_DOWN_DUR_SCALE_FACTOR = 0.8f;
diff --git a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
index 489174614..97cd38a11 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
@@ -47,7 +47,6 @@ import com.android.launcher3.LauncherStateManager;
import com.android.launcher3.LauncherStateManager.StateHandler;
import com.android.launcher3.QuickstepAppTransitionManagerImpl;
import com.android.launcher3.Utilities;
-import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.proxy.ProxyActivityStarter;
import com.android.launcher3.proxy.StartActivityParams;
import com.android.quickstep.OverviewInteractionState;
@@ -64,10 +63,14 @@ import java.util.zip.Deflater;
public class UiFactory extends RecentsUiFactory {
- public static Runnable enableLiveTouchControllerChanges(DragLayer dl) {
- NavigationModeChangeListener listener = m -> dl.recreateControllers();
- SysUINavigationMode mode = SysUINavigationMode.INSTANCE.get(dl.getContext());
- mode.addModeChangeListener(listener);
+ public static Runnable enableLiveUIChanges(Launcher launcher) {
+ NavigationModeChangeListener listener = m -> {
+ launcher.getDragLayer().recreateControllers();
+ launcher.getRotationHelper().setRotationHadDifferentUI(m != Mode.NO_BUTTON);
+ };
+ SysUINavigationMode mode = SysUINavigationMode.INSTANCE.get(launcher);
+ SysUINavigationMode.Mode m = mode.addModeChangeListener(listener);
+ launcher.getRotationHelper().setRotationHadDifferentUI(m != Mode.NO_BUTTON);
return () -> mode.removeModeChangeListener(listener);
}
diff --git a/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java b/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java
index c77726e61..a412b3970 100644
--- a/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java
+++ b/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java
@@ -18,14 +18,17 @@ package com.android.quickstep;
import com.android.launcher3.ui.AbstractLauncherUiTest;
-import org.junit.Rule;
+import org.junit.rules.RuleChain;
import org.junit.rules.TestRule;
/**
* Base class for all instrumentation tests that deal with Quickstep.
*/
public abstract class AbstractQuickStepTest extends AbstractLauncherUiTest {
- @Rule
- public TestRule mQuickstepOnOffExecutor =
- new NavigationModeSwitchRule(mLauncher);
+ @Override
+ protected TestRule getRulesInsideActivityMonitor() {
+ return RuleChain.
+ outerRule(new NavigationModeSwitchRule(mLauncher)).
+ around(super.getRulesInsideActivityMonitor());
+ }
}
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 67086a578..151e2ca13 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -880,6 +880,9 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
@Override
protected void onStart() {
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "Launcher.onStart");
+ }
RaceConditionTracker.onEvent(ON_START_EVT, ENTER);
super.onStart();
if (mLauncherCallbacks != null) {
@@ -1064,7 +1067,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
// Setup the drag layer
mDragLayer.setup(mDragController, mWorkspace);
- mCancelTouchController = UiFactory.enableLiveTouchControllerChanges(mDragLayer);
+ mCancelTouchController = UiFactory.enableLiveUIChanges(this);
mWorkspace.setup(mDragController);
// Until the workspace is bound, ensure that we keep the wallpaper offset locked to the
diff --git a/src/com/android/launcher3/LauncherState.java b/src/com/android/launcher3/LauncherState.java
index 3a92dfb96..c63f976a8 100644
--- a/src/com/android/launcher3/LauncherState.java
+++ b/src/com/android/launcher3/LauncherState.java
@@ -258,9 +258,6 @@ public class LauncherState {
* Called when the start transition ends and the user settles on this particular state.
*/
public void onStateTransitionEnd(Launcher launcher) {
- if (this == NORMAL || this == SPRING_LOADED) {
- UiFactory.resetOverview(launcher);
- }
if (this == NORMAL) {
// Clear any rotation locks when going to normal state
launcher.getRotationHelper().setCurrentStateRequest(REQUEST_NONE);
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index f784226a5..9f846bbc4 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -1394,6 +1394,10 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
builder.play(stepAnimator);
}
+ public WorkspaceStateTransitionAnimation getStateTransitionAnimation() {
+ return mStateTransitionAnimation;
+ }
+
public void updateAccessibilityFlags() {
// TODO: Update the accessibility flags appropriately when dragging.
int accessibilityFlag = mLauncher.getStateManager().getState().workspaceAccessibilityFlag;
diff --git a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
index 8d0259d05..065d06568 100644
--- a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
+++ b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
@@ -130,7 +130,10 @@ public class WorkspaceStateTransitionAnimation {
propertySetter.setFloat(mWorkspace.getPageIndicator(), View.TRANSLATION_Y,
hotseatScaleAndTranslation.translationY, translationInterpolator);
- // Set scrim
+ setScrim(propertySetter, state);
+ }
+
+ public void setScrim(PropertySetter propertySetter, LauncherState state) {
WorkspaceAndHotseatScrim scrim = mLauncher.getDragLayer().getScrim();
propertySetter.setFloat(scrim, SCRIM_PROGRESS, state.getWorkspaceScrimAlpha(mLauncher),
LINEAR);
diff --git a/src/com/android/launcher3/states/RotationHelper.java b/src/com/android/launcher3/states/RotationHelper.java
index cd96d6ed8..abf90e22c 100644
--- a/src/com/android/launcher3/states/RotationHelper.java
+++ b/src/com/android/launcher3/states/RotationHelper.java
@@ -73,7 +73,8 @@ public class RotationHelper implements OnSharedPreferenceChangeListener {
// This is used to defer setting rotation flags until the activity is being created
private boolean mInitialized;
- public boolean mDestroyed;
+ private boolean mDestroyed;
+ private boolean mRotationHasDifferentUI;
private int mLastActivityFlags = -1;
@@ -92,8 +93,12 @@ public class RotationHelper implements OnSharedPreferenceChangeListener {
}
}
+ public void setRotationHadDifferentUI(boolean rotationHasDifferentUI) {
+ mRotationHasDifferentUI = rotationHasDifferentUI;
+ }
+
public boolean homeScreenCanRotate() {
- return mIgnoreAutoRotateSettings || mAutoRotateEnabled
+ return mRotationHasDifferentUI || mIgnoreAutoRotateSettings || mAutoRotateEnabled
|| mStateHandlerRequest != REQUEST_NONE
|| mLauncher.getDeviceProfile().isMultiWindowMode;
}
diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java
index e60b665ea..6ffc2d9cd 100644
--- a/src/com/android/launcher3/testing/TestProtocol.java
+++ b/src/com/android/launcher3/testing/TestProtocol.java
@@ -77,4 +77,5 @@ public final class TestProtocol {
public static final String NO_DRAG_TAG = "b/133009122";
public static final String NO_START_TAG = "b/132900132";
public static final String NO_START_TASK_TAG = "b/133765434";
+ public static final String NO_OVERVIEW_EVENT_TAG = "b/134532571";
}
diff --git a/src/com/android/launcher3/util/TraceHelper.java b/src/com/android/launcher3/util/TraceHelper.java
index 4fea2e92a..c24bb6781 100644
--- a/src/com/android/launcher3/util/TraceHelper.java
+++ b/src/com/android/launcher3/util/TraceHelper.java
@@ -27,16 +27,17 @@ import android.util.MutableLong;
import com.android.launcher3.config.FeatureFlags;
/**
- * A wrapper around {@link Trace} to allow easier proguarding for production builds.
+ * A wrapper around {@link Trace} with some utility information.
*
* To enable any tracing log, execute the following command:
+ * $ adb shell setprop log.tag.LAUNCHER_TRACE VERBOSE
* $ adb shell setprop log.tag.TAGNAME VERBOSE
*/
public class TraceHelper {
- private static final boolean ENABLED = FeatureFlags.IS_DOGFOOD_BUILD;
+ private static final boolean ENABLED = isLoggable("LAUNCHER_TRACE", VERBOSE);
- private static final boolean SYSTEM_TRACE = false;
+ private static final boolean SYSTEM_TRACE = ENABLED;
private static final ArrayMap<String, MutableLong> sUpTimes = ENABLED ? new ArrayMap<>() : null;
public static void beginSection(String sectionName) {
diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java
index 95c96817a..339681cd6 100644
--- a/src/com/android/launcher3/views/FloatingIconView.java
+++ b/src/com/android/launcher3/views/FloatingIconView.java
@@ -124,6 +124,7 @@ public class FloatingIconView extends View implements
private boolean mIsVerticalBarLayout = false;
private boolean mIsAdaptiveIcon = false;
+ private boolean mIsOpening;
private @Nullable Drawable mBadge;
private @Nullable Drawable mForeground;
@@ -178,8 +179,10 @@ public class FloatingIconView extends View implements
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
- getViewTreeObserver().addOnGlobalLayoutListener(this);
- mLauncher.getRotationHelper().setCurrentTransitionRequest(REQUEST_LOCK);
+ if (!mIsOpening) {
+ getViewTreeObserver().addOnGlobalLayoutListener(this);
+ mLauncher.getRotationHelper().setCurrentTransitionRequest(REQUEST_LOCK);
+ }
}
@Override
@@ -326,7 +329,7 @@ public class FloatingIconView extends View implements
* - For BubbleTextView, we return the icon bounds.
*/
private float getLocationBoundsForView(View v, RectF outRect) {
- boolean ignoreTransform = true;
+ boolean ignoreTransform = !mIsOpening;
if (v instanceof DeepShortcutView) {
v = ((DeepShortcutView) v).getBubbleText();
ignoreTransform = false;
@@ -627,6 +630,7 @@ public class FloatingIconView extends View implements
view.recycle();
view.mIsVerticalBarLayout = launcher.getDeviceProfile().isVerticalBarLayout();
+ view.mIsOpening = isOpening;
view.mOriginalIcon = originalView;
view.mPositionOut = positionOut;
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java b/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
index 550327d96..e41916cf4 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
@@ -27,7 +27,6 @@ import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState.ScaleAndTranslation;
import com.android.launcher3.LauncherStateManager.StateHandler;
-import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.graphics.RotationMode;
import com.android.launcher3.util.TouchController;
@@ -40,7 +39,7 @@ public class UiFactory {
launcher.getDragController(), new AllAppsSwipeController(launcher)};
}
- public static Runnable enableLiveTouchControllerChanges(DragLayer dl) {
+ public static Runnable enableLiveUIChanges(Launcher l) {
return null;
}
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index c7c36b0d4..64fe2d7d7 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -58,19 +58,17 @@ import com.android.launcher3.model.AppLaunchTracker;
import com.android.launcher3.tapl.LauncherInstrumentation;
import com.android.launcher3.tapl.TestHelpers;
import com.android.launcher3.util.Wait;
+import com.android.launcher3.util.rule.FailureWatcher;
import com.android.launcher3.util.rule.LauncherActivityRule;
import com.android.launcher3.util.rule.ShellCommandRule;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
+import org.junit.rules.RuleChain;
import org.junit.rules.TestRule;
-import org.junit.rules.TestWatcher;
-import org.junit.runner.Description;
import org.junit.runners.model.Statement;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
import java.io.IOException;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
@@ -93,11 +91,11 @@ public abstract class AbstractLauncherUiTest {
public static final long SHORT_UI_TIMEOUT = 300;
public static final long DEFAULT_UI_TIMEOUT = 10000;
private static final String TAG = "AbstractLauncherUiTest";
- private static int sScreenshotCount = 0;
protected MainThreadExecutor mMainThreadExecutor = new MainThreadExecutor();
protected final UiDevice mDevice = UiDevice.getInstance(getInstrumentation());
- protected final LauncherInstrumentation mLauncher;
+ protected final LauncherInstrumentation mLauncher =
+ new LauncherInstrumentation(getInstrumentation());
protected Context mTargetContext;
protected String mTargetPackage;
@@ -108,11 +106,9 @@ public abstract class AbstractLauncherUiTest {
throw new RuntimeException(e);
}
if (TestHelpers.isInLauncherProcess()) Utilities.enableRunningInTestHarnessForTests();
- mLauncher = new LauncherInstrumentation(getInstrumentation());
}
- @Rule
- public LauncherActivityRule mActivityMonitor = new LauncherActivityRule();
+ protected final LauncherActivityRule mActivityMonitor = new LauncherActivityRule();
@Rule
public ShellCommandRule mDefaultLauncherRule =
@@ -166,43 +162,18 @@ public abstract class AbstractLauncherUiTest {
}
} : base;
- @Rule
- public TestWatcher mFailureWatcher = new TestWatcher() {
- private void dumpViewHierarchy() {
- final ByteArrayOutputStream stream = new ByteArrayOutputStream();
- try {
- mDevice.dumpWindowHierarchy(stream);
- stream.flush();
- stream.close();
- for (String line : stream.toString().split("\\r?\\n")) {
- Log.e(TAG, line.trim());
- }
- } catch (IOException e) {
- Log.e(TAG, "error dumping XML to logcat", e);
- }
- }
+ protected TestRule getRulesInsideActivityMonitor() {
+ return new FailureWatcher(this);
+ }
- @Override
- protected void failed(Throwable e, Description description) {
- if (mDevice == null) return;
- final String pathname = getInstrumentation().getTargetContext().
- getFilesDir().getPath() + "/TaplTestScreenshot" + sScreenshotCount++ + ".png";
- Log.e(TAG, "Failed test " + description.getMethodName() +
- ", screenshot will be saved to " + pathname +
- ", track trace is below, UI object dump is further below:\n" +
- Log.getStackTraceString(e));
- dumpViewHierarchy();
-
- try {
- final String dumpsysResult = mDevice.executeShellCommand(
- "dumpsys activity service TouchInteractionService");
- Log.d(TAG, "TouchInteractionService: " + dumpsysResult);
- } catch (IOException ex) {
- }
+ @Rule
+ public TestRule mOrderSensitiveRules = RuleChain.
+ outerRule(mActivityMonitor).
+ around(getRulesInsideActivityMonitor());
- mDevice.takeScreenshot(new File(pathname));
- }
- };
+ public UiDevice getDevice() {
+ return mDevice;
+ }
@Before
public void setUp() throws Exception {
diff --git a/tests/src/com/android/launcher3/util/rule/FailureWatcher.java b/tests/src/com/android/launcher3/util/rule/FailureWatcher.java
new file mode 100644
index 000000000..09cc98de0
--- /dev/null
+++ b/tests/src/com/android/launcher3/util/rule/FailureWatcher.java
@@ -0,0 +1,59 @@
+package com.android.launcher3.util.rule;
+
+import static androidx.test.InstrumentationRegistry.getInstrumentation;
+
+import android.util.Log;
+
+import com.android.launcher3.ui.AbstractLauncherUiTest;
+
+import org.junit.rules.TestWatcher;
+import org.junit.runner.Description;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+
+public class FailureWatcher extends TestWatcher {
+ private static final String TAG = "FailureWatcher";
+ private static int sScreenshotCount = 0;
+ private AbstractLauncherUiTest mAbstractLauncherUiTest;
+
+ public FailureWatcher(AbstractLauncherUiTest abstractLauncherUiTest) {
+ mAbstractLauncherUiTest = abstractLauncherUiTest;
+ }
+
+ private void dumpViewHierarchy() {
+ final ByteArrayOutputStream stream = new ByteArrayOutputStream();
+ try {
+ mAbstractLauncherUiTest.getDevice().dumpWindowHierarchy(stream);
+ stream.flush();
+ stream.close();
+ for (String line : stream.toString().split("\\r?\\n")) {
+ Log.e(TAG, line.trim());
+ }
+ } catch (IOException e) {
+ Log.e(TAG, "error dumping XML to logcat", e);
+ }
+ }
+
+ @Override
+ protected void failed(Throwable e, Description description) {
+ if (mAbstractLauncherUiTest.getDevice() == null) return;
+ final String pathname = getInstrumentation().getTargetContext().
+ getFilesDir().getPath() + "/TaplTestScreenshot" + sScreenshotCount++ + ".png";
+ Log.e(TAG, "Failed test " + description.getMethodName() +
+ ", screenshot will be saved to " + pathname +
+ ", track trace is below, UI object dump is further below:\n" +
+ Log.getStackTraceString(e));
+ dumpViewHierarchy();
+
+ try {
+ final String dumpsysResult = mAbstractLauncherUiTest.getDevice().executeShellCommand(
+ "dumpsys activity service TouchInteractionService");
+ Log.d(TAG, "TouchInteractionService: " + dumpsysResult);
+ } catch (IOException ex) {
+ }
+
+ mAbstractLauncherUiTest.getDevice().takeScreenshot(new File(pathname));
+ }
+}
diff --git a/tests/tapl/com/android/launcher3/tapl/Background.java b/tests/tapl/com/android/launcher3/tapl/Background.java
index ce952983f..6c4619235 100644
--- a/tests/tapl/com/android/launcher3/tapl/Background.java
+++ b/tests/tapl/com/android/launcher3/tapl/Background.java
@@ -59,6 +59,7 @@ public class Background extends LauncherInstrumentation.VisibleContainer {
}
protected void goToOverviewUnchecked(int expectedState) {
+ mLauncher.getTestInfo(TestProtocol.REQUEST_ENABLE_DEBUG_TRACING);
switch (mLauncher.getNavigationModel()) {
case ZERO_BUTTON: {
final int centerX = mLauncher.getDevice().getDisplayWidth() / 2;
@@ -103,6 +104,7 @@ public class Background extends LauncherInstrumentation.VisibleContainer {
mLauncher.waitForSystemUiObject("recent_apps").click();
break;
}
+ mLauncher.getTestInfo(TestProtocol.REQUEST_DISABLE_DEBUG_TRACING);
}
protected String getSwipeHeightRequestName() {