Merge "cleanup misleading logs around restore and grid migration" into main
diff --git a/quickstep/dagger/LauncherAppComponent.java b/quickstep/dagger/com/android/launcher3/dagger/LauncherAppComponent.java
similarity index 91%
rename from quickstep/dagger/LauncherAppComponent.java
rename to quickstep/dagger/com/android/launcher3/dagger/LauncherAppComponent.java
index 068f01c..a4cb420 100644
--- a/quickstep/dagger/LauncherAppComponent.java
+++ b/quickstep/dagger/com/android/launcher3/dagger/LauncherAppComponent.java
@@ -17,7 +17,6 @@
package com.android.launcher3.dagger;
-import com.android.quickstep.dagger.QuickStepModule;
import com.android.quickstep.dagger.QuickstepBaseAppComponent;
import dagger.Component;
@@ -26,7 +25,7 @@
* Root component for Dagger injection for Launcher Quickstep.
*/
@LauncherAppSingleton
-@Component(modules = QuickStepModule.class)
+@Component(modules = LauncherAppModule.class)
public interface LauncherAppComponent extends QuickstepBaseAppComponent {
/** Builder for quickstep LauncherAppComponent. */
@Component.Builder
diff --git a/quickstep/dagger/com/android/launcher3/dagger/LauncherAppModule.java b/quickstep/dagger/com/android/launcher3/dagger/LauncherAppModule.java
new file mode 100644
index 0000000..1711fc1
--- /dev/null
+++ b/quickstep/dagger/com/android/launcher3/dagger/LauncherAppModule.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.dagger;
+
+import com.android.quickstep.dagger.QuickStepModule;
+
+import dagger.Module;
+
+@Module(includes = QuickStepModule.class)
+public class LauncherAppModule {}
diff --git a/quickstep/res/layout/floating_header_content.xml b/quickstep/res/layout/floating_header_content.xml
index b21c34b..0021e22 100644
--- a/quickstep/res/layout/floating_header_content.xml
+++ b/quickstep/res/layout/floating_header_content.xml
@@ -3,8 +3,8 @@
<com.android.launcher3.appprediction.PredictionRowView
android:id="@+id/prediction_row"
- android:accessibilityPaneTitle="@string/title_app_suggestions"
android:layout_width="match_parent"
+ android:importantForAccessibility="yes"
android:layout_height="wrap_content" />
<com.android.launcher3.appprediction.AppsDividerView
diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml
index 026e25c..df949c3 100644
--- a/quickstep/res/values/strings.xml
+++ b/quickstep/res/values/strings.xml
@@ -125,8 +125,6 @@
<string name="back_gesture_intro_title">Swipe to go back</string>
<!-- Introduction subtitle for the Back gesture tutorial. [CHAR LIMIT=200] -->
<string name="back_gesture_intro_subtitle">To go back to the last screen, swipe from the left or right edge to the middle of the screen.</string>
- <!-- Introduction subtitle for the Back gesture tutorial that will be spoken by screen readers. [CHAR LIMIT=200] -->
- <string name="back_gesture_spoken_intro_subtitle">To go back to the last screen, swipe with 2 fingers from the left or right edge to the middle of the screen.</string>
<!-- Title of the gesture tutorial section educating users on how to go back to the previous screen. [CHAR LIMIT=100] -->
<string name="back_gesture_tutorial_title">Go back</string>
<!-- Subtitle of the gesture tutorial section educating users on how to go to back to the previous screen [CHAR LIMIT=100] -->
@@ -145,8 +143,6 @@
<string name="home_gesture_intro_title">Swipe to go home</string>
<!-- Introduction subtitle for the Home gesture tutorial. [CHAR LIMIT=100] -->
<string name="home_gesture_intro_subtitle">Swipe up from the bottom of your screen. This gesture always takes you to the Home screen.</string>
- <!-- Introduction subtitle for the Home gesture tutorial that will be spoken by screen readers. [CHAR LIMIT=100] -->
- <string name="home_gesture_spoken_intro_subtitle">Swipe up with 2 fingers from the bottom of the screen. This gesture always takes you to the Home screen.</string>
<!-- Title of the gesture tutorial section educating users on how to go to the home screen. [CHAR LIMIT=100] -->
<string name="home_gesture_tutorial_title">Go home</string>
<!-- Subtitle of the gesture tutorial section educating users on how to go to the home screen [CHAR LIMIT=100] -->
@@ -168,8 +164,6 @@
<string name="overview_gesture_intro_title">Swipe to switch apps</string>
<!-- Introduction subtitle for the Overview gesture tutorial. [CHAR LIMIT=100] -->
<string name="overview_gesture_intro_subtitle">To switch between apps, swipe up from the bottom of your screen, hold, then release.</string>
- <!-- Introduction subtitle for the Overview gesture tutorial that will be spoken by screen readers. [CHAR LIMIT=100] -->
- <string name="overview_gesture_spoken_intro_subtitle">To switch between apps, swipe up with 2 fingers from the bottom of your screen, hold, then release.</string>
<!-- Title of the gesture tutorial section educating users on how to switch between apps. [CHAR LIMIT=100] -->
<string name="overview_gesture_tutorial_title">Switch apps</string>
<!-- Subtitle of the gesture tutorial section educating users on how to switch between apps [CHAR LIMIT=100] -->
diff --git a/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java b/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java
index 8e80aa5..22e491f 100644
--- a/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java
+++ b/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java
@@ -16,12 +16,16 @@
package com.android.launcher3.appprediction;
+import static android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE;
+
import android.content.Context;
import android.graphics.Canvas;
+import android.os.Build;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.LinearLayout;
import androidx.annotation.NonNull;
@@ -91,6 +95,14 @@
}
@Override
+ public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(info);
+ if (Build.VERSION.SDK_INT >= UPSIDE_DOWN_CAKE) {
+ info.setContainerTitle(mActivityContext.getString(R.string.title_app_suggestions));
+ }
+ }
+
+ @Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
mActivityContext.addOnDeviceProfileChangeListener(this);
diff --git a/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java
index 6a908ca..d6327bc 100644
--- a/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java
@@ -28,7 +28,6 @@
import com.android.launcher3.statemanager.StatefulContainer;
import com.android.quickstep.TopTaskTracker;
import com.android.quickstep.fallback.RecentsState;
-import com.android.quickstep.util.TISBindHelper;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.RecentsViewContainer;
@@ -139,12 +138,6 @@
return topTask.isHomeTask() || topTask.isRecentsTask();
}
- @Nullable
- @Override
- protected TISBindHelper getTISBindHelper() {
- return mRecentsContainer.getTISBindHelper();
- }
-
@Override
protected String getTaskbarUIControllerName() {
return "FallbackTaskbarUIController<" + mRecentsContainer.getClass().getSimpleName() + ">";
diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
index ea42d77..a6eee08 100644
--- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
@@ -49,7 +49,6 @@
import com.android.quickstep.RecentsAnimationCallbacks;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.util.GroupTask;
-import com.android.quickstep.util.TISBindHelper;
import com.android.quickstep.views.RecentsView;
import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
import com.android.wm.shell.shared.bubbles.BubbleBarLocation;
@@ -485,12 +484,6 @@
mTaskbarLauncherStateController.resetIconAlignment();
}
- @Nullable
- @Override
- protected TISBindHelper getTISBindHelper() {
- return mLauncher.getTISBindHelper();
- }
-
@Override
public void dumpLogs(String prefix, PrintWriter pw) {
super.dumpLogs(prefix, pw);
diff --git a/quickstep/src/com/android/launcher3/taskbar/ManageWindowsTaskbarShortcut.kt b/quickstep/src/com/android/launcher3/taskbar/ManageWindowsTaskbarShortcut.kt
index 032eb51..75ce7c3 100644
--- a/quickstep/src/com/android/launcher3/taskbar/ManageWindowsTaskbarShortcut.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/ManageWindowsTaskbarShortcut.kt
@@ -148,11 +148,19 @@
FLAG_AUTOHIDE_SUSPEND_MULTI_INSTANCE_MENU_OPEN,
false,
)
+ controllers.taskbarPopupController.cleanUpMultiInstanceMenuReference()
}
}
)
}
+ /** Closes the multi-instance menu if it has been initialized. */
+ fun closeMultiInstanceMenu() {
+ if (::taskbarShortcutAllWindowsView.isInitialized) {
+ taskbarShortcutAllWindowsView.animateClose()
+ }
+ }
+
/**
* A view container for displaying the window of open instances of an app
*
@@ -238,6 +246,7 @@
)
taskbarOverlayContext.dragLayer?.removeView(menuView.rootView)
taskbarOverlayContext.dragLayer.removeTouchController(this)
+ controllers.taskbarPopupController.cleanUpMultiInstanceMenuReference()
}
/** TouchController implementations for closing the carousel when touched outside */
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 7b326c1..933eb96 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -1401,6 +1401,7 @@
Log.e(TAG, "Unknown type clicked: " + tag);
}
+ mControllers.taskbarPopupController.maybeCloseMultiInstanceMenu();
if (shouldCloseAllOpenViews) {
AbstractFloatingView.closeAllOpenViews(this);
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
index 9407e73..3e9a073 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
@@ -47,6 +47,7 @@
import android.provider.Settings;
import android.util.Log;
import android.util.SparseArray;
+import android.util.SparseBooleanArray;
import android.view.Display;
import android.view.MotionEvent;
import android.view.WindowManager;
@@ -116,7 +117,6 @@
private final Context mWindowContext;
private final @Nullable Context mNavigationBarPanelContext;
private WindowManager mWindowManager;
- private boolean mAddedWindow;
private final TaskbarNavButtonController mDefaultNavButtonController;
private final ComponentCallbacks mDefaultComponentCallbacks;
@@ -133,6 +133,8 @@
private final SparseArray<TaskbarActivityContext> mTaskbars = new SparseArray<>();
/** DisplayId - {@link FrameLayout} map for Connected Display. */
private final SparseArray<FrameLayout> mRootLayouts = new SparseArray<>();
+ /** DisplayId - {@link Boolean} map indicating if RootLayout was added to window. */
+ private final SparseBooleanArray mAddedRootLayouts = new SparseBooleanArray();
private StatefulActivity mActivity;
private RecentsViewContainer mRecentsViewContainer;
@@ -742,23 +744,42 @@
private void addTaskbarRootViewToWindow(int displayId) {
TaskbarActivityContext taskbar = getTaskbarForDisplay(displayId);
- if (enableTaskbarNoRecreate() && !mAddedWindow && taskbar != null) {
+ if (!enableTaskbarNoRecreate() || taskbar == null) {
+ return;
+ }
+
+ if (!isTaskbarRootLayoutAddedForDisplay(displayId)) {
mWindowManager.addView(getTaskbarRootLayoutForDisplay(displayId),
taskbar.getWindowLayoutParams());
- mAddedWindow = true;
+ mAddedRootLayouts.put(displayId, true);
}
}
private void removeTaskbarRootViewFromWindow(int displayId) {
FrameLayout rootLayout = getTaskbarRootLayoutForDisplay(displayId);
- if (enableTaskbarNoRecreate() && mAddedWindow && rootLayout != null) {
+ if (!enableTaskbarNoRecreate() || rootLayout == null) {
+ return;
+ }
+
+ if (isTaskbarRootLayoutAddedForDisplay(displayId)) {
mWindowManager.removeViewImmediate(rootLayout);
- mAddedWindow = false;
+ mAddedRootLayouts.put(displayId, false);
removeTaskbarRootLayoutFromMap(displayId);
}
}
/**
+ * Retrieves whether RootLayout was added to window for specific display, or false if no
+ * such mapping has been made.
+ *
+ * @param displayId The ID of the display for which to retrieve the taskbar root layout.
+ * @return if RootLayout was added to window {@link Boolean} for a display or {@code false}.
+ */
+ private boolean isTaskbarRootLayoutAddedForDisplay(int displayId) {
+ return mAddedRootLayouts.get(displayId);
+ }
+
+ /**
* Returns the {@link TaskbarActivityContext} associated with the given display ID.
*
* @param displayId The ID of the display to retrieve the taskbar for.
@@ -853,6 +874,7 @@
*/
private void removeTaskbarRootLayoutFromMap(int displayId) {
if (mRootLayouts.contains(displayId)) {
+ mAddedRootLayouts.delete(displayId);
mRootLayouts.delete(displayId);
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java
index 4881836..d1f9be0 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java
@@ -344,6 +344,10 @@
mCallbacks.onToggleOverview();
}
+ public void hideOverview() {
+ mCallbacks.onHideOverview();
+ }
+
void sendBackKeyEvent(int action, boolean cancelled) {
if (action == mLastSentBackAction) {
// There must always be an alternating sequence of ACTION_DOWN and ACTION_UP events
@@ -411,5 +415,8 @@
/** Callback invoked when the overview button is pressed. */
default void onToggleOverview() {}
+
+ /** Callback invoken when a visible overview needs to be hidden. */
+ default void onHideOverview() { }
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java
index 772d45d..6789824 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java
@@ -87,6 +87,8 @@
private TaskbarControllers mControllers;
private boolean mAllowInitialSplitSelection;
private AppInfo[] mAppInfosList;
+ private ManageWindowsTaskbarShortcut<BaseTaskbarContext> mManageWindowsTaskbarShortcut;
+
public TaskbarPopupController(TaskbarActivityContext context) {
mContext = context;
@@ -112,6 +114,19 @@
mPopupDataProvider.setDeepShortcutMap(deepShortcutMapCopy);
}
+ /** Closes the multi-instance menu if it is enabled and currently open. */
+ public void maybeCloseMultiInstanceMenu() {
+ if (Flags.enableMultiInstanceMenuTaskbar() && mManageWindowsTaskbarShortcut != null) {
+ mManageWindowsTaskbarShortcut.closeMultiInstanceMenu();
+ cleanUpMultiInstanceMenuReference();
+ }
+ }
+
+ /** Releases the reference to the Taskbar multi-instance menu */
+ public void cleanUpMultiInstanceMenuReference() {
+ mManageWindowsTaskbarShortcut = null;
+ }
+
public void setAllowInitialSplitSelection(boolean allowInitialSplitSelection) {
mAllowInitialSplitSelection = allowInitialSplitSelection;
}
@@ -210,6 +225,7 @@
if (Flags.enableMultiInstanceMenuTaskbar()
&& DesktopModeStatus.canEnterDesktopMode(mContext)
&& !mControllers.taskbarStashController.isInOverview()) {
+ maybeCloseMultiInstanceMenu();
shortcuts.addAll(getMultiInstanceMenuOptions().toList());
}
return shortcuts.stream();
@@ -329,8 +345,9 @@
public SystemShortcut.Factory<BaseTaskbarContext> createManageWindowsShortcutFactory() {
return (context, itemInfo, originalView) -> {
if (shouldShowMultiInstanceOptions(itemInfo)) {
- return new ManageWindowsTaskbarShortcut<>(context, itemInfo, originalView,
- mControllers);
+ mManageWindowsTaskbarShortcut = new ManageWindowsTaskbarShortcut<>(
+ context, itemInfo, originalView, mControllers);
+ return mManageWindowsTaskbarShortcut;
}
return null;
};
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
index 8b636dd..f29f95d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
@@ -39,10 +39,7 @@
import com.android.launcher3.taskbar.bubbles.BubbleBarController;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.SplitConfigurationOptions;
-import com.android.quickstep.OverviewCommandHelper;
-import com.android.quickstep.OverviewCommandHelper.CommandType;
import com.android.quickstep.util.GroupTask;
-import com.android.quickstep.util.TISBindHelper;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskContainer;
import com.android.quickstep.views.TaskView;
@@ -389,26 +386,13 @@
/** Adjusts the hotseat for the bubble bar. */
public void adjustHotseatForBubbleBar(boolean isBubbleBarVisible) {}
- @Nullable
- protected TISBindHelper getTISBindHelper() {
- return null;
- }
-
/**
* Launches the focused task in the Keyboard Quick Switch view through the OverviewCommandHelper
* <p>
* Use this helper method when the focused task may be the overview task.
*/
public void launchKeyboardFocusedTask() {
- TISBindHelper tisBindHelper = getTISBindHelper();
- if (tisBindHelper == null) {
- return;
- }
- OverviewCommandHelper overviewCommandHelper = tisBindHelper.getOverviewCommandHelper();
- if (overviewCommandHelper == null) {
- return;
- }
- overviewCommandHelper.addCommand(CommandType.HIDE);
+ mControllers.navButtonController.hideOverview();
}
/**
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java
index 07d86e4..ddbf3b7 100644
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java
@@ -141,6 +141,7 @@
if (isOpen()) {
mSlideInView.close(true);
} else {
+ mControllers.taskbarPopupController.maybeCloseMultiInstanceMenu();
show(true, showKeyboard);
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt
index 3bff58b..745c689 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt
@@ -531,7 +531,7 @@
bubbleStashController.getStashedHandlePhysicsAnimator().cancelIfRunning()
resetBubbleBarPropertiesOnInterrupt()
bubbleStashController.onNewBubbleAnimationInterrupted(
- /* isStashed= */ bubbleBarView.alpha == 0f,
+ /* isStashed= */ bubbleStashController.isStashed,
bubbleBarView.translationY,
)
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index e17771c..4c5e655 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -1434,12 +1434,6 @@
return (mTaskbarUIController != null && mTaskbarUIController.hasBubbles());
}
- @NonNull
- @Override
- public TISBindHelper getTISBindHelper() {
- return mTISBindHelper;
- }
-
@Override
public boolean handleIncorrectSplitTargetSelection() {
if (!enableSplitContextually() || !mSplitSelectStateController.isSplitSelectActive()) {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
index d387794..dae63af 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
@@ -102,7 +102,7 @@
@Override
public int getTitle() {
- return R.string.all_apps_label;
+ return R.string.all_apps_list_label;
}
@Override
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 3740a68..03394ef 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -131,7 +131,6 @@
import com.android.launcher3.util.WindowBounds;
import com.android.quickstep.GestureState.GestureEndTarget;
import com.android.quickstep.RemoteTargetGluer.RemoteTargetHandle;
-import com.android.quickstep.fallback.window.RecentsWindowFactory;
import com.android.quickstep.util.ActiveGestureErrorDetector;
import com.android.quickstep.util.ActiveGestureLog;
import com.android.quickstep.util.ActiveGestureProtoLogProxy;
@@ -310,7 +309,6 @@
private static final int LOG_NO_OP_PAGE_INDEX = -1;
protected final TaskAnimationManager mTaskAnimationManager;
- protected final RecentsWindowFactory mRecentsWindowFactory;
// Either RectFSpringAnim (if animating home) or ObjectAnimator (from mCurrentShift) otherwise
private RunningWindowAnim[] mRunningWindowAnim;
// Possible second animation running at the same time as mRunningWindowAnim
@@ -376,7 +374,7 @@
public AbsSwipeUpHandler(Context context, RecentsAnimationDeviceState deviceState,
TaskAnimationManager taskAnimationManager, GestureState gestureState,
long touchTimeMs, boolean continuingLastGesture,
- InputConsumerController inputConsumer, RecentsWindowFactory recentsWindowFactory,
+ InputConsumerController inputConsumer,
MSDLPlayerWrapper msdlPlayerWrapper) {
super(context, deviceState, gestureState);
mContainerInterface = gestureState.getContainerInterface();
@@ -393,7 +391,6 @@
endLauncherTransitionController();
}, new InputProxyHandlerFactory(mContainerInterface, mGestureState));
mTaskAnimationManager = taskAnimationManager;
- mRecentsWindowFactory = recentsWindowFactory;
mTouchTimeMs = touchTimeMs;
mContinuingLastGesture = continuingLastGesture;
diff --git a/quickstep/src/com/android/quickstep/DisplayModel.kt b/quickstep/src/com/android/quickstep/DisplayModel.kt
new file mode 100644
index 0000000..cbc2f7d
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/DisplayModel.kt
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2024 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
+
+import android.content.Context
+import android.hardware.display.DisplayManager
+import android.util.Log
+import android.util.SparseArray
+import androidx.core.util.valueIterator
+import com.android.quickstep.DisplayModel.DisplayResource
+
+/** data model for managing resources with lifecycles that match that of the connected display */
+abstract class DisplayModel<RESOURCE_TYPE : DisplayResource>(val context: Context) {
+
+ companion object {
+ private const val TAG = "DisplayViewModel"
+ private const val DEBUG = false
+ }
+
+ protected val displayManager =
+ context.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
+ protected val displayResourceArray = SparseArray<RESOURCE_TYPE>()
+
+ abstract fun createDisplayResource(displayId: Int)
+
+ protected val displayListener: DisplayManager.DisplayListener =
+ (object : DisplayManager.DisplayListener {
+ override fun onDisplayAdded(displayId: Int) {
+ if (DEBUG) Log.d(TAG, "onDisplayAdded: displayId=$displayId")
+ createDisplayResource(displayId)
+ }
+
+ override fun onDisplayRemoved(displayId: Int) {
+ if (DEBUG) Log.d(TAG, "onDisplayRemoved: displayId=$displayId")
+ deleteDisplayResource(displayId)
+ }
+
+ override fun onDisplayChanged(displayId: Int) {
+ if (DEBUG) Log.d(TAG, "onDisplayChanged: displayId=$displayId")
+ }
+ })
+
+ fun destroy() {
+ displayResourceArray.valueIterator().forEach { displayResource ->
+ displayResource.cleanup()
+ }
+ displayResourceArray.clear()
+ displayManager.unregisterDisplayListener(displayListener)
+ }
+
+ fun getDisplayResource(displayId: Int): RESOURCE_TYPE? {
+ if (DEBUG) Log.d(TAG, "get: displayId=$displayId")
+ return displayResourceArray[displayId]
+ }
+
+ fun deleteDisplayResource(displayId: Int) {
+ if (DEBUG) Log.d(TAG, "delete: displayId=$displayId")
+ getDisplayResource(displayId)?.cleanup()
+ displayResourceArray.remove(displayId)
+ }
+
+ abstract class DisplayResource() {
+ abstract fun cleanup()
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java b/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
index b0c69cf..1e857ca 100644
--- a/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
@@ -106,7 +106,7 @@
boolean continuingLastGesture, InputConsumerController inputConsumer,
MSDLPlayerWrapper msdlPlayerWrapper) {
super(context, deviceState, taskAnimationManager, gestureState, touchTimeMs,
- continuingLastGesture, inputConsumer, null, msdlPlayerWrapper);
+ continuingLastGesture, inputConsumer, msdlPlayerWrapper);
mRunningOverHome = mGestureState.getRunningTask() != null
&& mGestureState.getRunningTask().isHomeTask();
diff --git a/quickstep/src/com/android/quickstep/FallbackWindowInterface.java b/quickstep/src/com/android/quickstep/FallbackWindowInterface.java
index a202ebd..f7836b0 100644
--- a/quickstep/src/com/android/quickstep/FallbackWindowInterface.java
+++ b/quickstep/src/com/android/quickstep/FallbackWindowInterface.java
@@ -41,8 +41,6 @@
import com.android.quickstep.util.ContextInitListener;
import com.android.quickstep.views.RecentsView;
-import java.util.HashMap;
-import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Predicate;
@@ -53,35 +51,13 @@
*/
public final class FallbackWindowInterface extends BaseWindowInterface{
- static Map<Integer, FallbackWindowInterface> sWindowInterfaceMap = new HashMap<>();
-
private final RecentsWindowManager mRecentsWindowManager;
- /**
- * This is only null before init() or after destroy()
- */
- @Nullable
- public static FallbackWindowInterface getInstance(int displayId) {
- return sWindowInterfaceMap.get(displayId);
- }
- /**
- * initializing instance and mapping it to display id
- */
- public static void init(int displayId, RecentsWindowManager recentsWindowManager) {
- if (!sWindowInterfaceMap.containsKey(displayId)) {
- sWindowInterfaceMap.put(displayId, new FallbackWindowInterface(recentsWindowManager));
- }
- }
-
- private FallbackWindowInterface(RecentsWindowManager recentsWindowManager) {
+ public FallbackWindowInterface(RecentsWindowManager recentsWindowManager) {
super(DEFAULT, BACKGROUND_APP);
mRecentsWindowManager = recentsWindowManager;
}
- public void destroy() {
- sWindowInterfaceMap.clear();
- }
-
/** 2 */
@Override
public int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context, Rect outRect,
diff --git a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
index 7dd2f2e..1827cc3 100644
--- a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
+++ b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
@@ -71,7 +71,7 @@
boolean continuingLastGesture, InputConsumerController inputConsumer,
MSDLPlayerWrapper msdlPlayerWrapper) {
super(context, deviceState, taskAnimationManager, gestureState, touchTimeMs,
- continuingLastGesture, inputConsumer, null, msdlPlayerWrapper);
+ continuingLastGesture, inputConsumer, msdlPlayerWrapper);
}
diff --git a/quickstep/src/com/android/quickstep/OverviewComponentObserver.java b/quickstep/src/com/android/quickstep/OverviewComponentObserver.java
index bac5e64..1fc0401 100644
--- a/quickstep/src/com/android/quickstep/OverviewComponentObserver.java
+++ b/quickstep/src/com/android/quickstep/OverviewComponentObserver.java
@@ -42,6 +42,7 @@
import com.android.launcher3.Flags;
import com.android.launcher3.R;
import com.android.launcher3.util.SimpleBroadcastReceiver;
+import com.android.quickstep.fallback.window.RecentsDisplayModel;
import com.android.quickstep.util.ActiveGestureProtoLogProxy;
import com.android.systemui.shared.system.PackageManagerWrapper;
@@ -181,7 +182,8 @@
if (Flags.enableLauncherOverviewInWindow() || Flags.enableFallbackOverviewInWindow()) {
mContainerInterface =
- FallbackWindowInterface.getInstance(mDeviceState.getDisplayId());
+ RecentsDisplayModel.getINSTANCE().get(mContext)
+ .getFallbackWindowInterface(mDeviceState.getDisplayId());
} else {
mContainerInterface = FallbackActivityInterface.INSTANCE;
}
diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java
index 61a150b..17c17cc 100644
--- a/quickstep/src/com/android/quickstep/RecentsActivity.java
+++ b/quickstep/src/com/android/quickstep/RecentsActivity.java
@@ -554,12 +554,6 @@
return overviewCommandHelper == null || overviewCommandHelper.canStartHomeSafely();
}
- @NonNull
- @Override
- public TISBindHelper getTISBindHelper() {
- return mTISBindHelper;
- }
-
@Override
public boolean isRecentsViewVisible() {
return getStateManager().getState().isRecentsViewVisible();
diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
index 2fcfa36..e0d4ddd 100644
--- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java
+++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
@@ -47,7 +47,7 @@
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.taskbar.TaskbarUIController;
import com.android.launcher3.util.DisplayController;
-import com.android.quickstep.fallback.window.RecentsWindowFactory;
+import com.android.quickstep.fallback.window.RecentsDisplayModel;
import com.android.quickstep.fallback.window.RecentsWindowManager;
import com.android.quickstep.util.ActiveGestureProtoLogProxy;
import com.android.quickstep.util.SystemUiFlagUtils;
@@ -66,7 +66,6 @@
SystemProperties.getBoolean("persist.wm.debug.shell_transit_rotate", false);
private final Context mCtx;
- private RecentsWindowFactory mRecentsWindowFactory;
private RecentsAnimationController mController;
private RecentsAnimationCallbacks mCallbacks;
private RecentsAnimationTargets mTargets;
@@ -103,11 +102,9 @@
}
};
- TaskAnimationManager(Context ctx, RecentsWindowFactory recentsWindowFactory,
- RecentsAnimationDeviceState deviceState) {
+ TaskAnimationManager(Context ctx, RecentsAnimationDeviceState deviceState) {
mCtx = ctx;
mDeviceState = deviceState;
- mRecentsWindowFactory = recentsWindowFactory;
}
SystemUiProxy getSystemUiProxy() {
return SystemUiProxy.INSTANCE.get(mCtx);
@@ -303,7 +300,8 @@
|| Flags.enableLauncherOverviewInWindow())) {
mRecentsAnimationStartPending = getSystemUiProxy().startRecentsActivity(intent, options,
mCallbacks, gestureState.useSyntheticRecentsTransition());
- mRecentsWindowFactory.create(mDeviceState.getDisplayId())
+ RecentsDisplayModel.getINSTANCE().get(mCtx)
+ .getRecentsWindowManager(mDeviceState.getDisplayId())
.startRecentsWindow(mCallbacks);
} else {
options.setPendingIntentBackgroundActivityStartMode(
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 4ddbcdb..9de96c7 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -90,7 +90,6 @@
import com.android.launcher3.util.ScreenOnTracker;
import com.android.launcher3.util.TraceHelper;
import com.android.quickstep.OverviewCommandHelper.CommandType;
-import com.android.quickstep.fallback.window.RecentsWindowFactory;
import com.android.quickstep.fallback.window.RecentsWindowSwipeHandler;
import com.android.quickstep.inputconsumers.BubbleBarInputConsumer;
import com.android.quickstep.inputconsumers.OneHandedModeInputConsumer;
@@ -613,6 +612,11 @@
public void onToggleOverview() {
mOverviewCommandHelper.addCommand(CommandType.TOGGLE);
}
+
+ @Override
+ public void onHideOverview() {
+ mOverviewCommandHelper.addCommand(CommandType.HIDE);
+ }
};
private ActivityManagerWrapper mAM;
@@ -632,7 +636,6 @@
private InputEventReceiver mInputEventReceiver;
private TaskbarManager mTaskbarManager;
- private RecentsWindowFactory mRecentsWindowFactory;
private Function<GestureState, AnimatedFloat> mSwipeUpProxyProvider = i -> null;
private AllAppsActionManager mAllAppsActionManager;
private InputManager mInputManager;
@@ -669,9 +672,6 @@
mDesktopAppLaunchTransitionManager =
new DesktopAppLaunchTransitionManager(this, SystemUiProxy.INSTANCE.get(this));
mDesktopAppLaunchTransitionManager.registerTransitions();
- if (Flags.enableLauncherOverviewInWindow() || Flags.enableFallbackOverviewInWindow()) {
- mRecentsWindowFactory = new RecentsWindowFactory(this);
- }
mInputConsumer = InputConsumerController.getRecentsAnimationInputConsumer();
// Call runOnUserUnlocked() before any other callbacks to ensure everything is initialized.
@@ -723,7 +723,7 @@
public void onUserUnlocked() {
Log.d(TAG, "onUserUnlocked: userId=" + getUserId()
+ " instance=" + System.identityHashCode(this));
- mTaskAnimationManager = new TaskAnimationManager(this, mRecentsWindowFactory, mDeviceState);
+ mTaskAnimationManager = new TaskAnimationManager(this, mDeviceState);
mOverviewComponentObserver = new OverviewComponentObserver(this, mDeviceState);
mOverviewCommandHelper = new OverviewCommandHelper(this,
mOverviewComponentObserver, mTaskAnimationManager);
@@ -830,10 +830,6 @@
mTrackpadsConnected.clear();
mTaskbarManager.destroy();
-
- if (mRecentsWindowFactory != null) {
- mRecentsWindowFactory.destroy();
- }
if (mDesktopAppLaunchTransitionManager != null) {
mDesktopAppLaunchTransitionManager.unregisterTransitions();
}
@@ -1289,6 +1285,6 @@
GestureState gestureState, long touchTimeMs) {
return new RecentsWindowSwipeHandler(this, mDeviceState, mTaskAnimationManager,
gestureState, touchTimeMs, mTaskAnimationManager.isRecentsAnimationRunning(),
- mInputConsumer, mRecentsWindowFactory, MSDLPlayerWrapper.INSTANCE.get(this));
+ mInputConsumer, MSDLPlayerWrapper.INSTANCE.get(this));
}
}
diff --git a/quickstep/src/com/android/quickstep/dagger/QuickstepBaseAppComponent.java b/quickstep/src/com/android/quickstep/dagger/QuickstepBaseAppComponent.java
index b2670e8..4255372 100644
--- a/quickstep/src/com/android/quickstep/dagger/QuickstepBaseAppComponent.java
+++ b/quickstep/src/com/android/quickstep/dagger/QuickstepBaseAppComponent.java
@@ -20,6 +20,7 @@
import com.android.launcher3.dagger.LauncherBaseAppComponent;
import com.android.launcher3.model.WellbeingModel;
import com.android.quickstep.SystemUiProxy;
+import com.android.quickstep.fallback.window.RecentsDisplayModel;
import com.android.quickstep.util.AsyncClockEventDelegate;
/**
@@ -37,4 +38,6 @@
AsyncClockEventDelegate getAsyncClockEventDelegate();
SystemUiProxy getSystemUiProxy();
+
+ RecentsDisplayModel getRecentsDisplayModel();
}
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
index 980dee4..9625d29 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -43,9 +43,9 @@
import com.android.launcher3.util.SplitConfigurationOptions.SplitSelectSource;
import com.android.quickstep.BaseContainerInterface;
import com.android.quickstep.FallbackActivityInterface;
-import com.android.quickstep.FallbackWindowInterface;
import com.android.quickstep.GestureState;
import com.android.quickstep.RotationTouchHelper;
+import com.android.quickstep.fallback.window.RecentsDisplayModel;
import com.android.quickstep.util.GroupTask;
import com.android.quickstep.util.SplitSelectStateController;
import com.android.quickstep.util.TaskViewSimulator;
@@ -80,8 +80,8 @@
@Override
public BaseContainerInterface<RecentsState, ?> getContainerInterface(int displayId) {
return (Flags.enableFallbackOverviewInWindow() || Flags.enableLauncherOverviewInWindow())
- ? FallbackWindowInterface.getInstance(displayId)
- : FallbackActivityInterface.INSTANCE;
+ ? RecentsDisplayModel.getINSTANCE().get(mContext)
+ .getFallbackWindowInterface(displayId) : FallbackActivityInterface.INSTANCE;
}
@Override
@@ -264,13 +264,13 @@
}
setFreezeViewVisibility(true);
- if (mContainer.getDesktopVisibilityController() != null) {
- mContainer.getDesktopVisibilityController().onLauncherStateChanged(toState);
- }
}
@Override
public void onStateTransitionComplete(RecentsState finalState) {
+ if (mContainer.getDesktopVisibilityController() != null) {
+ mContainer.getDesktopVisibilityController().onLauncherStateChanged(finalState);
+ }
if (!finalState.isRecentsViewVisible()) {
// Clean-up logic that occurs when recents is no longer in use/visible.
reset();
diff --git a/quickstep/src/com/android/quickstep/fallback/window/RecentsDisplayModel.kt b/quickstep/src/com/android/quickstep/fallback/window/RecentsDisplayModel.kt
new file mode 100644
index 0000000..a9259d9
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/fallback/window/RecentsDisplayModel.kt
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2024 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.fallback.window
+
+import android.content.Context
+import android.os.Handler
+import android.util.Log
+import android.view.Display
+import com.android.launcher3.Flags
+import com.android.launcher3.dagger.ApplicationContext
+import com.android.launcher3.dagger.LauncherAppSingleton
+import com.android.launcher3.util.DaggerSingletonObject
+import com.android.quickstep.DisplayModel
+import com.android.quickstep.FallbackWindowInterface
+import com.android.quickstep.dagger.QuickstepBaseAppComponent
+import com.android.quickstep.fallback.window.RecentsDisplayModel.RecentsDisplayResource
+import javax.inject.Inject
+
+@LauncherAppSingleton
+class RecentsDisplayModel @Inject constructor(@ApplicationContext context: Context) :
+ DisplayModel<RecentsDisplayResource>(context) {
+
+ companion object {
+ private const val TAG = "RecentsDisplayModel"
+ private const val DEBUG = false
+
+ @JvmStatic
+ val INSTANCE: DaggerSingletonObject<RecentsDisplayModel> =
+ DaggerSingletonObject<RecentsDisplayModel>(
+ QuickstepBaseAppComponent::getRecentsDisplayModel
+ )
+ }
+
+ init {
+ if (Flags.enableFallbackOverviewInWindow() || Flags.enableLauncherOverviewInWindow()) {
+ displayManager.registerDisplayListener(displayListener, Handler.getMain())
+ createDisplayResource(Display.DEFAULT_DISPLAY)
+ }
+ }
+
+ override fun createDisplayResource(displayId: Int) {
+ if (DEBUG) Log.d(TAG, "create: displayId=$displayId")
+ getDisplayResource(displayId)?.let {
+ return
+ }
+ val display = displayManager.getDisplay(displayId)
+ displayResourceArray[displayId] =
+ RecentsDisplayResource(displayId, context.createDisplayContext(display))
+ }
+
+ fun getRecentsWindowManager(displayId: Int): RecentsWindowManager? {
+ return getDisplayResource(displayId)?.recentsWindowManager
+ }
+
+ fun getFallbackWindowInterface(displayId: Int): FallbackWindowInterface? {
+ return getDisplayResource(displayId)?.fallbackWindowInterface
+ }
+
+ data class RecentsDisplayResource(var displayId: Int, var displayContext: Context) :
+ DisplayResource() {
+ val recentsWindowManager = RecentsWindowManager(displayContext)
+ val fallbackWindowInterface: FallbackWindowInterface =
+ FallbackWindowInterface(recentsWindowManager)
+
+ override fun cleanup() {
+ recentsWindowManager.destroy()
+ }
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowFactory.kt b/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowFactory.kt
deleted file mode 100644
index ac0593e..0000000
--- a/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowFactory.kt
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2024 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.fallback.window
-
-import android.content.Context
-import android.hardware.display.DisplayManager
-import android.os.Handler
-import android.util.Log
-import android.util.SparseArray
-import android.view.Display
-import androidx.core.util.valueIterator
-
-
-/**
- * Factory for creating [RecentsWindowManager] instances based on context per display.
- */
-class RecentsWindowFactory(private val context: Context) {
-
- companion object {
- private const val TAG = "RecentsWindowFactory"
- private const val DEBUG = false
- }
-
- private val displayManager = context.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
- private val managerArray = SparseArray<RecentsWindowManager>()
-
- private val displayListener: DisplayManager.DisplayListener =
- (object : DisplayManager.DisplayListener {
- override fun onDisplayAdded(displayId: Int) {
- if (DEBUG) Log.d(TAG, "onDisplayAdded: displayId=$displayId")
- create(displayId)
- }
-
- override fun onDisplayRemoved(displayId: Int) {
- if (DEBUG) Log.d(TAG, "onDisplayRemoved: displayId=$displayId")
- delete(displayId)
- }
-
- override fun onDisplayChanged(displayId: Int) {
- if (DEBUG) Log.d(TAG, "onDisplayChanged: displayId=$displayId")
- }
- })
-
- init {
- create(Display.DEFAULT_DISPLAY) // create manager for first display early.
- displayManager.registerDisplayListener(displayListener, Handler.getMain())
- }
-
- fun destroy() {
- managerArray.valueIterator().forEach { manager ->
- manager.destroy()
- }
- managerArray.clear()
- displayManager.unregisterDisplayListener(displayListener)
- }
-
- fun get(displayId: Int): RecentsWindowManager? {
- if (DEBUG) Log.d(TAG, "get: displayId=$displayId")
- return managerArray[displayId]
- }
-
- fun delete(displayId: Int) {
- if (DEBUG) Log.d(TAG, "delete: displayId=$displayId")
- get(displayId)?.destroy()
- managerArray.remove(displayId)
- }
-
- fun create(displayId: Int): RecentsWindowManager {
- if (DEBUG) Log.d(TAG, "create: displayId=$displayId")
- get(displayId)?.let {
- return it
- }
- val display = displayManager.getDisplay(displayId)
- val displayContext = context.createDisplayContext(display)
- val recentsWindowManager = RecentsWindowManager(displayId, displayContext)
- managerArray[displayId] = recentsWindowManager
- return recentsWindowManager
- }
-}
diff --git a/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowManager.kt b/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowManager.kt
index b3cc3e9..9bd7a19 100644
--- a/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowManager.kt
+++ b/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowManager.kt
@@ -50,7 +50,6 @@
import com.android.launcher3.util.SystemUiController
import com.android.launcher3.views.BaseDragLayer
import com.android.launcher3.views.ScrimView
-import com.android.quickstep.FallbackWindowInterface
import com.android.quickstep.OverviewComponentObserver
import com.android.quickstep.RecentsAnimationCallbacks
import com.android.quickstep.RecentsAnimationCallbacks.RecentsAnimationListener
@@ -89,7 +88,7 @@
* To add new protologs, see [RecentsWindowProtoLogProxy]. To enable logging to logcat, see
* [QuickstepProtoLogGroup.Constants.DEBUG_RECENTS_WINDOW]
*/
-class RecentsWindowManager(private val displayId: Int, context: Context) :
+class RecentsWindowManager(context: Context) :
RecentsWindowContext(context), RecentsViewContainer, StatefulContainer<RecentsState> {
companion object {
@@ -98,6 +97,9 @@
class RecentsWindowTracker : ContextTracker<RecentsWindowManager?>() {
override fun isHomeStarted(context: RecentsWindowManager?): Boolean {
+ // if we need to change this block to use context in some way, we will need to
+ // refactor RecentsWindowTracker to be an instance (instead of a singleton) managed
+ // by RecentsDisplayModel. Otherwise bad things will occur.
return true
}
}
@@ -152,14 +154,12 @@
}
init {
- FallbackWindowInterface.init(displayId, this)
TaskStackChangeListeners.getInstance().registerTaskStackListener(taskStackChangeListener)
}
override fun destroy() {
super.destroy()
cleanupRecentsWindow()
- FallbackWindowInterface.getInstance(displayId)?.destroy()
TaskStackChangeListeners.getInstance().unregisterTaskStackListener(taskStackChangeListener)
callbacks?.removeListener(recentsAnimationListener)
recentsWindowTracker.onContextDestroyed(this)
@@ -322,10 +322,6 @@
return taskbarUIController
}
- override fun getTISBindHelper(): TISBindHelper {
- return tisBindHelper
- }
-
fun registerInitListener(onInitListener: Predicate<Boolean>) {
this.onInitListener = onInitListener
}
diff --git a/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowSwipeHandler.java b/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowSwipeHandler.java
index 4a08d12..afc8879 100644
--- a/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowSwipeHandler.java
@@ -101,6 +101,8 @@
private static StaticMessageReceiver sMessageReceiver = null;
private FallbackHomeAnimationFactory mActiveAnimationFactory;
+ private final RecentsDisplayModel mRecentsDisplayModel;
+
private final boolean mRunningOverHome;
private final Matrix mTmpMatrix = new Matrix();
@@ -111,10 +113,11 @@
public RecentsWindowSwipeHandler(Context context, RecentsAnimationDeviceState deviceState,
TaskAnimationManager taskAnimationManager, GestureState gestureState, long touchTimeMs,
boolean continuingLastGesture, InputConsumerController inputConsumer,
- RecentsWindowFactory recentsWindowFactory, MSDLPlayerWrapper msdlPlayerWrapper) {
+ MSDLPlayerWrapper msdlPlayerWrapper) {
super(context, deviceState, taskAnimationManager, gestureState, touchTimeMs,
- continuingLastGesture, inputConsumer, recentsWindowFactory, msdlPlayerWrapper);
+ continuingLastGesture, inputConsumer, msdlPlayerWrapper);
+ mRecentsDisplayModel = RecentsDisplayModel.getINSTANCE().get(context);
mRunningOverHome = mGestureState.getRunningTask() != null
&& mGestureState.getRunningTask().isHomeTask();
@@ -160,7 +163,8 @@
boolean fromHomeToHome = mRunningOverHome
&& endTarget == GestureState.GestureEndTarget.HOME;
if (fromHomeToHome) {
- RecentsWindowManager manager = mRecentsWindowFactory.get(mDeviceState.getDisplayId());
+ RecentsWindowManager manager =
+ mRecentsDisplayModel.getRecentsWindowManager(mDeviceState.getDisplayId());
if (manager != null) {
manager.startHome(/* finishRecentsAnimation= */ false);
}
@@ -225,7 +229,7 @@
recentsCallback = () -> {
callback.run();
RecentsWindowManager manager =
- mRecentsWindowFactory.get(mDeviceState.getDisplayId());
+ mRecentsDisplayModel.getRecentsWindowManager(mDeviceState.getDisplayId());
if (manager != null) {
manager.startHome();
}
diff --git a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
index be7f8e5..7fe4278 100644
--- a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
@@ -65,11 +65,6 @@
}
@Override
- public int getSpokenIntroductionSubtitle() {
- return R.string.back_gesture_spoken_intro_subtitle;
- }
-
- @Override
public int getSuccessFeedbackTitle() {
return R.string.gesture_tutorial_nice;
}
diff --git a/quickstep/src/com/android/quickstep/interaction/EdgeBackGestureHandler.java b/quickstep/src/com/android/quickstep/interaction/EdgeBackGestureHandler.java
index 700fbf8..72bff7f 100644
--- a/quickstep/src/com/android/quickstep/interaction/EdgeBackGestureHandler.java
+++ b/quickstep/src/com/android/quickstep/interaction/EdgeBackGestureHandler.java
@@ -29,9 +29,9 @@
import androidx.annotation.Nullable;
+import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Utilities;
import com.android.launcher3.testing.shared.ResourceUtils;
-import com.android.launcher3.util.DisplayController;
/**
* Utility class to handle edge swipes for back gestures.
@@ -45,6 +45,7 @@
"gestures.back_timeout", 250);
private final Context mContext;
+ private final DeviceProfile mDeviceProfile;
private final Point mDisplaySize = new Point();
@@ -89,9 +90,10 @@
}
};
- EdgeBackGestureHandler(Context context) {
+ EdgeBackGestureHandler(Context context, DeviceProfile deviceProfile) {
final Resources res = context.getResources();
mContext = context;
+ mDeviceProfile = deviceProfile;
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
mLongPressTimeout = Math.min(MAX_LONG_PRESS_TIMEOUT,
@@ -116,8 +118,7 @@
// Add a nav bar panel window.
mEdgeBackPanel = new EdgeBackGesturePanel(mContext, parent, createLayoutParams());
mEdgeBackPanel.setBackCallback(mBackCallback);
- Point currentSize = DisplayController.INSTANCE.get(mContext).getInfo().currentSize;
- mDisplaySize.set(currentSize.x, currentSize.y);
+ mDisplaySize.set(mDeviceProfile.widthPx, mDeviceProfile.heightPx);
mEdgeBackPanel.setDisplaySize(mDisplaySize);
}
}
diff --git a/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java b/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java
index bc5cc15..0365f89 100644
--- a/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java
+++ b/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java
@@ -115,22 +115,13 @@
private void initWindowInsets() {
View root = findViewById(android.R.id.content);
- root.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
- @Override
- public void onLayoutChange(View v, int left, int top, int right, int bottom,
- int oldLeft, int oldTop, int oldRight, int oldBottom) {
- updateExclusionRects(root);
- }
- });
+ root.addOnLayoutChangeListener(
+ (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) ->
+ updateExclusionRects(root));
// Return CONSUMED if you don't want want the window insets to keep being
// passed down to descendant views.
- root.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() {
- @Override
- public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {
- return WindowInsets.CONSUMED;
- }
- });
+ root.setOnApplyWindowInsetsListener((v, insets) -> WindowInsets.CONSUMED);
}
private void updateExclusionRects(View rootView) {
diff --git a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
index bf4eaf2..b059695 100644
--- a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
@@ -58,11 +58,6 @@
}
@Override
- public int getSpokenIntroductionSubtitle() {
- return R.string.home_gesture_spoken_intro_subtitle;
- }
-
- @Override
public int getSuccessFeedbackTitle() {
return R.string.home_gesture_tutorial_success;
}
diff --git a/quickstep/src/com/android/quickstep/interaction/NavBarGestureHandler.java b/quickstep/src/com/android/quickstep/interaction/NavBarGestureHandler.java
index c00f508..fdbd509 100644
--- a/quickstep/src/com/android/quickstep/interaction/NavBarGestureHandler.java
+++ b/quickstep/src/com/android/quickstep/interaction/NavBarGestureHandler.java
@@ -33,6 +33,7 @@
import androidx.annotation.Nullable;
+import com.android.launcher3.DeviceProfile;
import com.android.launcher3.testing.shared.ResourceUtils;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.NavigationMode;
@@ -57,15 +58,16 @@
@Nullable
private NavBarGestureAttemptCallback mGestureCallback;
- NavBarGestureHandler(Context context) {
+ NavBarGestureHandler(Context context, DeviceProfile deviceProfile) {
mContext = context;
- DisplayController.Info displayInfo = DisplayController.INSTANCE.get(mContext).getInfo();
- Point currentSize = displayInfo.currentSize;
- mDisplaySize.set(currentSize.x, currentSize.y);
- mSwipeUpTouchTracker =
- new TriggerSwipeUpTouchTracker(context, true /*disableHorizontalSwipe*/,
- new NavBarPosition(NavigationMode.NO_BUTTON, displayInfo),
- this);
+ mDisplaySize.set(deviceProfile.widthPx, deviceProfile.heightPx);
+ mSwipeUpTouchTracker = new TriggerSwipeUpTouchTracker(
+ context,
+ /* disableHorizontalSwipe= */ true,
+ new NavBarPosition(
+ NavigationMode.NO_BUTTON,
+ DisplayController.INSTANCE.get(mContext).getInfo()),
+ /* onSwipeUp= */ this);
mMotionPauseDetector = new MotionPauseDetector(context);
final Resources resources = context.getResources();
diff --git a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
index e45f8d8..ff0d6d1 100644
--- a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
@@ -73,11 +73,6 @@
}
@Override
- public int getSpokenIntroductionSubtitle() {
- return R.string.overview_gesture_spoken_intro_subtitle;
- }
-
- @Override
public int getSuccessFeedbackTitle() {
return R.string.overview_gesture_tutorial_success;
}
diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialController.java b/quickstep/src/com/android/quickstep/interaction/TutorialController.java
index 9510a05..7d14a3e 100644
--- a/quickstep/src/com/android/quickstep/interaction/TutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/TutorialController.java
@@ -318,11 +318,6 @@
}
@StringRes
- public int getSpokenIntroductionSubtitle() {
- return NO_ID;
- }
-
- @StringRes
public int getSuccessFeedbackSubtitle() {
return NO_ID;
}
@@ -401,17 +396,13 @@
isGestureSuccessful
? getSuccessFeedbackTitle() : R.string.gesture_tutorial_try_again,
subtitleResId,
- NO_ID,
- isGestureSuccessful,
- false);
+ isGestureSuccessful);
}
void showFeedback(
int titleResId,
int subtitleResId,
- int spokenSubtitleResId,
- boolean isGestureSuccessful,
- boolean useGestureAnimationDelay) {
+ boolean isGestureSuccessful) {
mFeedbackTitleView.removeCallbacks(mTitleViewCallback);
if (mFeedbackViewCallback != null) {
mFeedbackView.removeCallbacks(mFeedbackViewCallback);
@@ -512,7 +503,6 @@
if (mTutorialType == TutorialType.BACK_NAVIGATION) {
resetViewsForBackGesture();
}
-
}
mGestureCompleted = false;
diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
index 2ff2c83..8174e13 100644
--- a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
@@ -48,6 +48,7 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
import com.android.launcher3.logging.StatsLogManager;
import com.android.quickstep.interaction.TutorialController.TutorialType;
@@ -175,8 +176,10 @@
Bundle args = savedInstanceState != null ? savedInstanceState : getArguments();
mTutorialType = (TutorialType) args.getSerializable(KEY_TUTORIAL_TYPE);
mGestureComplete = args.getBoolean(KEY_GESTURE_COMPLETE, false);
- mEdgeBackGestureHandler = new EdgeBackGestureHandler(getContext());
- mNavBarGestureHandler = new NavBarGestureHandler(getContext());
+ DeviceProfile deviceProfile = LauncherAppState.getInstance(getContext())
+ .getInvariantDeviceProfile().getDeviceProfile(getContext());
+ mEdgeBackGestureHandler = new EdgeBackGestureHandler(getContext(), deviceProfile);
+ mNavBarGestureHandler = new NavBarGestureHandler(getContext(), deviceProfile);
mDeviceProfile = InvariantDeviceProfile.INSTANCE.get(getContext())
.getDeviceProfile(getContext());
@@ -212,7 +215,6 @@
public View onCreateView(
@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
-
mRootView = (RootSandboxLayout) inflater.inflate(
R.layout.redesigned_gesture_tutorial_fragment,
container,
@@ -268,9 +270,7 @@
mTutorialController.showFeedback(
introTitleResId,
introSubtitleResId,
- mTutorialController.getSpokenIntroductionSubtitle(),
- false,
- true);
+ /* isGestureSuccessful= */ false);
mIntroductionShown = true;
}
}
diff --git a/quickstep/src/com/android/quickstep/recents/di/RecentsDependencies.kt b/quickstep/src/com/android/quickstep/recents/di/RecentsDependencies.kt
index 95ecbe9..9d8fc4f 100644
--- a/quickstep/src/com/android/quickstep/recents/di/RecentsDependencies.kt
+++ b/quickstep/src/com/android/quickstep/recents/di/RecentsDependencies.kt
@@ -243,13 +243,17 @@
private const val DEFAULT_SCOPE_ID = "RecentsDependencies::GlobalScope"
private const val TAG = "RecentsDependencies"
private const val DEBUG = false
+ private var activeRecentsCount = 0
@Volatile private lateinit var instance: RecentsDependencies
fun initialize(view: View): RecentsDependencies = initialize(view.context)
fun initialize(context: Context): RecentsDependencies {
- synchronized(this) { instance = RecentsDependencies(context.applicationContext) }
+ synchronized(this) {
+ activeRecentsCount++
+ instance = RecentsDependencies(context.applicationContext)
+ }
return instance
}
@@ -263,9 +267,29 @@
return instance
}
+ @JvmStatic
fun destroy() {
- instance.scopes.clear()
- instance.startDefaultScope(instance.appContext)
+ // When Launcher Activity restarts, the old view's RecentsView.onDetachedFromWindow
+ // happens after the new view's creation. This means that destroy can be called after a
+ // new initialisation. This check prevents a newly initialised tree from being
+ // destroyed. Ideally we would have 1 instance of the dependency tree for each
+ // RecentsView.
+ //
+ // This check is sufficient to avoid a leak of the dependency tree after the Activity is
+ // destroyed while also allowing Launcher auto-restarts (production behaviour) to easily
+ // reinitialise the dependency tree.
+ //
+ // TODO(b/353917593): Better lifecycle decisions will be implemented in this bug or when
+ // replacing with Dagger (b/371370483).
+ activeRecentsCount--
+ if (activeRecentsCount == 0) {
+ instance.scopes.clear()
+ } else {
+ instance.log(
+ "RecentsDependencies was not destroyed. " +
+ "There is still an active RecentsView instance."
+ )
+ }
}
}
}
diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.kt b/quickstep/src/com/android/quickstep/views/GroupedTaskView.kt
index 2e94534..3f0b520 100644
--- a/quickstep/src/com/android/quickstep/views/GroupedTaskView.kt
+++ b/quickstep/src/com/android/quickstep/views/GroupedTaskView.kt
@@ -38,6 +38,7 @@
import com.android.quickstep.util.SplitSelectStateController
import com.android.systemui.shared.recents.model.Task
import com.android.systemui.shared.system.InteractionJankMonitorWrapper
+import com.android.wm.shell.Flags.enableFlexibleTwoAppSplit
import com.android.wm.shell.shared.split.SplitScreenConstants.PersistentSnapPosition
/**
@@ -52,6 +53,9 @@
*/
class GroupedTaskView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
TaskView(context, attrs, type = TaskViewType.GROUPED) {
+
+ private val MINIMUM_RATIO_TO_SHOW_ICON = 0.2f
+
// TODO(b/336612373): Support new TTV for GroupedTaskView
var splitBoundsConfig: SplitConfigurationOptions.SplitBounds? = null
private set
@@ -176,14 +180,32 @@
private fun updateIconPlacement() {
val splitBoundsConfig = splitBoundsConfig ?: return
- val taskIconHeight = container.deviceProfile.overviewTaskIconSizePx
+ val deviceProfile = container.deviceProfile
+ val taskIconHeight = deviceProfile.overviewTaskIconSizePx
val isRtl = layoutDirection == LAYOUT_DIRECTION_RTL
val inSplitSelection = getThisTaskCurrentlyInSplitSelection() != INVALID_TASK_ID
+ if (enableFlexibleTwoAppSplit()) {
+ val topLeftTaskPercent =
+ if (deviceProfile.isLeftRightSplit) splitBoundsConfig.leftTaskPercent
+ else splitBoundsConfig.topTaskPercent
+ val bottomRightTaskPercent = 1 - topLeftTaskPercent
+ taskContainers[0]
+ .iconView
+ .setFlexSplitAlpha(
+ if (topLeftTaskPercent < MINIMUM_RATIO_TO_SHOW_ICON) 0f else 1f
+ )
+ taskContainers[1]
+ .iconView
+ .setFlexSplitAlpha(
+ if (bottomRightTaskPercent < MINIMUM_RATIO_TO_SHOW_ICON) 0f else 1f
+ )
+ }
+
if (enableOverviewIconMenu()) {
val groupedTaskViewSizes =
pagedOrientationHandler.getGroupedTaskViewSizes(
- container.deviceProfile,
+ deviceProfile,
splitBoundsConfig,
layoutParams.width,
layoutParams.height,
@@ -197,7 +219,7 @@
layoutParams.height,
layoutParams.width,
isRtl,
- container.deviceProfile,
+ deviceProfile,
splitBoundsConfig,
inSplitSelection,
)
@@ -211,7 +233,7 @@
measuredHeight,
measuredWidth,
isRtl,
- container.deviceProfile,
+ deviceProfile,
splitBoundsConfig,
inSplitSelection,
)
diff --git a/quickstep/src/com/android/quickstep/views/IconAppChipView.java b/quickstep/src/com/android/quickstep/views/IconAppChipView.java
index ba42594..5270477 100644
--- a/quickstep/src/com/android/quickstep/views/IconAppChipView.java
+++ b/quickstep/src/com/android/quickstep/views/IconAppChipView.java
@@ -56,10 +56,12 @@
private static final int MENU_BACKGROUND_REVEAL_DURATION = 417;
private static final int MENU_BACKGROUND_HIDE_DURATION = 333;
- private static final int NUM_ALPHA_CHANNELS = 3;
+ private static final int NUM_ALPHA_CHANNELS = 4;
private static final int INDEX_CONTENT_ALPHA = 0;
private static final int INDEX_COLOR_FILTER_ALPHA = 1;
private static final int INDEX_MODAL_ALPHA = 2;
+ /** Used to hide the app chip for 90:10 flex split. */
+ private static final int INDEX_MINIMUM_RATIO_ALPHA = 3;
private final MultiValueAlpha mMultiValueAlpha;
@@ -349,6 +351,11 @@
}
@Override
+ public void setFlexSplitAlpha(float alpha) {
+ mMultiValueAlpha.get(INDEX_MINIMUM_RATIO_ALPHA).setValue(alpha);
+ }
+
+ @Override
public int getDrawableWidth() {
return mIconView == null ? 0 : mIconView.getDrawableWidth();
}
diff --git a/quickstep/src/com/android/quickstep/views/IconView.kt b/quickstep/src/com/android/quickstep/views/IconView.kt
index 3ee12ab..2e6c4bf 100644
--- a/quickstep/src/com/android/quickstep/views/IconView.kt
+++ b/quickstep/src/com/android/quickstep/views/IconView.kt
@@ -133,6 +133,10 @@
multiValueAlpha[INDEX_MODAL_ALPHA].setValue(alpha)
}
+ override fun setFlexSplitAlpha(alpha: Float) {
+ multiValueAlpha[INDEX_FLEX_SPLIT_ALPHA].setValue(alpha)
+ }
+
/**
* Set the tint color of the icon, useful for scrimming or dimming.
*
@@ -178,8 +182,9 @@
}
companion object {
- private const val NUM_ALPHA_CHANNELS = 2
+ private const val NUM_ALPHA_CHANNELS = 3
private const val INDEX_CONTENT_ALPHA = 0
private const val INDEX_MODAL_ALPHA = 1
+ private const val INDEX_FLEX_SPLIT_ALPHA = 2
}
}
diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
index 4f823e6..f983e38 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -164,13 +164,14 @@
}
setFreezeViewVisibility(true);
- if (mContainer.getDesktopVisibilityController() != null) {
- mContainer.getDesktopVisibilityController().onLauncherStateChanged(toState);
- }
}
@Override
public void onStateTransitionComplete(LauncherState finalState) {
+ if (mContainer.getDesktopVisibilityController() != null) {
+ mContainer.getDesktopVisibilityController().onLauncherStateChanged(finalState);
+ }
+
if (!finalState.isRecentsViewVisible) {
// Clean-up logic that occurs when recents is no longer in use/visible.
reset();
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index fca115e..9df3af8 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -1296,6 +1296,7 @@
reset();
if (enableRefactorTaskThumbnail()) {
mHelper.onDetachedFromWindow();
+ RecentsDependencies.destroy();
}
}
@@ -5824,19 +5825,19 @@
@Override
public void addChildrenForAccessibility(ArrayList<View> outChildren) {
- // Add children in reverse order
- for (int i = getChildCount() - 1; i >= 0; --i) {
- outChildren.add(getChildAt(i));
- }
+ outChildren.addAll(getAccessibilityChildren());
+ }
+
+ public List<View> getAccessibilityChildren() {
+ return mUtils.getAccessibilityChildren();
}
@Override
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(info);
final AccessibilityNodeInfo.CollectionInfo
- collectionInfo = AccessibilityNodeInfo.CollectionInfo.obtain(
- 1, getTaskViewCount(), false,
- AccessibilityNodeInfo.CollectionInfo.SELECTION_MODE_NONE);
+ collectionInfo = new AccessibilityNodeInfo.CollectionInfo(
+ 1, getAccessibilityChildren().size(), false);
info.setCollectionInfo(collectionInfo);
}
@@ -5845,14 +5846,12 @@
super.onInitializeAccessibilityEvent(event);
event.setScrollable(hasTaskViews());
- // TODO(b/379942019): Revisit the logic below to make sure it does not rely on the
- // `taskViewCount` to update the indices or make it indices free.
- final int taskViewCount = getTaskViewCount();
if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_SCROLLED) {
+ final List<View> accessibilityChildren = getAccessibilityChildren();
final int[] visibleTasks = getVisibleChildrenRange();
- event.setFromIndex(taskViewCount - visibleTasks[1]);
- event.setToIndex(taskViewCount - visibleTasks[0]);
- event.setItemCount(taskViewCount);
+ event.setFromIndex(accessibilityChildren.indexOf(getChildAt(visibleTasks[1])));
+ event.setToIndex(accessibilityChildren.indexOf(getChildAt(visibleTasks[0])));
+ event.setItemCount(accessibilityChildren.size());
}
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java b/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java
index b04753b..a1d22fe 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java
@@ -25,7 +25,6 @@
import android.view.View;
import android.view.Window;
-import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.launcher3.BaseActivity;
@@ -34,7 +33,6 @@
import com.android.launcher3.taskbar.TaskbarUIController;
import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.views.ScrimView;
-import com.android.quickstep.util.TISBindHelper;
/**
* Interface to be implemented by the parent view of RecentsView
@@ -217,6 +215,4 @@
void setTaskbarUIController(@Nullable TaskbarUIController taskbarUIController);
@Nullable TaskbarUIController getTaskbarUIController();
-
- @NonNull TISBindHelper getTISBindHelper();
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsViewUtils.kt b/quickstep/src/com/android/quickstep/views/RecentsViewUtils.kt
index 6eeffda..ccf22ce 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsViewUtils.kt
+++ b/quickstep/src/com/android/quickstep/views/RecentsViewUtils.kt
@@ -16,6 +16,8 @@
package com.android.quickstep.views
+import android.view.View
+import androidx.core.view.children
import com.android.launcher3.Flags.enableLargeDesktopWindowingTile
import com.android.quickstep.util.GroupTask
import com.android.quickstep.views.RecentsView.RUNNING_TASK_ATTACH_ALPHA
@@ -94,6 +96,12 @@
/** Returns the last TaskView that should be displayed as a large tile. */
fun getLastLargeTaskView(): TaskView? = recentsView.taskViews.lastOrNull { it.isLargeTile }
+ /**
+ * Gets the list of accessibility children. Currently all the children of RecentsViews are
+ * added, and in the reverse order to the list.
+ */
+ fun getAccessibilityChildren(): List<View> = recentsView.children.toList().reversed()
+
@JvmOverloads
/** Returns the first [TaskView], with some tasks possibly hidden in the carousel. */
fun getFirstTaskViewInCarousel(
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.kt b/quickstep/src/com/android/quickstep/views/TaskView.kt
index 084ea4b..0dbad70 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.kt
+++ b/quickstep/src/com/android/quickstep/views/TaskView.kt
@@ -658,10 +658,10 @@
recentsView?.let {
collectionItemInfo =
- AccessibilityNodeInfo.CollectionItemInfo.obtain(
+ AccessibilityNodeInfo.CollectionItemInfo(
0,
1,
- it.taskViewCount - it.indexOfChild(this@TaskView) - 1,
+ it.getAccessibilityChildren().indexOf(this@TaskView),
1,
false,
)
diff --git a/quickstep/src/com/android/quickstep/views/TaskViewIcon.java b/quickstep/src/com/android/quickstep/views/TaskViewIcon.java
index 94739cb..80e3a2b 100644
--- a/quickstep/src/com/android/quickstep/views/TaskViewIcon.java
+++ b/quickstep/src/com/android/quickstep/views/TaskViewIcon.java
@@ -48,6 +48,11 @@
void setModalAlpha(float alpha);
/**
+ * Sets the opacity of the view for flex split state.
+ */
+ void setFlexSplitAlpha(float alpha);
+
+ /**
* Returns this icon view's drawable.
*/
@Nullable Drawable getDrawable();
diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt
index 44070cf..5471072 100644
--- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt
@@ -240,6 +240,7 @@
// verify the hide bubble animation is pending
assertThat(animatorScheduler.delayedBlock).isNotNull()
+ whenever(bubbleStashController.isStashed).thenReturn(true)
InstrumentationRegistry.getInstrumentation().runOnMainSync {
animator.onStashStateChangingWhileAnimating()
}
@@ -249,7 +250,7 @@
assertThat(animator.isAnimating).isFalse()
assertThat(bubbleBarView.scaleX).isEqualTo(1)
assertThat(bubbleBarView.scaleY).isEqualTo(1)
- verify(bubbleStashController).onNewBubbleAnimationInterrupted(any(), any())
+ verify(bubbleStashController).onNewBubbleAnimationInterrupted(eq(true), any())
// PhysicsAnimatorTestUtils posts the cancellation to the main thread so we need to wait
// again
diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/rules/TaskbarWindowSandboxContext.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/rules/TaskbarWindowSandboxContext.kt
index 8c51216..0b94dfd 100644
--- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/rules/TaskbarWindowSandboxContext.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/rules/TaskbarWindowSandboxContext.kt
@@ -25,6 +25,7 @@
import com.android.launcher3.FakeLauncherPrefs
import com.android.launcher3.LauncherPrefs
import com.android.launcher3.dagger.LauncherAppComponent
+import com.android.launcher3.dagger.LauncherAppModule
import com.android.launcher3.dagger.LauncherAppSingleton
import com.android.launcher3.util.MainThreadInitializedObject.ObjectSandbox
import com.android.launcher3.util.SandboxApplication
@@ -116,7 +117,7 @@
}
@LauncherAppSingleton
-@Component
+@Component(modules = [LauncherAppModule::class])
interface TaskbarSandboxComponent : LauncherAppComponent {
@Component.Builder
interface Builder : LauncherAppComponent.Builder {
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/AbsSwipeUpHandlerTestCase.java b/quickstep/tests/multivalentTests/src/com/android/quickstep/AbsSwipeUpHandlerTestCase.java
index 6dce10b..c334552 100644
--- a/quickstep/tests/multivalentTests/src/com/android/quickstep/AbsSwipeUpHandlerTestCase.java
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/AbsSwipeUpHandlerTestCase.java
@@ -52,7 +52,6 @@
import android.view.ViewTreeObserver;
import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
import androidx.test.platform.app.InstrumentationRegistry;
import com.android.launcher3.DeviceProfile;
@@ -60,9 +59,9 @@
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.statemanager.BaseState;
import com.android.launcher3.statemanager.StatefulContainer;
+import com.android.launcher3.util.LauncherModelHelper;
import com.android.launcher3.util.MSDLPlayerWrapper;
import com.android.launcher3.util.SystemUiController;
-import com.android.quickstep.fallback.window.RecentsWindowFactory;
import com.android.quickstep.util.ContextInitListener;
import com.android.quickstep.util.MotionPauseDetector;
import com.android.quickstep.views.RecentsView;
@@ -90,8 +89,9 @@
SWIPE_HANDLER extends AbsSwipeUpHandler<RECENTS_CONTAINER, RECENTS_VIEW, STATE_TYPE>,
CONTAINER_INTERFACE extends BaseContainerInterface<STATE_TYPE, RECENTS_CONTAINER>> {
- protected final Context mContext =
- InstrumentationRegistry.getInstrumentation().getTargetContext();
+ protected final LauncherModelHelper mLauncherModelHelper = new LauncherModelHelper();
+ protected final LauncherModelHelper.SandboxModelContext mContext =
+ mLauncherModelHelper.sandboxContext;
protected final InputConsumerController mInputConsumerController =
InputConsumerController.getRecentsAnimationInputConsumer();
protected final ActivityManager.RunningTaskInfo mRunningTaskInfo =
@@ -180,8 +180,7 @@
@Before
public void setUpRecentsContainer() {
- mTaskAnimationManager = new TaskAnimationManager(mContext, getRecentsWindowFactory(),
- mRecentsAnimationDeviceState);
+ mTaskAnimationManager = new TaskAnimationManager(mContext, mRecentsAnimationDeviceState);
RecentsViewContainer recentsContainer = getRecentsContainer();
RECENTS_VIEW recentsView = getRecentsView();
@@ -383,11 +382,6 @@
return createSwipeHandler(SystemClock.uptimeMillis(), false);
}
- @Nullable
- protected RecentsWindowFactory getRecentsWindowFactory() {
- return null;
- }
-
@NonNull
protected abstract SWIPE_HANDLER createSwipeHandler(
long touchTimeMs, boolean continuingLastGesture);
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/DisplayModelTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/DisplayModelTest.kt
new file mode 100644
index 0000000..a939e84
--- /dev/null
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/DisplayModelTest.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2024 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
+
+import android.content.Context
+import android.view.Display
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import org.junit.Assert.assertNotNull
+import org.junit.Assert.assertNull
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class DisplayModelTest {
+ private val context: Context = ApplicationProvider.getApplicationContext()
+
+ class TestableResource : DisplayModel.DisplayResource() {
+ var isCleanupCalled = false
+
+ override fun cleanup() {
+ isCleanupCalled = true
+ }
+ }
+
+ private val testableDisplayModel =
+ object : DisplayModel<TestableResource>(context) {
+ override fun createDisplayResource(displayId: Int) {
+ displayResourceArray.put(displayId, TestableResource())
+ }
+ }
+
+ @Test
+ fun testCreate() {
+ testableDisplayModel.createDisplayResource(Display.DEFAULT_DISPLAY)
+ val resource = testableDisplayModel.getDisplayResource(Display.DEFAULT_DISPLAY)
+ assertNotNull(resource)
+ }
+
+ @Test
+ fun testCleanAndDelete() {
+ testableDisplayModel.createDisplayResource(Display.DEFAULT_DISPLAY)
+ val resource = testableDisplayModel.getDisplayResource(Display.DEFAULT_DISPLAY)!!
+ assertNotNull(resource)
+ testableDisplayModel.deleteDisplayResource(Display.DEFAULT_DISPLAY)
+ assert(resource.isCleanupCalled)
+ assertNull(testableDisplayModel.getDisplayResource(Display.DEFAULT_DISPLAY))
+ }
+}
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2Test.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2Test.kt
index 37accdb..50ba55c 100644
--- a/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2Test.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2Test.kt
@@ -19,15 +19,13 @@
import android.graphics.PointF
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.launcher3.Flags.enableLauncherOverviewInWindow
import com.android.launcher3.R
import com.android.launcher3.dagger.LauncherAppComponent
+import com.android.launcher3.dagger.LauncherAppModule
import com.android.launcher3.dagger.LauncherAppSingleton
import com.android.launcher3.util.LauncherModelHelper
import com.android.launcher3.util.MSDLPlayerWrapper
-import com.android.quickstep.dagger.QuickStepModule
-import com.android.quickstep.fallback.window.RecentsWindowFactory
+import com.android.quickstep.fallback.window.RecentsDisplayModel
import com.android.systemui.contextualeducation.GestureType
import com.android.systemui.shared.system.InputConsumerController
import dagger.BindsInstance
@@ -55,6 +53,8 @@
@Mock private lateinit var systemUiProxy: SystemUiProxy
+ @Mock private lateinit var recentsDisplayModel: RecentsDisplayModel
+
@Mock private lateinit var msdlPlayerWrapper: MSDLPlayerWrapper
private lateinit var underTest: LauncherSwipeHandlerV2
@@ -70,20 +70,14 @@
@Before
fun setup() {
sandboxContext.initDaggerComponent(
- DaggerTestComponent.builder().bindSystemUiProxy(systemUiProxy)
+ DaggerTestComponent.builder()
+ .bindSystemUiProxy(systemUiProxy)
+ .bindRecentsDisplayModel(recentsDisplayModel)
)
+
val deviceState = mock(RecentsAnimationDeviceState::class.java)
whenever(deviceState.rotationTouchHelper).thenReturn(mock(RotationTouchHelper::class.java))
- if (enableLauncherOverviewInWindow()) {
- // Initialize an instance of RecentsWindowFactory directly to simulate its
- // initialization in TouchInteractionService#onCreate.
- // This instance will then be used in OverviewComponentObserver.
- InstrumentationRegistry.getInstrumentation().runOnMainSync {
- RecentsWindowFactory(sandboxContext)
- }
- }
-
gestureState = spy(GestureState(OverviewComponentObserver(sandboxContext, deviceState), 0))
underTest =
@@ -123,12 +117,14 @@
}
@LauncherAppSingleton
-@Component(modules = [QuickStepModule::class])
+@Component(modules = [LauncherAppModule::class])
interface TestComponent : LauncherAppComponent {
@Component.Builder
interface Builder : LauncherAppComponent.Builder {
@BindsInstance fun bindSystemUiProxy(proxy: SystemUiProxy): Builder
+ @BindsInstance fun bindRecentsDisplayModel(model: RecentsDisplayModel): Builder
+
override fun build(): TestComponent
}
}
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/RecentsWindowSwipeHandlerTestCase.java b/quickstep/tests/multivalentTests/src/com/android/quickstep/RecentsWindowSwipeHandlerTestCase.java
index 3287fb5..40fefae 100644
--- a/quickstep/tests/multivalentTests/src/com/android/quickstep/RecentsWindowSwipeHandlerTestCase.java
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/RecentsWindowSwipeHandlerTestCase.java
@@ -16,17 +16,16 @@
package com.android.quickstep;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.when;
-
import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
import androidx.test.filters.SmallTest;
+import com.android.launcher3.dagger.LauncherAppComponent;
+import com.android.launcher3.dagger.LauncherAppSingleton;
import com.android.launcher3.util.LauncherMultivalentJUnit;
+import com.android.quickstep.dagger.QuickStepModule;
import com.android.quickstep.fallback.FallbackRecentsView;
import com.android.quickstep.fallback.RecentsState;
-import com.android.quickstep.fallback.window.RecentsWindowFactory;
+import com.android.quickstep.fallback.window.RecentsDisplayModel;
import com.android.quickstep.fallback.window.RecentsWindowManager;
import com.android.quickstep.fallback.window.RecentsWindowSwipeHandler;
import com.android.quickstep.views.RecentsViewContainer;
@@ -35,6 +34,9 @@
import org.junit.runner.RunWith;
import org.mockito.Mock;
+import dagger.BindsInstance;
+import dagger.Component;
+
@SmallTest
@RunWith(LauncherMultivalentJUnit.class)
public class RecentsWindowSwipeHandlerTestCase extends AbsSwipeUpHandlerTestCase<
@@ -44,13 +46,14 @@
RecentsWindowSwipeHandler,
FallbackWindowInterface> {
- @Mock private RecentsWindowFactory mRecentsWindowFactory;
+ @Mock private RecentsDisplayModel mRecentsDisplayModel;
@Mock private FallbackRecentsView<RecentsWindowManager> mRecentsView;
@Mock private RecentsWindowManager mRecentsWindowManager;
@Before
- public void setupRecentsWindowFactory() {
- when(mRecentsWindowFactory.get(anyInt())).thenReturn(mRecentsWindowManager);
+ public void setRecentsDisplayModel() {
+ mContext.initDaggerComponent(DaggerRecentsWindowSwipeHandlerTestCase_TestComponent.builder()
+ .bindRecentsDisplayModel(mRecentsDisplayModel));
}
@NonNull
@@ -65,16 +68,9 @@
touchTimeMs,
continuingLastGesture,
mInputConsumerController,
- mRecentsWindowFactory,
mMSDLPlayerWrapper);
}
- @Nullable
- @Override
- protected RecentsWindowFactory getRecentsWindowFactory() {
- return mRecentsWindowFactory;
- }
-
@NonNull
@Override
protected RecentsViewContainer getRecentsContainer() {
@@ -86,4 +82,14 @@
protected FallbackRecentsView<RecentsWindowManager> getRecentsView() {
return mRecentsView;
}
+
+ @LauncherAppSingleton
+ @Component(modules = { QuickStepModule.class })
+ interface TestComponent extends LauncherAppComponent {
+ @Component.Builder
+ interface Builder extends LauncherAppComponent.Builder {
+ @BindsInstance Builder bindRecentsDisplayModel(RecentsDisplayModel model);
+ @Override LauncherAppComponent build();
+ }
+ }
}
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/window/RecentsDisplayModelTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/window/RecentsDisplayModelTest.kt
new file mode 100644
index 0000000..d2aa6ac
--- /dev/null
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/window/RecentsDisplayModelTest.kt
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2024 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.recents.window
+
+import android.graphics.Point
+import android.hardware.display.DisplayManager
+import android.platform.test.annotations.EnableFlags
+import android.platform.test.flag.junit.SetFlagsRule
+import android.view.Display
+import android.view.DisplayAdjustments
+import android.view.Surface
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.launcher3.Flags.FLAG_ENABLE_FALLBACK_OVERVIEW_IN_WINDOW
+import com.android.launcher3.Flags.FLAG_ENABLE_LAUNCHER_OVERVIEW_IN_WINDOW
+import com.android.launcher3.dagger.LauncherAppComponent
+import com.android.launcher3.dagger.LauncherAppModule
+import com.android.launcher3.dagger.LauncherAppSingleton
+import com.android.launcher3.util.LauncherModelHelper
+import com.android.launcher3.util.window.CachedDisplayInfo
+import com.android.quickstep.fallback.window.RecentsDisplayModel
+import dagger.BindsInstance
+import dagger.Component
+import org.junit.Assert
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.spy
+import org.mockito.kotlin.whenever
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@EnableFlags(FLAG_ENABLE_LAUNCHER_OVERVIEW_IN_WINDOW, FLAG_ENABLE_FALLBACK_OVERVIEW_IN_WINDOW)
+class RecentsDisplayModelTest {
+ @get:Rule val setFlagsRule = SetFlagsRule()
+
+ // initiate dagger components for injection
+ private val launcherModelHelper = LauncherModelHelper()
+ private val context = spy(launcherModelHelper.sandboxContext)
+ private val displayManager: DisplayManager = context.spyService(DisplayManager::class.java)
+ private val display: Display = mock()
+
+ private lateinit var recentsDisplayModel: RecentsDisplayModel
+
+ private val width = 2208
+ private val height = 1840
+
+ @Before
+ fun setup() {
+ // Mock display
+ val displayInfo = CachedDisplayInfo(Point(width, height), Surface.ROTATION_0)
+ whenever(display.rotation).thenReturn(displayInfo.rotation)
+ whenever(display.displayAdjustments).thenReturn(DisplayAdjustments())
+ whenever(context.display).thenReturn(display)
+
+ // Mock displayManager
+ whenever(displayManager.getDisplay(anyInt())).thenReturn(display)
+
+ runOnMainSync { recentsDisplayModel = RecentsDisplayModel.INSTANCE.get(context) }
+ context.initDaggerComponent(
+ DaggerRecentsDisplayModelComponent.builder()
+ .bindRecentsDisplayModel(recentsDisplayModel)
+ )
+ }
+
+ @Test
+ fun testEnsureSingleton() {
+ val recentsDisplayModel2 = RecentsDisplayModel.INSTANCE.get(context)
+ assert(recentsDisplayModel == recentsDisplayModel2)
+ }
+
+ @Test
+ fun testDefaultDisplayCreation() {
+ Assert.assertNotNull(recentsDisplayModel.getRecentsWindowManager(Display.DEFAULT_DISPLAY))
+ Assert.assertNotNull(
+ recentsDisplayModel.getFallbackWindowInterface(Display.DEFAULT_DISPLAY)
+ )
+ }
+
+ @Test
+ fun testCreateSeparateInstances() {
+ val display = Display.DEFAULT_DISPLAY + 1
+ runOnMainSync { recentsDisplayModel.createDisplayResource(display) }
+
+ val defaultManager = recentsDisplayModel.getRecentsWindowManager(Display.DEFAULT_DISPLAY)
+ val secondaryManager = recentsDisplayModel.getRecentsWindowManager(display)
+ Assert.assertNotSame(defaultManager, secondaryManager)
+
+ val defaultInterface =
+ recentsDisplayModel.getFallbackWindowInterface(Display.DEFAULT_DISPLAY)
+ val secondInterface = recentsDisplayModel.getFallbackWindowInterface(display)
+ Assert.assertNotSame(defaultInterface, secondInterface)
+ }
+
+ @Test
+ fun testDestroy() {
+ Assert.assertNotNull(recentsDisplayModel.getRecentsWindowManager(Display.DEFAULT_DISPLAY))
+ Assert.assertNotNull(
+ recentsDisplayModel.getFallbackWindowInterface(Display.DEFAULT_DISPLAY)
+ )
+ recentsDisplayModel.destroy()
+ Assert.assertNull(recentsDisplayModel.getRecentsWindowManager(Display.DEFAULT_DISPLAY))
+ Assert.assertNull(recentsDisplayModel.getFallbackWindowInterface(Display.DEFAULT_DISPLAY))
+ }
+
+ private fun runOnMainSync(f: Runnable) {
+ InstrumentationRegistry.getInstrumentation().runOnMainSync { f.run() }
+ }
+}
+
+@LauncherAppSingleton
+@Component(modules = [LauncherAppModule::class])
+interface RecentsDisplayModelComponent : LauncherAppComponent {
+ @Component.Builder
+ interface Builder : LauncherAppComponent.Builder {
+ @BindsInstance fun bindRecentsDisplayModel(model: RecentsDisplayModel): Builder
+
+ override fun build(): RecentsDisplayModelComponent
+ }
+}
diff --git a/quickstep/tests/src/com/android/quickstep/InputConsumerUtilsTest.java b/quickstep/tests/src/com/android/quickstep/InputConsumerUtilsTest.java
index 2c6b750..f522a2c 100644
--- a/quickstep/tests/src/com/android/quickstep/InputConsumerUtilsTest.java
+++ b/quickstep/tests/src/com/android/quickstep/InputConsumerUtilsTest.java
@@ -56,7 +56,6 @@
import com.android.launcher3.util.LockedUserState;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.views.BaseDragLayer;
-import com.android.quickstep.fallback.window.RecentsWindowFactory;
import com.android.quickstep.inputconsumers.AccessibilityInputConsumer;
import com.android.quickstep.inputconsumers.BubbleBarInputConsumer;
import com.android.quickstep.inputconsumers.DeviceLockedInputConsumer;
@@ -122,7 +121,7 @@
@Before
public void setupTaskAnimationManager() {
mTaskAnimationManager = new TaskAnimationManager(
- mContext, mock(RecentsWindowFactory.class), mDeviceState);
+ mContext, mDeviceState);
}
@Before
diff --git a/quickstep/tests/src/com/android/quickstep/TaplPrivateSpaceTest.java b/quickstep/tests/src/com/android/quickstep/TaplPrivateSpaceTest.java
index b15b78e..e065dba 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplPrivateSpaceTest.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplPrivateSpaceTest.java
@@ -23,6 +23,7 @@
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeFalse;
+import android.os.Process;
import android.util.Log;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -74,8 +75,9 @@
}
private void createAndStartPrivateProfileUser() {
- String createUserOutput = executeShellCommand("pm create-user --profileOf 0 --user-type "
- + "android.os.usertype.profile.PRIVATE " + PRIVATE_PROFILE_NAME);
+ int myUserId = Process.myUserHandle().getIdentifier();
+ String createUserOutput = executeShellCommand("pm create-user --profileOf " + myUserId
+ + " --user-type android.os.usertype.profile.PRIVATE " + PRIVATE_PROFILE_NAME);
updatePrivateProfileSetupSuccessful("pm create-user", createUserOutput);
String[] tokens = createUserOutput.split("\\s+");
mProfileUserId = Integer.parseInt(tokens[tokens.length - 1]);
diff --git a/quickstep/tests/src/com/android/quickstep/TaskAnimationManagerTest.java b/quickstep/tests/src/com/android/quickstep/TaskAnimationManagerTest.java
index 960a467..098b417 100644
--- a/quickstep/tests/src/com/android/quickstep/TaskAnimationManagerTest.java
+++ b/quickstep/tests/src/com/android/quickstep/TaskAnimationManagerTest.java
@@ -30,8 +30,6 @@
import androidx.test.filters.SmallTest;
import androidx.test.platform.app.InstrumentationRegistry;
-import com.android.quickstep.fallback.window.RecentsWindowFactory;
-
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
@@ -45,9 +43,6 @@
InstrumentationRegistry.getInstrumentation().getTargetContext();
@Mock
- private RecentsWindowFactory mRecentsWindowFactory;
-
- @Mock
private SystemUiProxy mSystemUiProxy;
private TaskAnimationManager mTaskAnimationManager;
@@ -62,8 +57,7 @@
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mTaskAnimationManager = new TaskAnimationManager(mContext, mRecentsWindowFactory,
- mRecentsAnimationDeviceState) {
+ mTaskAnimationManager = new TaskAnimationManager(mContext, mRecentsAnimationDeviceState) {
@Override
SystemUiProxy getSystemUiProxy() {
return mSystemUiProxy;
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 2fc039e..6f293b6 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -190,6 +190,8 @@
<!-- Label for the header text of the All Apps section in All Apps view, used to separate Predicted Apps and Actions section from All Apps section. [CHAR_LIMIT=50] -->
<string name="all_apps_label">All apps</string>
+ <string name="all_apps_list_label">Apps list</string>
+
<!-- Popup items -->
<!-- Text to display as the header above notifications. [CHAR_LIMIT=30] -->
<string name="notifications_header">Notifications</string>
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 1fc14ec..c78666e 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -743,7 +743,7 @@
appTitleBounds = new RectF((tmpRect.width() - titleLength) / 2.f - getCompoundPaddingLeft(),
0, (tmpRect.width() + titleLength) / 2.f + getCompoundPaddingRight(),
(int) Math.ceil(fm.bottom - fm.top));
- appTitleBounds.inset(mRoundRectPadding * 2, 0);
+ appTitleBounds.inset((mAppTitleHorizontalPadding) * 2, 0);
if (mIcon != null) {
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 6814ce7..94b1a2a 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -58,6 +58,7 @@
import static com.android.launcher3.LauncherConstants.TraceEvents.ON_NEW_INTENT_EVT;
import static com.android.launcher3.LauncherConstants.TraceEvents.ON_RESUME_EVT;
import static com.android.launcher3.LauncherConstants.TraceEvents.ON_START_EVT;
+import static com.android.launcher3.LauncherPrefs.FIXED_LANDSCAPE_MODE;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_DESKTOP;
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
import static com.android.launcher3.LauncherState.ALL_APPS;
@@ -785,9 +786,13 @@
return;
}
// When the flag oneGridSpecs is on we want to disable ALLOW_ROTATION which is replaced
- // by FIXED_LANDSCAPE_MODE, ALLOW_ROTATION will only be used on Tablets afterwards.
- if (getDeviceProfile().isPhone || getDeviceProfile().isTwoPanels) {
+ // by FIXED_LANDSCAPE_MODE, ALLOW_ROTATION will only be used on Tablets and foldables
+ // afterwards.
+ if (getDeviceProfile().isPhone) {
LauncherPrefs.get(this).put(LauncherPrefs.ALLOW_ROTATION, false);
+ } else if (getDeviceProfile().isTablet) {
+ // Tablet do not use fixed landscape mode, make sure it can't be activated by mistake
+ LauncherPrefs.get(this).put(FIXED_LANDSCAPE_MODE, false);
}
getRotationHelper().setFixedLandscape(
Objects.requireNonNull(mDeviceProfile.inv).isFixedLandscape
diff --git a/src_no_quickstep/com/android/launcher3/dagger/LauncherAppComponent.java b/src_no_quickstep/com/android/launcher3/dagger/LauncherAppComponent.java
index 63d87e8..f4f5a08 100644
--- a/src_no_quickstep/com/android/launcher3/dagger/LauncherAppComponent.java
+++ b/src_no_quickstep/com/android/launcher3/dagger/LauncherAppComponent.java
@@ -22,7 +22,7 @@
* Root component for Dagger injection for Launcher AOSP.
*/
@LauncherAppSingleton
-@Component
+@Component(modules = LauncherAppModule.class)
public interface LauncherAppComponent extends LauncherBaseAppComponent {
/** Builder for aosp LauncherAppComponent. */
@Component.Builder
diff --git a/src_no_quickstep/com/android/launcher3/dagger/LauncherAppModule.java b/src_no_quickstep/com/android/launcher3/dagger/LauncherAppModule.java
new file mode 100644
index 0000000..f7b8489
--- /dev/null
+++ b/src_no_quickstep/com/android/launcher3/dagger/LauncherAppModule.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.dagger;
+
+import dagger.Module;
+
+@Module
+public class LauncherAppModule { }
diff --git a/tests/multivalentTests/src/com/android/launcher3/AbstractDeviceProfileTest.kt b/tests/multivalentTests/src/com/android/launcher3/AbstractDeviceProfileTest.kt
index c80093a..8598917 100644
--- a/tests/multivalentTests/src/com/android/launcher3/AbstractDeviceProfileTest.kt
+++ b/tests/multivalentTests/src/com/android/launcher3/AbstractDeviceProfileTest.kt
@@ -29,6 +29,7 @@
import androidx.test.core.app.ApplicationProvider.getApplicationContext
import androidx.test.platform.app.InstrumentationRegistry
import com.android.launcher3.dagger.LauncherAppComponent
+import com.android.launcher3.dagger.LauncherAppModule
import com.android.launcher3.dagger.LauncherAppSingleton
import com.android.launcher3.testing.shared.ResourceUtils
import com.android.launcher3.util.DisplayController
@@ -68,7 +69,7 @@
protected lateinit var context: SandboxContext
protected open val runningContext: Context = getApplicationContext()
private val displayController: DisplayController = mock()
- private val windowManagerProxy: WindowManagerProxy = mock()
+ private val windowManagerProxy: MyWmProxy = mock()
private val launcherPrefs: LauncherPrefs = mock()
@get:Rule val setFlagsRule = SetFlagsRule(SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT)
@@ -362,12 +363,17 @@
}
}
+class MyWmProxy : WindowManagerProxy()
+
@LauncherAppSingleton
-@Component
+@Component(modules = [LauncherAppModule::class])
interface AbsDPTestSandboxComponent : LauncherAppComponent {
+
+ override fun getWmProxy(): MyWmProxy
+
@Component.Builder
interface Builder : LauncherAppComponent.Builder {
- @BindsInstance fun bindWMProxy(proxy: WindowManagerProxy): Builder
+ @BindsInstance fun bindWMProxy(proxy: MyWmProxy): Builder
override fun build(): AbsDPTestSandboxComponent
}
diff --git a/tests/multivalentTests/src/com/android/launcher3/AutoInstallsLayoutTest.kt b/tests/multivalentTests/src/com/android/launcher3/AutoInstallsLayoutTest.kt
index f73a9d3..fcbb94b 100644
--- a/tests/multivalentTests/src/com/android/launcher3/AutoInstallsLayoutTest.kt
+++ b/tests/multivalentTests/src/com/android/launcher3/AutoInstallsLayoutTest.kt
@@ -42,6 +42,7 @@
import com.android.launcher3.LauncherSettings.Favorites.SPANY
import com.android.launcher3.LauncherSettings.Favorites._ID
import com.android.launcher3.dagger.LauncherAppComponent
+import com.android.launcher3.dagger.LauncherAppModule
import com.android.launcher3.dagger.LauncherAppSingleton
import com.android.launcher3.model.data.AppInfo
import com.android.launcher3.pm.UserCache
@@ -66,7 +67,7 @@
import org.mockito.Mock
import org.mockito.MockitoAnnotations
import org.mockito.kotlin.doReturn
-import org.mockito.kotlin.spy
+import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever
/** Tests for [AutoInstallsLayout] */
@@ -165,7 +166,9 @@
@Test
fun work_item_added_to_home() {
- val apiWrapperMock = spy(ApiWrapper.INSTANCE[targetContext])
+ val original = ApiWrapper.INSTANCE[targetContext]
+ val apiWrapperMock =
+ mock<MyApiWrapper>(defaultAnswer = { it.method.invoke(original, *it.arguments) })
targetContext.initDaggerComponent(
DaggerAutoInstallsLayoutTestComponent.builder().bindApiWrapper(apiWrapperMock)
)
@@ -221,12 +224,17 @@
}
}
+class MyApiWrapper : ApiWrapper(null) {}
+
@LauncherAppSingleton
-@Component
+@Component(modules = [LauncherAppModule::class])
interface AutoInstallsLayoutTestComponent : LauncherAppComponent {
+
+ override fun getApiWrapper(): MyApiWrapper
+
@Component.Builder
interface Builder : LauncherAppComponent.Builder {
- @BindsInstance fun bindApiWrapper(wrapper: ApiWrapper): Builder
+ @BindsInstance fun bindApiWrapper(wrapper: MyApiWrapper): Builder
override fun build(): AutoInstallsLayoutTestComponent
}
diff --git a/tests/multivalentTests/src/com/android/launcher3/util/DisplayControllerTest.kt b/tests/multivalentTests/src/com/android/launcher3/util/DisplayControllerTest.kt
index 32df84c..d0cf610 100644
--- a/tests/multivalentTests/src/com/android/launcher3/util/DisplayControllerTest.kt
+++ b/tests/multivalentTests/src/com/android/launcher3/util/DisplayControllerTest.kt
@@ -30,6 +30,7 @@
import com.android.launcher3.LauncherPrefs.Companion.TASKBAR_PINNING
import com.android.launcher3.LauncherPrefs.Companion.TASKBAR_PINNING_IN_DESKTOP_MODE
import com.android.launcher3.dagger.LauncherAppComponent
+import com.android.launcher3.dagger.LauncherAppModule
import com.android.launcher3.dagger.LauncherAppSingleton
import com.android.launcher3.util.DisplayController.CHANGE_DENSITY
import com.android.launcher3.util.DisplayController.CHANGE_ROTATION
@@ -64,7 +65,7 @@
class DisplayControllerTest {
private val context = spy(SandboxModelContext())
- private val windowManagerProxy: WindowManagerProxy = mock()
+ private val windowManagerProxy: MyWmProxy = mock()
private val launcherPrefs: LauncherPrefs = mock()
private lateinit var displayManager: DisplayManager
private val display: Display = mock()
@@ -230,12 +231,17 @@
}
}
+class MyWmProxy : WindowManagerProxy()
+
@LauncherAppSingleton
-@Component
+@Component(modules = [LauncherAppModule::class])
interface DisplayControllerTestComponent : LauncherAppComponent {
+
+ override fun getWmProxy(): MyWmProxy
+
@Component.Builder
interface Builder : LauncherAppComponent.Builder {
- @BindsInstance fun bindWMProxy(proxy: WindowManagerProxy): Builder
+ @BindsInstance fun bindWMProxy(proxy: MyWmProxy): Builder
override fun build(): DisplayControllerTestComponent
}
diff --git a/tests/src/com/android/launcher3/pm/InstallSessionHelperTest.kt b/tests/src/com/android/launcher3/pm/InstallSessionHelperTest.kt
index f381d4b..94b2c7e 100644
--- a/tests/src/com/android/launcher3/pm/InstallSessionHelperTest.kt
+++ b/tests/src/com/android/launcher3/pm/InstallSessionHelperTest.kt
@@ -104,7 +104,7 @@
.thenReturn(listOf(expectedVerifiedSession))
// When
val actualSession =
- installSessionHelper.getActiveSessionInfo(UserHandle(0), expectedAppPackage)
+ installSessionHelper.getActiveSessionInfo(myUserHandle(), expectedAppPackage)
// Then
assertThat(actualSession).isEqualTo(expectedVerifiedSession)
}
diff --git a/tests/src/com/android/launcher3/popup/SystemShortcutTest.java b/tests/src/com/android/launcher3/popup/SystemShortcutTest.java
index ae54e95..075f667 100644
--- a/tests/src/com/android/launcher3/popup/SystemShortcutTest.java
+++ b/tests/src/com/android/launcher3/popup/SystemShortcutTest.java
@@ -62,15 +62,12 @@
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.R;
import com.android.launcher3.allapps.PrivateProfileManager;
-import com.android.launcher3.dagger.LauncherAppComponent;
-import com.android.launcher3.dagger.LauncherAppSingleton;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.logging.StatsLogManager.StatsLogger;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.pm.UserCache;
-import com.android.launcher3.util.ApiWrapper;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.LauncherModelHelper.SandboxModelContext;
import com.android.launcher3.util.LauncherMultivalentJUnit;
@@ -81,9 +78,6 @@
import com.android.launcher3.widget.picker.model.WidgetPickerDataProvider;
import com.android.launcher3.widget.picker.model.data.WidgetPickerData;
-import dagger.BindsInstance;
-import dagger.Component;
-
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
@@ -109,7 +103,6 @@
private AppInfo mAppInfo;
@Mock UserCache mUserCache;
- @Mock ApiWrapper mApiWrapper;
@Mock UserIconInfo mUserIconInfo;
@Mock LauncherActivityInfo mLauncherActivityInfo;
@Mock ApplicationInfo mApplicationInfo;
@@ -120,9 +113,6 @@
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mSandboxContext.initDaggerComponent(
- DaggerSystemShortcutTest_TestComponent.builder().bindApiWrapper(
- ApiWrapper.INSTANCE.get(mSandboxContext)));
mSandboxContext.putObject(UserCache.INSTANCE, mUserCache);
mTestContext = new TestSandboxModelContextWrapper(mSandboxContext) {
@Override
@@ -412,16 +402,4 @@
systemShortcut.onClick(mView);
verify(mSandboxContext).startActivity(any());
}
-
- @LauncherAppSingleton
- @Component
- interface TestComponent extends LauncherAppComponent {
- @Component.Builder
- interface Builder extends LauncherAppComponent.Builder {
- @BindsInstance Builder bindApiWrapper(ApiWrapper wrapper);
-
- @Override
- TestComponent build();
- }
- }
}
diff --git a/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java b/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java
index e5c5c19..d49168f 100644
--- a/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java
+++ b/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java
@@ -1,11 +1,16 @@
package com.android.launcher3.ui;
+import static com.android.launcher3.LauncherPrefs.FIXED_LANDSCAPE_MODE;
+
import android.util.Log;
import android.view.Surface;
+import com.android.launcher3.Flags;
import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.tapl.TestHelpers;
import com.android.launcher3.util.rule.FailureWatcher;
+import com.android.launcher3.util.window.WindowManagerProxy;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
@@ -67,9 +72,11 @@
Log.e(TAG, "Error", e);
throw e;
} finally {
+
mTest.mDevice.setOrientationNatural();
mTest.executeOnLauncher(launcher ->
{
+ LauncherPrefs.get(launcher).put(FIXED_LANDSCAPE_MODE, false);
if (launcher != null) {
launcher.getRotationHelper().forceAllowRotationForTesting(false);
}
@@ -90,6 +97,13 @@
}
private void evaluateInLandscape() throws Throwable {
+ if (Flags.oneGridSpecs()
+ && WindowManagerProxy.INSTANCE.get(mTest.mTargetContext)
+ .isTaskbarDrawnInProcess()) {
+ mTest.executeOnLauncher(launcher -> LauncherPrefs.get(launcher)
+ .put(FIXED_LANDSCAPE_MODE, true)
+ );
+ }
mTest.mDevice.setOrientationLeft();
mTest.mLauncher.setExpectedRotation(Surface.ROTATION_90);
AbstractLauncherUiTest.checkDetectedLeaks(mTest.mLauncher, true);