Merge "Always use Transient Taskbar All apps icon for taskbar pinning" into main
diff --git a/quickstep/res/layout/taskbar.xml b/quickstep/res/layout/taskbar.xml
index 94388b4..72d7485 100644
--- a/quickstep/res/layout/taskbar.xml
+++ b/quickstep/res/layout/taskbar.xml
@@ -45,9 +45,6 @@
android:id="@+id/start_contextual_buttons"
android:layout_width="wrap_content"
android:layout_height="match_parent"
- android:paddingStart="@dimen/taskbar_contextual_button_padding"
- android:paddingEnd="@dimen/taskbar_contextual_button_padding"
- android:paddingTop="@dimen/taskbar_contextual_padding_top"
android:gravity="center_vertical"
android:layout_gravity="start"/>
@@ -63,7 +60,6 @@
android:id="@+id/end_contextual_buttons"
android:layout_width="wrap_content"
android:layout_height="match_parent"
- android:paddingTop="@dimen/taskbar_contextual_padding_top"
android:gravity="center_vertical"
android:layout_gravity="end"/>
</FrameLayout>
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index cca0fd4..d2be94a 100644
--- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
@@ -1824,7 +1824,7 @@
StartingWindowListener startingWindowListener, RunnableList onEndCallback) {
View viewToUse = findLaunchableViewWithBackground(v);
if (viewToUse == null) {
- viewToUse = v;
+ return null;
}
// The CUJ is logged by the click handler, so we don't log it inside the animation
diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
index 4b16019..be4426d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
@@ -471,7 +471,7 @@
/**
* @return {@code true} if A11y is showing in 3 button nav taskbar
*/
- private boolean isContextualButtonShowing() {
+ private boolean isA11yButtonPersistent() {
return mContext.isThreeButtonNav() && (mState & FLAG_A11Y_VISIBLE) != 0;
}
@@ -742,7 +742,7 @@
mA11yButton, res, isInKidsMode, isInSetup, isThreeButtonNav,
TaskbarManager.isPhoneMode(dp),
mWindowManagerProxy.getRotation(mContext));
- navButtonLayoutter.layoutButtons(dp, isContextualButtonShowing());
+ navButtonLayoutter.layoutButtons(dp, isA11yButtonPersistent());
updateNavButtonColor();
return;
}
@@ -838,7 +838,7 @@
int contextualWidth = mEndContextualContainer.getWidth();
// If contextual buttons are showing, we check if the end margin is enough for the
// contextual button to be showing - if not, move the nav buttons over a smidge
- if (isContextualButtonShowing() && navMarginEnd < contextualWidth) {
+ if (isA11yButtonPersistent() && navMarginEnd < contextualWidth) {
// Additional spacing, eat up half of space between last icon and nav button
navMarginEnd += res.getDimensionPixelSize(R.dimen.taskbar_hotseat_nav_spacing) / 2;
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/AbstractNavButtonLayoutter.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/AbstractNavButtonLayoutter.kt
index 7529508..b516d6f 100644
--- a/quickstep/src/com/android/launcher3/taskbar/navbutton/AbstractNavButtonLayoutter.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/AbstractNavButtonLayoutter.kt
@@ -69,4 +69,18 @@
params.gravity = Gravity.CENTER
return params;
}
+
+ open fun repositionContextualContainer(contextualContainer: ViewGroup, barAxisMargin: Int,
+ gravity: Int) {
+ val contextualContainerParams = FrameLayout.LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT)
+ contextualContainerParams.apply {
+ marginStart = barAxisMargin
+ marginEnd = barAxisMargin
+ topMargin = 0
+ bottomMargin = 0
+ }
+ contextualContainerParams.gravity = gravity or Gravity.CENTER_VERTICAL
+ contextualContainer.layoutParams = contextualContainerParams
+ }
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/KidsNavLayoutter.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/KidsNavLayoutter.kt
index e7847f3..3f51958 100644
--- a/quickstep/src/com/android/launcher3/taskbar/navbutton/KidsNavLayoutter.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/KidsNavLayoutter.kt
@@ -25,6 +25,7 @@
import android.widget.ImageView
import android.widget.LinearLayout
import com.android.launcher3.DeviceProfile
+import com.android.launcher3.R
import com.android.launcher3.taskbar.navbutton.LayoutResourceHelper.*
import com.android.systemui.shared.rotation.RotationButton
@@ -47,7 +48,7 @@
a11yButton
) {
- override fun layoutButtons(dp: DeviceProfile, isContextualButtonShowing: Boolean) {
+ override fun layoutButtons(dp: DeviceProfile, isA11yButtonPersistent: Boolean) {
val iconSize: Int = resources.getDimensionPixelSize(DIMEN_TASKBAR_ICON_SIZE_KIDS)
val buttonWidth: Int = resources.getDimensionPixelSize(DIMEN_TASKBAR_NAV_BUTTONS_WIDTH_KIDS)
val buttonHeight: Int =
@@ -100,15 +101,10 @@
endContextualContainer.removeAllViews()
startContextualContainer.removeAllViews()
- val endContextualContainerParams = FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT)
- endContextualContainerParams.gravity = Gravity.END or Gravity.CENTER_VERTICAL
- endContextualContainer.layoutParams = endContextualContainerParams
-
- val startContextualContainerParams = FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT)
- startContextualContainerParams.gravity = Gravity.START or Gravity.CENTER_VERTICAL
- startContextualContainer.layoutParams = startContextualContainerParams
+ val contextualMargin = resources.getDimensionPixelSize(
+ R.dimen.taskbar_contextual_button_padding)
+ repositionContextualContainer(endContextualContainer, 0, Gravity.END)
+ repositionContextualContainer(startContextualContainer, contextualMargin, Gravity.START)
if (imeSwitcher != null) {
startContextualContainer.addView(imeSwitcher)
diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/NavButtonLayoutFactory.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/NavButtonLayoutFactory.kt
index c502cdb..6b05e9a 100644
--- a/quickstep/src/com/android/launcher3/taskbar/navbutton/NavButtonLayoutFactory.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/NavButtonLayoutFactory.kt
@@ -162,6 +162,6 @@
/** Lays out and provides access to the home, recents, and back buttons for various mischief */
interface NavButtonLayoutter {
- fun layoutButtons(dp: DeviceProfile, isContextualButtonShowing: Boolean)
+ fun layoutButtons(dp: DeviceProfile, isA11yButtonPersistent: Boolean)
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneGestureLayoutter.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneGestureLayoutter.kt
index d6ea7f0..5a7bc49 100644
--- a/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneGestureLayoutter.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneGestureLayoutter.kt
@@ -43,7 +43,7 @@
a11yButton
) {
- override fun layoutButtons(dp: DeviceProfile, isContextualButtonShowing: Boolean) {
+ override fun layoutButtons(dp: DeviceProfile, isA11yButtonPersistent: Boolean) {
endContextualContainer.removeAllViews()
startContextualContainer.removeAllViews()
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneLandscapeNavLayoutter.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneLandscapeNavLayoutter.kt
index 54edd21..382e298 100644
--- a/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneLandscapeNavLayoutter.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneLandscapeNavLayoutter.kt
@@ -48,7 +48,7 @@
a11yButton
) {
- override fun layoutButtons(dp: DeviceProfile, isContextualButtonShowing: Boolean) {
+ override fun layoutButtons(dp: DeviceProfile, isA11yButtonPersistent: Boolean) {
// TODO(b/230395757): Polish pending, this is just to make it usable
val endStartMargins = resources.getDimensionPixelSize(R.dimen.taskbar_nav_buttons_size)
val taskbarDimensions = DimensionUtils.getTaskbarPhoneDimensions(dp, resources,
@@ -104,10 +104,9 @@
endContextualContainer.removeAllViews()
startContextualContainer.removeAllViews()
- val startContextualContainerParams = FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
- startContextualContainerParams.gravity = Gravity.TOP or Gravity.CENTER_HORIZONTAL
- startContextualContainer.layoutParams = startContextualContainerParams
+ val contextualMargin = resources.getDimensionPixelSize(
+ R.dimen.taskbar_contextual_button_padding)
+ repositionContextualContainer(startContextualContainer, contextualMargin, Gravity.TOP)
if (imeSwitcher != null) {
startContextualContainer.addView(imeSwitcher)
@@ -121,4 +120,18 @@
rotationButton.currentView.layoutParams = getParamsToCenterView()
}
}
+
+ override fun repositionContextualContainer(contextualContainer: ViewGroup, barAxisMargin: Int,
+ gravity: Int) {
+ val contextualContainerParams = FrameLayout.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
+ contextualContainerParams.apply {
+ marginStart = 0
+ marginEnd = 0
+ topMargin = barAxisMargin
+ bottomMargin = barAxisMargin
+ }
+ contextualContainerParams.gravity = gravity or Gravity.CENTER_HORIZONTAL
+ contextualContainer.layoutParams = contextualContainerParams
+ }
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/PhonePortraitNavLayoutter.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/PhonePortraitNavLayoutter.kt
index 34df282..e1ffa4d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/navbutton/PhonePortraitNavLayoutter.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/PhonePortraitNavLayoutter.kt
@@ -47,7 +47,7 @@
a11yButton
) {
- override fun layoutButtons(dp: DeviceProfile, isContextualButtonShowing: Boolean) {
+ override fun layoutButtons(dp: DeviceProfile, isA11yButtonPersistent: Boolean) {
// TODO(b/230395757): Polish pending, this is just to make it usable
val taskbarDimensions =
DimensionUtils.getTaskbarPhoneDimensions(dp, resources,
@@ -102,10 +102,9 @@
endContextualContainer.removeAllViews()
startContextualContainer.removeAllViews()
- val endContextualContainerParams = FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT)
- endContextualContainerParams.gravity = Gravity.END or Gravity.CENTER_VERTICAL
- endContextualContainer.layoutParams = endContextualContainerParams
+ val contextualMargin = resources.getDimensionPixelSize(
+ R.dimen.taskbar_contextual_button_padding)
+ repositionContextualContainer(endContextualContainer, contextualMargin, Gravity.END)
if (imeSwitcher != null) {
endContextualContainer.addView(imeSwitcher)
diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneSeascapeNavLayoutter.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneSeascapeNavLayoutter.kt
index cfe1276..0368b1d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneSeascapeNavLayoutter.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneSeascapeNavLayoutter.kt
@@ -19,9 +19,9 @@
import android.content.res.Resources
import android.view.Gravity
import android.view.ViewGroup
-import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.LinearLayout
+import com.android.launcher3.R
import com.android.systemui.shared.rotation.RotationButton
class PhoneSeascapeNavLayoutter(
@@ -54,10 +54,9 @@
endContextualContainer.removeAllViews()
startContextualContainer.removeAllViews()
- val endContextualContainerParams = FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
- endContextualContainerParams.gravity = Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL
- endContextualContainer.layoutParams = endContextualContainerParams
+ val contextualMargin = resources.getDimensionPixelSize(
+ R.dimen.taskbar_contextual_button_padding)
+ repositionContextualContainer(endContextualContainer, contextualMargin, Gravity.BOTTOM)
if (imeSwitcher != null) {
endContextualContainer.addView(imeSwitcher)
diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/SetupNavLayoutter.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/SetupNavLayoutter.kt
index 36f5150..abdd32c 100644
--- a/quickstep/src/com/android/launcher3/taskbar/navbutton/SetupNavLayoutter.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/SetupNavLayoutter.kt
@@ -23,6 +23,7 @@
import android.widget.ImageView
import android.widget.LinearLayout
import com.android.launcher3.DeviceProfile
+import com.android.launcher3.R
import com.android.systemui.shared.rotation.RotationButton
class SetupNavLayoutter(
@@ -44,7 +45,7 @@
a11yButton
) {
- override fun layoutButtons(dp: DeviceProfile, isContextualButtonShowing: Boolean) {
+ override fun layoutButtons(dp: DeviceProfile, isA11yButtonPersistent: Boolean) {
// Since setup wizard only has back button enabled, it looks strange to be
// end-aligned, so start-align instead.
val navButtonsLayoutParams = navButtonContainer.layoutParams as FrameLayout.LayoutParams
@@ -58,15 +59,10 @@
endContextualContainer.removeAllViews()
startContextualContainer.removeAllViews()
- val endContextualContainerParams = FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT)
- endContextualContainerParams.gravity = Gravity.END or Gravity.CENTER_VERTICAL
- endContextualContainer.layoutParams = endContextualContainerParams
-
- val startContextualContainerParams = FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT)
- startContextualContainerParams.gravity = Gravity.START or Gravity.CENTER_VERTICAL
- startContextualContainer.layoutParams = startContextualContainerParams
+ val contextualMargin = resources.getDimensionPixelSize(
+ R.dimen.taskbar_contextual_button_padding)
+ repositionContextualContainer(endContextualContainer, 0, Gravity.END)
+ repositionContextualContainer(startContextualContainer, contextualMargin, Gravity.START)
if (imeSwitcher != null) {
startContextualContainer.addView(imeSwitcher)
diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/TaskbarNavLayoutter.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/TaskbarNavLayoutter.kt
index 58dce69..f5a4c64 100644
--- a/quickstep/src/com/android/launcher3/taskbar/navbutton/TaskbarNavLayoutter.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/TaskbarNavLayoutter.kt
@@ -27,8 +27,7 @@
import com.android.systemui.shared.rotation.RotationButton
/**
- * Layoutter for rendering task bar in large screen. {@param isContextualButtonShowing} is true in
- * 3-button mode.
+ * Layoutter for rendering task bar in large screen, both in 3-button and gesture nav mode.
*/
class TaskbarNavLayoutter(
resources: Resources,
@@ -49,13 +48,13 @@
a11yButton
) {
- override fun layoutButtons(dp: DeviceProfile, isContextualButtonShowing: Boolean) {
+ override fun layoutButtons(dp: DeviceProfile, isA11yButtonPersistent: Boolean) {
// Add spacing after the end of the last nav button
var navMarginEnd = resources.getDimension(dp.inv.inlineNavButtonsEndSpacing).toInt()
val contextualWidth = endContextualContainer.width
// If contextual buttons are showing, we check if the end margin is enough for the
// contextual button to be showing - if not, move the nav buttons over a smidge
- if (isContextualButtonShowing && navMarginEnd < contextualWidth) {
+ if (isA11yButtonPersistent && navMarginEnd < contextualWidth) {
// Additional spacing, eat up half of space between last icon and nav button
navMarginEnd += resources.getDimensionPixelSize(R.dimen.taskbar_hotseat_nav_spacing) / 2
}
@@ -92,16 +91,11 @@
endContextualContainer.removeAllViews()
startContextualContainer.removeAllViews()
- if (isContextualButtonShowing) {
- val endContextualContainerParams = FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT)
- endContextualContainerParams.gravity = Gravity.END or Gravity.CENTER_VERTICAL
- endContextualContainer.layoutParams = endContextualContainerParams
-
- val startContextualContainerParams = FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT)
- startContextualContainerParams.gravity = Gravity.START or Gravity.CENTER_VERTICAL
- startContextualContainer.layoutParams = startContextualContainerParams
+ if (!dp.isGestureMode) {
+ val contextualMargin = resources.getDimensionPixelSize(
+ R.dimen.taskbar_contextual_button_padding)
+ repositionContextualContainer(endContextualContainer, 0, Gravity.END)
+ repositionContextualContainer(startContextualContainer, contextualMargin, Gravity.START)
if (imeSwitcher != null) {
startContextualContainer.addView(imeSwitcher)
diff --git a/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java b/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java
index 1f8ddf0..406e9f4 100644
--- a/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java
+++ b/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java
@@ -185,6 +185,13 @@
@Override
public void onBackProgressed(BackMotionEvent backMotionEvent) {
mHandler.post(() -> {
+ LauncherBackAnimationController controller = mControllerRef.get();
+ if (controller == null
+ || controller.mLauncher == null
+ || !controller.mLauncher.isStarted()) {
+ // Skip animating back progress if Launcher isn't visible yet.
+ return;
+ }
mProgressAnimator.onBackProgressed(backMotionEvent);
});
}
@@ -294,6 +301,10 @@
SurfaceControl parent = viewRootImpl != null
? viewRootImpl.getSurfaceControl()
: null;
+ if (parent == null || !parent.isValid()) {
+ // Parent surface is not ready at the moment. Retry later.
+ return;
+ }
boolean isDarkTheme = Utilities.isDarkTheme(mLauncher);
mScrimLayer = new SurfaceControl.Builder()
.setName("Back to launcher background scrim")
@@ -326,6 +337,10 @@
if (!mBackInProgress || mBackTarget == null) {
return;
}
+ if (mScrimLayer == null) {
+ // Scrim hasn't been attached yet. Let's attach it.
+ addScrimLayer();
+ }
float screenWidth = mStartRect.width();
float screenHeight = mStartRect.height();
float width = Utilities.mapRange(progress, 1, MIN_WINDOW_SCALE) * screenWidth;
@@ -446,6 +461,9 @@
mScrimAlphaAnimator.cancel();
mScrimAlphaAnimator = null;
}
+ if (mScrimLayer != null) {
+ removeScrimLayer();
+ }
}
private void startTransitionAnimations(RectFSpringAnim springAnim, AnimatorSet anim) {
diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java
index 3c7fbf0..38e896e 100644
--- a/quickstep/src/com/android/quickstep/RecentsActivity.java
+++ b/quickstep/src/com/android/quickstep/RecentsActivity.java
@@ -37,7 +37,6 @@
import android.os.Handler;
import android.os.Looper;
import android.os.Trace;
-import android.util.Log;
import android.view.Display;
import android.view.RemoteAnimationAdapter;
import android.view.RemoteAnimationTarget;
@@ -68,7 +67,6 @@
import com.android.launcher3.statemanager.StatefulActivity;
import com.android.launcher3.taskbar.FallbackTaskbarUIController;
import com.android.launcher3.taskbar.TaskbarManager;
-import com.android.launcher3.testing.shared.TestProtocol;
import com.android.launcher3.util.ActivityOptionsWrapper;
import com.android.launcher3.util.ActivityTracker;
import com.android.launcher3.util.RunnableList;
@@ -418,7 +416,6 @@
}
public void startHome() {
- Log.d(TestProtocol.INCORRECT_HOME_STATE, "start home from recents activity");
RecentsView recentsView = getOverviewPanel();
recentsView.switchToScreenshot(() -> recentsView.finishRecentsAnimation(true,
this::startHomeInternal));
diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
index 4b47209..0bc44e1 100644
--- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java
+++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
@@ -21,6 +21,7 @@
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.launcher3.util.NavigationMode.NO_BUTTON;
import static com.android.quickstep.GestureState.GestureEndTarget.RECENTS;
+import static com.android.quickstep.GestureState.STATE_END_TARGET_ANIMATION_FINISHED;
import static com.android.quickstep.GestureState.STATE_RECENTS_ANIMATION_INITIALIZED;
import static com.android.quickstep.GestureState.STATE_RECENTS_ANIMATION_STARTED;
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.START_RECENTS_ANIMATION;
@@ -38,9 +39,7 @@
import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.testing.shared.TestProtocol;
import com.android.launcher3.util.DisplayController;
-import com.android.quickstep.TopTaskTracker.CachedTaskInfo;
import com.android.quickstep.util.ActiveGestureLog;
import com.android.quickstep.views.RecentsView;
import com.android.systemui.shared.recents.model.ThumbnailData;
@@ -154,6 +153,24 @@
mLastAppearedTaskTargets[i] = task;
}
mLastGestureState.updateLastAppearedTaskTargets(mLastAppearedTaskTargets);
+
+ if (ENABLE_SHELL_TRANSITIONS && mTargets.hasRecents
+ // The filtered (MODE_CLOSING) targets only contain 1 home activity.
+ && mTargets.apps.length == 1
+ && mTargets.apps[0].windowConfiguration.getActivityType()
+ == ACTIVITY_TYPE_HOME) {
+ // This is launching RecentsActivity on top of a 3p launcher. There are no
+ // other apps need to keep visible so finish the animating state after the
+ // enter animation of overview is done. Then 3p launcher can be stopped.
+ mLastGestureState.runOnceAtState(STATE_END_TARGET_ANIMATION_FINISHED, () -> {
+ // Only finish if the end target is RECENTS. Otherwise, if the target is
+ // NEW_TASK, startActivityFromRecents will be skipped.
+ if (mLastGestureState.getEndTarget() == RECENTS) {
+ finishRunningRecentsAnimation(false /* toHome */,
+ true /* forceFinish */, null /* forceFinishCb */);
+ }
+ });
+ }
}
@Override
@@ -181,9 +198,6 @@
RecentsView recentsView =
activityInterface.getCreatedActivity().getOverviewPanel();
if (recentsView != null) {
- Log.d(TestProtocol.INCORRECT_HOME_STATE,
- "finish recents animation on "
- + compat.taskInfo.description);
recentsView.finishRecentsAnimation(true, null);
}
return;
@@ -256,15 +270,8 @@
if (ENABLE_SHELL_TRANSITIONS) {
final ActivityOptions options = ActivityOptions.makeBasic();
- // Allowing to pause Home if Home is top activity and Recents is not Home. So when user
- // start home when recents animation is playing, the home activity can be resumed again
- // to let the transition controller collect Home activity.
- CachedTaskInfo cti = gestureState.getRunningTask();
- boolean homeIsOnTop = cti != null && cti.isHomeTask();
- if (activityInterface.allowAllAppsFromOverview()) {
- homeIsOnTop = true;
- }
- if (!homeIsOnTop) {
+ // Use regular (non-transient) launch for all apps page to control IME.
+ if (!activityInterface.allowAllAppsFromOverview()) {
options.setTransientLaunch();
}
options.setSourceInfo(ActivityOptions.SourceInfo.TYPE_RECENTS_ANIMATION, eventTime);
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java
index f9f1579..1af4bad 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java
@@ -20,8 +20,6 @@
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import android.content.Context;
-import android.view.GestureDetector;
-import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
@@ -37,51 +35,36 @@
*/
public class NavHandleLongPressInputConsumer extends DelegateInputConsumer {
- private final GestureDetector mLongPressDetector;
private final NavHandleLongPressHandler mNavHandleLongPressHandler;
private final float mNavHandleWidth;
private final float mScreenWidth;
+ private final ViewConfiguration mViewConfiguration;
- // Below are only used if CUSTOM_LPNH_THRESHOLDS is enabled.
- private final float mCustomTouchSlopSquared;
- private final int mCustomLongPressTimeout;
- private final Runnable mTriggerCustomLongPress = this::triggerCustomLongPress;
- private MotionEvent mCurrentCustomDownEvent;
+ private final Runnable mTriggerLongPress = this::triggerLongPress;
+ private final float mTouchSlopSquared;
+ private final int mLongPressTimeout;
+
+ private MotionEvent mCurrentDownEvent;
public NavHandleLongPressInputConsumer(Context context, InputConsumer delegate,
InputMonitorCompat inputMonitor) {
super(delegate, inputMonitor);
+ mViewConfiguration = ViewConfiguration.get(context);
mNavHandleWidth = context.getResources().getDimensionPixelSize(
R.dimen.navigation_home_handle_width);
mScreenWidth = DisplayController.INSTANCE.get(context).getInfo().currentSize.x;
- float customSlopMultiplier =
- LauncherPrefs.get(context).get(LONG_PRESS_NAV_HANDLE_SLOP_PERCENTAGE) / 100f;
- float customTouchSlop =
- ViewConfiguration.get(context).getScaledEdgeSlop() * customSlopMultiplier;
- mCustomTouchSlopSquared = customTouchSlop * customTouchSlop;
- mCustomLongPressTimeout = LauncherPrefs.get(context).get(LONG_PRESS_NAV_HANDLE_TIMEOUT_MS);
-
+ float touchSlop;
+ if (FeatureFlags.CUSTOM_LPNH_THRESHOLDS.get()) {
+ float customSlopMultiplier =
+ LauncherPrefs.get(context).get(LONG_PRESS_NAV_HANDLE_SLOP_PERCENTAGE) / 100f;
+ touchSlop = mViewConfiguration.getScaledEdgeSlop() * customSlopMultiplier;
+ mLongPressTimeout = LauncherPrefs.get(context).get(LONG_PRESS_NAV_HANDLE_TIMEOUT_MS);
+ } else {
+ touchSlop = mViewConfiguration.getScaledTouchSlop();
+ mLongPressTimeout = ViewConfiguration.getLongPressTimeout();
+ }
+ mTouchSlopSquared = touchSlop * touchSlop;
mNavHandleLongPressHandler = NavHandleLongPressHandler.newInstance(context);
-
- mLongPressDetector = new GestureDetector(context, new SimpleOnGestureListener() {
- @Override
- public void onLongPress(MotionEvent motionEvent) {
- if (isInNavBarHorizontalArea(motionEvent.getRawX())) {
- Runnable longPressRunnable = mNavHandleLongPressHandler.getLongPressRunnable();
- if (longPressRunnable != null) {
- OtherActivityInputConsumer oaic = getInputConsumerOfClass(
- OtherActivityInputConsumer.class);
- if (oaic != null) {
- oaic.setForceFinishRecentsTransitionCallback(longPressRunnable);
- setActive(motionEvent);
- } else {
- setActive(motionEvent);
- MAIN_EXECUTOR.post(longPressRunnable);
- }
- }
- }
- }
- });
}
@Override
@@ -91,30 +74,41 @@
@Override
public void onMotionEvent(MotionEvent ev) {
- if (!FeatureFlags.CUSTOM_LPNH_THRESHOLDS.get()) {
- mLongPressDetector.onTouchEvent(ev);
- } else {
- switch (ev.getAction()) {
- case MotionEvent.ACTION_DOWN -> {
- if (mCurrentCustomDownEvent != null) {
- mCurrentCustomDownEvent.recycle();
- }
- mCurrentCustomDownEvent = MotionEvent.obtain(ev);
- if (isInNavBarHorizontalArea(ev.getRawX())) {
- MAIN_EXECUTOR.getHandler().postDelayed(mTriggerCustomLongPress,
- mCustomLongPressTimeout);
- }
+ switch (ev.getAction()) {
+ case MotionEvent.ACTION_DOWN -> {
+ if (mCurrentDownEvent != null) {
+ mCurrentDownEvent.recycle();
}
- case MotionEvent.ACTION_MOVE -> {
- double touchDeltaSquared =
- Math.pow(ev.getX() - mCurrentCustomDownEvent.getX(), 2)
- + Math.pow(ev.getY() - mCurrentCustomDownEvent.getY(), 2);
- if (touchDeltaSquared > mCustomTouchSlopSquared) {
- cancelCustomLongPress();
- }
+ mCurrentDownEvent = MotionEvent.obtain(ev);
+ if (isInNavBarHorizontalArea(ev.getRawX())) {
+ MAIN_EXECUTOR.getHandler().postDelayed(mTriggerLongPress,
+ mLongPressTimeout);
}
- case MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> cancelCustomLongPress();
}
+ case MotionEvent.ACTION_MOVE -> {
+ float touchSlopSquared = mTouchSlopSquared;
+ float dx = ev.getX() - mCurrentDownEvent.getX();
+ float dy = ev.getY() - mCurrentDownEvent.getY();
+ double distanceSquared = (dx * dx) + (dy * dy);
+ // If the gesture is ambiguous then require more movement before classifying this
+ // as a NON long press gesture.
+ if (ev.getClassification() == MotionEvent.CLASSIFICATION_AMBIGUOUS_GESTURE) {
+ float ambiguousGestureMultiplier =
+ mViewConfiguration.getScaledAmbiguousGestureMultiplier();
+ touchSlopSquared *= ambiguousGestureMultiplier * ambiguousGestureMultiplier;
+ }
+ if (distanceSquared > touchSlopSquared) {
+ cancelLongPress();
+ }
+ }
+ case MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> cancelLongPress();
+ }
+
+ // If the gesture is deep press then trigger long press asap
+ if (MAIN_EXECUTOR.getHandler().hasCallbacks(mTriggerLongPress)
+ && ev.getClassification() == MotionEvent.CLASSIFICATION_DEEP_PRESS) {
+ MAIN_EXECUTOR.getHandler().removeCallbacks(mTriggerLongPress);
+ MAIN_EXECUTOR.getHandler().post(mTriggerLongPress);
}
if (mState != STATE_ACTIVE) {
@@ -122,17 +116,23 @@
}
}
- private void triggerCustomLongPress() {
+ private void triggerLongPress() {
Runnable longPressRunnable = mNavHandleLongPressHandler.getLongPressRunnable();
if (longPressRunnable != null) {
- setActive(mCurrentCustomDownEvent);
-
- MAIN_EXECUTOR.post(longPressRunnable);
+ OtherActivityInputConsumer oaic = getInputConsumerOfClass(
+ OtherActivityInputConsumer.class);
+ if (oaic != null) {
+ oaic.setForceFinishRecentsTransitionCallback(longPressRunnable);
+ setActive(mCurrentDownEvent);
+ } else {
+ setActive(mCurrentDownEvent);
+ MAIN_EXECUTOR.post(longPressRunnable);
+ }
}
}
- private void cancelCustomLongPress() {
- MAIN_EXECUTOR.getHandler().removeCallbacks(mTriggerCustomLongPress);
+ private void cancelLongPress() {
+ MAIN_EXECUTOR.getHandler().removeCallbacks(mTriggerLongPress);
}
private boolean isInNavBarHorizontalArea(float x) {
diff --git a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
index b1daac4..71673f3 100644
--- a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
+++ b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
@@ -224,6 +224,7 @@
private LauncherAtom.Slice mSlice;
private Optional<Integer> mCardinality = Optional.empty();
private int mInputType = SysUiStatsLog.LAUNCHER_UICHANGED__INPUT_TYPE__UNKNOWN;
+ private Optional<Integer> mFeatures = Optional.empty();
StatsCompatLogger(Context context, ActivityContext activityContext) {
mContext = context;
@@ -323,6 +324,12 @@
}
@Override
+ public StatsLogger withFeatures(int feature) {
+ this.mFeatures = Optional.of(feature);
+ return this;
+ }
+
+ @Override
public void log(EventEnum event) {
if (!Utilities.ATLEAST_R) {
return;
@@ -451,6 +458,7 @@
return;
}
int cardinality = mCardinality.orElseGet(() -> getCardinality(atomInfo));
+ int features = mFeatures.orElseGet(() -> getFeatures(atomInfo));
SysUiStatsLog.write(
SysUiStatsLog.LAUNCHER_EVENT,
SysUiStatsLog.LAUNCHER_UICHANGED__ACTION__DEFAULT_ACTION /* deprecated */,
@@ -477,7 +485,7 @@
atomInfo.getFolderIcon().getToLabelState().getNumber() /* toState */,
atomInfo.getFolderIcon().getLabelInfo() /* edittext */,
cardinality /* cardinality */,
- getFeatures(atomInfo) /* features */,
+ features /* features */,
getSearchAttributes(atomInfo) /* searchAttributes */,
getAttributes(atomInfo) /* attributes */,
inputType /* input_type */
diff --git a/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java b/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java
index e0b5272..61ba5ac 100644
--- a/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java
+++ b/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java
@@ -35,6 +35,7 @@
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.util.HorizontalInsettableView;
import com.android.quickstep.SystemUiProxy;
+import com.android.quickstep.util.unfold.LauncherJankMonitorTransitionProgressListener;
import com.android.quickstep.util.unfold.PreemptiveUnfoldTransitionProgressProvider;
import com.android.systemui.unfold.UnfoldTransitionProgressProvider;
import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener;
@@ -91,6 +92,8 @@
}
unfoldTransitionProgressProvider.addCallback(mExternalTransitionStatusProvider);
+ unfoldTransitionProgressProvider.addCallback(
+ new LauncherJankMonitorTransitionProgressListener(launcher::getRootView));
mUnfoldMoveFromCenterHotseatAnimator = new UnfoldMoveFromCenterHotseatAnimator(launcher,
windowManager, rotationChangeProvider);
diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
index efe0540..8e3b5ec 100644
--- a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
+++ b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
@@ -17,7 +17,6 @@
package com.android.quickstep.util;
import static com.android.launcher3.Utilities.postAsyncCallback;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_SPLIT_FROM_DESKTOP_TO_WORKSPACE;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_DESKTOP_MODE_SPLIT_LEFT_TOP;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_DESKTOP_MODE_SPLIT_RIGHT_BOTTOM;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
@@ -92,6 +91,7 @@
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.TaskAnimationManager;
import com.android.quickstep.TaskViewUtils;
+import com.android.quickstep.views.DesktopTaskView;
import com.android.quickstep.views.FloatingTaskView;
import com.android.quickstep.views.GroupedTaskView;
import com.android.quickstep.views.RecentsView;
@@ -815,7 +815,7 @@
@Override
public boolean onRequestSplitSelect(ActivityManager.RunningTaskInfo taskInfo,
int splitPosition, Rect taskBounds) {
- if (!ENABLE_SPLIT_FROM_DESKTOP_TO_WORKSPACE.get()) return false;
+ if (!DesktopTaskView.DESKTOP_MODE_SUPPORTED) return false;
MAIN_EXECUTOR.execute(() -> enterSplitSelect(taskInfo, splitPosition,
taskBounds));
return true;
diff --git a/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java b/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java
index 0fa8a29..00b5621 100644
--- a/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java
+++ b/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java
@@ -16,7 +16,6 @@
package com.android.quickstep.util;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_SPLIT_FROM_DESKTOP_TO_WORKSPACE;
import static com.android.launcher3.config.FeatureFlags.ENABLE_SPLIT_FROM_FULLSCREEN_WITH_KEYBOARD_SHORTCUTS;
import static com.android.launcher3.config.FeatureFlags.ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
@@ -45,6 +44,7 @@
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.model.data.PackageItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
+import com.android.quickstep.views.DesktopTaskView;
import com.android.quickstep.views.FloatingTaskView;
import com.android.quickstep.views.RecentsView;
import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
@@ -193,7 +193,7 @@
private boolean shouldIgnoreSecondSplitLaunch() {
return (!ENABLE_SPLIT_FROM_FULLSCREEN_WITH_KEYBOARD_SHORTCUTS.get()
&& !ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE.get()
- && !ENABLE_SPLIT_FROM_DESKTOP_TO_WORKSPACE.get())
+ && !DesktopTaskView.DESKTOP_MODE_SUPPORTED)
|| !mController.isSplitSelectActive();
}
}
diff --git a/quickstep/src/com/android/quickstep/util/unfold/LauncherJankMonitorTransitionProgressListener.kt b/quickstep/src/com/android/quickstep/util/unfold/LauncherJankMonitorTransitionProgressListener.kt
new file mode 100644
index 0000000..4f89c7e
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/util/unfold/LauncherJankMonitorTransitionProgressListener.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.util.unfold
+
+import android.view.View
+import com.android.systemui.shared.system.InteractionJankMonitorWrapper
+import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
+import java.util.function.Supplier
+
+/** Reports beginning and end of the unfold animation to interaction jank monitor */
+class LauncherJankMonitorTransitionProgressListener(
+ private val attachedViewProvider: Supplier<View>
+) : TransitionProgressListener {
+
+ override fun onTransitionStarted() {
+ InteractionJankMonitorWrapper.begin(
+ attachedViewProvider.get(),
+ InteractionJankMonitorWrapper.CUJ_LAUNCHER_UNFOLD_ANIM
+ )
+ }
+
+ override fun onTransitionFinished() {
+ InteractionJankMonitorWrapper.end(InteractionJankMonitorWrapper.CUJ_LAUNCHER_UNFOLD_ANIM)
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
index 71758ad..a4a53d1 100644
--- a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
@@ -2,7 +2,7 @@
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
-import static com.android.launcher3.config.FeatureFlags.enableOverviewIconMenu;
+import static com.android.launcher3.Flags.enableOverviewIconMenu;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
import static com.android.quickstep.util.SplitScreenUtils.convertLauncherSplitBoundsToShell;
@@ -169,7 +169,9 @@
mIconLoadRequest2 = iconCache.updateIconInBackground(mSecondaryTask,
(task) -> {
setIcon(mIconView2, task.icon);
- setText(mIconView2, TaskUtils.getTitle(getContext(), task));
+ if (enableOverviewIconMenu()) {
+ setText(mIconView2, TaskUtils.getTitle(getContext(), task));
+ }
mDigitalWellBeingToast2.initialize(mSecondaryTask);
mDigitalWellBeingToast2.setSplitConfiguration(mSplitBoundsConfig);
mDigitalWellBeingToast.setSplitConfiguration(mSplitBoundsConfig);
@@ -184,7 +186,9 @@
}
if (needsUpdate(changes, FLAG_UPDATE_ICON)) {
setIcon(mIconView2, null);
- setText(mIconView2, null);
+ if (enableOverviewIconMenu()) {
+ setText(mIconView2, null);
+ }
}
}
}
diff --git a/quickstep/src/com/android/quickstep/views/IconAppChipView.java b/quickstep/src/com/android/quickstep/views/IconAppChipView.java
index 960a09e..5a2e135 100644
--- a/quickstep/src/com/android/quickstep/views/IconAppChipView.java
+++ b/quickstep/src/com/android/quickstep/views/IconAppChipView.java
@@ -16,7 +16,7 @@
package com.android.quickstep.views;
import static com.android.app.animation.Interpolators.EMPHASIZED;
-import static com.android.launcher3.config.FeatureFlags.enableOverviewIconMenu;
+import static com.android.launcher3.Flags.enableOverviewIconMenu;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
diff --git a/quickstep/src/com/android/quickstep/views/IconView.java b/quickstep/src/com/android/quickstep/views/IconView.java
index 222f9ca..64caba7 100644
--- a/quickstep/src/com/android/quickstep/views/IconView.java
+++ b/quickstep/src/com/android/quickstep/views/IconView.java
@@ -15,7 +15,7 @@
*/
package com.android.quickstep.views;
-import static com.android.launcher3.config.FeatureFlags.enableOverviewIconMenu;
+import static com.android.launcher3.Flags.enableOverviewIconMenu;
import android.content.Context;
import android.graphics.Canvas;
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index ef908c5..0a195c3 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -5270,8 +5270,6 @@
cleanupRemoteTargets();
if (mRecentsAnimationController == null) {
- Log.d(TestProtocol.INCORRECT_HOME_STATE, "finish recents animation but recents "
- + "animation controller was null. returning.");
if (onFinishComplete != null) {
onFinishComplete.run();
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskMenuView.java b/quickstep/src/com/android/quickstep/views/TaskMenuView.java
index 62c0bef..8f12909 100644
--- a/quickstep/src/com/android/quickstep/views/TaskMenuView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskMenuView.java
@@ -17,7 +17,7 @@
package com.android.quickstep.views;
import static com.android.app.animation.Interpolators.EMPHASIZED;
-import static com.android.launcher3.config.FeatureFlags.enableOverviewIconMenu;
+import static com.android.launcher3.Flags.enableOverviewIconMenu;
import static com.android.quickstep.views.TaskThumbnailView.DIM_ALPHA;
import android.animation.Animator;
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index df907e7..92b942d 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -25,7 +25,7 @@
import static com.android.app.animation.Interpolators.LINEAR;
import static com.android.launcher3.LauncherState.BACKGROUND_APP;
import static com.android.launcher3.Utilities.getDescendantCoordRelativeToAncestor;
-import static com.android.launcher3.config.FeatureFlags.enableOverviewIconMenu;
+import static com.android.launcher3.Flags.enableOverviewIconMenu;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_ICON_TAP_OR_LONGPRESS;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_LAUNCH_TAP;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
@@ -1020,6 +1020,17 @@
mActivity.getStateManager(), recentsView,
recentsView.getDepthController());
anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ if (!recentsView.showAsGrid()) {
+ return;
+ }
+ recentsView.runActionOnRemoteHandles(
+ (Consumer<RemoteTargetHandle>) remoteTargetHandle ->
+ remoteTargetHandle
+ .getTaskViewSimulator()
+ .setDrawsBelowRecents(false));
+ }
@Override
public void onAnimationEnd(Animator animator) {
@@ -1081,7 +1092,9 @@
mIconLoadRequest = iconCache.updateIconInBackground(mTask,
(task) -> {
setIcon(mIconView, task.icon);
- setText(mIconView, TaskUtils.getTitle(getContext(), task));
+ if (enableOverviewIconMenu()) {
+ setText(mIconView, TaskUtils.getTitle(getContext(), task));
+ }
mDigitalWellBeingToast.initialize(task);
});
}
@@ -1097,7 +1110,9 @@
}
if (needsUpdate(changes, FLAG_UPDATE_ICON)) {
setIcon(mIconView, null);
- setText(mIconView, null);
+ if (enableOverviewIconMenu()) {
+ setText(mIconView, null);
+ }
}
}
}
diff --git a/quickstep/tests/src/com/android/quickstep/AbstractTaplTestsTaskbar.java b/quickstep/tests/src/com/android/quickstep/AbstractTaplTestsTaskbar.java
index efc00bb..ba9ae67 100644
--- a/quickstep/tests/src/com/android/quickstep/AbstractTaplTestsTaskbar.java
+++ b/quickstep/tests/src/com/android/quickstep/AbstractTaplTestsTaskbar.java
@@ -37,7 +37,6 @@
public class AbstractTaplTestsTaskbar extends AbstractQuickStepTest {
- protected static final String TEST_APP_NAME = "LauncherTestApp";
protected static final String TEST_APP_PACKAGE =
getInstrumentation().getContext().getPackageName();
protected static final String CALCULATOR_APP_PACKAGE =
diff --git a/quickstep/tests/src/com/android/quickstep/RecentsModelTest.java b/quickstep/tests/src/com/android/quickstep/RecentsModelTest.java
index c552d83..648fa93 100644
--- a/quickstep/tests/src/com/android/quickstep/RecentsModelTest.java
+++ b/quickstep/tests/src/com/android/quickstep/RecentsModelTest.java
@@ -101,11 +101,6 @@
when(mContext.getResources()).thenReturn(mResource);
}
- @After
- public void tearDown() throws Exception {
- mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_GRID_ONLY_OVERVIEW);
- }
-
@Test
@UiThreadTest
public void preloadOnHighResolutionEnabled() {
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
index e8f0447..61f1f74 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
@@ -17,7 +17,6 @@
package com.android.quickstep;
import static com.android.launcher3.config.FeatureFlags.ENABLE_CURSOR_HOVER_STATES;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_OVERVIEW_ICON_MENU;
import static com.android.quickstep.TaskbarModeSwitchRule.Mode.PERSISTENT;
import static com.android.quickstep.TaskbarModeSwitchRule.Mode.TRANSIENT;
@@ -44,7 +43,6 @@
import com.android.launcher3.tapl.Overview;
import com.android.launcher3.tapl.OverviewActions;
import com.android.launcher3.tapl.OverviewTask;
-import com.android.launcher3.tapl.OverviewTaskMenu;
import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape;
import com.android.launcher3.ui.TaplTestsLauncher3;
import com.android.launcher3.util.TestUtil;
@@ -64,7 +62,6 @@
@RunWith(AndroidJUnit4.class)
public class TaplTestsQuickstep extends AbstractQuickStepTest {
- private static final String APP_NAME = "LauncherTestApp";
private static final String CALCULATOR_APP_PACKAGE =
resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR);
private static final String READ_DEVICE_CONFIG_PERMISSION =
@@ -196,38 +193,6 @@
actionsView.clickAndDismissScreenshot();
}
-
- @PlatinumTest(focusArea = "launcher")
- @Test
- public void testOverviewActionsMenu() throws Exception {
- startTestAppsWithCheck();
-
- OverviewTaskMenu menu = mLauncher.goHome().switchToOverview().getCurrentTask().tapMenu();
-
- assertNotNull("Tapping App info menu item returned null", menu.tapAppInfoMenuItem());
- executeOnLauncher(launcher -> assertTrue(
- "Launcher activity is the top activity; expecting another activity to be the top",
- isInLaunchedApp(launcher)));
- }
-
-
- @Test
- @ScreenRecord // b/303329286
- public void testOverviewActionsMenu_iconAppChipMenu() throws Exception {
- try (AutoCloseable c = TestUtil.overrideFlag(ENABLE_OVERVIEW_ICON_MENU, true)) {
- startTestAppsWithCheck();
-
- OverviewTaskMenu menu =
- mLauncher.goHome().switchToOverview().getCurrentTask().tapMenu();
-
- assertNotNull("Tapping App info menu item returned null", menu.tapAppInfoMenuItem());
- executeOnLauncher(launcher -> assertTrue(
- "Launcher activity is the top activity; expecting another activity to be the "
- + "top",
- isInLaunchedApp(launcher)));
- }
- }
-
private int getCurrentOverviewPage(Launcher launcher) {
return launcher.<RecentsView>getOverviewPanel().getCurrentPage();
}
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java b/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java
index 1e99f17..acbb58f 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java
@@ -16,7 +16,6 @@
package com.android.quickstep;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_OVERVIEW_ICON_MENU;
import static com.android.launcher3.util.rule.TestStabilityRule.LOCAL;
import static com.android.launcher3.util.rule.TestStabilityRule.PLATFORM_POSTSUBMIT;
@@ -30,10 +29,8 @@
import androidx.test.filters.LargeTest;
import androidx.test.platform.app.InstrumentationRegistry;
-import com.android.launcher3.tapl.OverviewTaskMenu;
import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape;
import com.android.launcher3.ui.TaplTestsLauncher3;
-import com.android.launcher3.util.TestUtil;
import com.android.launcher3.util.rule.TestStabilityRule;
import com.android.quickstep.TaskbarModeSwitchRule.TaskbarModeSwitch;
import com.android.wm.shell.Flags;
@@ -142,42 +139,6 @@
.hasMenuItem("Save app pair"));
}
- @Test
- public void testTapBothIconMenus() {
- createAndLaunchASplitPair();
-
- OverviewTaskMenu taskMenu =
- mLauncher.goHome().switchToOverview().getCurrentTask().tapMenu();
- assertTrue("App info item not appearing in expanded task menu.",
- taskMenu.hasMenuItem("App info"));
- taskMenu.touchOutsideTaskMenuToDismiss();
-
- OverviewTaskMenu splitMenu =
- mLauncher.getOverview().getCurrentTask().tapSplitTaskMenu();
- assertTrue("App info item not appearing in expanded split task's menu.",
- splitMenu.hasMenuItem("App info"));
- splitMenu.touchOutsideTaskMenuToDismiss();
- }
-
- @Test
- public void testTapBothIconMenus_iconAppChipMenu() throws Exception {
- try (AutoCloseable c = TestUtil.overrideFlag(ENABLE_OVERVIEW_ICON_MENU, true)) {
- createAndLaunchASplitPair();
-
- OverviewTaskMenu taskMenu =
- mLauncher.goHome().switchToOverview().getCurrentTask().tapMenu();
- assertTrue("App info item not appearing in expanded task menu.",
- taskMenu.hasMenuItem("App info"));
- taskMenu.touchOutsideTaskMenuToDismiss();
-
- OverviewTaskMenu splitMenu =
- mLauncher.getOverview().getCurrentTask().tapSplitTaskMenu();
- assertTrue("App info item not appearing in expanded split task's menu.",
- splitMenu.hasMenuItem("App info"));
- splitMenu.touchOutsideTaskMenuToDismiss();
- }
- }
-
private void createAndLaunchASplitPair() {
startTestActivity(2);
startTestActivity(3);
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java b/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java
index 093c45d..0e382a4 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java
@@ -15,6 +15,7 @@
*/
package com.android.quickstep;
+import static com.android.launcher3.util.TestConstants.AppNames.TEST_APP_NAME;
import static com.android.quickstep.TaplTestsTaskbar.TaskbarMode.PERSISTENT;
import static com.android.quickstep.TaplTestsTaskbar.TaskbarMode.TRANSIENT;
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsTransientTaskbar.java b/quickstep/tests/src/com/android/quickstep/TaplTestsTransientTaskbar.java
index b3cec4e..fc23a05 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsTransientTaskbar.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsTransientTaskbar.java
@@ -16,6 +16,7 @@
package com.android.quickstep;
import static com.android.launcher3.config.FeatureFlags.ENABLE_CURSOR_HOVER_STATES;
+import static com.android.launcher3.util.TestConstants.AppNames.TEST_APP_NAME;
import static com.android.quickstep.TaskbarModeSwitchRule.Mode.TRANSIENT;
import androidx.test.filters.LargeTest;
diff --git a/res/drawable/encrypted_24px.xml b/res/drawable/encrypted_24px.xml
new file mode 100644
index 0000000..cf4d2df
--- /dev/null
+++ b/res/drawable/encrypted_24px.xml
@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="960"
+ android:viewportHeight="960"
+ android:tint="?attr/colorControlNormal">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M420,600L540,600L517,471Q537,461 548.5,442Q560,423 560,400Q560,367 536.5,343.5Q513,320 480,320Q447,320 423.5,343.5Q400,367 400,400Q400,423 411.5,442Q423,461 443,471L420,600ZM480,880Q341,845 250.5,720.5Q160,596 160,444L160,200L480,80L800,200L800,444Q800,596 709.5,720.5Q619,845 480,880ZM480,796Q584,763 652,664Q720,565 720,444L720,255L480,165L240,255L240,444Q240,565 308,664Q376,763 480,796ZM480,480Q480,480 480,480Q480,480 480,480L480,480L480,480L480,480L480,480Q480,480 480,480Q480,480 480,480Z"/>
+</vector>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 57163ff..4e865d0 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -453,4 +453,7 @@
<string name="search_pref_screen_title_tablet">Search your tablet</string>
<!-- Failed action error message: e.g. Failed: Pause -->
<string name="remote_action_failed">Failed: <xliff:g id="what" example="Pause">%1$s</xliff:g></string>
+
+ <!-- Private space label -->
+ <string name="private_space_label">Private space</string>
</resources>
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index 08e5def..91fbe53 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -117,6 +117,8 @@
// return an (x, y) value from helper functions. Do NOT use them to maintain other state.
@Thunk final int[] mTmpPoint = new int[2];
@Thunk final int[] mTempLocation = new int[2];
+
+ @Thunk final Rect mTempOnDrawCellToRect = new Rect();
final PointF mTmpPointF = new PointF();
protected GridOccupancy mOccupied;
@@ -600,23 +602,18 @@
DeviceProfile dp = mActivity.getDeviceProfile();
int paddingX = Math.min((mCellWidth - dp.iconSizePx) / 2, dp.gridVisualizationPaddingX);
int paddingY = Math.min((mCellHeight - dp.iconSizePx) / 2, dp.gridVisualizationPaddingY);
- mVisualizeGridRect.set(paddingX, paddingY,
- mCellWidth - paddingX,
- mCellHeight - paddingY);
mVisualizeGridPaint.setStrokeWidth(8);
- int paintAlpha = (int) (120 * mGridAlpha);
- mVisualizeGridPaint.setColor(ColorUtils.setAlphaComponent(mGridColor, paintAlpha));
+ // This is used for debugging purposes only
if (mVisualizeCells) {
+ int paintAlpha = (int) (120 * mGridAlpha);
+ mVisualizeGridPaint.setColor(ColorUtils.setAlphaComponent(mGridColor, paintAlpha));
for (int i = 0; i < mCountX; i++) {
for (int j = 0; j < mCountY; j++) {
- int transX = i * mCellWidth + (i * mBorderSpace.x) + getPaddingLeft()
- + paddingX;
- int transY = j * mCellHeight + (j * mBorderSpace.y) + getPaddingTop()
- + paddingY;
-
- mVisualizeGridRect.offsetTo(transX, transY);
+ cellToRect(i, j, 1, 1, mTempOnDrawCellToRect);
+ mVisualizeGridRect.set(mTempOnDrawCellToRect);
+ mVisualizeGridRect.inset(paddingX, paddingY);
mVisualizeGridPaint.setStyle(Paint.Style.FILL);
canvas.drawRoundRect(mVisualizeGridRect, mGridVisualizationRoundingRadius,
mGridVisualizationRoundingRadius, mVisualizeGridPaint);
@@ -628,25 +625,13 @@
for (int i = 0; i < mDragOutlines.length; i++) {
final float alpha = mDragOutlineAlphas[i];
if (alpha <= 0) continue;
+ CellLayoutLayoutParams params = mDragOutlines[i];
+ cellToRect(params.getCellX(), params.getCellY(), params.cellHSpan, params.cellVSpan,
+ mTempOnDrawCellToRect);
+ mVisualizeGridRect.set(mTempOnDrawCellToRect);
+ mVisualizeGridRect.inset(paddingX, paddingY);
mVisualizeGridPaint.setAlpha(255);
- int x = mDragOutlines[i].getCellX();
- int y = mDragOutlines[i].getCellY();
- int spanX = mDragOutlines[i].cellHSpan;
- int spanY = mDragOutlines[i].cellVSpan;
-
- // TODO b/194414754 clean this up, reconcile with cellToRect
- mVisualizeGridRect.set(paddingX, paddingY,
- mCellWidth * spanX + mBorderSpace.x * (spanX - 1) - paddingX,
- mCellHeight * spanY + mBorderSpace.y * (spanY - 1) - paddingY);
-
- int transX = x * mCellWidth + (x * mBorderSpace.x)
- + getPaddingLeft() + paddingX;
- int transY = y * mCellHeight + (y * mBorderSpace.y)
- + getPaddingTop() + paddingY;
-
- mVisualizeGridRect.offsetTo(transX, transY);
-
mVisualizeGridPaint.setStyle(Paint.Style.STROKE);
mVisualizeGridPaint.setColor(Color.argb((int) (alpha),
Color.red(mGridColor), Color.green(mGridColor), Color.blue(mGridColor)));
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index c96e22d..2ac6098 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -24,7 +24,7 @@
import static com.android.launcher3.Utilities.dpiFromPx;
import static com.android.launcher3.Utilities.pxFromSp;
import static com.android.launcher3.config.FeatureFlags.ENABLE_MULTI_DISPLAY_PARTIAL_DEPTH;
-import static com.android.launcher3.config.FeatureFlags.enableOverviewIconMenu;
+import static com.android.launcher3.Flags.enableOverviewIconMenu;
import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.ICON_OVERLAP_FACTOR;
import static com.android.launcher3.icons.GraphicsUtils.getShapePath;
import static com.android.launcher3.icons.IconNormalizer.ICON_VISIBLE_AREA_FACTOR;
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index 04e8da1..75f4bb2 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -486,7 +486,9 @@
iconBitmapSize, fillResIconDpi, numDatabaseAllAppsColumns, dbFile};
}
- private void onConfigChanged(Context context) {
+ /** Updates IDP using the provided context. Notifies listeners of change. */
+ @VisibleForTesting
+ public void onConfigChanged(Context context) {
Object[] oldState = toModelState();
// Re-init grid
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index dfcd279..7d62045 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -383,9 +383,6 @@
private PopupDataProvider mPopupDataProvider;
- private IntSet mSynchronouslyBoundPages = new IntSet();
- @NonNull private IntSet mPagesToBindSynchronously = new IntSet();
-
// We only want to get the SharedPreferences once since it does an FS stat each time we get
// it from the context.
private SharedPreferences mSharedPrefs;
@@ -560,7 +557,7 @@
if (savedInstanceState != null) {
int[] pageIds = savedInstanceState.getIntArray(RUNTIME_STATE_CURRENT_SCREEN_IDS);
if (pageIds != null) {
- mPagesToBindSynchronously = IntSet.wrap(pageIds);
+ mModelCallbacks.setPagesToBindSynchronously(IntSet.wrap(pageIds));
}
}
@@ -1648,8 +1645,9 @@
@Override
public void onRestoreInstanceState(Bundle state) {
super.onRestoreInstanceState(state);
- if (mSynchronouslyBoundPages != null) {
- mSynchronouslyBoundPages.forEach(screenId -> {
+ IntSet synchronouslyBoundPages = mModelCallbacks.getSynchronouslyBoundPages();
+ if (synchronouslyBoundPages != null) {
+ synchronouslyBoundPages.forEach(screenId -> {
int pageIndex = mWorkspace.getPageIndexForScreenId(screenId);
if (pageIndex != PagedView.INVALID_PAGE) {
mWorkspace.restoreInstanceStateForChild(pageIndex);
@@ -2072,41 +2070,7 @@
@Override
public IntSet getPagesToBindSynchronously(IntArray orderedScreenIds) {
- IntSet visibleIds;
- if (!mPagesToBindSynchronously.isEmpty()) {
- visibleIds = mPagesToBindSynchronously;
- } else if (!mWorkspaceLoading) {
- visibleIds = mWorkspace.getCurrentPageScreenIds();
- } else {
- // If workspace binding is still in progress, getCurrentPageScreenIds won't be accurate,
- // and we should use mSynchronouslyBoundPages that's set during initial binding.
- visibleIds = mSynchronouslyBoundPages;
- }
- IntArray actualIds = new IntArray();
-
- IntSet result = new IntSet();
- if (visibleIds.isEmpty()) {
- return result;
- }
- for (int id : orderedScreenIds.toArray()) {
- actualIds.add(id);
- }
- int firstId = visibleIds.getArray().get(0);
- int pairId = mWorkspace.getScreenPair(firstId);
- // Double check that actual screenIds contains the visibleId, as empty screens are hidden
- // in single panel.
- if (actualIds.contains(firstId)) {
- result.add(firstId);
- if (mDeviceProfile.isTwoPanels && actualIds.contains(pairId)) {
- result.add(pairId);
- }
- } else if (LauncherAppState.getIDP(this).supportedProfiles.stream().anyMatch(
- deviceProfile -> deviceProfile.isTwoPanels) && actualIds.contains(pairId)) {
- // Add the right panel if left panel is hidden when switching display, due to empty
- // pages being hidden in single panel.
- result.add(pairId);
- }
- return result;
+ return mModelCallbacks.getPagesToBindSynchronously(orderedScreenIds);
}
/**
@@ -2608,8 +2572,8 @@
@TargetApi(Build.VERSION_CODES.S)
public void onInitialBindComplete(IntSet boundPages, RunnableList pendingTasks,
int workspaceItemCount, boolean isBindSync) {
- mSynchronouslyBoundPages = boundPages;
- mPagesToBindSynchronously = new IntSet();
+ mModelCallbacks.setSynchronouslyBoundPages(boundPages);
+ mModelCallbacks.setPagesToBindSynchronously(new IntSet());
clearPendingBinds();
ViewOnDrawExecutor executor = new ViewOnDrawExecutor(pendingTasks);
@@ -2631,26 +2595,24 @@
Trace.endAsyncSection(DISPLAY_WORKSPACE_TRACE_METHOD_NAME,
DISPLAY_WORKSPACE_TRACE_COOKIE);
}
- mStartupLatencyLogger
- .logCardinality(workspaceItemCount)
- .logEnd(isBindSync
- ? LAUNCHER_LATENCY_STARTUP_WORKSPACE_LOADER_SYNC
- : LAUNCHER_LATENCY_STARTUP_WORKSPACE_LOADER_ASYNC);
- // In the first rootview's onDraw after onInitialBindComplete(), log end of startup latency.
+ MAIN_EXECUTOR.getHandler().postAtFrontOfQueue(() -> {
+ mStartupLatencyLogger
+ .logCardinality(workspaceItemCount)
+ .logEnd(isBindSync
+ ? LAUNCHER_LATENCY_STARTUP_WORKSPACE_LOADER_SYNC
+ : LAUNCHER_LATENCY_STARTUP_WORKSPACE_LOADER_ASYNC)
+ .logEnd(LAUNCHER_LATENCY_STARTUP_TOTAL_DURATION)
+ .log()
+ .reset();
+ if (mIsColdStartupAfterReboot) {
+ Trace.endAsyncSection(COLD_STARTUP_TRACE_METHOD_NAME,
+ COLD_STARTUP_TRACE_COOKIE);
+ }
+ });
getRootView().getViewTreeObserver().addOnDrawListener(
new ViewTreeObserver.OnDrawListener() {
-
@Override
public void onDraw() {
- mStartupLatencyLogger
- .logEnd(LAUNCHER_LATENCY_STARTUP_TOTAL_DURATION)
- .log()
- .reset();
- if (mIsColdStartupAfterReboot) {
- Trace.endAsyncSection(COLD_STARTUP_TRACE_METHOD_NAME,
- COLD_STARTUP_TRACE_COOKIE);
- }
-
MAIN_EXECUTOR.getHandler().postAtFrontOfQueue(
() -> getRootView().getViewTreeObserver()
.removeOnDrawListener(this));
@@ -2682,7 +2644,7 @@
// Since we are just resetting the current page without user interaction,
// override the previous page so we don't log the page switch.
mWorkspace.setCurrentPage(currentPage, currentPage /* overridePrevPage */);
- mPagesToBindSynchronously = new IntSet();
+ mModelCallbacks.setPagesToBindSynchronously(new IntSet());
// Cache one page worth of icons
getViewCache().setCacheSize(R.layout.folder_application,
@@ -3259,7 +3221,7 @@
* @param pages should not be null.
*/
public void setPagesToBindSynchronously(@NonNull IntSet pages) {
- mPagesToBindSynchronously = pages;
+ mModelCallbacks.setPagesToBindSynchronously(pages);
}
@Override
diff --git a/src/com/android/launcher3/ModelCallbacks.kt b/src/com/android/launcher3/ModelCallbacks.kt
index 679f7d4..8304e96 100644
--- a/src/com/android/launcher3/ModelCallbacks.kt
+++ b/src/com/android/launcher3/ModelCallbacks.kt
@@ -8,12 +8,18 @@
import com.android.launcher3.model.data.WorkspaceItemInfo
import com.android.launcher3.popup.PopupContainerWithArrow
import com.android.launcher3.util.ComponentKey
+import com.android.launcher3.util.IntArray as LIntArray
+import com.android.launcher3.util.IntSet as LIntSet
import com.android.launcher3.util.PackageUserKey
import com.android.launcher3.util.Preconditions
import com.android.launcher3.widget.model.WidgetsListBaseEntry
import java.util.function.Predicate
class ModelCallbacks(private var launcher: Launcher) : BgDataModel.Callbacks {
+
+ var synchronouslyBoundPages = LIntSet()
+ var pagesToBindSynchronously = LIntSet()
+
override fun preAddApps() {
// If there's an undo snackbar, force it to complete to ensure empty screens are removed
// before trying to add new items.
@@ -93,4 +99,40 @@
override fun bindAllWidgets(allWidgets: List<WidgetsListBaseEntry?>?) {
launcher.popupDataProvider.allWidgets = allWidgets
}
+
+ /** Returns the ids of the workspaces to bind. */
+ override fun getPagesToBindSynchronously(orderedScreenIds: LIntArray): LIntSet {
+ // If workspace binding is still in progress, getCurrentPageScreenIds won't be
+ // accurate, and we should use mSynchronouslyBoundPages that's set during initial binding.
+ val visibleIds =
+ when {
+ !pagesToBindSynchronously.isEmpty -> pagesToBindSynchronously
+ !launcher.isWorkspaceLoading -> launcher.workspace.currentPageScreenIds
+ else -> synchronouslyBoundPages
+ }
+ // Launcher IntArray has the same name as Kotlin IntArray
+ val result = LIntSet()
+ if (visibleIds.isEmpty) {
+ return result
+ }
+ val actualIds = orderedScreenIds.clone()
+ val firstId = visibleIds.first()
+ val pairId = launcher.workspace.getScreenPair(firstId)
+ // Double check that actual screenIds contains the visibleId, as empty screens are hidden
+ // in single panel.
+ if (actualIds.contains(firstId)) {
+ result.add(firstId)
+ if (launcher.deviceProfile.isTwoPanels && actualIds.contains(pairId)) {
+ result.add(pairId)
+ }
+ } else if (
+ LauncherAppState.getIDP(launcher).supportedProfiles.any(DeviceProfile::isTwoPanels) &&
+ actualIds.contains(pairId)
+ ) {
+ // Add the right panel if left panel is hidden when switching display, due to empty
+ // pages being hidden in single panel.
+ result.add(pairId)
+ }
+ return result
+ }
}
diff --git a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
index dabe84d..61ca95b 100644
--- a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
@@ -80,6 +80,7 @@
import com.android.launcher3.keyboard.FocusedItemDecorator;
import com.android.launcher3.model.StringCache;
import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.recyclerview.AllAppsRecyclerViewPool;
import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.util.Themes;
import com.android.launcher3.views.ActivityContext;
@@ -93,7 +94,6 @@
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
-import java.util.stream.Stream;
/**
* All apps container view with search support for use in a dragging activity.
@@ -623,16 +623,18 @@
private static void setUpCustomRecyclerViewPool(
@NonNull AllAppsRecyclerView mainRecyclerView,
@Nullable AllAppsRecyclerView workRecyclerView,
- @NonNull RecyclerView.RecycledViewPool recycledViewPool) {
+ @NonNull AllAppsRecyclerViewPool recycledViewPool) {
if (!ENABLE_ALL_APPS_RV_PREINFLATION.get()) {
return;
}
+ final boolean hasWorkProfile = workRecyclerView != null;
+ recycledViewPool.setHasWorkProfile(hasWorkProfile);
mainRecyclerView.setRecycledViewPool(recycledViewPool);
if (workRecyclerView != null) {
workRecyclerView.setRecycledViewPool(recycledViewPool);
}
if (ALL_APPS_GONE_VISIBILITY.get()) {
- mainRecyclerView.updatePoolSize();
+ mainRecyclerView.updatePoolSize(hasWorkProfile);
}
}
diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
index cffddfc..b0f13ef 100644
--- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
@@ -95,6 +95,10 @@
}
protected void updatePoolSize() {
+ updatePoolSize(false);
+ }
+
+ void updatePoolSize(boolean hasWorkProfile) {
DeviceProfile grid = ActivityContext.lookupContext(getContext()).getDeviceProfile();
RecyclerView.RecycledViewPool pool = getRecycledViewPool();
pool.setMaxRecycledViews(AllAppsGridAdapter.VIEW_TYPE_EMPTY_SEARCH, 1);
@@ -111,6 +115,9 @@
maxPoolSizeForAppIcons +=
PREINFLATE_ICONS_ROW_COUNT * grid.numShownAllAppsColumns + EXTRA_ICONS_COUNT;
}
+ if (hasWorkProfile) {
+ maxPoolSizeForAppIcons *= 2;
+ }
pool.setMaxRecycledViews(
AllAppsGridAdapter.VIEW_TYPE_ICON, maxPoolSizeForAppIcons);
}
diff --git a/src/com/android/launcher3/allapps/AllAppsStore.java b/src/com/android/launcher3/allapps/AllAppsStore.java
index 7867f44..9f6e0fc 100644
--- a/src/com/android/launcher3/allapps/AllAppsStore.java
+++ b/src/com/android/launcher3/allapps/AllAppsStore.java
@@ -27,7 +27,6 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.RecyclerView.RecycledViewPool;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.model.data.AppInfo;
@@ -110,7 +109,7 @@
}
}
- RecycledViewPool getRecyclerViewPool() {
+ AllAppsRecyclerViewPool getRecyclerViewPool() {
return mAllAppsRecyclerViewPool;
}
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index e70c9d0..5b44069 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -319,15 +319,6 @@
+ "waiting for SystemUI and then merging the SystemUI progress whenever we "
+ "start receiving the events");
- // Aconfig migration complete for ENABLE_OVERVIEW_ICON_MENU.
- @VisibleForTesting
- public static final BooleanFlag ENABLE_OVERVIEW_ICON_MENU = getDebugFlag(257950105,
- "ENABLE_OVERVIEW_ICON_MENU", TEAMFOOD,
- "Enable updated overview icon and menu within task.");
- public static boolean enableOverviewIconMenu() {
- return ENABLE_OVERVIEW_ICON_MENU.get() || Flags.enableOverviewIconMenu();
- }
-
// Aconfig migration complete for ENABLE_CURSOR_HOVER_STATES.
@VisibleForTesting
public static final BooleanFlag ENABLE_CURSOR_HOVER_STATES = getDebugFlag(243191650,
@@ -397,10 +388,6 @@
270393453, "ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE", DISABLED,
"Enable initiating split screen from workspace to workspace.");
- public static final BooleanFlag ENABLE_SPLIT_FROM_DESKTOP_TO_WORKSPACE = getDebugFlag(
- 279586624, "ENABLE_SPLIT_FROM_DESKTOP_TO_WORKSPACE", DISABLED,
- "Enable initiating split screen from desktop mode to workspace.");
-
public static final BooleanFlag ENABLE_TRACKPAD_GESTURE = getDebugFlag(271010401,
"ENABLE_TRACKPAD_GESTURE", ENABLED, "Enables trackpad gesture.");
diff --git a/src/com/android/launcher3/graphics/GridCustomizationsProvider.java b/src/com/android/launcher3/graphics/GridCustomizationsProvider.java
index ae5d8d4..18200f6 100644
--- a/src/com/android/launcher3/graphics/GridCustomizationsProvider.java
+++ b/src/com/android/launcher3/graphics/GridCustomizationsProvider.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright (C) 2023 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.graphics;
import static com.android.launcher3.LauncherPrefs.THEMED_ICONS;
@@ -21,6 +36,7 @@
import android.os.Messenger;
import android.util.ArrayMap;
import android.util.Log;
+import android.util.Pair;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.InvariantDeviceProfile.GridOption;
@@ -70,7 +86,11 @@
private static final int MESSAGE_ID_UPDATE_PREVIEW = 1337;
- private final ArrayMap<IBinder, PreviewLifecycleObserver> mActivePreviews = new ArrayMap<>();
+ /**
+ * Here we use the IBinder and the screen ID as the key of the active previews.
+ */
+ private final ArrayMap<Pair<IBinder, Integer>, PreviewLifecycleObserver> mActivePreviews =
+ new ArrayMap<>();
@Override
public boolean onCreate() {
@@ -176,11 +196,10 @@
try {
PreviewSurfaceRenderer renderer = new PreviewSurfaceRenderer(getContext(), request);
- // Destroy previous
- destroyObserver(mActivePreviews.get(renderer.getHostToken()));
-
observer = new PreviewLifecycleObserver(renderer);
- mActivePreviews.put(renderer.getHostToken(), observer);
+ // Destroy previous
+ destroyObserver(mActivePreviews.get(observer.getIdentifier()));
+ mActivePreviews.put(observer.getIdentifier(), observer);
renderer.loadAsync();
renderer.getHostToken().linkToDeath(observer, 0);
@@ -210,9 +229,9 @@
observer.destroyed = true;
observer.renderer.getHostToken().unlinkToDeath(observer, 0);
Executors.MAIN_EXECUTOR.execute(observer.renderer::destroy);
- PreviewLifecycleObserver cached = mActivePreviews.get(observer.renderer.getHostToken());
+ PreviewLifecycleObserver cached = mActivePreviews.get(observer.getIdentifier());
if (cached == observer) {
- mActivePreviews.remove(observer.renderer.getHostToken());
+ mActivePreviews.remove(observer.getIdentifier());
}
}
@@ -242,5 +261,14 @@
public void binderDied() {
destroyObserver(this);
}
+
+ /**
+ * Returns a key that should make the PreviewSurfaceRenderer unique and if two of them have
+ * the same key they will be treated as the same PreviewSurfaceRenderer. Primary this is
+ * used to prevent memory leaks by removing the old PreviewSurfaceRenderer.
+ */
+ public Pair<IBinder, Integer> getIdentifier() {
+ return new Pair<>(renderer.getHostToken(), renderer.getDisplayId());
+ }
}
}
diff --git a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
index aebcdd4..683354b 100644
--- a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
+++ b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
@@ -114,12 +114,17 @@
mDisplay = context.getSystemService(DisplayManager.class)
.getDisplay(bundle.getInt(KEY_DISPLAY_ID));
- mSurfaceControlViewHost = MAIN_EXECUTOR.submit(() -> new SurfaceControlViewHost(mContext,
- context.getSystemService(DisplayManager.class).getDisplay(DEFAULT_DISPLAY),
- mHostToken)).get(5, TimeUnit.SECONDS);
+ mSurfaceControlViewHost = MAIN_EXECUTOR.submit(() ->
+ new SurfaceControlViewHost(mContext, context.getSystemService(DisplayManager.class)
+ .getDisplay(DEFAULT_DISPLAY), mHostToken)
+ ).get(5, TimeUnit.SECONDS);
mOnDestroyCallbacks.add(mSurfaceControlViewHost::release);
}
+ public int getDisplayId() {
+ return mDisplay.getDisplayId();
+ }
+
public IBinder getHostToken() {
return mHostToken;
}
@@ -225,7 +230,7 @@
PreviewContext previewContext = new PreviewContext(inflationContext, idp);
// Copy existing data to preview DB
LauncherDbUtils.copyTable(LauncherAppState.getInstance(mContext)
- .getModel().getModelDbController().getDb(),
+ .getModel().getModelDbController().getDb(),
TABLE_NAME,
LauncherAppState.getInstance(previewContext)
.getModel().getModelDbController().getDb(),
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index 4307566..632ca24 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -835,6 +835,13 @@
}
/**
+ * Set the features of the log message.
+ */
+ default StatsLogger withFeatures(int feature) {
+ return this;
+ }
+
+ /**
* Builds the final message and logs it as {@link EventEnum}.
*/
default void log(EventEnum event) {
diff --git a/src/com/android/launcher3/recyclerview/AllAppsRecyclerViewPool.kt b/src/com/android/launcher3/recyclerview/AllAppsRecyclerViewPool.kt
index 1d71805..45174a7 100644
--- a/src/com/android/launcher3/recyclerview/AllAppsRecyclerViewPool.kt
+++ b/src/com/android/launcher3/recyclerview/AllAppsRecyclerViewPool.kt
@@ -40,6 +40,8 @@
private var future: Future<Void>? = null
+ var hasWorkProfile = false
+
/**
* Preinflate app icons. If all apps RV cannot be scrolled down, we don't need to preinflate.
*/
@@ -95,6 +97,9 @@
val grid = ActivityContext.lookupContext<T>(context).deviceProfile
targetPreinflateCount += grid.maxAllAppsRowCount * grid.numShownAllAppsColumns
}
+ if (hasWorkProfile) {
+ targetPreinflateCount *= 2
+ }
val existingPreinflateCount = getRecycledViewCount(BaseAllAppsAdapter.VIEW_TYPE_ICON)
return targetPreinflateCount - existingPreinflateCount
}
diff --git a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
index d434ad2..c80f243 100644
--- a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
+++ b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
@@ -27,7 +27,7 @@
import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X;
import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y;
-import static com.android.launcher3.config.FeatureFlags.enableOverviewIconMenu;
+import static com.android.launcher3.Flags.enableOverviewIconMenu;
import static com.android.launcher3.touch.SingleAxisSwipeDetector.HORIZONTAL;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
index b3189b7..62ef229 100644
--- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
+++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
@@ -27,7 +27,7 @@
import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X;
import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y;
-import static com.android.launcher3.config.FeatureFlags.enableOverviewIconMenu;
+import static com.android.launcher3.Flags.enableOverviewIconMenu;
import static com.android.launcher3.touch.SingleAxisSwipeDetector.VERTICAL;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
diff --git a/src/com/android/launcher3/touch/SeascapePagedViewHandler.java b/src/com/android/launcher3/touch/SeascapePagedViewHandler.java
index dac7964..4409572 100644
--- a/src/com/android/launcher3/touch/SeascapePagedViewHandler.java
+++ b/src/com/android/launcher3/touch/SeascapePagedViewHandler.java
@@ -22,7 +22,7 @@
import static android.view.Gravity.RIGHT;
import static android.view.Gravity.START;
-import static com.android.launcher3.config.FeatureFlags.enableOverviewIconMenu;
+import static com.android.launcher3.Flags.enableOverviewIconMenu;
import static com.android.launcher3.touch.SingleAxisSwipeDetector.HORIZONTAL;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_UNDEFINED;
diff --git a/src/com/android/launcher3/util/MainThreadInitializedObject.java b/src/com/android/launcher3/util/MainThreadInitializedObject.java
index 1cb9994..b966d8e 100644
--- a/src/com/android/launcher3/util/MainThreadInitializedObject.java
+++ b/src/com/android/launcher3/util/MainThreadInitializedObject.java
@@ -93,7 +93,7 @@
* Abstract Context which allows custom implementations for
* {@link MainThreadInitializedObject} providers
*/
- public static abstract class SandboxContext extends ContextWrapper {
+ public static class SandboxContext extends ContextWrapper {
private static final String TAG = "SandboxContext";
@@ -165,5 +165,14 @@
protected <T> T createObject(MainThreadInitializedObject<T> object) {
return object.mProvider.get(this);
}
+
+ /**
+ * Put a value into mObjectMap, can be used to put mocked MainThreadInitializedObject
+ * instances into SandboxContext.
+ */
+ @VisibleForTesting
+ public <T> void putObject(MainThreadInitializedObject<T> object, T value) {
+ mObjectMap.put(object, value);
+ }
}
}
diff --git a/src/com/android/launcher3/util/WindowBounds.java b/src/com/android/launcher3/util/WindowBounds.java
index 91480e1..ec3b642 100644
--- a/src/com/android/launcher3/util/WindowBounds.java
+++ b/src/com/android/launcher3/util/WindowBounds.java
@@ -67,7 +67,8 @@
return false;
}
WindowBounds other = (WindowBounds) obj;
- return other.bounds.equals(bounds) && other.insets.equals(insets);
+ return other.bounds.equals(bounds) && other.insets.equals(insets)
+ && other.rotationHint == rotationHint;
}
@Override
diff --git a/tests/Android.bp b/tests/Android.bp
index 0f2a2f8..29a45aa 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -45,6 +45,7 @@
"src/com/android/launcher3/allapps/TaplOpenCloseAllApps.java",
"src/com/android/launcher3/allapps/TaplTestsAllAppsIconsWorking.java",
"src/com/android/launcher3/appiconmenu/TaplAppIconMenuTest.java",
+ "src/com/android/launcher3/appiconmenu/TaplOverviewIconTest.java",
"src/com/android/launcher3/dragging/TaplDragTest.java",
"src/com/android/launcher3/dragging/TaplUninstallRemove.java",
"src/com/android/launcher3/ui/AbstractLauncherUiTest.java",
@@ -53,6 +54,7 @@
"src/com/android/launcher3/ui/widget/TaplWidgetPickerTest.java",
"src/com/android/launcher3/ui/workspace/TaplWorkspaceTest.java",
"src/com/android/launcher3/util/LauncherLayoutBuilder.java",
+ "src/com/android/launcher3/util/TestConstants.java",
"src/com/android/launcher3/util/TestUtil.java",
"src/com/android/launcher3/util/Wait.java",
"src/com/android/launcher3/util/WidgetUtils.java",
diff --git a/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java b/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java
index 51f457d..3e80e6b 100644
--- a/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java
+++ b/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java
@@ -158,7 +158,6 @@
public static final String PERMANENT_DIAG_TAG = "TaplTarget";
public static final String TWO_TASKBAR_LONG_CLICKS = "b/262282528";
public static final String ICON_MISSING = "b/282963545";
- public static final String INCORRECT_HOME_STATE = "b/293191790";
public static final String REQUEST_EMULATE_DISPLAY = "emulate-display";
public static final String REQUEST_STOP_EMULATE_DISPLAY = "stop-emulate-display";
diff --git a/tests/src/com/android/launcher3/AbstractDeviceProfileTest.kt b/tests/src/com/android/launcher3/AbstractDeviceProfileTest.kt
index 84fa988..0b31469 100644
--- a/tests/src/com/android/launcher3/AbstractDeviceProfileTest.kt
+++ b/tests/src/com/android/launcher3/AbstractDeviceProfileTest.kt
@@ -24,6 +24,7 @@
import androidx.test.core.app.ApplicationProvider
import com.android.launcher3.testing.shared.ResourceUtils
import com.android.launcher3.util.DisplayController
+import com.android.launcher3.util.MainThreadInitializedObject.SandboxContext
import com.android.launcher3.util.NavigationMode
import com.android.launcher3.util.WindowBounds
import com.android.launcher3.util.rule.TestStabilityRule
@@ -35,8 +36,6 @@
import java.io.StringWriter
import kotlin.math.max
import kotlin.math.min
-import org.junit.After
-import org.junit.Before
import org.junit.Rule
import org.mockito.kotlin.any
import org.mockito.kotlin.mock
@@ -50,30 +49,14 @@
* For an implementation that mocks InvariantDeviceProfile, use [FakeInvariantDeviceProfileTest]
*/
abstract class AbstractDeviceProfileTest {
- protected var context: Context? = null
+ protected lateinit var context: SandboxContext
protected open val runningContext: Context = ApplicationProvider.getApplicationContext()
private val displayController: DisplayController = mock()
private val windowManagerProxy: WindowManagerProxy = mock()
- private lateinit var originalDisplayController: DisplayController
- private lateinit var originalWindowManagerProxy: WindowManagerProxy
+ private val launcherPrefs: LauncherPrefs = mock()
@Rule @JvmField val testStabilityRule = TestStabilityRule()
- @Before
- open fun setUp() {
- val appContext: Context = ApplicationProvider.getApplicationContext()
- originalWindowManagerProxy = WindowManagerProxy.INSTANCE.get(appContext)
- originalDisplayController = DisplayController.INSTANCE.get(appContext)
- WindowManagerProxy.INSTANCE.initializeForTesting(windowManagerProxy)
- DisplayController.INSTANCE.initializeForTesting(displayController)
- }
-
- @After
- open fun tearDown() {
- WindowManagerProxy.INSTANCE.initializeForTesting(originalWindowManagerProxy)
- DisplayController.INSTANCE.initializeForTesting(originalDisplayController)
- }
-
class DeviceSpec(
val naturalSize: Pair<Int, Int>,
var densityDpi: Int,
@@ -304,8 +287,19 @@
screenHeightDp = (realBounds.bounds.height() / density).toInt()
smallestScreenWidthDp = min(screenWidthDp, screenHeightDp)
}
- context = runningContext.createConfigurationContext(config)
+ val configurationContext = runningContext.createConfigurationContext(config)
+ context =
+ SandboxContext(
+ configurationContext,
+ DisplayController.INSTANCE,
+ WindowManagerProxy.INSTANCE,
+ LauncherPrefs.INSTANCE
+ )
+ context.putObject(DisplayController.INSTANCE, displayController)
+ context.putObject(WindowManagerProxy.INSTANCE, windowManagerProxy)
+ context.putObject(LauncherPrefs.INSTANCE, launcherPrefs)
+ whenever(launcherPrefs.get(LauncherPrefs.TASKBAR_PINNING)).thenReturn(false)
val info = spy(DisplayController.Info(context, windowManagerProxy, perDisplayBoundsCache))
whenever(displayController.info).thenReturn(info)
whenever(info.isTransientTaskbar).thenReturn(isGestureMode)
diff --git a/tests/src/com/android/launcher3/appiconmenu/TaplAppIconMenuTest.java b/tests/src/com/android/launcher3/appiconmenu/TaplAppIconMenuTest.java
index 85cf52e..0f5d85b 100644
--- a/tests/src/com/android/launcher3/appiconmenu/TaplAppIconMenuTest.java
+++ b/tests/src/com/android/launcher3/appiconmenu/TaplAppIconMenuTest.java
@@ -15,7 +15,7 @@
*/
package com.android.launcher3.appiconmenu;
-import static com.android.launcher3.ui.TaplTestsLauncher3.APP_NAME;
+import static com.android.launcher3.util.TestConstants.AppNames.TEST_APP_NAME;
import static com.android.launcher3.ui.TaplTestsLauncher3.initialize;
import static org.junit.Assert.assertEquals;
@@ -64,7 +64,7 @@
final AllApps allApps = mLauncher.getWorkspace().switchToAllApps();
allApps.freeze();
try {
- final AppIconMenu menu = allApps.getAppIcon(APP_NAME).openDeepShortcutMenu();
+ final AppIconMenu menu = allApps.getAppIcon(TEST_APP_NAME).openDeepShortcutMenu();
executeOnLauncher(
launcher -> assertTrue("Launcher internal state didn't switch to Showing Menu",
@@ -89,9 +89,9 @@
final HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
allApps.freeze();
try {
- allApps.getAppIcon(APP_NAME).dragToWorkspace(false, false);
+ allApps.getAppIcon(TEST_APP_NAME).dragToWorkspace(false, false);
final AppIconMenu menu = mLauncher.getWorkspace().getWorkspaceAppIcon(
- APP_NAME).openDeepShortcutMenu();
+ TEST_APP_NAME).openDeepShortcutMenu();
executeOnLauncher(
launcher -> assertTrue("Launcher internal state didn't switch to Showing Menu",
diff --git a/tests/src/com/android/launcher3/appiconmenu/TaplOverviewIconAppChipMenuTest.java b/tests/src/com/android/launcher3/appiconmenu/TaplOverviewIconAppChipMenuTest.java
new file mode 100644
index 0000000..4070c03
--- /dev/null
+++ b/tests/src/com/android/launcher3/appiconmenu/TaplOverviewIconAppChipMenuTest.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 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.appiconmenu;
+
+import com.android.launcher3.Flags;
+import com.android.launcher3.InvariantDeviceProfile;
+
+import org.junit.Before;
+
+/**
+ * Tests the Icon App Chip Menu in overview.
+ *
+ * <p>Same tests as TaplOverviewIconTest with the Flag FLAG_ENABLE_OVERVIEW_ICON_MENU enabled.
+ * This class can be removed once FLAG_ENABLE_OVERVIEW_ICON_MENU is enabled by default.
+ */
+public class TaplOverviewIconAppChipMenuTest extends TaplOverviewIconTest {
+
+ @Before
+ public void setUp() throws Exception {
+ mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_OVERVIEW_ICON_MENU); // Call before super.setUp
+ super.setUp();
+ executeOnLauncher(launcher -> InvariantDeviceProfile.INSTANCE.get(launcher).onConfigChanged(
+ launcher));
+ }
+}
diff --git a/tests/src/com/android/launcher3/appiconmenu/TaplOverviewIconTest.java b/tests/src/com/android/launcher3/appiconmenu/TaplOverviewIconTest.java
new file mode 100644
index 0000000..7340264
--- /dev/null
+++ b/tests/src/com/android/launcher3/appiconmenu/TaplOverviewIconTest.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2023 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.appiconmenu;
+
+import static com.android.launcher3.ui.TaplTestsLauncher3.initialize;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import android.content.Intent;
+import android.platform.test.annotations.PlatinumTest;
+
+import com.android.launcher3.tapl.OverviewTaskMenu;
+import com.android.launcher3.ui.AbstractLauncherUiTest;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * This test run in both Out of process (Oop) and in-process (Ipc).
+ * Tests the app Icon in overview.
+ */
+public class TaplOverviewIconTest extends AbstractLauncherUiTest {
+
+ private static final String CALCULATOR_APP_PACKAGE =
+ resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR);
+
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ initialize(this);
+ }
+
+ @PlatinumTest(focusArea = "launcher")
+ @Test
+ public void testOverviewActionsMenu() {
+ startTestAppsWithCheck();
+
+ OverviewTaskMenu menu = mLauncher.goHome().switchToOverview().getCurrentTask().tapMenu();
+
+ assertNotNull("Tapping App info menu item returned null", menu.tapAppInfoMenuItem());
+ executeOnLauncher(launcher -> assertTrue(
+ "Launcher activity is the top activity; expecting another activity to be the top",
+ isInLaunchedApp(launcher)));
+ }
+
+ private void startTestAppsWithCheck() {
+ startTestApps();
+ executeOnLauncher(launcher -> assertTrue(
+ "Launcher activity is the top activity; expecting another activity to be the top "
+ + "one",
+ isInLaunchedApp(launcher)));
+ }
+
+ private void startTestApps() {
+ startAppFast(getAppPackageName());
+ startAppFast(CALCULATOR_APP_PACKAGE);
+ startTestActivity(2);
+ }
+
+ @Test
+ public void testSplitTaskTapBothIconMenus() {
+ createAndLaunchASplitPair();
+
+ OverviewTaskMenu taskMenu =
+ mLauncher.goHome().switchToOverview().getCurrentTask().tapMenu();
+ assertTrue("App info item not appearing in expanded task menu.",
+ taskMenu.hasMenuItem("App info"));
+ taskMenu.touchOutsideTaskMenuToDismiss();
+
+ OverviewTaskMenu splitMenu =
+ mLauncher.getOverview().getCurrentTask().tapSplitTaskMenu();
+ assertTrue("App info item not appearing in expanded split task's menu.",
+ splitMenu.hasMenuItem("App info"));
+ splitMenu.touchOutsideTaskMenuToDismiss();
+ }
+
+ private void createAndLaunchASplitPair() {
+ startTestActivity(2);
+ startTestActivity(3);
+
+ if (mLauncher.isTablet()) {
+ mLauncher.goHome().switchToOverview().getOverviewActions()
+ .clickSplit()
+ .getTestActivityTask(2)
+ .open();
+ } else {
+ mLauncher.goHome().switchToOverview().getCurrentTask()
+ .tapMenu()
+ .tapSplitMenuItem()
+ .getCurrentTask()
+ .open();
+ }
+ }
+}
diff --git a/tests/src/com/android/launcher3/dragging/TaplDragTest.java b/tests/src/com/android/launcher3/dragging/TaplDragTest.java
index c652b98..7ec7826 100644
--- a/tests/src/com/android/launcher3/dragging/TaplDragTest.java
+++ b/tests/src/com/android/launcher3/dragging/TaplDragTest.java
@@ -15,10 +15,10 @@
*/
package com.android.launcher3.dragging;
-import static com.android.launcher3.ui.TaplTestsLauncher3.APP_NAME;
-import static com.android.launcher3.ui.TaplTestsLauncher3.GMAIL_APP_NAME;
-import static com.android.launcher3.ui.TaplTestsLauncher3.MAPS_APP_NAME;
-import static com.android.launcher3.ui.TaplTestsLauncher3.STORE_APP_NAME;
+import static com.android.launcher3.util.TestConstants.AppNames.TEST_APP_NAME;
+import static com.android.launcher3.util.TestConstants.AppNames.GMAIL_APP_NAME;
+import static com.android.launcher3.util.TestConstants.AppNames.MAPS_APP_NAME;
+import static com.android.launcher3.util.TestConstants.AppNames.STORE_APP_NAME;
import static com.android.launcher3.ui.TaplTestsLauncher3.initialize;
import static org.junit.Assert.assertEquals;
@@ -118,7 +118,7 @@
allApps.freeze();
try {
final HomeAppIconMenuItem menuItem = allApps
- .getAppIcon(APP_NAME)
+ .getAppIcon(TEST_APP_NAME)
.openDeepShortcutMenu()
.getMenuItem(0);
final String actualShortcutName = menuItem.getText();
@@ -147,7 +147,7 @@
final HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
allApps.freeze();
try {
- allApps.getAppIcon(APP_NAME)
+ allApps.getAppIcon(TEST_APP_NAME)
.openDeepShortcutMenu()
.getMenuItem(0)
.dragToWorkspace(target.x, target.y);
@@ -194,8 +194,8 @@
final HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
allApps.freeze();
try {
- allApps.getAppIcon(APP_NAME).dragToWorkspace(false, false);
- mLauncher.getWorkspace().getWorkspaceAppIcon(APP_NAME).launch(getAppPackageName());
+ allApps.getAppIcon(TEST_APP_NAME).dragToWorkspace(false, false);
+ mLauncher.getWorkspace().getWorkspaceAppIcon(TEST_APP_NAME).launch(getAppPackageName());
} finally {
allApps.unfreeze();
}
@@ -222,7 +222,7 @@
final HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
allApps.freeze();
try {
- allApps.getAppIcon(APP_NAME).dragToWorkspace(target.x, target.y);
+ allApps.getAppIcon(TEST_APP_NAME).dragToWorkspace(target.x, target.y);
} finally {
allApps.unfreeze();
}
@@ -235,7 +235,7 @@
}
// test to move a shortcut to other cell.
- final HomeAppIcon launcherTestAppIcon = createShortcutInCenterIfNotExist(APP_NAME);
+ final HomeAppIcon launcherTestAppIcon = createShortcutInCenterIfNotExist(TEST_APP_NAME);
for (Point target : targets) {
startTime = SystemClock.uptimeMillis();
launcherTestAppIcon.dragToWorkspace(target.x, target.y);
diff --git a/tests/src/com/android/launcher3/dragging/TaplUninstallRemove.java b/tests/src/com/android/launcher3/dragging/TaplUninstallRemove.java
index 5b87a05..7027e85 100644
--- a/tests/src/com/android/launcher3/dragging/TaplUninstallRemove.java
+++ b/tests/src/com/android/launcher3/dragging/TaplUninstallRemove.java
@@ -16,11 +16,12 @@
package com.android.launcher3.dragging;
import static com.android.launcher3.testing.shared.TestProtocol.ICON_MISSING;
-import static com.android.launcher3.ui.TaplTestsLauncher3.APP_NAME;
-import static com.android.launcher3.ui.TaplTestsLauncher3.DUMMY_APP_NAME;
-import static com.android.launcher3.ui.TaplTestsLauncher3.MAPS_APP_NAME;
-import static com.android.launcher3.ui.TaplTestsLauncher3.STORE_APP_NAME;
import static com.android.launcher3.ui.TaplTestsLauncher3.initialize;
+import static com.android.launcher3.util.TestConstants.AppNames.DUMMY_APP_NAME;
+import static com.android.launcher3.util.TestConstants.AppNames.GMAIL_APP_NAME;
+import static com.android.launcher3.util.TestConstants.AppNames.MAPS_APP_NAME;
+import static com.android.launcher3.util.TestConstants.AppNames.STORE_APP_NAME;
+import static com.android.launcher3.util.TestConstants.AppNames.TEST_APP_NAME;
import static com.google.common.truth.Truth.assertThat;
@@ -62,7 +63,7 @@
@Test
@PortraitLandscape
public void testDeleteFromWorkspace() {
- for (String appName : new String[]{"Gmail", "Play Store", APP_NAME}) {
+ for (String appName : new String[]{GMAIL_APP_NAME, STORE_APP_NAME, TEST_APP_NAME}) {
final HomeAppIcon homeAppIcon = createShortcutInCenterIfNotExist(appName);
Workspace workspace = mLauncher.getWorkspace().deleteAppIcon(homeAppIcon);
workspace.verifyWorkspaceAppIconIsGone(
@@ -174,9 +175,9 @@
mLauncher.getWorkspace()
.deleteAppIcon(mLauncher.getWorkspace().getHotseatAppIcon(0))
.switchToAllApps()
- .getAppIcon(APP_NAME)
+ .getAppIcon(TEST_APP_NAME)
.dragToHotseat(0);
mLauncher.getWorkspace().deleteAppIcon(
- mLauncher.getWorkspace().getHotseatAppIcon(APP_NAME));
+ mLauncher.getWorkspace().getHotseatAppIcon(TEST_APP_NAME));
}
}
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index 34ebe11..56a74a9 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -39,6 +39,7 @@
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.system.OsConstants;
import android.util.Log;
@@ -202,6 +203,15 @@
@Rule
public ScreenRecordRule mScreenRecordRule = new ScreenRecordRule();
+ @Rule
+ public SetFlagsRule mSetFlagsRule = getFlagsRule();
+
+ private SetFlagsRule getFlagsRule() {
+ SetFlagsRule flagsRule = new SetFlagsRule();
+ flagsRule.initAllFlagsToReleaseConfigDefault();
+ return flagsRule;
+ }
+
protected void clearPackageData(String pkg) throws IOException, InterruptedException {
final CountDownLatch count = new CountDownLatch(2);
final SimpleBroadcastReceiver broadcastReceiver =
diff --git a/tests/src/com/android/launcher3/ui/BubbleTextViewTest.java b/tests/src/com/android/launcher3/ui/BubbleTextViewTest.java
index 6c2950c..b019414 100644
--- a/tests/src/com/android/launcher3/ui/BubbleTextViewTest.java
+++ b/tests/src/com/android/launcher3/ui/BubbleTextViewTest.java
@@ -97,9 +97,7 @@
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
- mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_TWOLINE_ALLAPPS);
- mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_CURSOR_HOVER_STATES);
- mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_OVERVIEW_ICON_MENU);
+ mSetFlagsRule.initAllFlagsToReleaseConfigDefault();
Utilities.enableRunningInTestHarnessForTests();
mContext = new ActivityContextWrapper(getApplicationContext());
mBubbleTextView = new BubbleTextView(mContext);
diff --git a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
index 799ef5b..f2cbd92 100644
--- a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
+++ b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
@@ -23,7 +23,6 @@
import androidx.test.runner.AndroidJUnit4;
import com.android.launcher3.LauncherState;
-import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape;
import org.junit.Before;
import org.junit.Test;
@@ -32,11 +31,6 @@
@LargeTest
@RunWith(AndroidJUnit4.class)
public class TaplTestsLauncher3 extends AbstractLauncherUiTest {
- public static final String APP_NAME = "LauncherTestApp";
- public static final String DUMMY_APP_NAME = "Aardwolf";
- public static final String MAPS_APP_NAME = "Maps";
- public static final String STORE_APP_NAME = "Play Store";
- public static final String GMAIL_APP_NAME = "Gmail";
@Before
public void setUp() throws Exception {
diff --git a/tests/src/com/android/launcher3/ui/workspace/TaplWorkspaceTest.java b/tests/src/com/android/launcher3/ui/workspace/TaplWorkspaceTest.java
index d8ae99c..d776f21 100644
--- a/tests/src/com/android/launcher3/ui/workspace/TaplWorkspaceTest.java
+++ b/tests/src/com/android/launcher3/ui/workspace/TaplWorkspaceTest.java
@@ -16,6 +16,7 @@
package com.android.launcher3.ui.workspace;
import static com.android.launcher3.ui.TaplTestsLauncher3.initialize;
+import static com.android.launcher3.util.TestConstants.AppNames.CHROME_APP_NAME;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -85,7 +86,8 @@
isWorkspaceScrollable(launcher)));
assertEquals("Initial workspace doesn't have the correct page", workspace.pagesPerScreen(),
workspace.getPageCount());
- workspace.verifyWorkspaceAppIconIsGone("Chrome app was found on empty workspace", "Chrome");
+ workspace.verifyWorkspaceAppIconIsGone("Chrome app was found on empty workspace",
+ CHROME_APP_NAME);
workspace.ensureWorkspaceIsScrollable();
executeOnLauncher(
@@ -96,7 +98,7 @@
launcher -> assertTrue("ensureScrollable didn't make workspace scrollable",
isWorkspaceScrollable(launcher)));
assertNotNull("ensureScrollable didn't add Chrome app",
- workspace.getWorkspaceAppIcon("Chrome"));
+ workspace.getWorkspaceAppIcon(CHROME_APP_NAME));
// Test flinging workspace.
workspace.flingBackward();
@@ -112,7 +114,7 @@
assertTrue("Launcher internal state is not Home", isInState(() -> LauncherState.NORMAL));
// Test starting a workspace app.
- final HomeAppIcon app = workspace.getWorkspaceAppIcon("Chrome");
+ final HomeAppIcon app = workspace.getWorkspaceAppIcon(CHROME_APP_NAME);
assertNotNull("No Chrome app in workspace", app);
}
diff --git a/tests/src/com/android/launcher3/ui/workspace/ThemeIconsTest.java b/tests/src/com/android/launcher3/ui/workspace/ThemeIconsTest.java
index 8e5e9cc..34c7707 100644
--- a/tests/src/com/android/launcher3/ui/workspace/ThemeIconsTest.java
+++ b/tests/src/com/android/launcher3/ui/workspace/ThemeIconsTest.java
@@ -15,6 +15,8 @@
*/
package com.android.launcher3.ui.workspace;
+import static com.android.launcher3.util.TestConstants.AppNames.TEST_APP_NAME;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@@ -51,7 +53,6 @@
public class ThemeIconsTest extends AbstractLauncherUiTest {
private static final String APP_NAME = "IconThemedActivity";
- private static final String SHORTCUT_APP_NAME = "LauncherTestApp";
private static final String SHORTCUT_NAME = "Shortcut 1";
@Test
@@ -81,7 +82,7 @@
allApps.freeze();
try {
- HomeAppIcon icon = allApps.getAppIcon(SHORTCUT_APP_NAME);
+ HomeAppIcon icon = allApps.getAppIcon(TEST_APP_NAME);
HomeAppIconMenuItem shortcutItem =
(HomeAppIconMenuItem) icon.openDeepShortcutMenu().getMenuItem(SHORTCUT_NAME);
shortcutItem.dragToWorkspace(false, false);
@@ -118,7 +119,7 @@
allApps.freeze();
try {
- HomeAppIcon icon = allApps.getAppIcon(SHORTCUT_APP_NAME);
+ HomeAppIcon icon = allApps.getAppIcon(TEST_APP_NAME);
HomeAppIconMenuItem shortcutItem =
(HomeAppIconMenuItem) icon.openDeepShortcutMenu().getMenuItem(SHORTCUT_NAME);
shortcutItem.dragToWorkspace(false, false);
diff --git a/tests/src/com/android/launcher3/ui/workspace/TwoPanelWorkspaceTest.java b/tests/src/com/android/launcher3/ui/workspace/TwoPanelWorkspaceTest.java
index 00e00fa..35b4883 100644
--- a/tests/src/com/android/launcher3/ui/workspace/TwoPanelWorkspaceTest.java
+++ b/tests/src/com/android/launcher3/ui/workspace/TwoPanelWorkspaceTest.java
@@ -16,6 +16,11 @@
package com.android.launcher3.ui.workspace;
+import static com.android.launcher3.util.TestConstants.AppNames.CHROME_APP_NAME;
+import static com.android.launcher3.util.TestConstants.AppNames.MAPS_APP_NAME;
+import static com.android.launcher3.util.TestConstants.AppNames.MESSAGES_APP_NAME;
+import static com.android.launcher3.util.TestConstants.AppNames.STORE_APP_NAME;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@@ -76,7 +81,7 @@
executeOnLauncher(launcher -> {
launcher.enableHotseatEdu(false);
assertPagesExist(launcher, 0, 1);
- assertItemsOnPage(launcher, 0, "Play Store", "Maps");
+ assertItemsOnPage(launcher, 0, STORE_APP_NAME, MAPS_APP_NAME);
assertPageEmpty(launcher, 1);
});
}
@@ -94,12 +99,12 @@
public void testDragIconToRightPanel() {
Workspace workspace = mLauncher.getWorkspace();
- workspace.dragIcon(workspace.getHotseatAppIcon("Chrome"), 1);
+ workspace.dragIcon(workspace.getHotseatAppIcon(CHROME_APP_NAME), 1);
executeOnLauncher(launcher -> {
assertPagesExist(launcher, 0, 1);
- assertItemsOnPage(launcher, 0, "Maps", "Play Store");
- assertItemsOnPage(launcher, 1, "Chrome");
+ assertItemsOnPage(launcher, 0, MAPS_APP_NAME, STORE_APP_NAME);
+ assertItemsOnPage(launcher, 1, CHROME_APP_NAME);
});
}
@@ -108,52 +113,52 @@
public void testSinglePageDragIconWhenMultiplePageScrollingIsPossible() {
Workspace workspace = mLauncher.getWorkspace();
- workspace.dragIcon(workspace.getHotseatAppIcon("Chrome"), 2);
+ workspace.dragIcon(workspace.getHotseatAppIcon(CHROME_APP_NAME), 2);
workspace.flingBackward();
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Maps"), 3);
+ workspace.dragIcon(workspace.getWorkspaceAppIcon(MAPS_APP_NAME), 3);
executeOnLauncher(launcher -> {
assertPagesExist(launcher, 0, 1, 2, 3);
- assertItemsOnPage(launcher, 0, "Play Store");
+ assertItemsOnPage(launcher, 0, STORE_APP_NAME);
assertPageEmpty(launcher, 1);
- assertItemsOnPage(launcher, 2, "Chrome");
- assertItemsOnPage(launcher, 3, "Maps");
+ assertItemsOnPage(launcher, 2, CHROME_APP_NAME);
+ assertItemsOnPage(launcher, 3, MAPS_APP_NAME);
});
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Maps"), 3);
+ workspace.dragIcon(workspace.getWorkspaceAppIcon(MAPS_APP_NAME), 3);
executeOnLauncher(launcher -> {
assertPagesExist(launcher, 0, 1, 2, 3, 4, 5);
- assertItemsOnPage(launcher, 0, "Play Store");
+ assertItemsOnPage(launcher, 0, STORE_APP_NAME);
assertPageEmpty(launcher, 1);
- assertItemsOnPage(launcher, 2, "Chrome");
+ assertItemsOnPage(launcher, 2, CHROME_APP_NAME);
assertPageEmpty(launcher, 3);
assertPageEmpty(launcher, 4);
- assertItemsOnPage(launcher, 5, "Maps");
+ assertItemsOnPage(launcher, 5, MAPS_APP_NAME);
});
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Maps"), -1);
+ workspace.dragIcon(workspace.getWorkspaceAppIcon(MAPS_APP_NAME), -1);
executeOnLauncher(launcher -> {
assertPagesExist(launcher, 0, 1, 2, 3);
- assertItemsOnPage(launcher, 0, "Play Store");
+ assertItemsOnPage(launcher, 0, STORE_APP_NAME);
assertPageEmpty(launcher, 1);
- assertItemsOnPage(launcher, 2, "Chrome");
- assertItemsOnPage(launcher, 3, "Maps");
+ assertItemsOnPage(launcher, 2, CHROME_APP_NAME);
+ assertItemsOnPage(launcher, 3, MAPS_APP_NAME);
});
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Maps"), -1);
+ workspace.dragIcon(workspace.getWorkspaceAppIcon(MAPS_APP_NAME), -1);
workspace.flingForward();
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Chrome"), -2);
+ workspace.dragIcon(workspace.getWorkspaceAppIcon(CHROME_APP_NAME), -2);
executeOnLauncher(launcher -> {
assertPagesExist(launcher, 0, 1);
- assertItemsOnPage(launcher, 0, "Chrome", "Play Store");
- assertItemsOnPage(launcher, 1, "Maps");
+ assertItemsOnPage(launcher, 0, CHROME_APP_NAME, STORE_APP_NAME);
+ assertItemsOnPage(launcher, 1, MAPS_APP_NAME);
});
}
@@ -162,13 +167,13 @@
public void testDragIconToPage2() {
Workspace workspace = mLauncher.getWorkspace();
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Maps"), 2);
+ workspace.dragIcon(workspace.getWorkspaceAppIcon(MAPS_APP_NAME), 2);
executeOnLauncher(launcher -> {
assertPagesExist(launcher, 0, 1, 2, 3);
- assertItemsOnPage(launcher, 0, "Play Store");
+ assertItemsOnPage(launcher, 0, STORE_APP_NAME);
assertPageEmpty(launcher, 1);
- assertItemsOnPage(launcher, 2, "Maps");
+ assertItemsOnPage(launcher, 2, MAPS_APP_NAME);
assertPageEmpty(launcher, 3);
});
}
@@ -179,14 +184,14 @@
Workspace workspace = mLauncher.getWorkspace();
// b/299522368 sometimes the phone app is not present in the hotseat.
- workspace.dragIcon(workspace.getHotseatAppIcon("Chrome"), 3);
+ workspace.dragIcon(workspace.getHotseatAppIcon(CHROME_APP_NAME), 3);
executeOnLauncher(launcher -> {
assertPagesExist(launcher, 0, 1, 2, 3);
- assertItemsOnPage(launcher, 0, "Play Store", "Maps");
+ assertItemsOnPage(launcher, 0, STORE_APP_NAME, MAPS_APP_NAME);
assertPageEmpty(launcher, 1);
assertPageEmpty(launcher, 2);
- assertItemsOnPage(launcher, 3, "Chrome");
+ assertItemsOnPage(launcher, 3, CHROME_APP_NAME);
});
}
@@ -195,44 +200,44 @@
public void testMultiplePageDragIcon() {
Workspace workspace = mLauncher.getWorkspace();
- workspace.dragIcon(workspace.getHotseatAppIcon("Messages"), 2);
+ workspace.dragIcon(workspace.getHotseatAppIcon(MESSAGES_APP_NAME), 2);
workspace.flingBackward();
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Maps"), 5);
+ workspace.dragIcon(workspace.getWorkspaceAppIcon(MAPS_APP_NAME), 5);
executeOnLauncher(launcher -> {
assertPagesExist(launcher, 0, 1, 2, 3, 4, 5);
- assertItemsOnPage(launcher, 0, "Play Store");
+ assertItemsOnPage(launcher, 0, STORE_APP_NAME);
assertPageEmpty(launcher, 1);
- assertItemsOnPage(launcher, 2, "Messages");
+ assertItemsOnPage(launcher, 2, MESSAGES_APP_NAME);
assertPageEmpty(launcher, 3);
assertPageEmpty(launcher, 4);
- assertItemsOnPage(launcher, 5, "Maps");
+ assertItemsOnPage(launcher, 5, MAPS_APP_NAME);
});
workspace.flingBackward();
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Messages"), 4);
+ workspace.dragIcon(workspace.getWorkspaceAppIcon(MESSAGES_APP_NAME), 4);
executeOnLauncher(launcher -> {
assertPagesExist(launcher, 0, 1, 4, 5, 6, 7);
- assertItemsOnPage(launcher, 0, "Play Store");
+ assertItemsOnPage(launcher, 0, STORE_APP_NAME);
assertPageEmpty(launcher, 1);
assertPageEmpty(launcher, 4);
- assertItemsOnPage(launcher, 5, "Maps");
- assertItemsOnPage(launcher, 6, "Messages");
+ assertItemsOnPage(launcher, 5, MAPS_APP_NAME);
+ assertItemsOnPage(launcher, 6, MESSAGES_APP_NAME);
assertPageEmpty(launcher, 7);
});
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Messages"), -3);
+ workspace.dragIcon(workspace.getWorkspaceAppIcon(MESSAGES_APP_NAME), -3);
executeOnLauncher(launcher -> {
assertPagesExist(launcher, 0, 1, 4, 5);
- assertItemsOnPage(launcher, 0, "Play Store");
- assertItemsOnPage(launcher, 1, "Messages");
+ assertItemsOnPage(launcher, 0, STORE_APP_NAME);
+ assertItemsOnPage(launcher, 1, MESSAGES_APP_NAME);
assertPageEmpty(launcher, 4);
- assertItemsOnPage(launcher, 5, "Maps");
+ assertItemsOnPage(launcher, 5, MAPS_APP_NAME);
});
}
@@ -241,38 +246,38 @@
public void testEmptyPageDoesNotGetRemovedIfPagePairIsNotEmpty() {
Workspace workspace = mLauncher.getWorkspace();
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Maps"), 3);
- workspace.dragIcon(workspace.getHotseatAppIcon("Chrome"), 0);
+ workspace.dragIcon(workspace.getWorkspaceAppIcon(MAPS_APP_NAME), 3);
+ workspace.dragIcon(workspace.getHotseatAppIcon(CHROME_APP_NAME), 0);
executeOnLauncher(launcher -> {
assertPagesExist(launcher, 0, 1, 2, 3);
- assertItemsOnPage(launcher, 0, "Play Store");
+ assertItemsOnPage(launcher, 0, STORE_APP_NAME);
assertPageEmpty(launcher, 1);
- assertItemsOnPage(launcher, 2, "Chrome");
- assertItemsOnPage(launcher, 3, "Maps");
+ assertItemsOnPage(launcher, 2, CHROME_APP_NAME);
+ assertItemsOnPage(launcher, 3, MAPS_APP_NAME);
});
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Maps"), -1);
+ workspace.dragIcon(workspace.getWorkspaceAppIcon(MAPS_APP_NAME), -1);
executeOnLauncher(launcher -> {
assertPagesExist(launcher, 0, 1, 2, 3);
- assertItemsOnPage(launcher, 0, "Play Store");
- assertItemsOnPage(launcher, 1, "Maps");
- assertItemsOnPage(launcher, 2, "Chrome");
+ assertItemsOnPage(launcher, 0, STORE_APP_NAME);
+ assertItemsOnPage(launcher, 1, MAPS_APP_NAME);
+ assertItemsOnPage(launcher, 2, CHROME_APP_NAME);
assertPageEmpty(launcher, 3);
});
// Move Chrome to the right panel as well, to make sure pages are not deleted whichever
// page is the empty one
workspace.flingForward();
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Chrome"), 1);
+ workspace.dragIcon(workspace.getWorkspaceAppIcon(CHROME_APP_NAME), 1);
executeOnLauncher(launcher -> {
assertPagesExist(launcher, 0, 1, 2, 3);
- assertItemsOnPage(launcher, 0, "Play Store");
- assertItemsOnPage(launcher, 1, "Maps");
+ assertItemsOnPage(launcher, 0, STORE_APP_NAME);
+ assertItemsOnPage(launcher, 1, MAPS_APP_NAME);
assertPageEmpty(launcher, 2);
- assertItemsOnPage(launcher, 3, "Chrome");
+ assertItemsOnPage(launcher, 3, CHROME_APP_NAME);
});
}
@@ -281,25 +286,25 @@
public void testEmptyPagesGetRemovedIfBothPagesAreEmpty() {
Workspace workspace = mLauncher.getWorkspace();
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Play Store"), 2);
- workspace.dragIcon(workspace.getHotseatAppIcon("Chrome"), 1);
+ workspace.dragIcon(workspace.getWorkspaceAppIcon(STORE_APP_NAME), 2);
+ workspace.dragIcon(workspace.getHotseatAppIcon(CHROME_APP_NAME), 1);
executeOnLauncher(launcher -> {
assertPagesExist(launcher, 0, 1, 2, 3);
- assertItemsOnPage(launcher, 0, "Maps");
+ assertItemsOnPage(launcher, 0, MAPS_APP_NAME);
assertPageEmpty(launcher, 1);
- assertItemsOnPage(launcher, 2, "Play Store");
- assertItemsOnPage(launcher, 3, "Chrome");
+ assertItemsOnPage(launcher, 2, STORE_APP_NAME);
+ assertItemsOnPage(launcher, 3, CHROME_APP_NAME);
});
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Chrome"), -1);
+ workspace.dragIcon(workspace.getWorkspaceAppIcon(CHROME_APP_NAME), -1);
workspace.flingForward();
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Play Store"), -2);
+ workspace.dragIcon(workspace.getWorkspaceAppIcon(STORE_APP_NAME), -2);
executeOnLauncher(launcher -> {
assertPagesExist(launcher, 0, 1);
- assertItemsOnPage(launcher, 0, "Play Store", "Maps");
- assertItemsOnPage(launcher, 1, "Chrome");
+ assertItemsOnPage(launcher, 0, STORE_APP_NAME, MAPS_APP_NAME);
+ assertItemsOnPage(launcher, 1, CHROME_APP_NAME);
});
}
@@ -308,28 +313,28 @@
public void testMiddleEmptyPagesGetRemoved() {
Workspace workspace = mLauncher.getWorkspace();
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Maps"), 2);
- workspace.dragIcon(workspace.getHotseatAppIcon("Messages"), 3);
+ workspace.dragIcon(workspace.getWorkspaceAppIcon(MAPS_APP_NAME), 2);
+ workspace.dragIcon(workspace.getHotseatAppIcon(MESSAGES_APP_NAME), 3);
executeOnLauncher(launcher -> {
assertPagesExist(launcher, 0, 1, 2, 3, 4, 5);
- assertItemsOnPage(launcher, 0, "Play Store");
+ assertItemsOnPage(launcher, 0, STORE_APP_NAME);
assertPageEmpty(launcher, 1);
- assertItemsOnPage(launcher, 2, "Maps");
+ assertItemsOnPage(launcher, 2, MAPS_APP_NAME);
assertPageEmpty(launcher, 3);
assertPageEmpty(launcher, 4);
- assertItemsOnPage(launcher, 5, "Messages");
+ assertItemsOnPage(launcher, 5, MESSAGES_APP_NAME);
});
workspace.flingBackward();
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Maps"), 2);
+ workspace.dragIcon(workspace.getWorkspaceAppIcon(MAPS_APP_NAME), 2);
executeOnLauncher(launcher -> {
assertPagesExist(launcher, 0, 1, 4, 5);
- assertItemsOnPage(launcher, 0, "Play Store");
+ assertItemsOnPage(launcher, 0, STORE_APP_NAME);
assertPageEmpty(launcher, 1);
- assertItemsOnPage(launcher, 4, "Maps");
- assertItemsOnPage(launcher, 5, "Messages");
+ assertItemsOnPage(launcher, 4, MAPS_APP_NAME);
+ assertItemsOnPage(launcher, 5, MESSAGES_APP_NAME);
});
}
diff --git a/tests/src/com/android/launcher3/util/TestConstants.java b/tests/src/com/android/launcher3/util/TestConstants.java
new file mode 100644
index 0000000..6f3c63a
--- /dev/null
+++ b/tests/src/com/android/launcher3/util/TestConstants.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2023 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.util;
+
+public class TestConstants {
+ public static class AppNames {
+
+ public static final String TEST_APP_NAME = "LauncherTestApp";
+ public static final String DUMMY_APP_NAME = "Aardwolf";
+ public static final String MAPS_APP_NAME = "Maps";
+ public static final String STORE_APP_NAME = "Play Store";
+ public static final String GMAIL_APP_NAME = "Gmail";
+ public static final String CHROME_APP_NAME = "Chrome";
+ public static final String MESSAGES_APP_NAME = "Messages";
+ }
+}
diff --git a/tests/src/com/android/launcher3/util/viewcapture_analysis/PositionJumpDetector.java b/tests/src/com/android/launcher3/util/viewcapture_analysis/PositionJumpDetector.java
index a1ddcb0..5f2c68c 100644
--- a/tests/src/com/android/launcher3/util/viewcapture_analysis/PositionJumpDetector.java
+++ b/tests/src/com/android/launcher3/util/viewcapture_analysis/PositionJumpDetector.java
@@ -46,7 +46,7 @@
DRAG_LAYER + "WidgetsTwoPaneSheet|SpringRelativeLayout:id/container",
DRAG_LAYER + "WidgetsFullSheet|SpringRelativeLayout:id/container",
DRAG_LAYER + "LauncherDragView",
- RECENTS_DRAG_LAYER + "FallbackRecentsView:id/overview_panel|TaskView",
+ RECENTS_DRAG_LAYER + "FallbackRecentsView:id/overview_panel",
CONTENT + "LauncherRootView:id/launcher|FloatingIconView",
DRAG_LAYER + "FloatingTaskView",
DRAG_LAYER + "LauncherRecentsView:id/overview_panel"
diff --git a/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java b/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java
index 9f8fb92..efeb5f6 100644
--- a/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java
+++ b/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java
@@ -54,13 +54,13 @@
private static final int STASHED_TASKBAR_BOTTOM_EDGE_DP = 1;
private final Condition<UiDevice, Boolean> mStashedTaskbarHintScaleCondition =
- device -> mLauncher.getTestInfo(REQUEST_STASHED_TASKBAR_SCALE).getFloat(
- TestProtocol.TEST_INFO_RESPONSE_FIELD) - UNSTASHED_TASKBAR_HANDLE_HINT_SCALE
+ device -> Math.abs(mLauncher.getTestInfo(REQUEST_STASHED_TASKBAR_SCALE).getFloat(
+ TestProtocol.TEST_INFO_RESPONSE_FIELD) - UNSTASHED_TASKBAR_HANDLE_HINT_SCALE)
< 0.00001f;
private final Condition<UiDevice, Boolean> mStashedTaskbarDefaultScaleCondition =
- device -> mLauncher.getTestInfo(REQUEST_STASHED_TASKBAR_SCALE).getFloat(
- TestProtocol.TEST_INFO_RESPONSE_FIELD) - 1f < 0.00001f;
+ device -> Math.abs(mLauncher.getTestInfo(REQUEST_STASHED_TASKBAR_SCALE).getFloat(
+ TestProtocol.TEST_INFO_RESPONSE_FIELD) - 1f) < 0.00001f;
LaunchedAppState(LauncherInstrumentation launcher) {
super(launcher);
@@ -284,7 +284,8 @@
Point stashedTaskbarHintArea = new Point(mLauncher.getRealDisplaySize().x / 2,
mLauncher.getRealDisplaySize().y - 1);
mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_HOVER_ENTER,
- new Point(stashedTaskbarHintArea.x, stashedTaskbarHintArea.y), null);
+ new Point(stashedTaskbarHintArea.x, stashedTaskbarHintArea.y), null,
+ InputDevice.SOURCE_MOUSE);
mLauncher.getDevice().wait(mStashedTaskbarHintScaleCondition,
LauncherInstrumentation.WAIT_TIME_MS);
@@ -296,7 +297,7 @@
mLauncher.getRealDisplaySize().y - 500);
mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_HOVER_EXIT,
new Point(outsideStashedTaskbarHintArea.x, outsideStashedTaskbarHintArea.y),
- null);
+ null, InputDevice.SOURCE_MOUSE);
mLauncher.getDevice().wait(mStashedTaskbarDefaultScaleCondition,
LauncherInstrumentation.WAIT_TIME_MS);