summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--go/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java5
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java11
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java5
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java2
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AssistantTouchConsumer.java19
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java55
-rw-r--r--quickstep/res/values/dimens.xml1
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/TogglableFlag.java21
-rw-r--r--quickstep/src/com/android/quickstep/views/ShelfScrimView.java6
-rw-r--r--quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java3
-rw-r--r--quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java1
-rw-r--r--quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java2
-rw-r--r--src/com/android/launcher3/BaseRecyclerView.java10
-rw-r--r--src/com/android/launcher3/BubbleTextView.java10
-rw-r--r--src/com/android/launcher3/FastBitmapDrawable.java7
-rw-r--r--src/com/android/launcher3/Launcher.java5
-rw-r--r--src/com/android/launcher3/LauncherAppState.java1
-rw-r--r--src/com/android/launcher3/allapps/AllAppsRecyclerView.java17
-rw-r--r--src/com/android/launcher3/allapps/AllAppsTransitionController.java11
-rw-r--r--src/com/android/launcher3/anim/AnimatorSetBuilder.java1
-rw-r--r--src/com/android/launcher3/compat/PackageInstallerCompatVL.java5
-rw-r--r--src/com/android/launcher3/config/BaseFlags.java25
-rw-r--r--src/com/android/launcher3/dragndrop/DragDriver.java3
-rw-r--r--src/com/android/launcher3/folder/Folder.java4
-rw-r--r--src/com/android/launcher3/folder/FolderIcon.java23
-rw-r--r--src/com/android/launcher3/icons/IconCache.java4
-rw-r--r--src/com/android/launcher3/popup/PopupContainerWithArrow.java10
-rw-r--r--src/com/android/launcher3/testing/TestInformationHandler.java11
-rw-r--r--src/com/android/launcher3/testing/TestProtocol.java2
-rw-r--r--src/com/android/launcher3/views/AbstractSlideInView.java8
-rw-r--r--src/com/android/launcher3/views/BaseDragLayer.java6
-rw-r--r--src/com/android/launcher3/views/FloatingIconView.java75
-rw-r--r--src/com/android/launcher3/views/IconLabelDotView.java24
-rw-r--r--src/com/android/launcher3/views/OptionsPopupView.java17
-rw-r--r--src/com/android/launcher3/views/ScrimView.java39
-rw-r--r--src_ui_overrides/com/android/launcher3/uioverrides/TogglableFlag.java6
-rw-r--r--tests/src/com/android/launcher3/compat/PromiseIconUiTest.java113
-rw-r--r--tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java31
-rw-r--r--tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java7
-rw-r--r--tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java6
-rw-r--r--tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java29
-rw-r--r--tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java24
-rw-r--r--tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java2
-rw-r--r--tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java11
-rw-r--r--tests/tapl/com/android/launcher3/tapl/Widgets.java38
-rw-r--r--tests/tapl/com/android/launcher3/tapl/Workspace.java14
46 files changed, 493 insertions, 237 deletions
diff --git a/go/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java b/go/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
index d0cfcf97a..212ce9bef 100644
--- a/go/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
+++ b/go/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
@@ -32,6 +32,7 @@ import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2;
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_7;
import static com.android.launcher3.states.RotationHelper.REQUEST_ROTATE;
+import android.content.Context;
import android.view.View;
import com.android.launcher3.DeviceProfile;
@@ -115,10 +116,10 @@ public class OverviewState extends LauncherState {
}
public static float getDefaultSwipeHeight(Launcher launcher) {
- return getDefaultSwipeHeight(launcher.getDeviceProfile());
+ return getDefaultSwipeHeight(launcher, launcher.getDeviceProfile());
}
- public static float getDefaultSwipeHeight(DeviceProfile dp) {
+ public static float getDefaultSwipeHeight(Context context, DeviceProfile dp) {
return dp.allAppsCellHeightPx - dp.allAppsIconTextSizePx;
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java
index 151ceb834..93d4de17d 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java
@@ -32,6 +32,7 @@ import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_7;
import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
import static com.android.launcher3.states.RotationHelper.REQUEST_ROTATE;
+import android.content.Context;
import android.graphics.Rect;
import android.view.View;
@@ -159,11 +160,15 @@ public class OverviewState extends LauncherState {
}
public static float getDefaultSwipeHeight(Launcher launcher) {
- return getDefaultSwipeHeight(launcher.getDeviceProfile());
+ return getDefaultSwipeHeight(launcher, launcher.getDeviceProfile());
}
- public static float getDefaultSwipeHeight(DeviceProfile dp) {
- return dp.allAppsCellHeightPx - dp.allAppsIconTextSizePx;
+ public static float getDefaultSwipeHeight(Context context, DeviceProfile dp) {
+ float swipeHeight = dp.allAppsCellHeightPx - dp.allAppsIconTextSizePx;
+ if (SysUINavigationMode.getMode(context) == SysUINavigationMode.Mode.NO_BUTTON) {
+ swipeHeight -= dp.getInsets().bottom;
+ }
+ return swipeHeight;
}
@Override
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
index 4f971809f..25cc33df0 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
@@ -172,8 +172,6 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe
AnimatorSetBuilder builder = new AnimatorSetBuilder();
// setRecentsAttachedToAppWindow() will animate recents out.
builder.addFlag(AnimatorSetBuilder.FLAG_DONT_ANIMATE_OVERVIEW);
- // We want to keep all apps content as GONE to avoid relayout during home animation.
- builder.addFlag(AnimatorSetBuilder.FLAG_DONT_UPDATE_ALL_APPS_VISIBILITY);
stateManager.createAtomicAnimation(BACKGROUND_APP, NORMAL, builder, ANIM_ALL, 0);
builder.build().start();
@@ -202,9 +200,6 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe
// This ensures then the next swipe up to all-apps starts from scroll 0.
activity.getAppsView().reset(false /* animate */);
- // Optimization, hide the all apps view to prevent layout while initializing
- activity.getAppsView().getContentView().setVisibility(View.GONE);
-
return new AnimationFactory() {
private ShelfAnimState mShelfState;
private boolean mIsAttachedToWindow;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java
index 4eb9df2cb..da4642636 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java
@@ -24,7 +24,7 @@ public class QuickstepTestInformationHandler extends TestInformationHandler {
switch (method) {
case TestProtocol.REQUEST_HOME_TO_OVERVIEW_SWIPE_HEIGHT: {
final float swipeHeight =
- OverviewState.getDefaultSwipeHeight(mDeviceProfile);
+ OverviewState.getDefaultSwipeHeight(mContext, mDeviceProfile);
response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, (int) swipeHeight);
return response;
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AssistantTouchConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AssistantTouchConsumer.java
index 38b5a137c..346969e59 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AssistantTouchConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/AssistantTouchConsumer.java
@@ -1,3 +1,4 @@
+
/*
* Copyright (C) 2019 The Android Open Source Project
*
@@ -82,7 +83,8 @@ public class AssistantTouchConsumer extends DelegateInputConsumer {
private int mDirection;
private ActivityControlHelper mActivityControlHelper;
- private final float mDistThreshold;
+ private final float mDragDistThreshold;
+ private final float mFlingDistThreshold;
private final long mTimeThreshold;
private final int mAngleThreshold;
private final float mSquaredSlop;
@@ -97,7 +99,8 @@ public class AssistantTouchConsumer extends DelegateInputConsumer {
final Resources res = context.getResources();
mContext = context;
mSysUiProxy = systemUiProxy;
- mDistThreshold = res.getDimension(R.dimen.gestures_assistant_drag_threshold);
+ mDragDistThreshold = res.getDimension(R.dimen.gestures_assistant_drag_threshold);
+ mFlingDistThreshold = res.getDimension(R.dimen.gestures_assistant_fling_threshold);
mTimeThreshold = res.getInteger(R.integer.assistant_gesture_min_time_threshold);
mAngleThreshold = res.getInteger(R.integer.assistant_gesture_corner_deg_threshold);
@@ -117,8 +120,6 @@ public class AssistantTouchConsumer extends DelegateInputConsumer {
@Override
public void onMotionEvent(MotionEvent ev) {
// TODO add logging
- mGestureDetector.onTouchEvent(ev);
-
switch (ev.getActionMasked()) {
case ACTION_DOWN: {
mActivePointerId = ev.getPointerId(0);
@@ -213,6 +214,8 @@ public class AssistantTouchConsumer extends DelegateInputConsumer {
break;
}
+ mGestureDetector.onTouchEvent(ev);
+
if (mState != STATE_ACTIVE) {
mDelegate.onMotionEvent(ev);
}
@@ -220,9 +223,9 @@ public class AssistantTouchConsumer extends DelegateInputConsumer {
private void updateAssistantProgress() {
if (!mLaunchedAssistant) {
- mLastProgress = Math.min(mDistance * 1f / mDistThreshold, 1) * mTimeFraction;
+ mLastProgress = Math.min(mDistance * 1f / mDragDistThreshold, 1) * mTimeFraction;
try {
- if (mDistance >= mDistThreshold && mTimeFraction >= 1) {
+ if (mDistance >= mDragDistThreshold && mTimeFraction >= 1) {
mSysUiProxy.onAssistantGestureCompletion(0);
startAssistantInternal(SWIPE);
@@ -271,7 +274,9 @@ public class AssistantTouchConsumer extends DelegateInputConsumer {
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
if (isValidAssistantGestureAngle(velocityX, -velocityY)
- && !mLaunchedAssistant && mState != STATE_DELEGATE_ACTIVE) {
+ && mDistance >= mFlingDistThreshold
+ && !mLaunchedAssistant
+ && mState != STATE_DELEGATE_ACTIVE) {
mLastProgress = 1;
try {
mSysUiProxy.onAssistantGestureCompletion(
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java
index 1069bed59..1aa5365fd 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java
@@ -29,6 +29,7 @@ import android.view.ViewGroup;
import androidx.annotation.Nullable;
+import com.android.launcher3.BubbleTextView;
import com.android.launcher3.CellLayout;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
@@ -40,7 +41,9 @@ import com.android.launcher3.Workspace;
import com.android.launcher3.anim.AnimatorSetBuilder;
import com.android.launcher3.anim.PropertySetter;
import com.android.launcher3.anim.SpringObjectAnimator;
+import com.android.launcher3.folder.FolderIcon;
import com.android.launcher3.graphics.OverviewScrim;
+import com.android.launcher3.views.IconLabelDotView;
import java.util.ArrayList;
import java.util.List;
@@ -62,7 +65,9 @@ public class StaggeredWorkspaceAnim {
private final float mVelocity;
private final float mSpringTransY;
- private final View mViewToIgnore;
+
+ // The original view of the {@link FloatingIconView}.
+ private final View mOriginalView;
private final List<Animator> mAnimators = new ArrayList<>();
@@ -72,9 +77,7 @@ public class StaggeredWorkspaceAnim {
public StaggeredWorkspaceAnim(Launcher launcher, @Nullable View floatingViewOriginalView,
float velocity) {
mVelocity = velocity;
- // We ignore this view since it's visibility and position is controlled by
- // the FloatingIconView.
- mViewToIgnore = floatingViewOriginalView;
+ mOriginalView = floatingViewOriginalView;
// Scale the translationY based on the initial velocity to better sync the workspace items
// with the floating view.
@@ -86,16 +89,21 @@ public class StaggeredWorkspaceAnim {
Workspace workspace = launcher.getWorkspace();
CellLayout cellLayout = (CellLayout) workspace.getChildAt(workspace.getCurrentPage());
ShortcutAndWidgetContainer currentPage = cellLayout.getShortcutsAndWidgets();
+ ViewGroup hotseat = launcher.getHotseat();
boolean workspaceClipChildren = workspace.getClipChildren();
boolean workspaceClipToPadding = workspace.getClipToPadding();
boolean cellLayoutClipChildren = cellLayout.getClipChildren();
boolean cellLayoutClipToPadding = cellLayout.getClipToPadding();
+ boolean hotseatClipChildren = hotseat.getClipChildren();
+ boolean hotseatClipToPadding = hotseat.getClipToPadding();
workspace.setClipChildren(false);
workspace.setClipToPadding(false);
cellLayout.setClipChildren(false);
cellLayout.setClipToPadding(false);
+ hotseat.setClipChildren(false);
+ hotseat.setClipToPadding(false);
// Hotseat and QSB takes up two additional rows.
int totalRows = grid.inv.numRows + (grid.isVerticalBarLayout() ? 0 : 2);
@@ -108,16 +116,18 @@ public class StaggeredWorkspaceAnim {
}
// Set up springs for the hotseat and qsb.
+ ViewGroup hotseatChild = (ViewGroup) hotseat.getChildAt(0);
if (grid.isVerticalBarLayout()) {
- ViewGroup hotseat = (ViewGroup) launcher.getHotseat().getChildAt(0);
- for (int i = hotseat.getChildCount() - 1; i >= 0; i--) {
- View child = hotseat.getChildAt(i);
+ for (int i = hotseatChild.getChildCount() - 1; i >= 0; i--) {
+ View child = hotseatChild.getChildAt(i);
CellLayout.LayoutParams lp = ((CellLayout.LayoutParams) child.getLayoutParams());
addStaggeredAnimationForView(child, lp.cellY + 1, totalRows);
}
} else {
- View hotseat = launcher.getHotseat().getChildAt(0);
- addStaggeredAnimationForView(hotseat, grid.inv.numRows + 1, totalRows);
+ for (int i = hotseatChild.getChildCount() - 1; i >= 0; i--) {
+ View child = hotseatChild.getChildAt(i);
+ addStaggeredAnimationForView(child, grid.inv.numRows + 1, totalRows);
+ }
View qsb = launcher.findViewById(R.id.search_container_all_apps);
addStaggeredAnimationForView(qsb, grid.inv.numRows + 2, totalRows);
@@ -140,6 +150,8 @@ public class StaggeredWorkspaceAnim {
workspace.setClipToPadding(workspaceClipToPadding);
cellLayout.setClipChildren(cellLayoutClipChildren);
cellLayout.setClipToPadding(cellLayoutClipToPadding);
+ hotseat.setClipChildren(hotseatClipChildren);
+ hotseat.setClipToPadding(hotseatClipToPadding);
}
};
@@ -180,16 +192,35 @@ public class StaggeredWorkspaceAnim {
springTransY.setStartDelay(startDelay);
mAnimators.add(springTransY);
- if (v == mViewToIgnore) {
- return;
+ ObjectAnimator alpha = getAlphaAnimator(v, startDelay);
+ if (v == mOriginalView) {
+ // For IconLabelDotViews, we just want the label to fade in.
+ // Icon, badge, and dots will animate in separately (controlled via FloatingIconView)
+ if (v instanceof IconLabelDotView) {
+ alpha.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ IconLabelDotView view = (IconLabelDotView) v;
+ view.setIconVisible(false);
+ view.setForceHideDot(true);
+ }
+ });
+ } else {
+ return;
+ }
}
v.setAlpha(0);
+ mAnimators.add(alpha);
+ }
+
+ private ObjectAnimator getAlphaAnimator(View v, long startDelay) {
ObjectAnimator alpha = ObjectAnimator.ofFloat(v, View.ALPHA, 0f, 1f);
alpha.setInterpolator(LINEAR);
alpha.setDuration(ALPHA_DURATION_MS);
alpha.setStartDelay(startDelay);
- mAnimators.add(alpha);
+ return alpha;
+
}
private void addScrimAnimationForState(Launcher launcher, LauncherState state, long duration) {
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index b0968f94c..78424ca51 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -69,6 +69,7 @@
<!-- Distance from the vertical edges of the screen in which assist gestures are recognized -->
<dimen name="gestures_assistant_width">48dp</dimen>
<dimen name="gestures_assistant_drag_threshold">55dp</dimen>
+ <dimen name="gestures_assistant_fling_threshold">55dp</dimen>
<!-- Distance to move elements when swiping up to go home from launcher -->
<dimen name="home_pullback_distance">28dp</dimen>
diff --git a/quickstep/src/com/android/launcher3/uioverrides/TogglableFlag.java b/quickstep/src/com/android/launcher3/uioverrides/TogglableFlag.java
index e42508814..853a1c6ac 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/TogglableFlag.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/TogglableFlag.java
@@ -16,17 +16,34 @@
package com.android.launcher3.uioverrides;
+import android.content.Context;
import android.provider.DeviceConfig;
import com.android.launcher3.config.BaseFlags.BaseTogglableFlag;
public class TogglableFlag extends BaseTogglableFlag {
+ public static final String NAMESPACE_LAUNCHER = "launcher";
+ public static final String TAG = "TogglableFlag";
public TogglableFlag(String key, boolean defaultValue, String description) {
super(key, defaultValue, description);
}
@Override
- public boolean getInitialValue(boolean value) {
- return DeviceConfig.getBoolean("launcher", getKey(), value);
+ public boolean getOverridenDefaultValue(boolean value) {
+ return DeviceConfig.getBoolean(NAMESPACE_LAUNCHER, getKey(), value);
+ }
+
+ @Override
+ public void addChangeListener(Context context, Runnable r) {
+ DeviceConfig.addOnPropertiesChangedListener(
+ NAMESPACE_LAUNCHER,
+ context.getMainExecutor(),
+ (properties) -> {
+ if (!NAMESPACE_LAUNCHER.equals(properties.getNamespace())) {
+ return;
+ }
+ initialize(context);
+ r.run();
+ });
}
}
diff --git a/quickstep/src/com/android/quickstep/views/ShelfScrimView.java b/quickstep/src/com/android/quickstep/views/ShelfScrimView.java
index 3747f9a8b..dc6b56eec 100644
--- a/quickstep/src/com/android/quickstep/views/ShelfScrimView.java
+++ b/quickstep/src/com/android/quickstep/views/ShelfScrimView.java
@@ -156,12 +156,14 @@ public class ShelfScrimView extends ScrimView implements NavigationModeChangeLis
mDragHandleProgress = 1;
mMidAlpha = 0;
} else {
- mMidAlpha = Themes.getAttrInteger(getContext(), R.attr.allAppsInterimScrimAlpha);
+ Context context = getContext();
+ mMidAlpha = Themes.getAttrInteger(context, R.attr.allAppsInterimScrimAlpha);
mMidProgress = OVERVIEW.getVerticalProgress(mLauncher);
Rect hotseatPadding = dp.getHotseatLayoutPadding();
int hotseatSize = dp.hotseatBarSizePx + dp.getInsets().bottom
- hotseatPadding.bottom - hotseatPadding.top;
- float dragHandleTop = Math.min(hotseatSize, OverviewState.getDefaultSwipeHeight(dp));
+ float dragHandleTop =
+ Math.min(hotseatSize, OverviewState.getDefaultSwipeHeight(context, dp));
mDragHandleProgress = 1 - (dragHandleTop / mShiftRange);
}
mTopOffset = dp.getInsets().top - mShelfOffset;
diff --git a/quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java b/quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java
index ec3d49afa..a7c33a954 100644
--- a/quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java
+++ b/quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java
@@ -69,10 +69,9 @@ public class DigitalWellBeingToastTest extends AbstractQuickStepTest {
private DigitalWellBeingToast getToast() {
executeOnLauncher(launcher -> launcher.getStateManager().goToState(OVERVIEW));
waitForState("Launcher internal state didn't switch to Overview", OVERVIEW);
- waitForLauncherCondition("No latest task", launcher -> getLatestTask(launcher) != null);
+ final TaskView task = getOnceNotNull("No latest task", launcher -> getLatestTask(launcher));
return getFromLauncher(launcher -> {
- final TaskView task = getLatestTask(launcher);
assertTrue("Latest task is not Calculator",
CALCULATOR_PACKAGE.equals(task.getTask().getTopComponent().getPackageName()));
return task.getDigitalWellBeingToast();
diff --git a/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java b/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java
index edd5011f2..e29552713 100644
--- a/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java
+++ b/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java
@@ -118,7 +118,6 @@ public class NavigationModeSwitchRule implements TestRule {
assertTrue("Couldn't set overlay",
setActiveOverlay(prevOverlayPkg, originalMode));
}
- mLauncher.disableDebugTracing();
}
private void evaluateWithThreeButtons() throws Throwable {
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
index be8506d83..885fdbf42 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
@@ -97,7 +97,6 @@ public class TaplTestsQuickstep extends AbstractQuickStepTest {
@Test
@PortraitLandscape
public void testOverview() throws Exception {
- mLauncher.enableDebugTracing();
startTestApps();
Overview overview = mLauncher.pressHome().switchToOverview();
assertTrue("Launcher internal state didn't switch to Overview",
@@ -177,7 +176,6 @@ public class TaplTestsQuickstep extends AbstractQuickStepTest {
executeOnLauncher(
launcher -> assertEquals("Still have tasks after dismissing all",
0, getTaskCount(launcher)));
- mLauncher.disableDebugTracing();
}
private int getCurrentOverviewPage(Launcher launcher) {
diff --git a/src/com/android/launcher3/BaseRecyclerView.java b/src/com/android/launcher3/BaseRecyclerView.java
index c84be4dac..864fa6e8a 100644
--- a/src/com/android/launcher3/BaseRecyclerView.java
+++ b/src/com/android/launcher3/BaseRecyclerView.java
@@ -22,6 +22,7 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
+import com.android.launcher3.compat.AccessibilityManagerCompat;
import com.android.launcher3.views.RecyclerViewFastScroller;
import androidx.recyclerview.widget.RecyclerView;
@@ -171,4 +172,13 @@ public abstract class BaseRecyclerView extends RecyclerView {
* <p>Override in each subclass of this base class.
*/
public void onFastScrollCompleted() {}
+
+ @Override
+ public void onScrollStateChanged(int state) {
+ super.onScrollStateChanged(state);
+
+ if (state == SCROLL_STATE_IDLE) {
+ AccessibilityManagerCompat.sendScrollFinishedEventToTest(getContext());
+ }
+ }
} \ No newline at end of file
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 22c69f59a..b1132494a 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -32,7 +32,6 @@ import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.text.TextUtils.TruncateAt;
import android.util.AttributeSet;
-import android.util.Log;
import android.util.Property;
import android.util.TypedValue;
import android.view.KeyEvent;
@@ -54,8 +53,8 @@ import com.android.launcher3.icons.DotRenderer;
import com.android.launcher3.icons.IconCache.IconLoadRequest;
import com.android.launcher3.icons.IconCache.ItemInfoUpdateReceiver;
import com.android.launcher3.model.PackageItemInfo;
-import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.views.ActivityContext;
+import com.android.launcher3.views.IconLabelDotView;
import java.text.NumberFormat;
@@ -64,7 +63,8 @@ import java.text.NumberFormat;
* because we want to make the bubble taller than the text and TextView's clip is
* too aggressive.
*/
-public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, OnResumeCallback {
+public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, OnResumeCallback,
+ IconLabelDotView {
private static final int DISPLAY_WORKSPACE = 0;
private static final int DISPLAY_ALL_APPS = 1;
@@ -413,7 +413,8 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
}
}
- public void forceHideDot(boolean forceHideDot) {
+ @Override
+ public void setForceHideDot(boolean forceHideDot) {
if (mForceHideDot == forceHideDot) {
return;
}
@@ -602,6 +603,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
}
}
+ @Override
public void setIconVisible(boolean visible) {
mIsIconVisible = visible;
Drawable icon = visible ? mIcon : new ColorDrawable(Color.TRANSPARENT);
diff --git a/src/com/android/launcher3/FastBitmapDrawable.java b/src/com/android/launcher3/FastBitmapDrawable.java
index 7ab88a008..a90025e97 100644
--- a/src/com/android/launcher3/FastBitmapDrawable.java
+++ b/src/com/android/launcher3/FastBitmapDrawable.java
@@ -142,8 +142,11 @@ public class FastBitmapDrawable extends Drawable {
@Override
public void setAlpha(int alpha) {
- mAlpha = alpha;
- mPaint.setAlpha(alpha);
+ if (mAlpha != alpha) {
+ mAlpha = alpha;
+ mPaint.setAlpha(alpha);
+ invalidateSelf();
+ }
}
@Override
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index d79230f8b..257f0dfcf 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -157,6 +157,7 @@ import java.util.List;
import java.util.function.Predicate;
import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
/**
* Default launcher application.
@@ -209,9 +210,9 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
private static final int ON_ACTIVITY_RESULT_ANIMATION_DELAY = 500;
// How long to wait before the new-shortcut animation automatically pans the workspace
- private static final int NEW_APPS_PAGE_MOVE_DELAY = 500;
+ @VisibleForTesting public static final int NEW_APPS_PAGE_MOVE_DELAY = 500;
private static final int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5;
- @Thunk static final int NEW_APPS_ANIMATION_DELAY = 500;
+ @Thunk @VisibleForTesting public static final int NEW_APPS_ANIMATION_DELAY = 500;
private static final int APPS_VIEW_ALPHA_CHANNEL_INDEX = 1;
private static final int SCRIM_VIEW_ALPHA_CHANNEL_INDEX = 0;
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 2a801d6ef..b4a2216c5 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -94,6 +94,7 @@ public class LauncherAppState {
if (FeatureFlags.IS_DOGFOOD_BUILD) {
filter.addAction(ACTION_FORCE_ROLOAD);
}
+ FeatureFlags.APP_SEARCH_IMPROVEMENTS.addChangeListener(context, mModel::forceReload);
mContext.registerReceiver(mModel, filter);
UserManagerCompat.getInstance(mContext).enableAndResetCache();
diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
index 139930292..f82e380f8 100644
--- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
@@ -34,6 +34,7 @@ import com.android.launcher3.ItemInfo;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
+import com.android.launcher3.allapps.AllAppsGridAdapter.AppsGridLayoutManager;
import com.android.launcher3.compat.AccessibilityManagerCompat;
import com.android.launcher3.logging.StatsLogUtils.LogContainerProvider;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
@@ -113,6 +114,13 @@ public class AllAppsRecyclerView extends BaseRecyclerView implements LogContaine
if (mScrollbar != null) {
mScrollbar.reattachThumbToScroll();
}
+ if (getLayoutManager() instanceof AppsGridLayoutManager) {
+ AppsGridLayoutManager layoutManager = (AppsGridLayoutManager) getLayoutManager();
+ if (layoutManager.findFirstCompletelyVisibleItemPosition() == 0) {
+ // We are at the top, so don't scrollToPosition (would cause unnecessary relayout).
+ return;
+ }
+ }
scrollToPosition(0);
}
@@ -419,13 +427,4 @@ public class AllAppsRecyclerView extends BaseRecyclerView implements LogContaine
public boolean hasOverlappingRendering() {
return false;
}
-
- @Override
- public void onScrollStateChanged(int state) {
- super.onScrollStateChanged(state);
-
- if (state == SCROLL_STATE_IDLE) {
- AccessibilityManagerCompat.sendScrollFinishedEventToTest(getContext());
- }
- }
}
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index dfddc61d3..3836c9fdb 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -1,7 +1,5 @@
package com.android.launcher3.allapps;
-import static android.view.View.ALPHA;
-
import static com.android.launcher3.LauncherState.ALL_APPS_CONTENT;
import static com.android.launcher3.LauncherState.ALL_APPS_HEADER_EXTRA;
import static com.android.launcher3.LauncherState.BACKGROUND_APP;
@@ -12,7 +10,6 @@ import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_ALL_APPS_FADE;
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_ALL_APPS_HEADER_FADE;
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_SCALE;
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_VERTICAL_PROGRESS;
-import static com.android.launcher3.anim.AnimatorSetBuilder.FLAG_DONT_UPDATE_ALL_APPS_VISIBILITY;
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.anim.PropertySetter.NO_ANIM_PROPERTY_SETTER;
@@ -21,7 +18,6 @@ import static com.android.launcher3.util.SystemUiController.UI_STATE_ALL_APPS;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.util.FloatProperty;
-import android.view.View;
import android.view.animation.Interpolator;
import com.android.launcher3.DeviceProfile;
@@ -215,12 +211,7 @@ public class AllAppsTransitionController implements StateHandler, OnDeviceProfil
Interpolator allAppsFade = builder.getInterpolator(ANIM_ALL_APPS_FADE, LINEAR);
Interpolator headerFade = builder.getInterpolator(ANIM_ALL_APPS_HEADER_FADE, allAppsFade);
- View allAppsContent = mAppsView.getContentView();
- if (!hasAllAppsContent && builder.hasFlag(FLAG_DONT_UPDATE_ALL_APPS_VISIBILITY)) {
- setter.setFloat(allAppsContent, ALPHA, 0, allAppsFade);
- } else {
- setter.setViewAlpha(allAppsContent, hasAllAppsContent ? 1 : 0, allAppsFade);
- }
+ setter.setViewAlpha(mAppsView.getContentView(), hasAllAppsContent ? 1 : 0, allAppsFade);
setter.setViewAlpha(mAppsView.getScrollBar(), hasAllAppsContent ? 1 : 0, allAppsFade);
mAppsView.getFloatingHeaderView().setContentVisibility(hasHeaderExtra, hasAllAppsContent,
setter, headerFade, allAppsFade);
diff --git a/src/com/android/launcher3/anim/AnimatorSetBuilder.java b/src/com/android/launcher3/anim/AnimatorSetBuilder.java
index 07e755345..cd30dea9c 100644
--- a/src/com/android/launcher3/anim/AnimatorSetBuilder.java
+++ b/src/com/android/launcher3/anim/AnimatorSetBuilder.java
@@ -43,7 +43,6 @@ public class AnimatorSetBuilder {
public static final int ANIM_ALL_APPS_HEADER_FADE = 12; // e.g. predictions
public static final int FLAG_DONT_ANIMATE_OVERVIEW = 1 << 0;
- public static final int FLAG_DONT_UPDATE_ALL_APPS_VISIBILITY = 1 << 1;
protected final ArrayList<Animator> mAnims = new ArrayList<>();
diff --git a/src/com/android/launcher3/compat/PackageInstallerCompatVL.java b/src/com/android/launcher3/compat/PackageInstallerCompatVL.java
index bca66f7db..48ac05b71 100644
--- a/src/com/android/launcher3/compat/PackageInstallerCompatVL.java
+++ b/src/com/android/launcher3/compat/PackageInstallerCompatVL.java
@@ -140,14 +140,15 @@ public class PackageInstallerCompatVL extends PackageInstallerCompat {
* Add a promise app icon to the workspace iff:
* - The settings for it are enabled
* - The user installed the app
- * - There is a provided app icon (For apps with no launching activity, no icon is provided).
+ * - There is an app icon and label (For apps with no launching activity, no icon is provided).
*/
private void tryQueuePromiseAppIcon(SessionInfo sessionInfo) {
if (Utilities.ATLEAST_OREO && FeatureFlags.PROMISE_APPS_NEW_INSTALLS.get()
&& SessionCommitReceiver.isEnabled(mAppContext)
- && sessionInfo != null
+ && verify(sessionInfo) != null
&& sessionInfo.getInstallReason() == PackageManager.INSTALL_REASON_USER
&& sessionInfo.getAppIcon() != null
+ && !TextUtils.isEmpty(sessionInfo.getAppLabel())
&& !mPromiseIconIds.contains(sessionInfo.getSessionId())) {
SessionCommitReceiver.queuePromiseAppIconAddition(mAppContext, sessionInfo);
mPromiseIconIds.add(sessionInfo.getSessionId());
diff --git a/src/com/android/launcher3/config/BaseFlags.java b/src/com/android/launcher3/config/BaseFlags.java
index ea6261a6a..025087b9d 100644
--- a/src/com/android/launcher3/config/BaseFlags.java
+++ b/src/com/android/launcher3/config/BaseFlags.java
@@ -143,6 +143,8 @@ public abstract class BaseFlags {
public static abstract class BaseTogglableFlag {
private final String key;
+ // should be value that is hardcoded in client side.
+ // Comparatively, getDefaultValue() can be overridden.
private final boolean defaultValue;
private final String description;
private boolean currentValue;
@@ -152,8 +154,9 @@ public abstract class BaseFlags {
boolean defaultValue,
String description) {
this.key = checkNotNull(key);
- this.currentValue = this.defaultValue = getInitialValue(defaultValue);
+ this.currentValue = this.defaultValue = defaultValue;
this.description = checkNotNull(description);
+
synchronized (sLock) {
sFlags.add((TogglableFlag)this);
}
@@ -169,16 +172,18 @@ public abstract class BaseFlags {
return key;
}
- void initialize(Context context) {
- currentValue = getFromStorage(context, defaultValue);
+ protected void initialize(Context context) {
+ currentValue = getFromStorage(context, getDefaultValue());
}
- protected abstract boolean getInitialValue(boolean value);
+ protected abstract boolean getOverridenDefaultValue(boolean value);
+
+ protected abstract void addChangeListener(Context context, Runnable r);
public void updateStorage(Context context, boolean value) {
SharedPreferences.Editor editor = context.getSharedPreferences(FLAGS_PREF_NAME,
Context.MODE_PRIVATE).edit();
- if (value == defaultValue) {
+ if (value == getDefaultValue()) {
editor.remove(key).apply();
} else {
editor.putBoolean(key, value).apply();
@@ -187,11 +192,11 @@ public abstract class BaseFlags {
boolean getFromStorage(Context context, boolean defaultValue) {
return context.getSharedPreferences(FLAGS_PREF_NAME, Context.MODE_PRIVATE)
- .getBoolean(key, defaultValue);
+ .getBoolean(key, getDefaultValue());
}
boolean getDefaultValue() {
- return defaultValue;
+ return getOverridenDefaultValue(defaultValue);
}
/** Returns the value of the flag at process start, including any overrides present. */
@@ -208,6 +213,8 @@ public abstract class BaseFlags {
return "TogglableFlag{"
+ "key=" + key + ", "
+ "defaultValue=" + defaultValue + ", "
+ + "overriddenDefaultValue=" + getOverridenDefaultValue(defaultValue) + ", "
+ + "currentValue=" + currentValue + ", "
+ "description=" + description
+ "}";
}
@@ -220,7 +227,7 @@ public abstract class BaseFlags {
if (o instanceof TogglableFlag) {
BaseTogglableFlag that = (BaseTogglableFlag) o;
return (this.key.equals(that.getKey()))
- && (this.defaultValue == that.getDefaultValue())
+ && (this.getDefaultValue() == that.getDefaultValue())
&& (this.description.equals(that.getDescription()));
}
return false;
@@ -232,7 +239,7 @@ public abstract class BaseFlags {
h$ *= 1000003;
h$ ^= key.hashCode();
h$ *= 1000003;
- h$ ^= defaultValue ? 1231 : 1237;
+ h$ ^= getDefaultValue() ? 1231 : 1237;
h$ *= 1000003;
h$ ^= description.hashCode();
return h$;
diff --git a/src/com/android/launcher3/dragndrop/DragDriver.java b/src/com/android/launcher3/dragndrop/DragDriver.java
index bd2a03b6c..01e0f923c 100644
--- a/src/com/android/launcher3/dragndrop/DragDriver.java
+++ b/src/com/android/launcher3/dragndrop/DragDriver.java
@@ -61,6 +61,9 @@ public abstract class DragDriver {
mEventListener.onDriverDragEnd(ev.getX(), ev.getY());
break;
case MotionEvent.ACTION_CANCEL:
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.NO_DRAG_TO_WORKSPACE, "DragDriver.ACTION_CANCEL");
+ }
mEventListener.onDriverDragCancel();
break;
}
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index 2ef6d707e..f22b53338 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -516,7 +516,7 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
- mFolderIcon.setBackgroundVisible(false);
+ mFolderIcon.setIconVisible(false);
mFolderIcon.drawLeaveBehindIfExists();
}
@Override
@@ -646,7 +646,7 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
clearFocus();
if (mFolderIcon != null) {
mFolderIcon.setVisibility(View.VISIBLE);
- mFolderIcon.setBackgroundVisible(true);
+ mFolderIcon.setIconVisible(true);
mFolderIcon.mFolderName.setTextVisibility(true);
if (wasAnimated) {
mFolderIcon.animateBgShadowAndStroke();
diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java
index 250169cdb..0e2d4673e 100644
--- a/src/com/android/launcher3/folder/FolderIcon.java
+++ b/src/com/android/launcher3/folder/FolderIcon.java
@@ -65,6 +65,7 @@ import com.android.launcher3.dragndrop.DragView;
import com.android.launcher3.icons.DotRenderer;
import com.android.launcher3.touch.ItemClickHandler;
import com.android.launcher3.util.Thunk;
+import com.android.launcher3.views.IconLabelDotView;
import com.android.launcher3.widget.PendingAddShortcutInfo;
import java.util.ArrayList;
@@ -73,7 +74,7 @@ import java.util.List;
/**
* An icon that can appear on in the workspace representing an {@link Folder}.
*/
-public class FolderIcon extends FrameLayout implements FolderListener {
+public class FolderIcon extends FrameLayout implements FolderListener, IconLabelDotView {
@Thunk Launcher mLauncher;
@Thunk Folder mFolder;
@@ -107,6 +108,7 @@ public class FolderIcon extends FrameLayout implements FolderListener {
private Alarm mOpenAlarm = new Alarm();
+ private boolean mForceHideDot;
@ViewDebug.ExportedProperty(category = "launcher", deepExport = true)
private FolderDotInfo mDotInfo = new FolderDotInfo();
private DotRenderer mDotRenderer;
@@ -409,6 +411,20 @@ public class FolderIcon extends FrameLayout implements FolderListener {
return mPreviewLayoutRule;
}
+ @Override
+ public void setForceHideDot(boolean forceHideDot) {
+ if (mForceHideDot == forceHideDot) {
+ return;
+ }
+ mForceHideDot = forceHideDot;
+
+ if (forceHideDot) {
+ invalidate();
+ } else if (hasDot()) {
+ animateDotScale(0, 1);
+ }
+ }
+
/**
* Sets mDotScale to 1 or 0, animating if wasDotted or isDotted is false
* (the dot is being added or removed).
@@ -468,7 +484,8 @@ public class FolderIcon extends FrameLayout implements FolderListener {
mBackground.setInvalidateDelegate(this);
}
- public void setBackgroundVisible(boolean visible) {
+ @Override
+ public void setIconVisible(boolean visible) {
mBackgroundIsVisible = visible;
invalidate();
}
@@ -509,7 +526,7 @@ public class FolderIcon extends FrameLayout implements FolderListener {
}
public void drawDot(Canvas canvas) {
- if ((mDotInfo != null && mDotInfo.hasDot()) || mDotScale > 0) {
+ if (!mForceHideDot && ((mDotInfo != null && mDotInfo.hasDot()) || mDotScale > 0)) {
Rect iconBounds = mDotParams.iconBounds;
BubbleTextView.getIconBounds(this, iconBounds,
mLauncher.getWallpaperDeviceProfile().iconSizePx);
diff --git a/src/com/android/launcher3/icons/IconCache.java b/src/com/android/launcher3/icons/IconCache.java
index 55d58b9c0..abff237e8 100644
--- a/src/com/android/launcher3/icons/IconCache.java
+++ b/src/com/android/launcher3/icons/IconCache.java
@@ -42,6 +42,7 @@ import com.android.launcher3.Utilities;
import com.android.launcher3.WorkspaceItemInfo;
import com.android.launcher3.compat.LauncherAppsCompat;
import com.android.launcher3.compat.UserManagerCompat;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.icons.ComponentWithLabel.ComponentCachingLogic;
import com.android.launcher3.icons.cache.BaseIconCache;
import com.android.launcher3.icons.cache.CachingLogic;
@@ -237,7 +238,8 @@ public class IconCache extends BaseIconCache {
@Override
protected String getIconSystemState(String packageName) {
- return mIconProvider.getSystemStateForPackage(mSystemState, packageName);
+ return mIconProvider.getSystemStateForPackage(mSystemState, packageName)
+ + ",flags_asi:" + FeatureFlags.APP_SEARCH_IMPROVEMENTS.get();
}
public static abstract class IconLoadRequest extends HandlerRunnable {
diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
index baaad6573..15fb4cea6 100644
--- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java
+++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
@@ -36,7 +36,6 @@ import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.util.AttributeSet;
-import android.util.Log;
import android.util.Pair;
import android.view.MotionEvent;
import android.view.View;
@@ -53,7 +52,6 @@ import com.android.launcher3.ItemInfoWithIcon;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherModel;
import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
import com.android.launcher3.accessibility.ShortcutMenuAccessibilityDelegate;
import com.android.launcher3.dot.DotInfo;
@@ -65,10 +63,8 @@ import com.android.launcher3.notification.NotificationInfo;
import com.android.launcher3.notification.NotificationItemView;
import com.android.launcher3.notification.NotificationKeyData;
import com.android.launcher3.popup.PopupDataProvider.PopupDataChangeListener;
-import com.android.launcher3.shortcuts.DeepShortcutManager;
import com.android.launcher3.shortcuts.DeepShortcutView;
import com.android.launcher3.shortcuts.ShortcutDragPreviewProvider;
-import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.touch.ItemClickHandler;
import com.android.launcher3.touch.ItemLongClickListener;
import com.android.launcher3.util.PackageUserKey;
@@ -301,7 +297,7 @@ public class PopupContainerWithArrow extends ArrowPopup implements DragSource,
}
mLauncher.getDragController().addDragListener(this);
- mOriginalIcon.forceHideDot(true);
+ mOriginalIcon.setForceHideDot(true);
// All views are added. Animate layout from now on.
setLayoutTransition(new LayoutTransition());
@@ -564,14 +560,14 @@ public class PopupContainerWithArrow extends ArrowPopup implements DragSource,
protected void onCreateCloseAnimation(AnimatorSet anim) {
// Animate original icon's text back in.
anim.play(mOriginalIcon.createTextAlphaAnimator(true /* fadeIn */));
- mOriginalIcon.forceHideDot(false);
+ mOriginalIcon.setForceHideDot(false);
}
@Override
protected void closeComplete() {
super.closeComplete();
mOriginalIcon.setTextVisibility(mOriginalIcon.shouldTextBeVisible());
- mOriginalIcon.forceHideDot(false);
+ mOriginalIcon.setForceHideDot(false);
}
@Override
diff --git a/src/com/android/launcher3/testing/TestInformationHandler.java b/src/com/android/launcher3/testing/TestInformationHandler.java
index 4fd0f884d..243ff6f96 100644
--- a/src/com/android/launcher3/testing/TestInformationHandler.java
+++ b/src/com/android/launcher3/testing/TestInformationHandler.java
@@ -17,6 +17,7 @@ package com.android.launcher3.testing;
import android.content.Context;
import android.os.Bundle;
+import android.os.Debug;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile;
@@ -113,13 +114,13 @@ public class TestInformationHandler implements ResourceBasedOverride {
break;
}
- case TestProtocol.REQUEST_ALLOCATED_MEMORY: {
- final Runtime runtime = Runtime.getRuntime();
- response.putLong(TestProtocol.TEST_INFO_RESPONSE_FIELD,
- runtime.totalMemory() - runtime.freeMemory());
+ case TestProtocol.REQUEST_TOTAL_PSS_KB: {
+ Debug.MemoryInfo mem = new Debug.MemoryInfo();
+ Debug.getMemoryInfo(mem);
+ response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, mem.getTotalPss());
break;
}
}
return response;
}
-}
+} \ No newline at end of file
diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java
index d569d4007..60a59ddfa 100644
--- a/src/com/android/launcher3/testing/TestProtocol.java
+++ b/src/com/android/launcher3/testing/TestProtocol.java
@@ -73,7 +73,7 @@ public final class TestProtocol {
public static final String REQUEST_APP_LIST_FREEZE_FLAGS = "app-list-freeze-flags";
public static final String REQUEST_OVERVIEW_LEFT_GESTURE_MARGIN = "overview-left-margin";
public static final String REQUEST_OVERVIEW_RIGHT_GESTURE_MARGIN = "overview-right-margin";
- public static final String REQUEST_ALLOCATED_MEMORY = "allocated-memory";
+ public static final String REQUEST_TOTAL_PSS_KB = "total_pss";
public static boolean sDebugTracing = false;
public static final String REQUEST_ENABLE_DEBUG_TRACING = "enable-debug-tracing";
diff --git a/src/com/android/launcher3/views/AbstractSlideInView.java b/src/com/android/launcher3/views/AbstractSlideInView.java
index f948beb8d..a4518bae3 100644
--- a/src/com/android/launcher3/views/AbstractSlideInView.java
+++ b/src/com/android/launcher3/views/AbstractSlideInView.java
@@ -153,15 +153,15 @@ public abstract class AbstractSlideInView extends AbstractFloatingView
}
protected void handleClose(boolean animate, long defaultDuration) {
- if (mIsOpen && !animate) {
+ if (!mIsOpen) {
+ return;
+ }
+ if (!animate) {
mOpenCloseAnimator.cancel();
setTranslationShift(TRANSLATION_SHIFT_CLOSED);
onCloseComplete();
return;
}
- if (!mIsOpen) {
- return;
- }
mOpenCloseAnimator.setValues(
PropertyValuesHolder.ofFloat(TRANSLATION_SHIFT, TRANSLATION_SHIFT_CLOSED));
mOpenCloseAnimator.addListener(new AnimatorListenerAdapter() {
diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java
index 799762d8f..c08b65931 100644
--- a/src/com/android/launcher3/views/BaseDragLayer.java
+++ b/src/com/android/launcher3/views/BaseDragLayer.java
@@ -29,6 +29,7 @@ import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Build;
import android.util.AttributeSet;
+import android.util.Log;
import android.util.Property;
import android.view.MotionEvent;
import android.view.View;
@@ -41,6 +42,7 @@ import android.widget.FrameLayout;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.InsettableFrameLayout;
import com.android.launcher3.Utilities;
+import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.util.MultiValueAlpha;
import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
import com.android.launcher3.util.TouchController;
@@ -261,6 +263,10 @@ public abstract class BaseDragLayer<T extends Context & ActivityContext>
}
case ACTION_CANCEL:
case ACTION_UP:
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.NO_DRAG_TO_WORKSPACE,
+ "BaseDragLayer.ACTION_UP/CANCEL " + ev);
+ }
mTouchDispatchState &= ~TOUCH_DISPATCHING_GESTURE;
mTouchDispatchState &= ~TOUCH_DISPATCHING_VIEW;
break;
diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java
index e09a9e8bf..f728a6776 100644
--- a/src/com/android/launcher3/views/FloatingIconView.java
+++ b/src/com/android/launcher3/views/FloatingIconView.java
@@ -18,7 +18,6 @@ package com.android.launcher3.views;
import static com.android.launcher3.LauncherAnimUtils.DRAWABLE_ALPHA;
import static com.android.launcher3.Utilities.getBadge;
import static com.android.launcher3.Utilities.getFullDrawable;
-import static com.android.launcher3.Utilities.isRtl;
import static com.android.launcher3.Utilities.mapToRange;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.config.FeatureFlags.ADAPTIVE_ICON_WINDOW_ANIM;
@@ -564,11 +563,6 @@ public class FloatingIconView extends View implements
*/
private void checkIconResult(View originalView, boolean isOpening) {
CancellationSignal cancellationSignal = new CancellationSignal();
- if (!isOpening) {
- // Hide immediately since the floating view starts at a different location.
- originalView.setVisibility(INVISIBLE);
- cancellationSignal.setOnCancelListener(() -> originalView.setVisibility(VISIBLE));
- }
if (mIconLoadResult == null) {
Log.w(TAG, "No icon load result found in checkIconResult");
@@ -580,7 +574,7 @@ public class FloatingIconView extends View implements
setIcon(originalView, mIconLoadResult.drawable, mIconLoadResult.badge,
mIconLoadResult.iconOffset);
if (isOpening) {
- originalView.setVisibility(INVISIBLE);
+ hideOriginalView(originalView);
}
} else {
mIconLoadResult.onIconLoaded = () -> {
@@ -591,15 +585,26 @@ public class FloatingIconView extends View implements
setIcon(originalView, mIconLoadResult.drawable, mIconLoadResult.badge,
mIconLoadResult.iconOffset);
- // Delay swapping views until the icon is loaded to prevent a flash.
setVisibility(VISIBLE);
- originalView.setVisibility(INVISIBLE);
+ if (isOpening) {
+ // Delay swapping views until the icon is loaded to prevent a flash.
+ hideOriginalView(originalView);
+ }
};
mLoadIconSignal = cancellationSignal;
}
}
}
+ private void hideOriginalView(View originalView) {
+ if (originalView instanceof BubbleTextView) {
+ ((BubbleTextView) originalView).setIconVisible(false);
+ ((BubbleTextView) originalView).setForceHideDot(true);
+ } else {
+ originalView.setVisibility(INVISIBLE);
+ }
+ }
+
private void setBackgroundDrawableBounds(float scale) {
sTmpRect.set(mFinalDrawableBounds);
Utilities.scaleRectAboutCenter(sTmpRect, scale);
@@ -716,7 +721,7 @@ public class FloatingIconView extends View implements
*/
@UiThread
public static IconLoadResult fetchIcon(Launcher l, View v, ItemInfo info, boolean isOpening) {
- IconLoadResult result = new IconLoadResult();
+ IconLoadResult result = new IconLoadResult(info);
new Handler(LauncherModel.getWorkerLooper()).postAtFrontOfQueue(() -> {
RectF position = new RectF();
getLocationBoundsForView(l, v, isOpening, position);
@@ -745,10 +750,13 @@ public class FloatingIconView extends View implements
// Get the drawable on the background thread
boolean shouldLoadIcon = originalView.getTag() instanceof ItemInfo && hideOriginal;
- view.mIconLoadResult = sIconLoadResult;
- if (shouldLoadIcon && view.mIconLoadResult == null) {
- view.mIconLoadResult = fetchIcon(launcher, originalView,
- (ItemInfo) originalView.getTag(), isOpening);
+ if (shouldLoadIcon) {
+ if (sIconLoadResult != null && sIconLoadResult.itemInfo == originalView.getTag()) {
+ view.mIconLoadResult = sIconLoadResult;
+ } else {
+ view.mIconLoadResult = fetchIcon(launcher, originalView,
+ (ItemInfo) originalView.getTag(), isOpening);
+ }
}
sIconLoadResult = null;
@@ -776,7 +784,12 @@ public class FloatingIconView extends View implements
if (hideOriginal) {
if (isOpening) {
- originalView.setVisibility(VISIBLE);
+ if (originalView instanceof BubbleTextView) {
+ ((BubbleTextView) originalView).setIconVisible(true);
+ ((BubbleTextView) originalView).setForceHideDot(false);
+ } else {
+ originalView.setVisibility(VISIBLE);
+ }
view.finish(dragLayer);
} else {
view.mFadeAnimatorSet = view.createFadeAnimation(originalView, dragLayer);
@@ -804,38 +817,33 @@ public class FloatingIconView extends View implements
}
});
- if (mBadge != null && !(mOriginalIcon instanceof FolderIcon)) {
+ if (mBadge != null) {
ObjectAnimator badgeFade = ObjectAnimator.ofInt(mBadge, DRAWABLE_ALPHA, 255);
badgeFade.addUpdateListener(valueAnimator -> invalidate());
fade.play(badgeFade);
}
- if (originalView instanceof BubbleTextView) {
- BubbleTextView btv = (BubbleTextView) originalView;
- btv.forceHideDot(true);
+ if (originalView instanceof IconLabelDotView) {
+ IconLabelDotView view = (IconLabelDotView) originalView;
fade.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- btv.forceHideDot(false);
+ view.setIconVisible(true);
+ view.setForceHideDot(false);
}
});
}
- if (originalView instanceof FolderIcon) {
- FolderIcon folderIcon = (FolderIcon) originalView;
- folderIcon.setBackgroundVisible(false);
- folderIcon.getFolderName().setTextVisibility(false);
- fade.play(folderIcon.getFolderName().createTextAlphaAnimator(true));
+ if (originalView instanceof BubbleTextView) {
+ BubbleTextView btv = (BubbleTextView) originalView;
fade.addListener(new AnimatorListenerAdapter() {
@Override
- public void onAnimationEnd(Animator animation) {
- folderIcon.setBackgroundVisible(true);
- if (folderIcon.hasDot()) {
- folderIcon.animateDotScale(0, 1f);
- }
+ public void onAnimationStart(Animator animation) {
+ btv.setIconVisible(true);
}
});
- } else {
+ fade.play(ObjectAnimator.ofInt(btv.getIcon(), DRAWABLE_ALPHA, 0, 255));
+ } else if (!(originalView instanceof FolderIcon)) {
fade.play(ObjectAnimator.ofFloat(originalView, ALPHA, 0f, 1f));
}
@@ -890,10 +898,15 @@ public class FloatingIconView extends View implements
}
private static class IconLoadResult {
+ final ItemInfo itemInfo;
Drawable drawable;
Drawable badge;
int iconOffset;
Runnable onIconLoaded;
boolean isIconLoaded;
+
+ public IconLoadResult(ItemInfo itemInfo) {
+ this.itemInfo = itemInfo;
+ }
}
}
diff --git a/src/com/android/launcher3/views/IconLabelDotView.java b/src/com/android/launcher3/views/IconLabelDotView.java
new file mode 100644
index 000000000..057caafe7
--- /dev/null
+++ b/src/com/android/launcher3/views/IconLabelDotView.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2019 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.views;
+
+/**
+ * A view that has an icon, label, and notification dot.
+ */
+public interface IconLabelDotView {
+ void setIconVisible(boolean visible);
+ void setForceHideDot(boolean hide);
+}
diff --git a/src/com/android/launcher3/views/OptionsPopupView.java b/src/com/android/launcher3/views/OptionsPopupView.java
index 63f742768..465df448e 100644
--- a/src/com/android/launcher3/views/OptionsPopupView.java
+++ b/src/com/android/launcher3/views/OptionsPopupView.java
@@ -18,10 +18,8 @@ package com.android.launcher3.views;
import static com.android.launcher3.Utilities.EXTRA_WALLPAPER_FLAVOR;
import static com.android.launcher3.Utilities.EXTRA_WALLPAPER_OFFSET;
-import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
-import android.content.pm.ResolveInfo;
import android.graphics.Rect;
import android.graphics.RectF;
import android.text.TextUtils;
@@ -33,6 +31,9 @@ import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.widget.Toast;
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
@@ -46,7 +47,6 @@ import com.android.launcher3.widget.WidgetsFullSheet;
import java.util.ArrayList;
import java.util.List;
-import androidx.annotation.VisibleForTesting;
/**
* Popup shown on long pressing an empty space in launcher
@@ -169,16 +169,17 @@ public class OptionsPopupView extends ArrowPopup
}
public static boolean onWidgetsClicked(View view) {
- return openWidgets(Launcher.getLauncher(view.getContext()));
+ return openWidgets(Launcher.getLauncher(view.getContext())) != null;
}
- public static boolean openWidgets(Launcher launcher) {
+ /** Returns WidgetsFullSheet that was opened, or null if nothing was opened. */
+ @Nullable
+ public static WidgetsFullSheet openWidgets(Launcher launcher) {
if (launcher.getPackageManager().isSafeMode()) {
Toast.makeText(launcher, R.string.safemode_widget_error, Toast.LENGTH_SHORT).show();
- return false;
+ return null;
} else {
- WidgetsFullSheet.show(launcher, true /* animated */);
- return true;
+ return WidgetsFullSheet.show(launcher, true /* animated */);
}
}
diff --git a/src/com/android/launcher3/views/ScrimView.java b/src/com/android/launcher3/views/ScrimView.java
index c36011745..da1df3f89 100644
--- a/src/com/android/launcher3/views/ScrimView.java
+++ b/src/com/android/launcher3/views/ScrimView.java
@@ -18,14 +18,14 @@ package com.android.launcher3.views;
import static android.content.Context.ACCESSIBILITY_SERVICE;
import static android.view.MotionEvent.ACTION_DOWN;
+import static androidx.core.graphics.ColorUtils.compositeColors;
+
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.anim.Interpolators.ACCEL;
import static com.android.launcher3.anim.Interpolators.DEACCEL;
import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
-import static androidx.core.graphics.ColorUtils.compositeColors;
-
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.Keyframe;
@@ -47,6 +47,13 @@ import android.view.View;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.core.view.ViewCompat;
+import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
+import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat;
+import androidx.customview.widget.ExploreByTouchHelper;
+
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Insettable;
import com.android.launcher3.Launcher;
@@ -62,15 +69,10 @@ import com.android.launcher3.userevent.nano.LauncherLogProto.ControlType;
import com.android.launcher3.util.MultiValueAlpha;
import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
import com.android.launcher3.util.Themes;
+import com.android.launcher3.widget.WidgetsFullSheet;
import java.util.List;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.core.view.ViewCompat;
-import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
-import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat;
-import androidx.customview.widget.ExploreByTouchHelper;
/**
* Simple scrim which draws a flat color
@@ -325,7 +327,7 @@ public class ScrimView extends View implements Insettable, OnChangeListener,
if (enabled) {
stateManager.addStateListener(this);
- handleStateChangedComplete(mLauncher.getStateManager().getState());
+ handleStateChangedComplete(stateManager.getState());
} else {
setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
}
@@ -437,7 +439,24 @@ public class ScrimView extends View implements Insettable, OnChangeListener,
} else if (action == WALLPAPERS) {
return OptionsPopupView.startWallpaperPicker(ScrimView.this);
} else if (action == WIDGETS) {
- return OptionsPopupView.onWidgetsClicked(ScrimView.this);
+ int originalImportanceForAccessibility = getImportantForAccessibility();
+ setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
+ WidgetsFullSheet widgetsFullSheet = OptionsPopupView.openWidgets(mLauncher);
+ if (widgetsFullSheet == null) {
+ setImportantForAccessibility(originalImportanceForAccessibility);
+ return false;
+ }
+ widgetsFullSheet.addOnAttachStateChangeListener(new OnAttachStateChangeListener() {
+ @Override
+ public void onViewAttachedToWindow(View view) {}
+
+ @Override
+ public void onViewDetachedFromWindow(View view) {
+ setImportantForAccessibility(originalImportanceForAccessibility);
+ widgetsFullSheet.removeOnAttachStateChangeListener(this);
+ }
+ });
+ return true;
} else if (action == SETTINGS) {
return OptionsPopupView.startSettings(ScrimView.this);
}
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/TogglableFlag.java b/src_ui_overrides/com/android/launcher3/uioverrides/TogglableFlag.java
index e875a3c46..60f12d82a 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/TogglableFlag.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/TogglableFlag.java
@@ -16,6 +16,7 @@
package com.android.launcher3.uioverrides;
+import android.content.Context;
import com.android.launcher3.config.BaseFlags.BaseTogglableFlag;
public class TogglableFlag extends BaseTogglableFlag {
@@ -25,7 +26,10 @@ public class TogglableFlag extends BaseTogglableFlag {
}
@Override
- public boolean getInitialValue(boolean value) {
+ public boolean getOverridenDefaultValue(boolean value) {
return value;
}
+
+ @Override
+ public void addChangeListener(Context context, Runnable r) { }
}
diff --git a/tests/src/com/android/launcher3/compat/PromiseIconUiTest.java b/tests/src/com/android/launcher3/compat/PromiseIconUiTest.java
new file mode 100644
index 000000000..efbd9c99c
--- /dev/null
+++ b/tests/src/com/android/launcher3/compat/PromiseIconUiTest.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2019 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.compat;
+
+import android.content.pm.PackageInstaller.SessionParams;
+import android.content.pm.PackageManager;
+import android.graphics.Bitmap;
+import android.text.TextUtils;
+
+import androidx.test.filters.LargeTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherState;
+import com.android.launcher3.Workspace;
+import com.android.launcher3.ui.AbstractLauncherUiTest;
+
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.UUID;
+
+
+/**
+ * Test to verify promise icon flow.
+ */
+@LargeTest
+@RunWith(AndroidJUnit4.class)
+public class PromiseIconUiTest extends AbstractLauncherUiTest {
+
+ private int mSessionId = -1;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ mDevice.pressHome();
+ waitForLauncherCondition("Launcher didn't start", launcher -> launcher != null);
+ waitForState("Launcher internal state didn't switch to Home", LauncherState.NORMAL);
+ mSessionId = -1;
+ }
+
+ @After
+ public void tearDown() {
+ if (mSessionId > -1) {
+ mTargetContext.getPackageManager().getPackageInstaller().abandonSession(mSessionId);
+ }
+ }
+
+ /**
+ * Create a session and return the id.
+ */
+ private int createSession(String label, Bitmap icon) throws Throwable {
+ SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL);
+ params.setAppPackageName("test.promise.app");
+ params.setAppLabel(label);
+ params.setAppIcon(icon);
+ params.setInstallReason(PackageManager.INSTALL_REASON_USER);
+ return mTargetContext.getPackageManager().getPackageInstaller().createSession(params);
+ }
+
+ @Test
+ public void testPromiseIcon_addedFromEligibleSession() throws Throwable {
+ final String appLabel = "Test Promise App " + UUID.randomUUID().toString();
+ final Workspace.ItemOperator findPromiseApp = (info, view) ->
+ info != null && TextUtils.equals(info.title, appLabel);
+
+ // Create and add test session
+ mSessionId = createSession(appLabel, Bitmap.createBitmap(100, 100, Bitmap.Config.ALPHA_8));
+
+ // Verify promise icon is added
+ waitForLauncherCondition("Test Promise App not found on workspace", launcher ->
+ launcher.getWorkspace().getFirstMatch(findPromiseApp) != null);
+
+ // Remove session
+ mTargetContext.getPackageManager().getPackageInstaller().abandonSession(mSessionId);
+ mSessionId = -1;
+
+ // Verify promise icon is removed
+ waitForLauncherCondition("Test Promise App not removed from workspace", launcher ->
+ launcher.getWorkspace().getFirstMatch(findPromiseApp) == null);
+ }
+
+ @Test
+ public void testPromiseIcon_notAddedFromIneligibleSession() throws Throwable {
+ final String appLabel = "Test Promise App " + UUID.randomUUID().toString();
+ final Workspace.ItemOperator findPromiseApp = (info, view) ->
+ info != null && TextUtils.equals(info.title, appLabel);
+
+ // Create and add test session without icon or label
+ mSessionId = createSession(null, null);
+
+ // Sleep for duration of animation if a view was to be added + some buffer time.
+ Thread.sleep(Launcher.NEW_APPS_PAGE_MOVE_DELAY + Launcher.NEW_APPS_ANIMATION_DELAY + 500);
+
+ // Verify promise icon is not added
+ waitForLauncherCondition("Test Promise App not found on workspace", launcher ->
+ launcher.getWorkspace().getFirstMatch(findPromiseApp) == null);
+ }
+}
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index fc19baace..dc890bb00 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -24,7 +24,6 @@ import static org.junit.Assert.assertTrue;
import static java.lang.System.exit;
-import android.app.Instrumentation;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@@ -112,6 +111,7 @@ public abstract class AbstractLauncherUiTest {
launcher ->
checkLauncherIntegrity(launcher, containerType)));
}
+ mLauncher.enableDebugTracing();
}
protected final LauncherActivityRule mActivityMonitor = new LauncherActivityRule();
@@ -187,14 +187,6 @@ public abstract class AbstractLauncherUiTest {
}
}
- protected void lockRotation(boolean naturalOrientation) throws RemoteException {
- if (naturalOrientation) {
- mDevice.setOrientationNatural();
- } else {
- mDevice.setOrientationRight();
- }
- }
-
protected void clearLauncherData() throws IOException, InterruptedException {
if (TestHelpers.isInLauncherProcess()) {
LauncherSettings.Settings.call(mTargetContext.getContentResolver(),
@@ -202,6 +194,7 @@ public abstract class AbstractLauncherUiTest {
resetLoaderState();
} else {
clearPackageData(mDevice.getLauncherPackageName());
+ mLauncher.enableDebugTracing();
}
}
@@ -275,6 +268,12 @@ public abstract class AbstractLauncherUiTest {
// Cannot be used in TaplTests after injecting any gesture using Tapl because this can hide
// flakiness.
+ protected <T> T getOnceNotNull(String message, Function<Launcher, T> f) {
+ return getOnceNotNull(message, f, DEFAULT_ACTIVITY_TIMEOUT);
+ }
+
+ // Cannot be used in TaplTests after injecting any gesture using Tapl because this can hide
+ // flakiness.
protected void waitForLauncherCondition(
String message, Function<Launcher, Boolean> condition, long timeout) {
if (!TestHelpers.isInLauncherProcess()) return;
@@ -283,6 +282,20 @@ public abstract class AbstractLauncherUiTest {
// Cannot be used in TaplTests after injecting any gesture using Tapl because this can hide
// flakiness.
+ protected <T> T getOnceNotNull(String message, Function<Launcher, T> f, long timeout) {
+ if (!TestHelpers.isInLauncherProcess()) return null;
+
+ final Object[] output = new Object[1];
+ Wait.atMost(message, () -> {
+ final Object fromLauncher = getFromLauncher(f);
+ output[0] = fromLauncher;
+ return fromLauncher != null;
+ }, timeout);
+ return (T) output[0];
+ }
+
+ // Cannot be used in TaplTests after injecting any gesture using Tapl because this can hide
+ // flakiness.
protected void waitForLauncherCondition(
String message,
Runnable testThreadAction, Function<Launcher, Boolean> condition,
diff --git a/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java b/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java
index ddcb4da88..80bb3eddd 100644
--- a/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java
+++ b/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java
@@ -44,8 +44,11 @@ class PortraitLandscapeRunner implements TestRule {
} finally {
mTest.mDevice.setOrientationNatural();
mTest.executeOnLauncher(launcher ->
- launcher.getRotationHelper().forceAllowRotationForTesting(
- false));
+ {
+ if (launcher != null) {
+ launcher.getRotationHelper().forceAllowRotationForTesting(false);
+ }
+ });
mTest.mLauncher.setExpectedRotation(Surface.ROTATION_0);
}
}
diff --git a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
index 0c87ab908..c2a3c1c52 100644
--- a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
+++ b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
@@ -173,7 +173,6 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest {
@Test
public void testWorkspace() throws Exception {
- mLauncher.enableDebugTracing();
final Workspace workspace = mLauncher.getWorkspace();
// Test that ensureWorkspaceIsScrollable adds a page by dragging an icon there.
@@ -209,7 +208,6 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest {
// Test starting a workspace app.
final AppIcon app = workspace.getWorkspaceAppIcon("Chrome");
assertNotNull("No Chrome app in workspace", app);
- mLauncher.disableDebugTracing();
}
public static void runIconLaunchFromAllAppsTest(AbstractLauncherUiTest test, AllApps allApps) {
@@ -300,7 +298,6 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest {
@Test
@PortraitLandscape
public void testDragAppIcon() throws Throwable {
- mLauncher.enableDebugTracing();
// 1. Open all apps and wait for load complete.
// 2. Drag icon to homescreen.
// 3. Verify that the icon works on homescreen.
@@ -317,13 +314,11 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest {
"Launcher activity is the top activity; expecting another activity to be the top "
+ "one",
isInBackground(launcher)));
- mLauncher.disableDebugTracing();
}
@Test
@PortraitLandscape
public void testDragShortcut() throws Throwable {
- mLauncher.enableDebugTracing();
// 1. Open all apps and wait for load complete.
// 2. Find the app and long press it to show shortcuts.
// 3. Press icon center until shortcuts appear
@@ -343,7 +338,6 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest {
} finally {
allApps.unfreeze();
}
- mLauncher.disableDebugTracing();
}
public static String getAppPackageName() {
diff --git a/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java
index 3206a69bb..7f427b303 100644
--- a/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java
@@ -69,34 +69,22 @@ public class AddConfigWidgetTest extends AbstractLauncherUiTest {
}
@Test
+ @PortraitLandscape
public void testWidgetConfig() throws Throwable {
- runTest(false, true);
- }
-
- @Test
- @Ignore // b/121280703
- public void testWidgetConfig_rotate() throws Throwable {
- runTest(true, true);
+ runTest(true);
}
@Test
+ @PortraitLandscape
public void testConfigCancelled() throws Throwable {
- runTest(false, false);
+ runTest(false);
}
- @Test
- @Ignore // b/121280703
- public void testConfigCancelled_rotate() throws Throwable {
- runTest(true, false);
- }
/**
- * @param rotateConfig should the config screen be rotated
* @param acceptConfig accept the config activity
*/
- private void runTest(boolean rotateConfig, boolean acceptConfig) throws Throwable {
- lockRotation(true);
-
+ private void runTest(boolean acceptConfig) throws Throwable {
clearHomescreen();
mDevice.pressHome();
@@ -110,13 +98,6 @@ public class AddConfigWidgetTest extends AbstractLauncherUiTest {
// Widget id for which the config activity was opened
mWidgetId = monitor.getWidgetId();
- if (rotateConfig) {
- // Rotate the screen and verify that the config activity is recreated
- monitor = new WidgetConfigStartupMonitor();
- lockRotation(false);
- assertEquals(mWidgetId, monitor.getWidgetId());
- }
-
// Verify that the widget id is valid and bound
assertNotNull(mAppWidgetManager.getAppWidgetInfo(mWidgetId));
diff --git a/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java
index 276c6144a..cb586aceb 100644
--- a/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java
@@ -15,6 +15,9 @@
*/
package com.android.launcher3.ui.widget;
+import static com.android.launcher3.ui.TaplTestsLauncher3.getAppPackageName;
+
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import androidx.test.filters.LargeTest;
@@ -22,6 +25,7 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.launcher3.LauncherAppWidgetInfo;
import com.android.launcher3.LauncherAppWidgetProviderInfo;
+import com.android.launcher3.tapl.Widget;
import com.android.launcher3.ui.AbstractLauncherUiTest;
import com.android.launcher3.ui.TestViewHelpers;
import com.android.launcher3.util.rule.ShellCommandRule;
@@ -41,19 +45,8 @@ public class AddWidgetTest extends AbstractLauncherUiTest {
@Rule public ShellCommandRule mGrantWidgetRule = ShellCommandRule.grantWidgetBind();
@Test
- public void testDragIcon_portrait() throws Throwable {
- lockRotation(true);
- performTest();
- }
-
- @Test
- @Ignore // b/121280703
- public void testDragIcon_landscape() throws Throwable {
- lockRotation(false);
- performTest();
- }
-
- private void performTest() throws Throwable {
+ @PortraitLandscape
+ public void testDragIcon() throws Throwable {
clearHomescreen();
mDevice.pressHome();
@@ -70,5 +63,10 @@ public class AddWidgetTest extends AbstractLauncherUiTest {
(info, view) -> info instanceof LauncherAppWidgetInfo &&
((LauncherAppWidgetInfo) info).providerName.getClassName().equals(
widgetInfo.provider.getClassName())).call());
+
+ final Widget widget = mLauncher.getWorkspace().tryGetWidget(widgetInfo.label,
+ DEFAULT_UI_TIMEOUT);
+ assertNotNull("Widget not found on the workspace", widget);
+ widget.launch(getAppPackageName());
}
}
diff --git a/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java b/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java
index a9a509098..07129ddd9 100644
--- a/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java
@@ -128,8 +128,6 @@ public class RequestPinItemTest extends AbstractLauncherUiTest {
if (!Utilities.ATLEAST_OREO) {
return;
}
- lockRotation(true);
-
clearHomescreen();
mDevice.pressHome();
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 9d433527d..c6e7daceb 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -368,7 +368,7 @@ public final class LauncherInstrumentation {
}
}
- private void assertEquals(String message, String expected, String actual) {
+ void assertEquals(String message, String expected, String actual) {
if (!TextUtils.equals(expected, actual)) {
fail(message + " expected: '" + expected + "' but was: '" + actual + "'");
}
@@ -763,8 +763,7 @@ public final class LauncherInstrumentation {
final Bundle parcel = (Bundle) executeAndWaitForEvent(
() -> linearGesture(startX, startY, endX, endY, steps),
event -> TestProtocol.SWITCHED_TO_STATE_MESSAGE.equals(event.getClassName()),
- "Swipe failed to receive an event for the swipe end: " + startX + ", " + startY
- + ", " + endX + ", " + endY);
+ "Swipe failed to receive an event for the swipe end");
assertEquals("Swipe switched launcher to a wrong state;",
TestProtocol.stateOrdinalToString(expectedState),
TestProtocol.stateOrdinalToString(parcel.getInt(TestProtocol.STATE_FIELD)));
@@ -958,8 +957,8 @@ public final class LauncherInstrumentation {
getTestInfo(TestProtocol.REQUEST_DISABLE_DEBUG_TRACING);
}
- public long getAllocatedMemory() {
- return getTestInfo(TestProtocol.REQUEST_ALLOCATED_MEMORY).
- getLong(TestProtocol.TEST_INFO_RESPONSE_FIELD);
+ public int getTotalPssKb() {
+ return getTestInfo(TestProtocol.REQUEST_TOTAL_PSS_KB).
+ getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD);
}
} \ No newline at end of file
diff --git a/tests/tapl/com/android/launcher3/tapl/Widgets.java b/tests/tapl/com/android/launcher3/tapl/Widgets.java
index 2495933ac..208a2235d 100644
--- a/tests/tapl/com/android/launcher3/tapl/Widgets.java
+++ b/tests/tapl/com/android/launcher3/tapl/Widgets.java
@@ -19,6 +19,7 @@ package com.android.launcher3.tapl;
import static org.junit.Assert.fail;
import android.graphics.Point;
+import android.graphics.Rect;
import androidx.test.uiautomator.By;
import androidx.test.uiautomator.BySelector;
@@ -31,7 +32,8 @@ import com.android.launcher3.ResourceUtils;
* All widgets container.
*/
public final class Widgets extends LauncherInstrumentation.VisibleContainer {
- private static final int FLING_SPEED = 1500;
+ private static final Rect MARGINS = new Rect(100, 100, 100, 100);
+ private static final int FLING_STEPS = 10;
Widgets(LauncherInstrumentation launcher) {
super(launcher);
@@ -46,11 +48,7 @@ public final class Widgets extends LauncherInstrumentation.VisibleContainer {
"want to fling forward in widgets")) {
LauncherInstrumentation.log("Widgets.flingForward enter");
final UiObject2 widgetsContainer = verifyActiveContainer();
- widgetsContainer.setGestureMargins(0, 0, 0,
- ResourceUtils.getNavbarSize(ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE,
- mLauncher.getResources()) + 1);
- widgetsContainer.fling(Direction.DOWN,
- (int) (FLING_SPEED * mLauncher.getDisplayDensity()));
+ mLauncher.scroll(widgetsContainer, Direction.DOWN, 1f, MARGINS, FLING_STEPS);
try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer("flung forward")) {
verifyActiveContainer();
}
@@ -66,10 +64,7 @@ public final class Widgets extends LauncherInstrumentation.VisibleContainer {
"want to fling backwards in widgets")) {
LauncherInstrumentation.log("Widgets.flingBackward enter");
final UiObject2 widgetsContainer = verifyActiveContainer();
- widgetsContainer.setGestureMargin(100);
- widgetsContainer.fling(Direction.UP,
- (int) (FLING_SPEED * mLauncher.getDisplayDensity()));
- mLauncher.waitForIdle();
+ mLauncher.scroll(widgetsContainer, Direction.UP, 1f, MARGINS, FLING_STEPS);
try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer("flung back")) {
verifyActiveContainer();
}
@@ -82,7 +77,7 @@ public final class Widgets extends LauncherInstrumentation.VisibleContainer {
return LauncherInstrumentation.ContainerType.WIDGETS;
}
- public Widget getWidget(String label) {
+ public Widget getWidget(String labelText) {
final int margin = ResourceUtils.getNavbarSize(
ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE, mLauncher.getResources()) + 1;
final UiObject2 widgetsContainer = verifyActiveContainer();
@@ -91,17 +86,24 @@ public final class Widgets extends LauncherInstrumentation.VisibleContainer {
final Point displaySize = mLauncher.getRealDisplaySize();
int i = 0;
- final BySelector selector = By.
- clazz("com.android.launcher3.widget.WidgetCell").
- hasDescendant(By.text(label));
+ final BySelector selector = By.clazz("android.widget.TextView").text(labelText);
for (; ; ) {
- final UiObject2 widget = mLauncher.tryWaitForLauncherObject(selector, 300);
- if (widget != null && widget.getVisibleBounds().bottom <= displaySize.y - margin) {
- return new Widget(mLauncher, widget);
+ final UiObject2 label = mLauncher.tryWaitForLauncherObject(selector, 300);
+ if (label != null) {
+ final UiObject2 widget = label.getParent().getParent();
+ mLauncher.assertEquals(
+ "View is not WidgetCell",
+ "com.android.launcher3.widget.WidgetCell",
+ widget.getClassName());
+
+ if (widget.getVisibleBounds().bottom <= displaySize.y - margin) {
+ return new Widget(mLauncher, widget);
+ }
}
+
if (++i > 40) fail("Too many attempts");
- widgetsContainer.scroll(Direction.DOWN, 1f);
+ mLauncher.scroll(widgetsContainer, Direction.DOWN, 0.8f, MARGINS, 50);
}
}
}
diff --git a/tests/tapl/com/android/launcher3/tapl/Workspace.java b/tests/tapl/com/android/launcher3/tapl/Workspace.java
index 639902fa0..510ea1409 100644
--- a/tests/tapl/com/android/launcher3/tapl/Workspace.java
+++ b/tests/tapl/com/android/launcher3/tapl/Workspace.java
@@ -21,6 +21,7 @@ import static com.android.launcher3.testing.TestProtocol.ALL_APPS_STATE_ORDINAL;
import static junit.framework.TestCase.assertTrue;
import android.graphics.Point;
+import android.graphics.Rect;
import android.os.SystemClock;
import android.view.KeyEvent;
import android.view.MotionEvent;
@@ -40,6 +41,7 @@ public final class Workspace extends Home {
private static final float FLING_SPEED =
LauncherInstrumentation.isAvd() ? 1500.0F : 3500.0F;
private static final int DRAG_DURACTION = 2000;
+ private static final int FLING_STEPS = 10;
private final UiObject2 mHotseat;
Workspace(LauncherInstrumentation launcher) {
@@ -180,9 +182,9 @@ public final class Workspace extends Home {
*/
public void flingForward() {
final UiObject2 workspace = verifyActiveContainer();
- workspace.setGestureMargins(0, 0, mLauncher.getEdgeSensitivityWidth(), 0);
- workspace.fling(Direction.RIGHT, (int) (FLING_SPEED * mLauncher.getDisplayDensity()));
- mLauncher.waitForIdle();
+ mLauncher.scroll(workspace, Direction.RIGHT, 1f,
+ new Rect(0, 0, mLauncher.getEdgeSensitivityWidth(), 0),
+ FLING_STEPS);
verifyActiveContainer();
}
@@ -192,9 +194,9 @@ public final class Workspace extends Home {
*/
public void flingBackward() {
final UiObject2 workspace = verifyActiveContainer();
- workspace.setGestureMargins(mLauncher.getEdgeSensitivityWidth(), 0, 0, 0);
- workspace.fling(Direction.LEFT, (int) (FLING_SPEED * mLauncher.getDisplayDensity()));
- mLauncher.waitForIdle();
+ mLauncher.scroll(workspace, Direction.LEFT, 1f,
+ new Rect(mLauncher.getEdgeSensitivityWidth(), 0, 0, 0),
+ FLING_STEPS);
verifyActiveContainer();
}