Merge "Fix mSubtractDisplacement when recatching" into ub-launcher3-qt-future-dev
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java
index cae273a..fa3be9c 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java
@@ -37,6 +37,7 @@
import com.android.launcher3.LauncherState;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
+import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.views.BaseDragLayer;
import com.android.quickstep.RecentsModel;
import com.android.quickstep.views.RecentsView;
@@ -50,8 +51,6 @@
import com.android.systemui.shared.system.TransactionCompat;
import com.android.systemui.shared.system.WindowManagerWrapper;
-import java.util.function.BiFunction;
-
/**
* Utility class to handle window clip animation
*/
@@ -213,6 +212,11 @@
}
mCurrentCornerRadius = cornerRadius;
}
+ // Fade out Assistant overlay.
+ if (app.activityType == RemoteAnimationTargetCompat.ACTIVITY_TYPE_ASSISTANT
+ && app.isNotInRecents) {
+ alpha = 1 - Interpolators.DEACCEL_2_5.getInterpolation(progress);
+ }
} else if (targetSet.hasRecents) {
// If home has a different target then recents, reverse anim the
// home target.
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
index b601834..c2cb720 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -35,6 +35,7 @@
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
+import android.widget.FrameLayout;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Hotseat;
@@ -45,11 +46,14 @@
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.appprediction.PredictionUiStateManager;
import com.android.launcher3.appprediction.PredictionUiStateManager.Client;
+import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
import com.android.launcher3.views.ScrimView;
import com.android.quickstep.SysUINavigationMode;
import com.android.quickstep.util.ClipAnimationHelper;
import com.android.quickstep.util.ClipAnimationHelper.TransformParams;
import com.android.quickstep.util.LayoutUtils;
+import com.android.systemui.plugins.PluginListener;
+import com.android.systemui.plugins.RecentsExtraCard;
/**
* {@link RecentsView} used in Launcher activity
@@ -61,6 +65,25 @@
private final TransformParams mTransformParams = new TransformParams();
+ private RecentsExtraCard mRecentsExtraCardPlugin;
+ private RecentsExtraViewContainer mRecentsExtraViewContainer;
+ private PluginListener<RecentsExtraCard> mRecentsExtraCardPluginListener =
+ new PluginListener<RecentsExtraCard>() {
+ @Override
+ public void onPluginConnected(RecentsExtraCard recentsExtraCard, Context context) {
+ createRecentsExtraCard();
+ mRecentsExtraCardPlugin = recentsExtraCard;
+ mRecentsExtraCardPlugin.setupView(context, mRecentsExtraViewContainer, mActivity);
+ }
+
+ @Override
+ public void onPluginDisconnected(RecentsExtraCard plugin) {
+ removeView(mRecentsExtraViewContainer);
+ mRecentsExtraCardPlugin = null;
+ mRecentsExtraViewContainer = null;
+ }
+ };
+
public LauncherRecentsView(Context context) {
this(context, null);
}
@@ -285,4 +308,66 @@
}
return super.shouldStealTouchFromSiblingsBelow(ev);
}
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ PluginManagerWrapper.INSTANCE.get(getContext())
+ .addPluginListener(mRecentsExtraCardPluginListener, RecentsExtraCard.class);
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ PluginManagerWrapper.INSTANCE.get(getContext()).removePluginListener(
+ mRecentsExtraCardPluginListener);
+ }
+
+ @Override
+ protected int computeMinScrollX() {
+ if (canComputeScrollX() && !mIsRtl) {
+ return computeScrollX();
+ }
+ return super.computeMinScrollX();
+ }
+
+ @Override
+ protected int computeMaxScrollX() {
+ if (canComputeScrollX() && mIsRtl) {
+ return computeScrollX();
+ }
+ return super.computeMaxScrollX();
+ }
+
+ private boolean canComputeScrollX() {
+ return mRecentsExtraCardPlugin != null && getTaskViewCount() > 0
+ && !mDisallowScrollToClearAll;
+ }
+
+ private int computeScrollX() {
+ int scrollIndex = getTaskViewStartIndex() - 1;
+ while (scrollIndex >= 0 && getChildAt(scrollIndex) instanceof RecentsExtraViewContainer
+ && ((RecentsExtraViewContainer) getChildAt(scrollIndex)).isScrollable()) {
+ scrollIndex--;
+ }
+ return getScrollForPage(scrollIndex + 1);
+ }
+
+ private void createRecentsExtraCard() {
+ mRecentsExtraViewContainer = new RecentsExtraViewContainer(getContext());
+ FrameLayout.LayoutParams helpCardParams =
+ new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
+ FrameLayout.LayoutParams.MATCH_PARENT);
+ mRecentsExtraViewContainer.setLayoutParams(helpCardParams);
+ mRecentsExtraViewContainer.setScrollable(true);
+ addView(mRecentsExtraViewContainer, 0);
+ }
+
+ @Override
+ public void resetTaskVisuals() {
+ super.resetTaskVisuals();
+ if (mRecentsExtraViewContainer != null) {
+ mRecentsExtraViewContainer.setAlpha(mContentAlpha);
+ }
+ }
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsExtraViewContainer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsExtraViewContainer.java
new file mode 100644
index 0000000..1ea6d4a
--- /dev/null
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsExtraViewContainer.java
@@ -0,0 +1,54 @@
+/*
+ * 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.quickstep.views;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.FrameLayout;
+
+/**
+ * Empty view to house recents overview extra card
+ */
+public class RecentsExtraViewContainer extends FrameLayout implements RecentsView.PageCallbacks {
+
+ private boolean mScrollable = false;
+
+ public RecentsExtraViewContainer(Context context) {
+ super(context);
+ }
+
+ public RecentsExtraViewContainer(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public RecentsExtraViewContainer(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ /**
+ * Determine whether the view should be scrolled to in the recents overview, similar to the
+ * taskviews.
+ * @return true if viewed should be scrolled to, false if not
+ */
+ public boolean isScrollable() {
+ return mScrollable;
+ }
+
+ public void setScrollable(boolean scrollable) {
+ this.mScrollable = scrollable;
+ }
+}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
index 02c43e4..6ad3cc6 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
@@ -17,6 +17,7 @@
package com.android.quickstep.views;
import static androidx.dynamicanimation.animation.DynamicAnimation.MIN_VISIBLE_CHANGE_PIXELS;
+
import static com.android.launcher3.BaseActivity.STATE_HANDLER_INVISIBILITY_FLAGS;
import static com.android.launcher3.InvariantDeviceProfile.CHANGE_FLAG_ICON_PARAMS;
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
@@ -186,7 +187,7 @@
private final ViewPool<TaskView> mTaskViewPool;
private boolean mDwbToastShown;
- private boolean mDisallowScrollToClearAll;
+ protected boolean mDisallowScrollToClearAll;
private boolean mOverlayEnabled;
private boolean mFreezeViewVisibility;
@@ -288,7 +289,7 @@
private LayoutTransition mLayoutTransition;
@ViewDebug.ExportedProperty(category = "launcher")
- private float mContentAlpha = 1;
+ protected float mContentAlpha = 1;
@ViewDebug.ExportedProperty(category = "launcher")
protected float mFullscreenProgress = 0;
@@ -1821,4 +1822,25 @@
final WindowInsets insets = getRootWindowInsets();
return Math.max(insets.getSystemGestureInsets().right, insets.getSystemWindowInsetRight());
}
+
+ @Override
+ public void addView(View child, int index) {
+ super.addView(child, index);
+ if (isExtraCardView(child, index)) {
+ mTaskViewStartIndex++;
+ }
+ }
+
+ @Override
+ public void removeView(View view) {
+ if (isExtraCardView(view, indexOfChild(view))) {
+ mTaskViewStartIndex--;
+ }
+ super.removeView(view);
+ }
+
+ private boolean isExtraCardView(View view, int index) {
+ return !(view instanceof TaskView) && !(view instanceof ClearAllButton)
+ && index <= mTaskViewStartIndex;
+ }
}
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
index 885fdbf..41f4a82 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
@@ -17,6 +17,7 @@
package com.android.quickstep;
import static com.android.launcher3.ui.TaplTestsLauncher3.getAppPackageName;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@@ -34,6 +35,7 @@
import com.android.launcher3.tapl.AllApps;
import com.android.launcher3.tapl.AllAppsFromOverview;
import com.android.launcher3.tapl.Background;
+import com.android.launcher3.tapl.LauncherInstrumentation.NavigationModel;
import com.android.launcher3.tapl.Overview;
import com.android.launcher3.tapl.OverviewTask;
import com.android.launcher3.tapl.TestHelpers;
@@ -210,16 +212,21 @@
@PortraitLandscape
public void testBackground() throws Exception {
startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR));
+ final Background background = getAndAssertBackground();
+
+ assertNotNull("Background.switchToOverview() returned null", background.switchToOverview());
+ assertTrue("Launcher internal state didn't switch to Overview",
+ isInState(LauncherState.OVERVIEW));
+ }
+
+ private Background getAndAssertBackground() {
final Background background = mLauncher.getBackground();
assertNotNull("Launcher.getBackground() returned null", background);
executeOnLauncher(launcher -> assertTrue(
"Launcher activity is the top activity; expecting another activity to be the top "
+ "one",
isInBackground(launcher)));
-
- assertNotNull("Background.switchToOverview() returned null", background.switchToOverview());
- assertTrue("Launcher internal state didn't switch to Overview",
- isInState(LauncherState.OVERVIEW));
+ return background;
}
@Test
@@ -237,4 +244,47 @@
assertTrue("Launcher internal state is not Home", isInState(LauncherState.NORMAL));
assertNotNull("getHome returned null", mLauncher.getWorkspace());
}
+
+ @Test
+ @NavigationModeSwitch
+ @PortraitLandscape
+ public void testQuickSwitchFromApp() throws Exception {
+ startAppFast(getAppPackageName());
+ startTestActivity(2);
+ String calculatorPackage = resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR);
+ startAppFast(calculatorPackage);
+
+ Background background = getAndAssertBackground();
+ background.quickSwitchToPreviousApp();
+ assertTrue("The first app we should have quick switched to is not running",
+ isTestActivityRunning("TestActivity2"));
+
+ background = getAndAssertBackground();
+ background.quickSwitchToPreviousApp();
+ if (mLauncher.getNavigationModel() == NavigationModel.THREE_BUTTON) {
+ // 3-button mode toggles between 2 apps, rather than going back further.
+ assertTrue("Second quick switch should have returned to the first app.",
+ mDevice.wait(Until.hasObject(By.pkg(calculatorPackage)), DEFAULT_UI_TIMEOUT));
+ } else {
+ assertTrue("The second app we should have quick switched to is not running",
+ isTestActivityRunning("Test Pin Item"));
+ }
+ getAndAssertBackground();
+ }
+
+ private boolean isTestActivityRunning(String activityLabel) {
+ return mDevice.wait(Until.hasObject(By.pkg(getAppPackageName()).text(activityLabel)),
+ DEFAULT_UI_TIMEOUT);
+ }
+
+ @Test
+ @NavigationModeSwitch
+ @PortraitLandscape
+ public void testQuickSwitchFromHome() throws Exception {
+ startTestActivity(2);
+ mLauncher.pressHome().quickSwitchToPreviousApp();
+ assertTrue("The most recent task is not running after quick switching from home",
+ isTestActivityRunning("TestActivity2"));
+ getAndAssertBackground();
+ }
}
diff --git a/src_plugins/com/android/systemui/plugins/RecentsExtraCard.java b/src_plugins/com/android/systemui/plugins/RecentsExtraCard.java
new file mode 100644
index 0000000..0ebea3d
--- /dev/null
+++ b/src_plugins/com/android/systemui/plugins/RecentsExtraCard.java
@@ -0,0 +1,42 @@
+/*
+ * 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.systemui.plugins;
+
+import android.app.Activity;
+import android.content.Context;
+import android.widget.FrameLayout;
+
+import com.android.systemui.plugins.annotations.ProvidesInterface;
+
+/**
+ * Implement this interface to allow extra card on recents overview.
+ */
+@ProvidesInterface(action = RecentsExtraCard.ACTION, version = RecentsExtraCard.VERSION)
+public interface RecentsExtraCard extends Plugin {
+
+ String ACTION = "com.android.systemui.action.PLUGIN_RECENTS_EXTRA_CARD";
+ int VERSION = 1;
+
+ /**
+ * Sets up the recents overview extra card and fills in data.
+ *
+ * @param context Plugin context
+ * @param frameLayout PlaceholderView
+ * @param activity Recents activity to hold extra view
+ */
+ void setupView(Context context, FrameLayout frameLayout, Activity activity);
+}
diff --git a/tests/tapl/com/android/launcher3/tapl/Background.java b/tests/tapl/com/android/launcher3/tapl/Background.java
index bcce8ef..0dd3e77 100644
--- a/tests/tapl/com/android/launcher3/tapl/Background.java
+++ b/tests/tapl/com/android/launcher3/tapl/Background.java
@@ -23,6 +23,7 @@
import android.view.MotionEvent;
import androidx.annotation.NonNull;
+import androidx.test.uiautomator.UiObject2;
import com.android.launcher3.testing.TestProtocol;
@@ -114,6 +115,46 @@
}
}
+ /**
+ * Swipes right or double presses the square button to switch to the previous app.
+ */
+ public Background quickSwitchToPreviousApp() {
+ try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+ "want to quick switch to the previous app")) {
+ verifyActiveContainer();
+ quickSwitchToPreviousApp(getExpectedStateForQuickSwitch());
+ return new Background(mLauncher);
+ }
+ }
+
+ protected int getExpectedStateForQuickSwitch() {
+ return BACKGROUND_APP_STATE_ORDINAL;
+ }
+
+ protected void quickSwitchToPreviousApp(int expectedState) {
+ switch (mLauncher.getNavigationModel()) {
+ case ZERO_BUTTON:
+ // Fall through, zero button and two button modes behave the same.
+ case TWO_BUTTON: {
+ // Swipe from the bottom left to the bottom right of the screen.
+ final int startX = 0;
+ final int startY = getSwipeStartY();
+ final int endX = mLauncher.getDevice().getDisplayWidth();
+ final int endY = startY;
+ mLauncher.swipeToState(startX, startY, endX, endY, 20, expectedState);
+ break;
+ }
+
+ case THREE_BUTTON:
+ // Double press the recents button.
+ UiObject2 recentsButton = mLauncher.waitForSystemUiObject("recent_apps");
+ recentsButton.click();
+ mLauncher.getOverview();
+ recentsButton.click();
+ break;
+ }
+ }
+
protected String getSwipeHeightRequestName() {
return TestProtocol.REQUEST_BACKGROUND_TO_OVERVIEW_SWIPE_HEIGHT;
}
diff --git a/tests/tapl/com/android/launcher3/tapl/Home.java b/tests/tapl/com/android/launcher3/tapl/Home.java
index cfc4374..e0fe933 100644
--- a/tests/tapl/com/android/launcher3/tapl/Home.java
+++ b/tests/tapl/com/android/launcher3/tapl/Home.java
@@ -17,6 +17,7 @@
package com.android.launcher3.tapl;
import static com.android.launcher3.testing.TestProtocol.OVERVIEW_STATE_ORDINAL;
+import static com.android.launcher3.testing.TestProtocol.QUICK_SWITCH_STATE_ORDINAL;
import androidx.annotation.NonNull;
@@ -58,4 +59,9 @@
}
}
}
+
+ @Override
+ protected int getExpectedStateForQuickSwitch() {
+ return QUICK_SWITCH_STATE_ORDINAL;
+ }
}
\ No newline at end of file