Snap for 11717025 from 9d4fb2b5be to 24Q3-release

Change-Id: I0f37bdaab4b9db4b2c2c7d36cf08d0f7c06a8359
This commit is contained in:
Android Build Coastguard Worker
2024-04-15 23:21:58 +00:00
17 changed files with 158 additions and 72 deletions
@@ -19,7 +19,7 @@ import static com.android.app.animation.Interpolators.DECELERATE_3;
import static com.android.launcher3.AbstractFloatingView.TYPE_ALL;
import static com.android.launcher3.AbstractFloatingView.TYPE_ALL_APPS_EDU;
import static com.android.launcher3.LauncherAnimUtils.SUCCESS_TRANSITION_PROGRESS;
import static com.android.launcher3.LauncherAnimUtils.newCancelListener;
import static com.android.launcher3.LauncherAnimUtils.newSingleUseCancelListener;
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.MotionEventsUtils.isTrackpadMotionEvent;
@@ -47,7 +47,6 @@ import com.android.launcher3.compat.AccessibilityManagerCompat;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.statemanager.StateManager;
import com.android.launcher3.touch.SingleAxisSwipeDetector;
import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.TouchController;
import com.android.quickstep.TaskUtils;
@@ -166,7 +165,7 @@ public class NavBarToHomeTouchController implements TouchController,
topView.addHintCloseAnim(mPullbackDistance, PULLBACK_INTERPOLATOR, builder);
}
mCurrentAnimation = builder.createPlaybackController();
mCurrentAnimation.getTarget().addListener(newCancelListener(this::clearState));
mCurrentAnimation.getTarget().addListener(newSingleUseCancelListener(this::clearState));
}
private void clearState() {
@@ -18,7 +18,7 @@ package com.android.launcher3.uioverrides.touchcontrollers;
import static com.android.app.animation.Interpolators.ACCELERATE_DECELERATE;
import static com.android.launcher3.LauncherAnimUtils.VIEW_BACKGROUND_COLOR;
import static com.android.launcher3.LauncherAnimUtils.newCancelListener;
import static com.android.launcher3.LauncherAnimUtils.newSingleUseCancelListener;
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.HINT_STATE;
import static com.android.launcher3.LauncherState.NORMAL;
@@ -226,7 +226,7 @@ public class NoButtonNavbarToOverviewTouchController extends PortraitStatesTouch
return;
}
mNormalToHintOverviewScrimAnimator = null;
mCurrentAnimation.getTarget().addListener(newCancelListener(() ->
mCurrentAnimation.getTarget().addListener(newSingleUseCancelListener(() ->
mLauncher.getStateManager().goToState(OVERVIEW, true, forSuccessCallback(() -> {
mOverviewResistYAnim = AnimatorControllerWithResistance
.createRecentsResistanceFromOverviewAnim(mLauncher, null)
@@ -109,7 +109,7 @@ public class NoButtonQuickSwitchTouchController implements TouchController,
private final float mMotionPauseMinDisplacement;
private final RecentsView mRecentsView;
protected final AnimatorListener mClearStateOnCancelListener =
newCancelListener(this::clearState);
newCancelListener(this::clearState, /* isSingleUse = */ false);
private boolean mNoIntercept;
private LauncherState mStartState;
@@ -97,6 +97,13 @@ public class RecentTasksList {
RecentTasksList.this.onRunningTaskVanished(taskInfo);
});
}
@Override
public void onRunningTaskChanged(ActivityManager.RunningTaskInfo taskInfo) {
mMainThreadExecutor.execute(() -> {
RecentTasksList.this.onRunningTaskChanged(taskInfo);
});
}
});
// We may receive onRunningTaskAppeared events later for tasks which have already been
// included in the list returned by mSysUiProxy.getRunningTasks(), or may receive
@@ -244,6 +251,20 @@ public class RecentTasksList {
}
}
private void onRunningTaskChanged(ActivityManager.RunningTaskInfo taskInfo) {
// Find the task from the list of running tasks, if it exists
for (ActivityManager.RunningTaskInfo existingTask : mRunningTasks) {
if (existingTask.taskId != taskInfo.taskId) continue;
mRunningTasks.remove(existingTask);
mRunningTasks.add(taskInfo);
if (mRunningTasksListener != null) {
mRunningTasksListener.onRunningTasksChanged();
}
return;
}
}
/**
* Loads and creates a list of all the recent tasks.
*/
@@ -390,4 +411,4 @@ public class RecentTasksList {
return mRequestId == requestId && (!mKeysOnly || loadKeysOnly);
}
}
}
}
@@ -17,8 +17,6 @@ package com.android.quickstep;
import static com.android.launcher3.Flags.enableCursorHoverStates;
import static com.android.launcher3.util.TestConstants.AppNames.TEST_APP_NAME;
import static com.android.launcher3.util.rule.TestStabilityRule.LOCAL;
import static com.android.launcher3.util.rule.TestStabilityRule.PLATFORM_POSTSUBMIT;
import static com.android.quickstep.TaskbarModeSwitchRule.Mode.TRANSIENT;
import static org.junit.Assume.assumeTrue;
@@ -26,9 +24,6 @@ import static org.junit.Assume.assumeTrue;
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape;
import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
import com.android.launcher3.util.rule.TestStabilityRule;
import com.android.quickstep.TaskbarModeSwitchRule.TaskbarModeSwitch;
import org.junit.Test;
@@ -72,9 +67,6 @@ public class TaplTestsTransientTaskbar extends AbstractTaplTestsTaskbar {
@Test
@TaskbarModeSwitch(mode = TRANSIENT)
@PortraitLandscape
@ScreenRecord // b/317798731
@TestStabilityRule.Stability(flavors = LOCAL | PLATFORM_POSTSUBMIT) // b/321083190
public void testSwipeToStashAndUnstash() {
getTaskbar().swipeDownToStash();
mLauncher.getLaunchedAppState().swipeUpToUnstashTaskbar();
@@ -22,9 +22,11 @@
android:pathData="M48 24A24 24 0 0 1 0 24A24 24 0 0 1 48 24Z"
android:fillColor="?androidprv:attr/materialColorSurfaceContainerLowest" />
<path
android:pathData="M33.3333 14.6667V33.3333H14.6667V14.6667H33.3333ZM33.3333 12H14.6667C13.2 12 12 13.2 12 14.6667V33.3333C12 34.8 13.2 36 14.6667 36H33.3333C34.8 36 36 34.8 36 33.3333V14.6667C36 13.2 34.8 12 33.3333 12Z"
android:pathData="M24.0021 10.6641L13.3354 14.6641V22.7841C13.3354 29.5174 17.8821 35.7974 24.0021 37.3307C30.1221 35.7974 34.6688 29.5174 34.6688 22.7841V14.6641L24.0021 10.6641ZM32.0021 22.7841C32.0021 28.1174 28.6021 33.0507 24.0021 34.5574C19.4021 33.0507 16.0021 28.1307 16.0021 22.7841V16.5174L24.0021 13.5174L32.0021 16.5174V22.7841Z"
android:fillType="evenOdd"
android:fillColor="?attr/materialColorOnSurface" />
<path
android:pathData="M25.2397 24.3597L25.9997 28.6663H21.9997L22.7597 24.3597C21.9063 23.9197 21.333 23.0263 21.333 21.9997C21.333 20.533 22.533 19.333 23.9997 19.333C25.4663 19.333 26.6663 20.533 26.6663 21.9997C26.6663 23.0263 26.093 23.9197 25.2397 24.3597Z"
android:pathData="M19.3354 20.6657C19.3354 22.7724 20.7488 24.5457 22.6688 25.119V31.999H25.3354V30.6657H28.0021V27.999H25.3354V25.119C27.2554 24.5457 28.6688 22.7857 28.6688 20.6657C28.6688 18.0924 26.5754 15.999 24.0021 15.999C21.4288 15.999 19.3354 18.0924 19.3354 20.6657ZM26.0021 20.6657C26.0021 21.7724 25.1088 22.6657 24.0021 22.6657C22.8954 22.6657 22.0021 21.7724 22.0021 20.6657C22.0021 19.559 22.8954 18.6657 24.0021 18.6657C25.1088 18.6657 26.0021 19.559 26.0021 20.6657Z"
android:fillType="evenOdd"
android:fillColor="?attr/materialColorOnSurface" />
</vector>
@@ -220,17 +220,28 @@ public class LauncherAnimUtils {
/**
* Utility method to create an {@link AnimatorListener} which executes a callback on animation
* cancel.
* cancel. Once the cancel has been dispatched, this listener will no longer be called.
*/
public static AnimatorListener newCancelListener(Runnable callback) {
return new AnimatorListenerAdapter() {
public static AnimatorListener newSingleUseCancelListener(Runnable callback) {
return newCancelListener(callback, true);
}
/**
* Utility method to create an {@link AnimatorListener} which executes a callback on animation
* cancel.
*
* @param isSingleUse {@code true} means the callback will be called at most once
*/
public static AnimatorListener newCancelListener(Runnable callback, boolean isSingleUse) {
return new AnimatorListenerAdapter() {
boolean mDispatched = false;
@Override
public void onAnimationCancel(Animator animation) {
if (!mDispatched) {
mDispatched = true;
if (isSingleUse) {
mDispatched = true;
}
callback.run();
}
}
@@ -572,7 +572,7 @@ public class IconCache extends BaseIconCache {
try (LauncherIcons li = LauncherIcons.obtain(mContext)) {
final BitmapInfo tempBitmap = li.createBadgedIconBitmap(
mContext.getDrawable(widgetSection.mSectionDrawable),
new BaseIconFactory.IconOptions().setShrinkNonAdaptiveIcons(false));
new BaseIconFactory.IconOptions());
mWidgetCategoryBitmapInfos.put(infoInOut.widgetCategory, tempBitmap);
infoInOut.bitmap = getBadgedIcon(tempBitmap, infoInOut.user);
} catch (Exception e) {
@@ -41,6 +41,7 @@ import androidx.annotation.Keep;
import androidx.annotation.Nullable;
import androidx.core.view.WindowInsetsCompat;
import com.android.launcher3.BaseActivity;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.CellLayout;
import com.android.launcher3.DeviceProfile;
@@ -136,6 +137,10 @@ public class TestInformationHandler implements ResourceBasedOverride {
});
}
case TestProtocol.REQUEST_IS_LAUNCHER_BINDING: {
return getUIProperty(Bundle::putBoolean, t -> isLauncherBinding(), () -> true);
}
case TestProtocol.REQUEST_IS_LAUNCHER_INITIALIZED: {
return getUIProperty(Bundle::putBoolean, t -> isLauncherInitialized(), () -> true);
}
@@ -484,6 +489,11 @@ public class TestInformationHandler implements ResourceBasedOverride {
return target;
}
protected boolean isLauncherBinding() {
BaseActivity baseActivity = Launcher.ACTIVITY_TRACKER.getCreatedActivity();
return baseActivity != null && baseActivity.isBindingItems();
}
protected boolean isLauncherInitialized() {
return Launcher.ACTIVITY_TRACKER.getCreatedActivity() == null
|| LauncherAppState.getInstance(mContext).getModel().isModelLoaded();
@@ -57,7 +57,7 @@ public abstract class AbstractStateChangeTouchController
protected final SingleAxisSwipeDetector.Direction mSwipeDirection;
protected final AnimatorListener mClearStateOnCancelListener =
newCancelListener(this::clearState);
newCancelListener(this::clearState, /* isSingleUse = */ false);
private final FlingBlockCheck mFlingBlockCheck = new FlingBlockCheck();
protected int mStartContainerType;
@@ -87,6 +87,7 @@ public final class TestProtocol {
"home-to-all-apps-swipe-height";
public static final String REQUEST_ICON_HEIGHT =
"icon-height";
public static final String REQUEST_IS_LAUNCHER_BINDING = "is-launcher-binding";
public static final String REQUEST_IS_LAUNCHER_INITIALIZED = "is-launcher-initialized";
public static final String REQUEST_IS_LAUNCHER_LAUNCHER_ACTIVITY_STARTED =
"is-launcher-activity-started";
@@ -39,6 +39,7 @@ import com.android.launcher3.ui.AbstractLauncherUiTest;
import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape;
import com.android.launcher3.util.TestUtil;
import com.android.launcher3.util.Wait;
import com.android.launcher3.util.rule.ScreenRecordRule;
import com.android.launcher3.util.rule.TestStabilityRule;
import org.junit.Test;
@@ -132,6 +133,7 @@ public class TaplUninstallRemoveTest extends AbstractLauncherUiTest<Launcher> {
*/
@Test
@PlatinumTest(focusArea = "launcher")
@ScreenRecordRule.ScreenRecord // b/319501259
public void uninstallWorkspaceIcon() throws IOException {
Point[] gridPositions = TestUtil.getCornersAndCenterPositions(mLauncher);
StringBuilder sb = new StringBuilder();
@@ -162,12 +164,10 @@ public class TaplUninstallRemoveTest extends AbstractLauncherUiTest<Launcher> {
mLauncher.getWorkspace().verifyWorkspaceAppIconIsGone(
DUMMY_APP_NAME + " was expected to disappear after uninstall.", DUMMY_APP_NAME);
if (!TestStabilityRule.isPresubmit()) { // b/315847371
Log.d(UIOBJECT_STALE_ELEMENT, "second getWorkspaceIconsPositions()");
Map<String, Point> finalPositions =
mLauncher.getWorkspace().getWorkspaceIconsPositions();
assertThat(finalPositions).doesNotContainKey(DUMMY_APP_NAME);
}
Log.d(UIOBJECT_STALE_ELEMENT, "second getWorkspaceIconsPositions()");
Map<String, Point> finalPositions =
mLauncher.getWorkspace().getWorkspaceIconsPositions();
assertThat(finalPositions).doesNotContainKey(DUMMY_APP_NAME);
} finally {
TestUtil.uninstallDummyApp();
}
@@ -15,8 +15,6 @@
*/
package com.android.launcher3.ui.widget;
import static com.android.launcher3.util.rule.ShellCommandRule.createEnableInputTransportPublisherRule;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@@ -32,9 +30,7 @@ import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
import com.android.launcher3.widget.picker.WidgetsFullSheet;
import com.android.launcher3.widget.picker.WidgetsRecyclerView;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
import org.junit.runner.RunWith;
/**
@@ -44,9 +40,6 @@ import org.junit.runner.RunWith;
@MediumTest
@RunWith(AndroidJUnit4.class)
public class TaplWidgetPickerTest extends AbstractLauncherUiTest<Launcher> {
// b/325377690 : To get the log printed where DOWN key event is getting lost from TAPL.
@Rule public final TestRule mEnableInputTransportPublisherRule =
createEnableInputTransportPublisherRule();
private WidgetsRecyclerView getWidgetsView(Launcher launcher) {
return WidgetsFullSheet.getWidgetsView(launcher);
@@ -0,0 +1,75 @@
/*
* Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.launcher3.util.rule;
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.test.uiautomator.UiDevice;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
/**
* Test rule which executes a set prop command at the start of the test.
* This rule needs the property tag and property value so that value can be set to a tag.
*/
public class SetPropRule implements TestRule {
private static final String SETPROP_PREFIX = "setprop";
private static final String GETPROP_PREFIX = "getprop";
private static final String UNKNOWN = "UNKNOWN";
@NonNull private final String mPropTag;
@NonNull private final String mPropValue;
public SetPropRule(@NonNull String propTag, @NonNull String propValue) {
mPropTag = propTag.trim();
mPropValue = propValue.trim();
}
@Override
public Statement apply(Statement base, Description description) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
String getpropCmd = GETPROP_PREFIX + " " + mPropTag;
String initialValue = UiDevice.getInstance(getInstrumentation())
.executeShellCommand(getpropCmd);
if (TextUtils.isEmpty(initialValue.trim())) {
initialValue = UNKNOWN;
}
// setprop command always follows format : setprop <TAG> <value>
String revertSetPropCmd = SETPROP_PREFIX + " " + mPropTag + " " + initialValue;
String setPropCmd = SETPROP_PREFIX + " " + mPropTag + " " + mPropValue;
new ShellCommandRule(setPropCmd, revertSetPropCmd)
.apply(base, description).evaluate();
}
};
}
/**
* Enables "InputTransportPublisher" debug flag. This prints the key input events dispatched by
* the system server.
* adb shell setprop log.tag.InputTransportPublisher DEBUG
* See {@link com.android.cts.input.DebugInputRule} for more details.
*/
public static SetPropRule createEnableInputTransportPublisherRule() {
return new SetPropRule("log.tag.InputTransportPublisher", "DEBUG");
}
}
@@ -15,13 +15,12 @@
*/
package com.android.launcher3.util.rule;
import static androidx.test.InstrumentationRegistry.getInstrumentation;
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import static com.android.launcher3.tapl.TestHelpers.getLauncherInMyProcess;
import android.content.ComponentName;
import android.content.pm.ActivityInfo;
import android.text.TextUtils;
import androidx.annotation.Nullable;
import androidx.test.InstrumentationRegistry;
@@ -40,10 +39,6 @@ import java.util.ArrayList;
* Test rule which executes a shell command at the start of the test.
*/
public class ShellCommandRule implements TestRule {
private static final String SETPROP_PREFIX = "setprop";
private static final String GETPROP_PREFIX = "getprop";
private static final String UNKNOWN = "UNKNOWN";
private final String mCmd;
private final String mRevertCommand;
private final boolean mCheckSuccess;
@@ -66,19 +61,6 @@ public class ShellCommandRule implements TestRule {
return new Statement() {
@Override
public void evaluate() throws Throwable {
String revertSetPropCmd = null;
if (mCmd.startsWith(SETPROP_PREFIX) && mRevertCommand == null) {
// setprop command always follows format : setprop <TAG> <value>
// We are stripping out only the TAG here
String tag = mCmd.split("\\s")[1];
String getpropCmd = GETPROP_PREFIX + " " + tag;
String initialValue = UiDevice.getInstance(
getInstrumentation()).executeShellCommand(getpropCmd);
if (TextUtils.isEmpty(initialValue.trim())) {
initialValue = UNKNOWN;
}
revertSetPropCmd = SETPROP_PREFIX + " " + tag + " " + initialValue;
}
final String result =
UiDevice.getInstance(getInstrumentation()).executeShellCommand(mCmd);
if (mCheckSuccess) {
@@ -90,15 +72,12 @@ public class ShellCommandRule implements TestRule {
try {
base.evaluate();
} finally {
if (mRevertCommand != null || revertSetPropCmd != null) {
String revertCmd =
mRevertCommand != null ? mRevertCommand : revertSetPropCmd;
if (mRevertCommand != null) {
final String revertResult = UiDevice.getInstance(
getInstrumentation()).executeShellCommand(
revertCmd);
getInstrumentation()).executeShellCommand(mRevertCommand);
if (mCheckSuccess) {
Assert.assertTrue(
"Failed command: " + revertCmd
"Failed command: " + mRevertCommand
+ ", result: " + revertResult,
"Success".equals(result.replaceAll("\\s", "")));
}
@@ -141,14 +120,4 @@ public class ShellCommandRule implements TestRule {
return new ShellCommandRule("settings put global heads_up_notifications_enabled 0",
"settings put global heads_up_notifications_enabled 1");
}
/**
* Enables "InputTransportPublisher" debug flag. This prints the key input events dispatched by
* the system server.
* adb shell setprop log.tag.InputTransportPublisher DEBUG
* See {@link com.android.cts.input.DebugInputRule} for more details.
*/
public static ShellCommandRule createEnableInputTransportPublisherRule() {
return new ShellCommandRule("setprop log.tag.InputTransportPublisher DEBUG", null);
}
}
@@ -1002,6 +1002,19 @@ public final class LauncherInstrumentation {
}
public void waitForLauncherInitialized() {
boolean isLauncherBinding = true;
for (int i = 0; i < 100; ++i) {
isLauncherBinding = getTestInfo(TestProtocol.REQUEST_IS_LAUNCHER_BINDING)
.getBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD);
if (!isLauncherBinding) {
break;
}
SystemClock.sleep(100);
}
if (isLauncherBinding) {
fail("Launcher didn't finish binding");
}
for (int i = 0; i < 100; ++i) {
if (getTestInfo(
TestProtocol.REQUEST_IS_LAUNCHER_INITIALIZED).
@@ -1010,7 +1023,6 @@ public final class LauncherInstrumentation {
}
SystemClock.sleep(100);
}
checkForAnomaly();
fail("Launcher didn't initialize");
}
@@ -347,6 +347,7 @@ public final class Workspace extends Home {
*/
public Map<String, Point> getWorkspaceIconsPositions() {
final UiObject2 workspace = verifyActiveContainer();
mLauncher.waitForLauncherInitialized(); // b/319501259
List<UiObject2> workspaceIcons =
mLauncher.waitForObjectsInContainer(workspace, AppIcon.getAnyAppIconSelector());
return workspaceIcons.stream()