Merge "polish for the app shortcut popup, fixing padding on several elements." into tm-qpr-dev
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index ea7eba3..da28cfa 100644
--- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
@@ -52,6 +52,7 @@
import static com.android.launcher3.config.FeatureFlags.KEYGUARD_ANIMATION;
import static com.android.launcher3.config.FeatureFlags.SEPARATE_RECENTS_ACTIVITY;
import static com.android.launcher3.model.data.ItemInfo.NO_MATCHING_ID;
+import static com.android.launcher3.util.DisplayController.isTransientTaskbar;
import static com.android.launcher3.util.MultiPropertyFactory.MULTI_PROPERTY_VALUE;
import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs;
import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATION;
@@ -122,7 +123,6 @@
import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.ActivityOptionsWrapper;
-import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.DynamicResource;
import com.android.launcher3.util.ObjectWrapper;
import com.android.launcher3.util.RunnableList;
@@ -448,7 +448,7 @@
}
if (mDeviceProfile.isTaskbarPresentInApps
&& !target.willShowImeOnTarget
- && !DisplayController.isTransientTaskbar(mLauncher)) {
+ && !isTransientTaskbar(mLauncher)) {
// Animate to above the taskbar.
bounds.bottom -= target.contentInsets.bottom;
}
@@ -635,7 +635,7 @@
RectF launcherIconBounds = new RectF();
FloatingIconView floatingView = getFloatingIconView(mLauncher, v,
- mLauncher.getTaskbarUIController() == null
+ (mLauncher.getTaskbarUIController() == null || !isTransientTaskbar(mLauncher))
? null
: mLauncher.getTaskbarUIController().findMatchingView(v),
!appTargetsAreTranslucent, launcherIconBounds, true /* isOpening */);
diff --git a/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java
index c165750..9bcc804 100644
--- a/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java
@@ -77,13 +77,14 @@
/**
* Creates an animation to animate the taskbar for the given state (but does not start it).
- * Currently this animation just force stashes the taskbar in Overview.
*/
public Animator createAnimToRecentsState(RecentsState toState, long duration) {
- boolean useStashedLauncherState = toState.hasOverviewActions();
- boolean stashedLauncherState =
- useStashedLauncherState && FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW.get()
- && toState == RecentsState.MODAL_TASK;
+ // Force stash the taskbar in overview modal state or when going home.
+ boolean useStashedLauncherState =
+ toState.hasOverviewActions() || toState == RecentsState.HOME;
+ boolean stashedLauncherState = useStashedLauncherState && (
+ (FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW.get() && toState == RecentsState.MODAL_TASK)
+ || toState == RecentsState.HOME);
TaskbarStashController stashController = mControllers.taskbarStashController;
// Set both FLAG_IN_STASHED_LAUNCHER_STATE and FLAG_IN_APP to ensure the state is respected.
// For all other states, just use the current stashed-in-app setting (e.g. if long clicked).
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 57e11de..62713ca 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -316,7 +316,6 @@
return mTransientTaskbarBounds;
}
- @VisibleForTesting
@Override
public StatsLogManager getStatsLogManager() {
// Used to mock, can't mock a default interface method directly
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
index 8c21778..e0acd3e 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
@@ -25,6 +25,8 @@
import static com.android.launcher3.config.FeatureFlags.FORCE_PERSISTENT_TASKBAR;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_LONGPRESS_HIDE;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_LONGPRESS_SHOW;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TRANSIENT_TASKBAR_HIDE;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TRANSIENT_TASKBAR_SHOW;
import static com.android.launcher3.taskbar.Utilities.appendFlag;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING;
@@ -972,6 +974,11 @@
mActivity.getStatsLogManager().logger().log(LAUNCHER_TASKBAR_LONGPRESS_SHOW);
}
}
+ if (hasAnyFlag(changedFlags, FLAG_STASHED_IN_APP_AUTO)) {
+ mActivity.getStatsLogManager().logger().log(hasAnyFlag(FLAG_STASHED_IN_APP_AUTO)
+ ? LAUNCHER_TRANSIENT_TASKBAR_HIDE
+ : LAUNCHER_TRANSIENT_TASKBAR_SHOW);
+ }
}
private void notifyStashChange(boolean visible, boolean stashed) {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
index d2f9294..214679a 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
@@ -75,9 +75,17 @@
@Override
public ScaleAndTranslation getWorkspaceScaleAndTranslation(Launcher launcher) {
RecentsView recentsView = launcher.getOverviewPanel();
- float workspacePageHeight = launcher.getDeviceProfile().getCellLayoutHeight();
recentsView.getTaskSize(sTempRect);
- float scale = (float) sTempRect.height() / workspacePageHeight;
+ float scale;
+ DeviceProfile deviceProfile = launcher.getDeviceProfile();
+ if (deviceProfile.isTwoPanels) {
+ // In two panel layout, width does not include both panels or space between them, so
+ // use height instead. We do not use height for handheld, as cell layout can be
+ // shorter than a task and we want the workspace to scale down to task size.
+ scale = (float) sTempRect.height() / deviceProfile.getCellLayoutHeight();
+ } else {
+ scale = (float) sTempRect.width() / deviceProfile.getCellLayoutWidth();
+ }
float parallaxFactor = 0.5f;
return new ScaleAndTranslation(scale, 0, -getDefaultSwipeHeight(launcher) * parallaxFactor);
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
index a02f3de..c7cd39c 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
@@ -32,6 +32,7 @@
import static com.android.launcher3.anim.Interpolators.DEACCEL_3;
import static com.android.launcher3.anim.Interpolators.EMPHASIZED_ACCELERATE;
import static com.android.launcher3.anim.Interpolators.EMPHASIZED_DECELERATE;
+import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
import static com.android.launcher3.anim.Interpolators.FINAL_FRAME;
import static com.android.launcher3.anim.Interpolators.INSTANT;
import static com.android.launcher3.anim.Interpolators.LINEAR;
@@ -103,7 +104,10 @@
}
config.setInterpolator(ANIM_OVERVIEW_ACTIONS_FADE, clampToProgress(LINEAR, 0, 0.25f));
- config.setInterpolator(ANIM_SCRIM_FADE, clampToProgress(LINEAR, 0.33f, 1));
+ config.setInterpolator(ANIM_SCRIM_FADE,
+ fromState == OVERVIEW_SPLIT_SELECT
+ ? clampToProgress(LINEAR, 0.33f, 1)
+ : LINEAR);
config.setInterpolator(ANIM_WORKSPACE_SCALE, DEACCEL);
config.setInterpolator(ANIM_WORKSPACE_FADE, ACCEL);
@@ -112,7 +116,10 @@
// Overview is going offscreen, so keep it at its current scale and opacity.
config.setInterpolator(ANIM_OVERVIEW_SCALE, FINAL_FRAME);
config.setInterpolator(ANIM_OVERVIEW_FADE, FINAL_FRAME);
- config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, EMPHASIZED_DECELERATE);
+ config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X,
+ fromState == OVERVIEW_SPLIT_SELECT
+ ? EMPHASIZED_DECELERATE
+ : clampToProgress(FAST_OUT_SLOW_IN, 0, 0.75f));
config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, FINAL_FRAME);
// Scroll RecentsView to page 0 as it goes offscreen, if necessary.
diff --git a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
index 1b05fd2..84f6b55 100644
--- a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
+++ b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
@@ -33,6 +33,7 @@
import com.android.launcher3.R;
import com.android.launcher3.testing.shared.ResourceUtils;
+import com.android.launcher3.testing.shared.TestProtocol;
import com.android.launcher3.util.DisplayController.Info;
import com.android.launcher3.util.NavigationMode;
import com.android.launcher3.util.window.CachedDisplayInfo;
@@ -119,7 +120,7 @@
}
void setNavigationMode(NavigationMode newMode, Info info, Resources newRes) {
- if (DEBUG) {
+ if (enableLog()) {
Log.d(TAG, "setNavigationMode new: " + newMode + " oldMode: " + mMode + " " + this);
}
if (mMode == newMode) {
@@ -206,7 +207,7 @@
* Ok to call multiple times.
*/
private void resetSwipeRegions(Info region) {
- if (DEBUG) {
+ if (enableLog()) {
Log.d(TAG, "clearing all regions except rotation: " + mCachedDisplayInfo.rotation);
}
@@ -230,9 +231,11 @@
}
private OrientationRectF createRegionForDisplay(Info display) {
- if (DEBUG) {
+ if (enableLog()) {
Log.d(TAG, "creating rotation region for: " + mCachedDisplayInfo.rotation
- + " with mode: " + mMode + " displayRotation: " + display.rotation);
+ + " with mode: " + mMode + " displayRotation: " + display.rotation +
+ " displaySize: " + display.currentSize +
+ " navBarHeight: " + mNavBarGesturalHeight);
}
Point size = display.currentSize;
@@ -296,9 +299,8 @@
}
boolean touchInValidSwipeRegions(float x, float y) {
- if (DEBUG) {
- Log.d(TAG, "touchInValidSwipeRegions " + x + "," + y + " in "
- + mLastRectTouched + " this: " + this);
+ if (enableLog()) {
+ Log.d(TAG, "touchInValidSwipeRegions " + x + "," + y + " in " + mLastRectTouched);
}
if (mLastRectTouched != null) {
return mLastRectTouched.contains(x, y);
@@ -357,11 +359,17 @@
}
case ACTION_POINTER_DOWN:
case ACTION_DOWN: {
+ if (enableLog()) {
+ Log.d(TAG, "ACTION_DOWN mLastRectTouched: " + mLastRectTouched);
+ }
if (mLastRectTouched != null) {
return;
}
for (OrientationRectF rect : mSwipeTouchRegions.values()) {
+ if (enableLog()) {
+ Log.d(TAG, "ACTION_DOWN rect: " + rect);
+ }
if (rect == null) {
continue;
}
@@ -376,7 +384,7 @@
mQuickStepStartingRotation = mLastRectTouched.getRotation();
resetSwipeRegions();
}
- if (DEBUG) {
+ if (enableLog()) {
Log.d(TAG, "set active region: " + rect);
}
return;
@@ -387,6 +395,10 @@
}
}
+ private boolean enableLog() {
+ return DEBUG || TestProtocol.sDebugTracing;
+ }
+
public void dump(PrintWriter pw) {
pw.println("OrientationTouchTransformerState: ");
pw.println(" currentActiveRotation=" + getCurrentActiveRotation());
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/TaskbarStashInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/TaskbarStashInputConsumer.java
index 9982162..1ddb855 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/TaskbarStashInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/TaskbarStashInputConsumer.java
@@ -53,6 +53,7 @@
private final float mScreenWidth;
private final int mTaskbarNavThreshold;
+ private final int mTaskbarNavThresholdY;
private final boolean mIsTaskbarAllAppsOpen;
private boolean mHasPassedTaskbarNavThreshold;
@@ -74,6 +75,8 @@
Resources res = context.getResources();
mUnstashArea = res.getDimensionPixelSize(R.dimen.taskbar_unstash_input_area);
mTaskbarNavThreshold = res.getDimensionPixelSize(R.dimen.taskbar_nav_threshold);
+ mTaskbarNavThresholdY = taskbarActivityContext.getDeviceProfile().heightPx
+ - mTaskbarNavThreshold;
mIsTaskbarAllAppsOpen =
mTaskbarActivityContext != null && mTaskbarActivityContext.isTaskbarAllAppsOpen();
@@ -163,7 +166,7 @@
}
if (dY < 0) {
- dY = -OverScroll.dampedScroll(-dY, mTaskbarNavThreshold);
+ dY = -OverScroll.dampedScroll(-dY, mTaskbarNavThresholdY);
if (mTransitionCallback != null && !mIsTaskbarAllAppsOpen) {
mTransitionCallback.onActionMove(dY);
}
diff --git a/quickstep/src/com/android/quickstep/util/BaseUnfoldMoveFromCenterAnimator.java b/quickstep/src/com/android/quickstep/util/BaseUnfoldMoveFromCenterAnimator.java
index 2a8bfa2..ad11b7e 100644
--- a/quickstep/src/com/android/quickstep/util/BaseUnfoldMoveFromCenterAnimator.java
+++ b/quickstep/src/com/android/quickstep/util/BaseUnfoldMoveFromCenterAnimator.java
@@ -86,6 +86,7 @@
}
private void clearRegisteredViews() {
+ restoreClippings();
mMoveFromCenterAnimation.clearRegisteredViews();
mOriginalClipChildren.clear();
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 614ef81..7c0cc2d 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -147,6 +147,8 @@
import com.android.launcher3.statehandlers.DepthController;
import com.android.launcher3.statemanager.BaseState;
import com.android.launcher3.statemanager.StatefulActivity;
+import com.android.launcher3.testing.TestLogging;
+import com.android.launcher3.testing.shared.TestProtocol;
import com.android.launcher3.touch.OverScroll;
import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.launcher3.util.DynamicResource;
@@ -3166,6 +3168,8 @@
InteractionJankMonitorWrapper.cancel(
InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER);
}
+
+ updateCurrentTaskActionsVisibility();
});
}
@@ -4495,6 +4499,7 @@
* Attempts to initiate split with an existing taskView, if one exists
*/
public void initiateSplitSelect(SplitSelectSource splitSelectSource) {
+ TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "enterSplitSelect");
mSplitSelectSource = splitSelectSource;
mSplitHiddenTaskView = getTaskViewByTaskId(splitSelectSource.alreadyRunningTaskId);
mSplitHiddenTaskViewIndex = indexOfChild(mSplitHiddenTaskView);
@@ -4666,6 +4671,11 @@
mSecondSplitHiddenView = null;
}
+ // We are leaving split selection state, so it is safe to reset thumbnail translations for
+ // the next time split is invoked.
+ setTaskViewsPrimarySplitTranslation(0);
+ setTaskViewsSecondarySplitTranslation(0);
+
if (mSplitHiddenTaskViewIndex == -1) {
return;
}
@@ -4680,11 +4690,6 @@
}
onLayout(false /* changed */, getLeft(), getTop(), getRight(), getBottom());
- // We are leaving split selection state, so it is safe to reset thumbnail translations for
- // the next time split is invoked.
- setTaskViewsPrimarySplitTranslation(0);
- setTaskViewsSecondarySplitTranslation(0);
-
resetTaskVisuals();
mSplitHiddenTaskViewIndex = -1;
if (mSplitHiddenTaskView != null) {
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java b/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java
new file mode 100644
index 0000000..d3fbe93
--- /dev/null
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java
@@ -0,0 +1,82 @@
+/*
+ * 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;
+
+import android.content.Intent;
+
+import com.android.launcher3.ui.TaplTestsLauncher3;
+import com.android.launcher3.util.rule.TestStabilityRule;
+import com.android.quickstep.TaskbarModeSwitchRule.TaskbarModeSwitch;
+
+import org.junit.After;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TaplTestsSplitscreen extends AbstractQuickStepTest {
+ private static final String CALCULATOR_APP_NAME = "Calculator";
+ private static final String CALCULATOR_APP_PACKAGE =
+ resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR);
+
+ @Override
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ TaplTestsLauncher3.initialize(this);
+
+ mLauncher.getWorkspace()
+ .deleteAppIcon(mLauncher.getWorkspace().getHotseatAppIcon(0))
+ .switchToAllApps()
+ .getAppIcon(CALCULATOR_APP_NAME)
+ .dragToHotseat(0);
+
+ startAppFast(CALCULATOR_APP_PACKAGE);
+ if (mLauncher.isTablet()) {
+ mLauncher.enableBlockTimeout(true);
+ mLauncher.showTaskbarIfHidden();
+ }
+ }
+
+ @After
+ public void tearDown() {
+ if (mLauncher.isTablet()) {
+ mLauncher.enableBlockTimeout(false);
+ }
+ }
+
+ @Test
+ // TODO (b/270201357): When this test is proven stable, remove this TestStabilityRule and
+ // introduce into presubmit as well.
+ @TestStabilityRule.Stability(
+ flavors = TestStabilityRule.LOCAL | TestStabilityRule.PLATFORM_POSTSUBMIT)
+ @PortraitLandscape
+ @TaskbarModeSwitch
+ public void testSplitAppFromHomeWithItself() throws Exception {
+ Assume.assumeTrue(mLauncher.isTablet());
+
+ mLauncher.goHome()
+ .switchToAllApps()
+ .getAppIcon(CALCULATOR_APP_NAME)
+ .openMenu()
+ .getSplitScreenMenuItem()
+ .click();
+
+ mLauncher.getLaunchedAppState()
+ .getTaskbar()
+ .getAppIcon(CALCULATOR_APP_NAME)
+ .launchIntoSplitScreen();
+ }
+}
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 801b740..865edcd 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -665,8 +665,9 @@
getPaddingBottom());
}
// only apply two line for all_apps
- if (FeatureFlags.ENABLE_TWOLINE_ALLAPPS.get() && (mLastOriginalText != null)
- && (mDisplay == DISPLAY_ALL_APPS)) {
+ if (((FeatureFlags.ENABLE_TWOLINE_ALLAPPS.get() && mDisplay == DISPLAY_ALL_APPS)
+ || (FeatureFlags.ENABLE_TWOLINE_DEVICESEARCH.get()
+ && mDisplay == DISPLAY_SEARCH_RESULT)) && (mLastOriginalText != null)) {
CharSequence modifiedString = modifyTitleToSupportMultiLine(
MeasureSpec.getSize(widthMeasureSpec) - getCompoundPaddingLeft()
- getCompoundPaddingRight(),
diff --git a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
index 8fbe997..8950203 100644
--- a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
@@ -19,6 +19,7 @@
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_COUNT;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_TAP_ON_PERSONAL_TAB;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_TAP_ON_WORK_TAB;
+import static com.android.launcher3.testing.shared.TestProtocol.WORK_TAB_MISSING;
import static com.android.launcher3.util.ScrollableLayoutManager.PREDICTIVE_BACK_MIN_SCALE;
import android.animation.Animator;
@@ -73,6 +74,7 @@
import com.android.launcher3.keyboard.FocusedItemDecorator;
import com.android.launcher3.model.StringCache;
import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.testing.shared.TestProtocol;
import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.util.Themes;
import com.android.launcher3.views.ActivityContext;
@@ -183,7 +185,12 @@
mNavBarScrimPaint = new Paint();
mNavBarScrimPaint.setColor(Themes.getAttrColor(context, R.attr.allAppsNavBarScrimColor));
- mAllAppsStore.addUpdateListener(this::onAppsUpdated);
+ AllAppsStore.OnUpdateListener onAppsUpdated = this::onAppsUpdated;
+ if (TestProtocol.sDebugTracing) {
+ Log.d(WORK_TAB_MISSING, "ActivityAllAppsContainer#init registeringListener: " +
+ onAppsUpdated);
+ }
+ mAllAppsStore.addUpdateListener(onAppsUpdated);
mActivityContext.addOnDeviceProfileChangeListener(this);
// This is a focus listener that proxies focus from a view into the list view. This is to
@@ -809,6 +816,10 @@
private void onAppsUpdated() {
mHasWorkApps = Stream.of(mAllAppsStore.getApps()).anyMatch(mWorkManager.getMatcher());
+ if (TestProtocol.sDebugTracing) {
+ Log.d(WORK_TAB_MISSING, "ActivityAllAppsContainerView#onAppsUpdated hasWorkApps: " +
+ mHasWorkApps + " allApps: " + mAllAppsStore.getApps().length);
+ }
if (!isSearching()) {
rebindAdapters();
if (mHasWorkApps) {
diff --git a/src/com/android/launcher3/allapps/AllAppsStore.java b/src/com/android/launcher3/allapps/AllAppsStore.java
index 7bc3eec..a977b3a 100644
--- a/src/com/android/launcher3/allapps/AllAppsStore.java
+++ b/src/com/android/launcher3/allapps/AllAppsStore.java
@@ -18,7 +18,9 @@
import static com.android.launcher3.model.data.AppInfo.COMPONENT_KEY_COMPARATOR;
import static com.android.launcher3.model.data.AppInfo.EMPTY_ARRAY;
import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_SHOW_DOWNLOAD_PROGRESS_MASK;
+import static com.android.launcher3.testing.shared.TestProtocol.WORK_TAB_MISSING;
+import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
@@ -27,6 +29,7 @@
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.testing.shared.TestProtocol;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.PackageUserKey;
@@ -119,6 +122,9 @@
return;
}
for (OnUpdateListener listener : mUpdateListeners) {
+ if (TestProtocol.sDebugTracing) {
+ Log.d(WORK_TAB_MISSING, "AllAppsStore#notifyUpdate listener: " + listener);
+ }
listener.onAppsUpdated();
}
}
diff --git a/src/com/android/launcher3/allapps/WorkProfileManager.java b/src/com/android/launcher3/allapps/WorkProfileManager.java
index f66ea34..30af502 100644
--- a/src/com/android/launcher3/allapps/WorkProfileManager.java
+++ b/src/com/android/launcher3/allapps/WorkProfileManager.java
@@ -25,6 +25,7 @@
import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_HAS_SHORTCUT_PERMISSION;
import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_QUIET_MODE_CHANGE_PERMISSION;
import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_QUIET_MODE_ENABLED;
+import static com.android.launcher3.testing.shared.TestProtocol.WORK_TAB_MISSING;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import android.os.Build;
@@ -46,6 +47,7 @@
import com.android.launcher3.allapps.BaseAllAppsAdapter.AdapterItem;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.testing.shared.TestProtocol;
import com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip;
import java.lang.annotation.Retention;
@@ -137,6 +139,10 @@
}
private void updateCurrentState(@WorkProfileState int currentState) {
+ if (TestProtocol.sDebugTracing) {
+ Log.d(WORK_TAB_MISSING, "WorkProfileManager#updateCurrentState: " +
+ currentState, new Throwable());
+ }
mCurrentState = currentState;
if (getAH() != null) {
getAH().mAppsList.updateAdapterItems();
@@ -155,6 +161,10 @@
* Creates and attaches for profile toggle button to {@link ActivityAllAppsContainerView}
*/
public boolean attachWorkModeSwitch() {
+ if (TestProtocol.sDebugTracing) {
+ Log.d(WORK_TAB_MISSING, "ActivityAllAppsContainerView#attachWorkModeSwitch "
+ + "mWorkModeSwitch: " + mWorkModeSwitch);
+ }
if (!mAllApps.getAppsStore().hasModelFlag(
FLAG_HAS_SHORTCUT_PERMISSION | FLAG_QUIET_MODE_CHANGE_PERMISSION)) {
Log.e(TAG, "unable to attach work mode switch; Missing required permissions");
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index 5f6df27..cf710da 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -636,6 +636,12 @@
@UiEvent(doc = "User scrolled up on the search result page.")
LAUNCHER_ALLAPPS_SEARCH_SCROLLED_UP(1286),
+
+ @UiEvent(doc = "User or automatic timeout has hidden transient taskbar.")
+ LAUNCHER_TRANSIENT_TASKBAR_HIDE(1330),
+
+ @UiEvent(doc = "User has swiped upwards from the gesture handle to show transient taskbar.")
+ LAUNCHER_TRANSIENT_TASKBAR_SHOW(1331),
;
// ADD MORE
diff --git a/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java b/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java
index f036b3e..c7db2ae 100644
--- a/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java
+++ b/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java
@@ -157,6 +157,7 @@
public static final String NPE_TRANSIENT_TASKBAR = "b/257549303";
public static final String FLAKY_BINDING = "b/270216650";
public static final String VIEW_AND_ACTIVITY_LEAKS = "b/260260325";
+ public static final String WORK_TAB_MISSING = "b/243688989";
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/ui/WorkProfileTest.java b/tests/src/com/android/launcher3/ui/WorkProfileTest.java
index c7628cc..9eeea24 100644
--- a/tests/src/com/android/launcher3/ui/WorkProfileTest.java
+++ b/tests/src/com/android/launcher3/ui/WorkProfileTest.java
@@ -18,6 +18,7 @@
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.allapps.AllAppsStore.DEFER_UPDATES_TEST;
+import static com.android.launcher3.testing.shared.TestProtocol.WORK_TAB_MISSING;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@@ -65,8 +66,13 @@
String[] tokens = output.split("\\s+");
mProfileUserId = Integer.parseInt(tokens[tokens.length - 1]);
output = mDevice.executeShellCommand("am start-user " + mProfileUserId);
+ StringBuilder logStr = new StringBuilder().append("profileId: ").append(mProfileUserId);
+ for (String str : tokens) {
+ logStr.append(str).append("\n");
+ }
updateWorkProfileSetupSuccessful("am start-user", output);
+ Log.d(WORK_TAB_MISSING, "workProfileSuccessful? " + mWorkProfileSetupSuccessful);
if (!mWorkProfileSetupSuccessful) {
return; // no need to setup launcher since all tests will skip.
}
@@ -99,6 +105,7 @@
private void waitForWorkTabSetup() {
waitForLauncherCondition("Work tab not setup", launcher -> {
if (launcher.getAppsView().getContentView() instanceof AllAppsPagedView) {
+ Log.d(WORK_TAB_MISSING, "Deferring AppsStore updates");
launcher.getAppsView().getAppsStore().enableDeferUpdates(DEFER_UPDATES_TEST);
return true;
}
diff --git a/tests/tapl/com/android/launcher3/tapl/AppIconMenu.java b/tests/tapl/com/android/launcher3/tapl/AppIconMenu.java
index 82d9630..667290f 100644
--- a/tests/tapl/com/android/launcher3/tapl/AppIconMenu.java
+++ b/tests/tapl/com/android/launcher3/tapl/AppIconMenu.java
@@ -54,5 +54,14 @@
return createMenuItem(menuItem);
}
+ /**
+ * Returns a menu item that matches the text "Split screen". Fails if it doesn't exist.
+ */
+ public SplitScreenMenuItem getSplitScreenMenuItem() {
+ final UiObject2 menuItem = mLauncher.waitForObjectInContainer(mDeepShortcutsContainer,
+ AppIcon.getAppIconSelector("Split screen", mLauncher));
+ return new SplitScreenMenuItem(mLauncher, menuItem);
+ }
+
protected abstract AppIconMenuItem createMenuItem(UiObject2 menuItem);
}
diff --git a/tests/tapl/com/android/launcher3/tapl/Launchable.java b/tests/tapl/com/android/launcher3/tapl/Launchable.java
index 3dcb437..48e327f 100644
--- a/tests/tapl/com/android/launcher3/tapl/Launchable.java
+++ b/tests/tapl/com/android/launcher3/tapl/Launchable.java
@@ -76,6 +76,27 @@
}
}
+ /**
+ * Clicks a launcher object to initiate splitscreen, where the selected app will be one of two
+ * apps running on the screen. Should be called when Launcher is in a "split staging" state
+ * and is waiting for the user's selection of a second app. Expects a SPLIT_START_EVENT to be
+ * fired when the click is executed.
+ */
+ public LaunchedAppState launchIntoSplitScreen() {
+ try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
+ "want to launch split tasks from " + launchableType())) {
+ LauncherInstrumentation.log("Launchable.launch before click "
+ + mObject.getVisibleCenter() + " in " + mLauncher.getVisibleBounds(mObject));
+
+ mLauncher.clickLauncherObject(mObject);
+
+ try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer("clicked")) {
+ mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, OverviewTask.SPLIT_START_EVENT);
+ return new LaunchedAppState(mLauncher);
+ }
+ }
+ }
+
protected LaunchedAppState assertAppLaunched(BySelector selector) {
mLauncher.assertTrue(
"App didn't start: (" + selector + ")",
diff --git a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
index adc993d..90f3d13 100644
--- a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
+++ b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
@@ -37,10 +37,9 @@
public final class OverviewTask {
private static final String SYSTEMUI_PACKAGE = "com.android.systemui";
- static final Pattern TASK_START_EVENT =
- Pattern.compile("startActivityFromRecentsAsync");
- static final Pattern SPLIT_START_EVENT =
- Pattern.compile("launchSplitTasks");
+ static final Pattern TASK_START_EVENT = Pattern.compile("startActivityFromRecentsAsync");
+ static final Pattern SPLIT_SELECT_EVENT = Pattern.compile("enterSplitSelect");
+ static final Pattern SPLIT_START_EVENT = Pattern.compile("launchSplitTasks");
private final LauncherInstrumentation mLauncher;
private final UiObject2 mTask;
private final BaseOverview mOverview;
diff --git a/tests/tapl/com/android/launcher3/tapl/SplitScreenMenuItem.java b/tests/tapl/com/android/launcher3/tapl/SplitScreenMenuItem.java
new file mode 100644
index 0000000..47cf20b
--- /dev/null
+++ b/tests/tapl/com/android/launcher3/tapl/SplitScreenMenuItem.java
@@ -0,0 +1,55 @@
+/*
+ * 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.tapl;
+
+import androidx.test.uiautomator.UiObject2;
+
+import com.android.launcher3.testing.shared.TestProtocol;
+
+/**
+ * A class representing the "Split screen" menu item in the app long-press menu. Used for TAPL
+ * testing in a similar way as other menu items {@link AppIconMenuItem}, but unlike AppIconMenuItem,
+ * the split screen command does not trigger an app launch. Instead, it causes Launcher to shift to
+ * a different state (OverviewSplitSelect).
+ */
+public final class SplitScreenMenuItem {
+ private final LauncherInstrumentation mLauncher;
+ private final UiObject2 mObject;
+
+ SplitScreenMenuItem(LauncherInstrumentation launcher, UiObject2 object) {
+ mLauncher = launcher;
+ mObject = object;
+ }
+
+ /**
+ * Executes a click command on this menu item. Expects a SPLIT_SELECT_EVENT to be fired.
+ */
+ public void click() {
+ try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
+ "want to enter split select from app long-press menu")) {
+ LauncherInstrumentation.log("clicking on split screen menu item "
+ + mObject.getVisibleCenter() + " in " + mLauncher.getVisibleBounds(mObject));
+
+ mLauncher.clickLauncherObject(mObject);
+
+ try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer("clicked")) {
+ mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, OverviewTask.SPLIT_SELECT_EVENT);
+ mLauncher.waitForLauncherObject("split_placeholder");
+ }
+ }
+ }
+}