Merge "Waiting for app install to finish before procedding with the test" into tm-qpr-dev
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 5cc5f10..7e4c2f6 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -48,7 +48,7 @@
import static com.android.quickstep.GestureState.STATE_RECENTS_SCROLLING_FINISHED;
import static com.android.quickstep.MultiStateCallback.DEBUG_STATES;
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.CANCEL_RECENTS_ANIMATION;
-import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.FINISH_RECENTS_ANIMATION;
+import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.EXPECTING_TASK_APPEARED;
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.ON_SETTLED_ON_END_TARGET;
import static com.android.quickstep.util.VibratorWrapper.OVERVIEW_HAPTIC;
import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHOLD;
@@ -1704,10 +1704,6 @@
private void resumeLastTask() {
if (mRecentsAnimationController != null) {
mRecentsAnimationController.finish(false /* toRecents */, null);
- ActiveGestureLog.INSTANCE.addLog(
- /* event= */ "finishRecentsAnimation",
- /* extras= */ false,
- /* gestureEvent= */ FINISH_RECENTS_ANIMATION);
}
doLogGesture(LAST_TASK, null);
reset();
@@ -1916,10 +1912,6 @@
mRecentsAnimationController.detachNavigationBarFromApp(true);
}
}
- ActiveGestureLog.INSTANCE.addLog(
- /* event= */ "finishRecentsAnimation",
- /* extras= */ true,
- /* gestureEvent= */ FINISH_RECENTS_ANIMATION);
}
private void finishCurrentTransitionToHome() {
@@ -1931,10 +1923,6 @@
finishRecentsControllerToHome(
() -> mStateCallback.setStateOnUiThread(STATE_CURRENT_TASK_FINISHED));
}
- ActiveGestureLog.INSTANCE.addLog(
- /* event= */ "finishRecentsAnimation",
- /* extras= */ true,
- /* gestureEvent= */ FINISH_RECENTS_ANIMATION);
doLogGesture(HOME, mRecentsView == null ? null : mRecentsView.getCurrentPageTaskView());
}
@@ -2045,6 +2033,9 @@
mGestureState.updateLastStartedTaskId(taskId);
boolean hasTaskPreviouslyAppeared = mGestureState.getPreviouslyAppearedTaskIds()
.contains(taskId);
+ if (!hasTaskPreviouslyAppeared) {
+ ActiveGestureLog.INSTANCE.trackEvent(EXPECTING_TASK_APPEARED);
+ }
nextTask.launchTask(success -> {
resultCallback.accept(success);
if (success) {
diff --git a/quickstep/src/com/android/quickstep/GestureState.java b/quickstep/src/com/android/quickstep/GestureState.java
index 3c4ee75..31b78b3 100644
--- a/quickstep/src/com/android/quickstep/GestureState.java
+++ b/quickstep/src/com/android/quickstep/GestureState.java
@@ -21,7 +21,6 @@
import static com.android.quickstep.MultiStateCallback.DEBUG_STATES;
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.SET_END_TARGET;
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.SET_END_TARGET_HOME;
-import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.SET_END_TARGET_LAST_TASK;
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.SET_END_TARGET_NEW_TASK;
import android.annotation.Nullable;
@@ -341,8 +340,6 @@
ActiveGestureLog.INSTANCE.trackEvent(SET_END_TARGET_NEW_TASK);
break;
case LAST_TASK:
- ActiveGestureLog.INSTANCE.trackEvent(SET_END_TARGET_LAST_TASK);
- break;
case RECENTS:
default:
// No-Op
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java b/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java
index 2451ad8..b82ff03 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java
@@ -130,7 +130,7 @@
public final void onAnimationCanceled(HashMap<Integer, ThumbnailData> thumbnailDatas) {
Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> {
ActiveGestureLog.INSTANCE.addLog(
- /* event= */ "onRecentsAnimationCancelled",
+ /* event= */ "RecentsAnimationCallbacks.onAnimationCanceled",
/* gestureEvent= */ CANCEL_RECENTS_ANIMATION);
for (RecentsAnimationListener listener : getListeners()) {
listener.onRecentsAnimationCanceled(thumbnailDatas);
@@ -142,7 +142,7 @@
@Override
public void onTasksAppeared(RemoteAnimationTarget[] apps) {
Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> {
- ActiveGestureLog.INSTANCE.addLog("onTasksAppeared",
+ ActiveGestureLog.INSTANCE.addLog("RecentsAnimationCallbacks.onTasksAppeared",
ActiveGestureErrorDetector.GestureEvent.TASK_APPEARED);
for (RecentsAnimationListener listener : getListeners()) {
listener.onTasksAppeared(apps);
@@ -164,6 +164,8 @@
private final void onAnimationFinished(RecentsAnimationController controller) {
Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> {
+ ActiveGestureLog.INSTANCE.addLog(
+ /* event= */ "RecentsAnimationCallbacks.onAnimationFinished");
for (RecentsAnimationListener listener : getListeners()) {
listener.onRecentsAnimationFinished(controller);
}
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationController.java b/quickstep/src/com/android/quickstep/RecentsAnimationController.java
index 81e3782..cf1c137 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationController.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationController.java
@@ -18,6 +18,7 @@
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.quickstep.TaskAnimationManager.ENABLE_SHELL_TRANSITIONS;
+import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.FINISH_RECENTS_ANIMATION;
import android.content.Context;
import android.os.RemoteException;
@@ -155,6 +156,10 @@
mPendingFinishCallbacks.add(callback);
return;
}
+ ActiveGestureLog.INSTANCE.addLog(
+ /* event= */ "finishRecentsAnimation",
+ /* extras= */ toRecents,
+ /* gestureEvent= */ FINISH_RECENTS_ANIMATION);
// Finish not yet requested
mFinishRequested = true;
diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
index 90e8091..c45b2f0 100644
--- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java
+++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
@@ -21,6 +21,7 @@
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.quickstep.GestureState.STATE_RECENTS_ANIMATION_INITIALIZED;
import static com.android.quickstep.GestureState.STATE_RECENTS_ANIMATION_STARTED;
+import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.START_RECENTS_ANIMATION;
import static com.android.systemui.shared.system.RemoteTransitionCompat.newRemoteTransition;
import android.app.ActivityManager;
@@ -38,6 +39,7 @@
import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
import com.android.quickstep.TopTaskTracker.CachedTaskInfo;
+import com.android.quickstep.util.ActiveGestureLog;
import com.android.quickstep.views.RecentsView;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -101,6 +103,9 @@
@UiThread
public RecentsAnimationCallbacks startRecentsAnimation(GestureState gestureState,
Intent intent, RecentsAnimationCallbacks.RecentsAnimationListener listener) {
+ ActiveGestureLog.INSTANCE.addLog(
+ /* event= */ "startRecentsAnimation",
+ /* gestureEvent= */ START_RECENTS_ANIMATION);
// Notify if recents animation is still running
if (mController != null) {
String msg = "New recents animation started before old animation completed";
@@ -250,6 +255,7 @@
* Continues the existing running recents animation for a new gesture.
*/
public RecentsAnimationCallbacks continueRecentsAnimation(GestureState gestureState) {
+ ActiveGestureLog.INSTANCE.addLog(/* event= */ "continueRecentsAnimation");
mCallbacks.removeListener(mLastGestureState);
mLastGestureState = gestureState;
mCallbacks.addListener(gestureState);
@@ -288,6 +294,8 @@
*/
public void finishRunningRecentsAnimation(boolean toHome) {
if (mController != null) {
+ ActiveGestureLog.INSTANCE.addLog(
+ /* event= */ "finishRunningRecentsAnimation", toHome);
mCallbacks.notifyAnimationCanceled();
Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), toHome
? mController::finishAnimationToHome
@@ -320,6 +328,7 @@
* Cleans up the recents animation entirely.
*/
private void cleanUpRecentsAnimation() {
+ ActiveGestureLog.INSTANCE.addLog(/* event= */ "cleanUpRecentsAnimation");
if (mLiveTileCleanUpHandler != null) {
mLiveTileCleanUpHandler.run();
mLiveTileCleanUpHandler = null;
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 43aafbe..4cdb5f8 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -15,6 +15,7 @@
*/
package com.android.quickstep;
+import static android.accessibilityservice.AccessibilityService.GLOBAL_ACTION_ACCESSIBILITY_ALL_APPS;
import static android.view.MotionEvent.ACTION_CANCEL;
import static android.view.MotionEvent.ACTION_DOWN;
import static android.view.MotionEvent.ACTION_UP;
@@ -22,6 +23,7 @@
import static com.android.launcher3.config.FeatureFlags.ASSISTANT_GIVES_LAUNCHER_FOCUS;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.quickstep.GestureState.DEFAULT_STATE;
+import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.FLAG_USING_OTHER_ACTIVITY_INPUT_CONSUMER;
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.MOTION_DOWN;
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.MOTION_UP;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
@@ -46,7 +48,6 @@
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
-import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.drawable.Icon;
import android.os.Build;
@@ -86,7 +87,6 @@
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.OnboardingPrefs;
import com.android.launcher3.util.TraceHelper;
-import com.android.launcher3.util.WindowBounds;
import com.android.quickstep.inputconsumers.AccessibilityInputConsumer;
import com.android.quickstep.inputconsumers.AssistantInputConsumer;
import com.android.quickstep.inputconsumers.DeviceLockedInputConsumer;
@@ -103,7 +103,6 @@
import com.android.quickstep.util.ActiveGestureLog.CompoundString;
import com.android.quickstep.util.ProtoTracer;
import com.android.quickstep.util.ProxyScreenStatusProvider;
-import com.android.quickstep.util.SplitScreenBounds;
import com.android.systemui.shared.recents.IOverviewProxy;
import com.android.systemui.shared.recents.ISystemUiProxy;
import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -142,18 +141,7 @@
private static final boolean BUBBLES_HOME_GESTURE_ENABLED =
SystemProperties.getBoolean("persist.wm.debug.bubbles_home_gesture", true);
- private static final String KEY_BACK_NOTIFICATION_COUNT = "backNotificationCount";
- private static final String NOTIFY_ACTION_BACK = "com.android.quickstep.action.BACK_GESTURE";
private static final String HAS_ENABLED_QUICKSTEP_ONCE = "launcher.has_enabled_quickstep_once";
- private static final int MAX_BACK_NOTIFICATION_COUNT = 3;
-
- /**
- * System Action ID to show all apps.
- * TODO: Use AccessibilityService's corresponding global action constant in S
- */
- private static final int SYSTEM_ACTION_ID_ALL_APPS = 14;
-
- private int mBackGestureNotificationCounter = -1;
private final TISBinder mTISBinder = new TISBinder();
@@ -264,12 +252,6 @@
MAIN_EXECUTOR.execute(() -> mDeviceState.setDeferredGestureRegion(region));
}
- @Override
- public void onSplitScreenSecondaryBoundsChanged(Rect bounds, Rect insets) {
- WindowBounds wb = new WindowBounds(bounds, insets);
- MAIN_EXECUTOR.execute(() -> SplitScreenBounds.INSTANCE.setSecondaryWindowBounds(wb));
- }
-
@BinderThread
@Override
public void onScreenTurnedOn() {
@@ -483,8 +465,6 @@
// Temporarily disable model preload
// new ModelPreload().start(this);
- mBackGestureNotificationCounter = Math.max(0, Utilities.getDevicePrefs(this)
- .getInt(KEY_BACK_NOTIFICATION_COUNT, MAX_BACK_NOTIFICATION_COUNT));
resetHomeBounceSeenOnQuickstepEnabledFirstTime();
mOverviewComponentObserver.setOverviewChangeListener(this::onOverviewTargetChange);
@@ -522,11 +502,11 @@
Icon.createWithResource(this, R.drawable.ic_apps),
getString(R.string.all_apps_label),
getString(R.string.all_apps_label),
- PendingIntent.getActivity(this, SYSTEM_ACTION_ID_ALL_APPS, intent,
+ PendingIntent.getActivity(this, GLOBAL_ACTION_ACCESSIBILITY_ALL_APPS, intent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE));
- am.registerSystemAction(allAppsAction, SYSTEM_ACTION_ID_ALL_APPS);
+ am.registerSystemAction(allAppsAction, GLOBAL_ACTION_ACCESSIBILITY_ALL_APPS);
} else {
- am.unregisterSystemAction(SYSTEM_ACTION_ID_ALL_APPS);
+ am.unregisterSystemAction(GLOBAL_ACTION_ACCESSIBILITY_ALL_APPS);
}
StatefulActivity newOverviewActivity = mOverviewComponentObserver.getActivityInterface()
@@ -604,7 +584,7 @@
ProtoTracer.INSTANCE.get(this).remove(this);
getSystemService(AccessibilityManager.class)
- .unregisterSystemAction(SYSTEM_ACTION_ID_ALL_APPS);
+ .unregisterSystemAction(GLOBAL_ACTION_ACCESSIBILITY_ALL_APPS);
mTaskbarManager.destroy();
sConnected = false;
@@ -927,6 +907,9 @@
.append(consumer.getName())
.append(". reason(s):")
.append(reasonString));
+ if ((consumer.getType() & InputConsumer.TYPE_OTHER_ACTIVITY) != 0) {
+ ActiveGestureLog.INSTANCE.trackEvent(FLAG_USING_OTHER_ACTIVITY_INPUT_CONSUMER);
+ }
}
private void handleOrientationSetup(InputConsumer baseInputConsumer) {
@@ -1251,12 +1234,22 @@
}
private void onCommand(PrintWriter pw, LinkedList<String> args) {
- switch (args.pollFirst()) {
+ String cmd = args.pollFirst();
+ if (cmd == null) {
+ pw.println("Command missing");
+ printAvailableCommands(pw);
+ return;
+ }
+ switch (cmd) {
case "clear-touch-log":
ActiveGestureLog.INSTANCE.clear();
break;
case "print-gesture-log":
ActiveGestureLog.INSTANCE.dump("", pw);
+ break;
+ default:
+ pw.println("Command does not exist: " + cmd);
+ printAvailableCommands(pw);
}
}
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
index 9d269fb..b3d3c3d 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
@@ -30,7 +30,6 @@
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.TraceHelper.FLAG_CHECK_FOR_RACE_CONDITIONS;
import static com.android.launcher3.util.VelocityUtils.PX_PER_MS;
-import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.START_RECENTS_ANIMATION;
import static com.android.quickstep.util.ActiveGestureLog.INTENT_EXTRA_LOG_TRACE_ID;
import android.annotation.TargetApi;
@@ -67,7 +66,6 @@
import com.android.quickstep.RecentsAnimationTargets;
import com.android.quickstep.RotationTouchHelper;
import com.android.quickstep.TaskAnimationManager;
-import com.android.quickstep.util.ActiveGestureLog;
import com.android.quickstep.util.CachedEventDispatcher;
import com.android.quickstep.util.MotionPauseDetector;
import com.android.quickstep.util.NavBarPosition;
@@ -387,10 +385,6 @@
}
private void startTouchTrackingForWindowAnimation(long touchTimeMs) {
- ActiveGestureLog.INSTANCE.addLog(
- /* event= */ "startRecentsAnimation",
- /* gestureEvent= */ START_RECENTS_ANIMATION);
-
mInteractionHandler = mHandlerFactory.newHandler(mGestureState, touchTimeMs);
mInteractionHandler.setGestureEndCallback(this::onInteractionGestureFinished);
mMotionPauseDetector.setOnMotionPauseListener(mInteractionHandler.getMotionPauseListener());
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/ProgressDelegateInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/ProgressDelegateInputConsumer.java
index b9b5e7c..2462394 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/ProgressDelegateInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/ProgressDelegateInputConsumer.java
@@ -28,8 +28,6 @@
import android.graphics.Point;
import android.view.MotionEvent;
-import androidx.annotation.Nullable;
-
import com.android.launcher3.anim.AnimatorListeners;
import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.testing.shared.TestProtocol;
@@ -43,7 +41,6 @@
import com.android.quickstep.RecentsAnimationController;
import com.android.quickstep.RecentsAnimationTargets;
import com.android.quickstep.TaskAnimationManager;
-import com.android.quickstep.util.ActiveGestureErrorDetector;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.InputMonitorCompat;
@@ -102,8 +99,7 @@
mDisplaySize = DisplayController.INSTANCE.get(context).getInfo().currentSize;
// Init states
- mStateCallback = new MultiStateCallback(
- STATE_NAMES, ProgressDelegateInputConsumer::getTrackedEventForState);
+ mStateCallback = new MultiStateCallback(STATE_NAMES);
mStateCallback.runOnceAtState(STATE_TARGET_RECEIVED | STATE_HANDLER_INVALIDATED,
this::endRemoteAnimation);
mStateCallback.runOnceAtState(STATE_TARGET_RECEIVED | STATE_FLING_FINISHED,
@@ -113,14 +109,6 @@
mSwipeDetector.setDetectableScrollConditions(DIRECTION_POSITIVE, false);
}
- @Nullable
- private static ActiveGestureErrorDetector.GestureEvent getTrackedEventForState(int stateFlag) {
- if (stateFlag == STATE_HANDLER_INVALIDATED) {
- return ActiveGestureErrorDetector.GestureEvent.STATE_HANDLER_INVALIDATED;
- }
- return null;
- }
-
@Override
public int getType() {
return TYPE_PROGRESS_DELEGATE;
diff --git a/quickstep/src/com/android/quickstep/util/ActiveGestureErrorDetector.java b/quickstep/src/com/android/quickstep/util/ActiveGestureErrorDetector.java
index 53e0c2b..60065fb 100644
--- a/quickstep/src/com/android/quickstep/util/ActiveGestureErrorDetector.java
+++ b/quickstep/src/com/android/quickstep/util/ActiveGestureErrorDetector.java
@@ -33,10 +33,11 @@
* Enums associated to gesture navigation events.
*/
public enum GestureEvent {
- MOTION_DOWN, MOTION_UP, SET_END_TARGET, SET_END_TARGET_HOME, SET_END_TARGET_LAST_TASK,
- SET_END_TARGET_NEW_TASK, ON_SETTLED_ON_END_TARGET, START_RECENTS_ANIMATION,
- FINISH_RECENTS_ANIMATION, CANCEL_RECENTS_ANIMATION, SET_ON_PAGE_TRANSITION_END_CALLBACK,
- CANCEL_CURRENT_ANIMATION, CLEANUP_SCREENSHOT, SCROLLER_ANIMATION_ABORTED, TASK_APPEARED,
+ MOTION_DOWN, MOTION_UP, SET_END_TARGET, SET_END_TARGET_HOME, SET_END_TARGET_NEW_TASK,
+ ON_SETTLED_ON_END_TARGET, START_RECENTS_ANIMATION, FINISH_RECENTS_ANIMATION,
+ CANCEL_RECENTS_ANIMATION, SET_ON_PAGE_TRANSITION_END_CALLBACK, CANCEL_CURRENT_ANIMATION,
+ CLEANUP_SCREENSHOT, SCROLLER_ANIMATION_ABORTED, TASK_APPEARED, EXPECTING_TASK_APPEARED,
+ FLAG_USING_OTHER_ACTIVITY_INPUT_CONSUMER,
/**
* These GestureEvents are specifically associated to state flags that get set in
@@ -91,35 +92,40 @@
case MOTION_UP:
errorDetected |= printErrorIfTrue(
!encounteredEvents.contains(GestureEvent.MOTION_DOWN),
- /* errorMessage= */ prefix + "\t\tMotion up detected before/without"
+ prefix,
+ /* errorMessage= */ "Motion up detected before/without"
+ " motion down.",
writer);
break;
case ON_SETTLED_ON_END_TARGET:
errorDetected |= printErrorIfTrue(
!encounteredEvents.contains(GestureEvent.SET_END_TARGET),
- /* errorMessage= */ prefix + "\t\tonSettledOnEndTarget called "
+ prefix,
+ /* errorMessage= */ "onSettledOnEndTarget called "
+ "before/without setEndTarget.",
writer);
break;
case FINISH_RECENTS_ANIMATION:
errorDetected |= printErrorIfTrue(
!encounteredEvents.contains(GestureEvent.START_RECENTS_ANIMATION),
- /* errorMessage= */ prefix + "\t\tfinishRecentsAnimation called "
+ prefix,
+ /* errorMessage= */ "finishRecentsAnimation called "
+ "before/without startRecentsAnimation.",
writer);
break;
case CANCEL_RECENTS_ANIMATION:
errorDetected |= printErrorIfTrue(
!encounteredEvents.contains(GestureEvent.START_RECENTS_ANIMATION),
- /* errorMessage= */ prefix + "\t\tcancelRecentsAnimation called "
+ prefix,
+ /* errorMessage= */ "cancelRecentsAnimation called "
+ "before/without startRecentsAnimation.",
writer);
break;
case CLEANUP_SCREENSHOT:
errorDetected |= printErrorIfTrue(
!encounteredEvents.contains(GestureEvent.STATE_SCREENSHOT_CAPTURED),
- /* errorMessage= */ prefix + "\t\trecents activity screenshot was "
+ prefix,
+ /* errorMessage= */ "recents activity screenshot was "
+ "cleaned up before/without STATE_SCREENSHOT_CAPTURED "
+ "being set.",
writer);
@@ -129,48 +135,66 @@
encounteredEvents.contains(GestureEvent.SET_END_TARGET_HOME)
&& !encounteredEvents.contains(
GestureEvent.ON_SETTLED_ON_END_TARGET),
- /* errorMessage= */ prefix + "\t\trecents view scroller animation "
+ prefix,
+ /* errorMessage= */ "recents view scroller animation "
+ "aborted after setting end target HOME, but before"
+ " settling on end target.",
writer);
break;
case TASK_APPEARED:
errorDetected |= printErrorIfTrue(
- !encounteredEvents.contains(GestureEvent.SET_END_TARGET_LAST_TASK)
- && !encounteredEvents.contains(
- GestureEvent.SET_END_TARGET_NEW_TASK),
- /* errorMessage= */ prefix + "\t\tonTasksAppeared called "
- + "before/without setting end target to last or new task",
+ !encounteredEvents.contains(GestureEvent.SET_END_TARGET_NEW_TASK),
+ prefix,
+ /* errorMessage= */ "onTasksAppeared called "
+ + "before/without setting end target to new task",
+ writer);
+ errorDetected |= printErrorIfTrue(
+ !encounteredEvents.contains(GestureEvent.EXPECTING_TASK_APPEARED),
+ prefix,
+ /* errorMessage= */ "onTasksAppeared was not expected to be called",
+ writer);
+ break;
+ case EXPECTING_TASK_APPEARED:
+ errorDetected |= printErrorIfTrue(
+ !encounteredEvents.contains(GestureEvent.SET_END_TARGET_NEW_TASK),
+ prefix,
+ /* errorMessage= */ "expecting onTasksAppeared to be called "
+ + "before/without setting end target to new task",
writer);
break;
case STATE_GESTURE_COMPLETED:
errorDetected |= printErrorIfTrue(
!encounteredEvents.contains(GestureEvent.MOTION_UP),
- /* errorMessage= */ prefix + "\t\tSTATE_GESTURE_COMPLETED set "
+ prefix,
+ /* errorMessage= */ "STATE_GESTURE_COMPLETED set "
+ "before/without motion up.",
writer);
errorDetected |= printErrorIfTrue(
!encounteredEvents.contains(GestureEvent.STATE_GESTURE_STARTED),
- /* errorMessage= */ prefix + "\t\tSTATE_GESTURE_COMPLETED set "
+ prefix,
+ /* errorMessage= */ "STATE_GESTURE_COMPLETED set "
+ "before/without STATE_GESTURE_STARTED.",
writer);
break;
case STATE_GESTURE_CANCELLED:
errorDetected |= printErrorIfTrue(
!encounteredEvents.contains(GestureEvent.MOTION_UP),
- /* errorMessage= */ prefix + "\t\tSTATE_GESTURE_CANCELLED set "
+ prefix,
+ /* errorMessage= */ "STATE_GESTURE_CANCELLED set "
+ "before/without motion up.",
writer);
errorDetected |= printErrorIfTrue(
!encounteredEvents.contains(GestureEvent.STATE_GESTURE_STARTED),
- /* errorMessage= */ prefix + "\t\tSTATE_GESTURE_CANCELLED set "
+ prefix,
+ /* errorMessage= */ "STATE_GESTURE_CANCELLED set "
+ "before/without STATE_GESTURE_STARTED.",
writer);
break;
case STATE_SCREENSHOT_CAPTURED:
errorDetected |= printErrorIfTrue(
!encounteredEvents.contains(GestureEvent.STATE_CAPTURE_SCREENSHOT),
- /* errorMessage= */ prefix + "\t\tSTATE_SCREENSHOT_CAPTURED set "
+ prefix,
+ /* errorMessage= */ "STATE_SCREENSHOT_CAPTURED set "
+ "before/without STATE_CAPTURE_SCREENSHOT.",
writer);
break;
@@ -178,7 +202,8 @@
errorDetected |= printErrorIfTrue(
!encounteredEvents.contains(
GestureEvent.SET_ON_PAGE_TRANSITION_END_CALLBACK),
- /* errorMessage= */ prefix + "\t\tSTATE_RECENTS_SCROLLING_FINISHED "
+ prefix,
+ /* errorMessage= */ "STATE_RECENTS_SCROLLING_FINISHED "
+ "set before/without calling "
+ "setOnPageTransitionEndCallback.",
writer);
@@ -187,16 +212,19 @@
errorDetected |= printErrorIfTrue(
!encounteredEvents.contains(
GestureEvent.START_RECENTS_ANIMATION),
- /* errorMessage= */ prefix + "\t\tSTATE_RECENTS_ANIMATION_CANCELED "
+ prefix,
+ /* errorMessage= */ "STATE_RECENTS_ANIMATION_CANCELED "
+ "set before/without startRecentsAnimation.",
writer);
break;
case MOTION_DOWN:
case SET_END_TARGET:
case SET_END_TARGET_HOME:
+ case SET_END_TARGET_NEW_TASK:
case START_RECENTS_ANIMATION:
case SET_ON_PAGE_TRANSITION_END_CALLBACK:
case CANCEL_CURRENT_ANIMATION:
+ case FLAG_USING_OTHER_ACTIVITY_INPUT_CONSUMER:
case STATE_GESTURE_STARTED:
case STATE_END_TARGET_ANIMATION_FINISHED:
case STATE_CAPTURE_SCREENSHOT:
@@ -210,31 +238,36 @@
// Check that all required events were found.
errorDetected |= printErrorIfTrue(
!encounteredEvents.contains(GestureEvent.MOTION_DOWN),
- /* errorMessage= */ prefix + "\t\tMotion down never detected.",
+ prefix,
+ /* errorMessage= */ "Motion down never detected.",
writer);
errorDetected |= printErrorIfTrue(
!encounteredEvents.contains(GestureEvent.MOTION_UP),
- /* errorMessage= */ prefix + "\t\tMotion up never detected.",
+ prefix,
+ /* errorMessage= */ "Motion up never detected.",
writer);
errorDetected |= printErrorIfTrue(
/* condition= */ encounteredEvents.contains(GestureEvent.SET_END_TARGET)
&& !encounteredEvents.contains(GestureEvent.ON_SETTLED_ON_END_TARGET),
- /* errorMessage= */ prefix + "\t\tsetEndTarget was called, but "
+ prefix,
+ /* errorMessage= */ "setEndTarget was called, but "
+ "onSettledOnEndTarget wasn't.",
writer);
errorDetected |= printErrorIfTrue(
/* condition= */ encounteredEvents.contains(GestureEvent.SET_END_TARGET)
&& !encounteredEvents.contains(
GestureEvent.STATE_END_TARGET_ANIMATION_FINISHED),
- /* errorMessage= */ prefix + "\t\tsetEndTarget was called, but "
+ prefix,
+ /* errorMessage= */ "setEndTarget was called, but "
+ "STATE_END_TARGET_ANIMATION_FINISHED was never set.",
writer);
errorDetected |= printErrorIfTrue(
/* condition= */ encounteredEvents.contains(GestureEvent.SET_END_TARGET)
&& !encounteredEvents.contains(
GestureEvent.STATE_RECENTS_SCROLLING_FINISHED),
- /* errorMessage= */ prefix + "\t\tsetEndTarget was called, but "
+ prefix,
+ /* errorMessage= */ "setEndTarget was called, but "
+ "STATE_RECENTS_SCROLLING_FINISHED was never set.",
writer);
errorDetected |= printErrorIfTrue(
@@ -243,7 +276,8 @@
&& encounteredEvents.contains(
GestureEvent.STATE_RECENTS_SCROLLING_FINISHED)
&& !encounteredEvents.contains(GestureEvent.ON_SETTLED_ON_END_TARGET),
- /* errorMessage= */ prefix + "\t\tSTATE_END_TARGET_ANIMATION_FINISHED and "
+ prefix,
+ /* errorMessage= */ "STATE_END_TARGET_ANIMATION_FINISHED and "
+ "STATE_RECENTS_SCROLLING_FINISHED were set, but onSettledOnEndTarget "
+ "wasn't called.",
writer);
@@ -253,7 +287,8 @@
GestureEvent.START_RECENTS_ANIMATION)
&& !encounteredEvents.contains(GestureEvent.FINISH_RECENTS_ANIMATION)
&& !encounteredEvents.contains(GestureEvent.CANCEL_RECENTS_ANIMATION),
- /* errorMessage= */ prefix + "\t\tstartRecentsAnimation was called, but "
+ prefix,
+ /* errorMessage= */ "startRecentsAnimation was called, but "
+ "finishRecentsAnimation and cancelRecentsAnimation weren't.",
writer);
@@ -261,7 +296,8 @@
/* condition= */ encounteredEvents.contains(GestureEvent.STATE_GESTURE_STARTED)
&& !encounteredEvents.contains(GestureEvent.STATE_GESTURE_COMPLETED)
&& !encounteredEvents.contains(GestureEvent.STATE_GESTURE_CANCELLED),
- /* errorMessage= */ prefix + "\t\tSTATE_GESTURE_STARTED was set, but "
+ prefix,
+ /* errorMessage= */ "STATE_GESTURE_STARTED was set, but "
+ "STATE_GESTURE_COMPLETED and STATE_GESTURE_CANCELLED weren't.",
writer);
@@ -269,7 +305,8 @@
/* condition= */ encounteredEvents.contains(
GestureEvent.STATE_CAPTURE_SCREENSHOT)
&& !encounteredEvents.contains(GestureEvent.STATE_SCREENSHOT_CAPTURED),
- /* errorMessage= */ prefix + "\t\tSTATE_CAPTURE_SCREENSHOT was set, but "
+ prefix,
+ /* errorMessage= */ "STATE_CAPTURE_SCREENSHOT was set, but "
+ "STATE_SCREENSHOT_CAPTURED wasn't.",
writer);
@@ -278,15 +315,18 @@
GestureEvent.SET_ON_PAGE_TRANSITION_END_CALLBACK)
&& !encounteredEvents.contains(
GestureEvent.STATE_RECENTS_SCROLLING_FINISHED),
- /* errorMessage= */ prefix + "\t\tsetOnPageTransitionEndCallback called, but "
+ prefix,
+ /* errorMessage= */ "setOnPageTransitionEndCallback called, but "
+ "STATE_RECENTS_SCROLLING_FINISHED wasn't set.",
writer);
errorDetected |= printErrorIfTrue(
- /* condition= */ !encounteredEvents.contains(
- GestureEvent.CANCEL_CURRENT_ANIMATION)
+ /* condition= */ encounteredEvents.contains(
+ GestureEvent.FLAG_USING_OTHER_ACTIVITY_INPUT_CONSUMER)
+ && !encounteredEvents.contains(GestureEvent.CANCEL_CURRENT_ANIMATION)
&& !encounteredEvents.contains(GestureEvent.STATE_HANDLER_INVALIDATED),
- /* errorMessage= */ prefix + "\t\tAbsSwipeUpHandler.cancelCurrentAnimation "
+ prefix,
+ /* errorMessage= */ "AbsSwipeUpHandler.cancelCurrentAnimation "
+ "wasn't called and STATE_HANDLER_INVALIDATED wasn't set.",
writer);
@@ -294,23 +334,17 @@
/* condition= */ encounteredEvents.contains(
GestureEvent.STATE_RECENTS_ANIMATION_CANCELED)
&& !encounteredEvents.contains(GestureEvent.CLEANUP_SCREENSHOT),
- /* errorMessage= */ prefix + "\t\tSTATE_RECENTS_ANIMATION_CANCELED was set but "
+ prefix,
+ /* errorMessage= */ "STATE_RECENTS_ANIMATION_CANCELED was set but "
+ "the task screenshot wasn't cleaned up.",
writer);
errorDetected |= printErrorIfTrue(
/* condition= */ encounteredEvents.contains(
- GestureEvent.SET_END_TARGET_LAST_TASK)
+ GestureEvent.EXPECTING_TASK_APPEARED)
&& !encounteredEvents.contains(GestureEvent.TASK_APPEARED),
- /* errorMessage= */ prefix + "\t\tend target set to last task, but "
- + "onTaskAppeared wasn't called.",
- writer);
- errorDetected |= printErrorIfTrue(
- /* condition= */ encounteredEvents.contains(
- GestureEvent.SET_END_TARGET_NEW_TASK)
- && !encounteredEvents.contains(GestureEvent.TASK_APPEARED),
- /* errorMessage= */ prefix + "\t\tend target set to new task, but "
- + "onTaskAppeared wasn't called.",
+ prefix,
+ /* errorMessage= */ "onTaskAppeared was expected to be called but wasn't.",
writer);
if (!errorDetected) {
@@ -320,11 +354,11 @@
}
private static boolean printErrorIfTrue(
- boolean condition, String errorMessage, PrintWriter writer) {
+ boolean condition, String prefix, String errorMessage, PrintWriter writer) {
if (!condition) {
return false;
}
- writer.println(errorMessage);
+ writer.println(prefix + "\t\t- " + errorMessage);
return true;
}
}
diff --git a/quickstep/src/com/android/quickstep/util/SplitScreenBounds.java b/quickstep/src/com/android/quickstep/util/SplitScreenBounds.java
deleted file mode 100644
index 483a1c6..0000000
--- a/quickstep/src/com/android/quickstep/util/SplitScreenBounds.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.quickstep.util;
-
-import static android.view.Surface.ROTATION_0;
-import static android.view.Surface.ROTATION_180;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.os.Build;
-import android.view.WindowManager;
-import android.view.WindowMetrics;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.UiThread;
-
-import com.android.launcher3.R;
-import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.WindowBounds;
-
-import java.util.ArrayList;
-
-/**
- * Utility class to hold the information abound a window bounds for split screen
- */
-@TargetApi(Build.VERSION_CODES.R)
-public class SplitScreenBounds {
-
- public static final SplitScreenBounds INSTANCE = new SplitScreenBounds();
- private final ArrayList<OnChangeListener> mListeners = new ArrayList<>();
-
- @Nullable
- private WindowBounds mBounds;
-
- private SplitScreenBounds() { }
-
- @UiThread
- public void setSecondaryWindowBounds(@NonNull WindowBounds bounds) {
- if (!bounds.equals(mBounds)) {
- mBounds = bounds;
- for (OnChangeListener listener : mListeners) {
- listener.onSecondaryWindowBoundsChanged();
- }
- }
- }
-
- public @NonNull WindowBounds getSecondaryWindowBounds(Context context) {
- if (mBounds == null) {
- mBounds = createDefaultWindowBounds(context);
- }
- return mBounds;
- }
-
- /**
- * Creates window bounds as 50% of device size
- */
- private static WindowBounds createDefaultWindowBounds(Context context) {
- WindowMetrics wm = context.getSystemService(WindowManager.class).getMaximumWindowMetrics();
- WindowBounds bounds = WindowBounds.fromWindowMetrics(wm);
-
- int rotation = DisplayController.INSTANCE.get(context).getInfo().rotation;
- int halfDividerSize = context.getResources()
- .getDimensionPixelSize(R.dimen.multi_window_task_divider_size) / 2;
-
- if (rotation == ROTATION_0 || rotation == ROTATION_180) {
- bounds.bounds.top = bounds.insets.top + bounds.availableSize.y / 2 + halfDividerSize;
- bounds.insets.top = 0;
- } else {
- bounds.bounds.left = bounds.insets.left + bounds.availableSize.x / 2 + halfDividerSize;
- bounds.insets.left = 0;
- }
- return new WindowBounds(bounds.bounds, bounds.insets);
- }
-
- public void addOnChangeListener(OnChangeListener listener) {
- mListeners.add(listener);
- }
-
- public void removeOnChangeListener(OnChangeListener listener) {
- mListeners.remove(listener);
- }
-
- /**
- * Interface to receive window bounds changes
- */
- public interface OnChangeListener {
-
- /**
- * Called when window bounds for secondary window changes
- */
- void onSecondaryWindowBoundsChanged();
- }
-}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 8be544e..35414a6 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -178,7 +178,6 @@
import com.android.quickstep.util.LayoutUtils;
import com.android.quickstep.util.RecentsOrientedState;
import com.android.quickstep.util.SplitAnimationTimings;
-import com.android.quickstep.util.SplitScreenBounds;
import com.android.quickstep.util.SplitSelectStateController;
import com.android.quickstep.util.SurfaceTransaction;
import com.android.quickstep.util.SurfaceTransactionApplier;
@@ -210,7 +209,7 @@
public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_TYPE>,
STATE_TYPE extends BaseState<STATE_TYPE>> extends PagedView implements Insettable,
TaskThumbnailCache.HighResLoadingState.HighResLoadingStateChangedCallback,
- TaskVisualsChangeListener, SplitScreenBounds.OnChangeListener {
+ TaskVisualsChangeListener {
private static final String TAG = "RecentsView";
private static final boolean DEBUG = false;
@@ -948,7 +947,6 @@
SystemUiProxy.INSTANCE.get(getContext()).setPipAnimationListener(
mIPipAnimationListener);
mOrientationState.initListeners();
- SplitScreenBounds.INSTANCE.addOnChangeListener(this);
mTaskOverlayFactory.initListeners();
}
@@ -965,7 +963,6 @@
executeSideTaskLaunchCallback();
RecentsModel.INSTANCE.get(getContext()).removeThumbnailChangeListener(this);
SystemUiProxy.INSTANCE.get(getContext()).setPipAnimationListener(null);
- SplitScreenBounds.INSTANCE.removeOnChangeListener(this);
mIPipAnimationListener.setActivityAndRecentsView(null, null);
mOrientationState.destroyListeners();
mTaskOverlayFactory.removeListeners();
@@ -2900,6 +2897,19 @@
InteractionJankMonitorWrapper.begin(this,
InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER, "First tile selected");
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ if (mSplitHiddenTaskView == getRunningTaskView()) {
+ finishRecentsAnimation(true /* toRecents */, false /* shouldPip */,
+ null /* onFinishComplete */);
+ } else {
+ switchToScreenshot(
+ () -> finishRecentsAnimation(true /* toRecents */,
+ false /* shouldPip */, null /* onFinishComplete */));
+ }
+ }
+ });
anim.addEndListener(success -> {
if (success) {
InteractionJankMonitorWrapper.end(
@@ -4190,8 +4200,6 @@
mSplitSelectStateController.setInitialTaskSelect(taskView.getTask(),
stagePosition, splitEvent, taskView.getItemInfo());
mSplitHiddenTaskViewIndex = indexOfChild(taskView);
- finishRecentsAnimation(true /* toRecents */, false /* shouldPip */,
- null /* onFinishComplete */);
}
/**
@@ -5198,12 +5206,6 @@
return null;
}
- @Override
- public void onSecondaryWindowBoundsChanged() {
- // Invalidate the task view size
- setInsets(mInsets);
- }
-
/** Enables or disables modal state for RecentsView */
public abstract void setModalStateEnabled(boolean isModalState, boolean animate);
diff --git a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
index 2ff992e..da86d98 100644
--- a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
@@ -107,8 +107,7 @@
new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
- updateHeaderScroll(
- ((AllAppsRecyclerView) recyclerView).computeVerticalScrollOffset());
+ updateHeaderScroll(recyclerView.computeVerticalScrollOffset());
}
};
@@ -192,7 +191,6 @@
reset(true);
}
}
-
}
@Override
@@ -815,6 +813,10 @@
}
}
+ protected void onInitializeRecyclerView(RecyclerView rv) {
+ rv.addOnScrollListener(mScrollListener);
+ }
+
/** Holds a {@link BaseAllAppsAdapter} and related fields. */
public class AdapterHolder {
public static final int MAIN = 0;
@@ -851,7 +853,7 @@
mRecyclerView.setHasFixedSize(true);
// No animations will occur when changes occur to the items in this RecyclerView.
mRecyclerView.setItemAnimator(null);
- mRecyclerView.addOnScrollListener(mScrollListener);
+ onInitializeRecyclerView(mRecyclerView);
FocusedItemDecorator focusedItemDecorator = new FocusedItemDecorator(mRecyclerView);
mRecyclerView.addItemDecoration(focusedItemDecorator);
mAdapter.setIconFocusListener(focusedItemDecorator.getFocusListener());
diff --git a/src/com/android/launcher3/allapps/BaseSearchConfig.java b/src/com/android/launcher3/allapps/BaseSearchConfig.java
index 9f47e8d..3900954 100644
--- a/src/com/android/launcher3/allapps/BaseSearchConfig.java
+++ b/src/com/android/launcher3/allapps/BaseSearchConfig.java
@@ -25,4 +25,11 @@
public boolean isKeyboardSyncEnabled() {
return false;
}
+
+ /**
+ * Returns whether IME is enabled on swipe up.
+ */
+ public boolean isImeEnabledOnSwipeUp() {
+ return false;
+ }
}
diff --git a/src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java b/src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java
index 20f5e74..92e29bb 100644
--- a/src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java
@@ -16,19 +16,50 @@
package com.android.launcher3.allapps;
import android.content.Context;
+import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.WindowInsets;
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.launcher3.ExtendedEditText;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.Utilities;
+import com.android.launcher3.config.FeatureFlags;
/**
* AllAppsContainerView with launcher specific callbacks
*/
public class LauncherAllAppsContainerView extends ActivityAllAppsContainerView<Launcher> {
+ private final RecyclerView.OnScrollListener mActivityScrollListener =
+ new RecyclerView.OnScrollListener() {
+ @Override
+ public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
+ int scrolledOffset = recyclerView.computeVerticalScrollOffset();
+ ExtendedEditText input = mSearchUiManager.getEditText();
+ // Scroll up and scroll to top
+ if (dy < 0 && scrolledOffset == 0 && input != null) {
+ boolean isImeEnabledOnSwipeUp = Launcher.getLauncher(mActivityContext)
+ .getSearchConfig().isImeEnabledOnSwipeUp();
+ if (isImeEnabledOnSwipeUp || !TextUtils.isEmpty(input.getText())) {
+ input.showKeyboard();
+ }
+ }
+ }
+ };
+
+ @Override
+ protected void onInitializeRecyclerView(RecyclerView rv) {
+ super.onInitializeRecyclerView(rv);
+ if (FeatureFlags.SCROLL_TOP_TO_RESET.get()) {
+ rv.addOnScrollListener(mActivityScrollListener);
+ }
+ }
+
public LauncherAllAppsContainerView(Context context) {
this(context, null);
}
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 32463a5..91c9929 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -290,6 +290,10 @@
public static final BooleanFlag ENABLE_WIDGET_PICKER_DEPTH = new DeviceFlag(
"ENABLE_WIDGET_PICKER_DEPTH", true, "Enable changing depth in widget picker.");
+ public static final BooleanFlag SCROLL_TOP_TO_RESET = new DeviceFlag(
+ "SCROLL_TOP_TO_RESET", false, "Bring up IME and focus on "
+ + "input when scroll to top if 'Always show keyboard' is enabled or in prefix state");
+
public static final BooleanFlag SHOW_DELIGHTFUL_PAGINATION = getDebugFlag(
"SHOW_DELIGHTFUL_PAGINATION", false,
"Enable showing the new 'delightful pagination' which is a brand"
diff --git a/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java b/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java
index 2846cae..9ba3f7b 100644
--- a/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java
+++ b/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java
@@ -116,7 +116,7 @@
FavoriteItemsTransaction transaction =
new FavoriteItemsTransaction(mTargetContext, this);
mWorkspaceBuilder.buildFromBoard(testCase.mStart, transaction).commit();
-
+ waitForLauncherCondition("Workspace didn't finish loading", l -> !l.isWorkspaceLoading());
Widget widget = mLauncher.getWorkspace().getWidgetAtCell(mainWidgetCellPos.x,
mainWidgetCellPos.y);
assertNotNull(widget);