Merge changes from topic "am-3e098e52-a5e6-4050-ac05-724b2c56ff1d" into ub-launcher3-master
* changes:
[automerger] Linking swipe animate to stateTransition to that it gets properly reset afterwards am: cc35bb88da
Linking swipe animate to stateTransition to that it gets properly reset afterwards
diff --git a/quickstep/libs/sysui_shared.jar b/quickstep/libs/sysui_shared.jar
index 8e2f2f1..19a9b17 100644
--- a/quickstep/libs/sysui_shared.jar
+++ b/quickstep/libs/sysui_shared.jar
Binary files differ
diff --git a/quickstep/res/layout/fallback_recents_activity.xml b/quickstep/res/layout/fallback_recents_activity.xml
index 22f8b55..7ecab32 100644
--- a/quickstep/res/layout/fallback_recents_activity.xml
+++ b/quickstep/res/layout/fallback_recents_activity.xml
@@ -20,13 +20,23 @@
android:layout_height="match_parent"
android:fitsSystemWindows="true">
- <com.android.quickstep.fallback.FallbackRecentsView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/overview_panel"
+ <com.android.quickstep.views.RecentsViewContainer
+ android:id="@+id/overview_panel_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:clipChildren="false"
- android:clipToPadding="false"
- android:theme="@style/HomeScreenElementTheme" />
+ >
+ <include layout="@layout/overview_clear_all_button"/>
-</com.android.quickstep.fallback.RecentsRootView>
\ No newline at end of file
+ <com.android.quickstep.fallback.FallbackRecentsView
+ android:id="@id/overview_panel"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:focusableInTouchMode="true"
+ android:theme="@style/HomeScreenElementTheme"
+ >
+
+ </com.android.quickstep.fallback.FallbackRecentsView>
+ </com.android.quickstep.views.RecentsViewContainer>
+</com.android.quickstep.fallback.RecentsRootView>
diff --git a/quickstep/res/layout/overview_clear_all_button.xml b/quickstep/res/layout/overview_clear_all_button.xml
new file mode 100644
index 0000000..79d8a61
--- /dev/null
+++ b/quickstep/res/layout/overview_clear_all_button.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<TextView
+ xmlns:launcher="http://schemas.android.com/apk/res-auto"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/clear_all_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="end|top"
+ android:fontFamily="sans-serif-medium"
+ android:text="@string/recents_clear_all"
+ android:textColor="?attr/workspaceTextColor"
+ android:background="?android:attr/selectableItemBackground"
+ launcher:layout_ignoreInsets="true"
+ android:textSize="14sp"
+/>
\ No newline at end of file
diff --git a/quickstep/res/layout/overview_panel.xml b/quickstep/res/layout/overview_panel.xml
index 89e0571..6102c38 100644
--- a/quickstep/res/layout/overview_panel.xml
+++ b/quickstep/res/layout/overview_panel.xml
@@ -14,14 +14,23 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<com.android.quickstep.views.LauncherRecentsView
+<com.android.quickstep.views.RecentsViewContainer
xmlns:android="http://schemas.android.com/apk/res/android"
- android:theme="@style/HomeScreenElementTheme"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:clipChildren="false"
- android:clipToPadding="false"
android:visibility="invisible"
- android:focusableInTouchMode="true" >
+>
+ <include layout="@layout/overview_clear_all_button"/>
-</com.android.quickstep.views.LauncherRecentsView>
\ No newline at end of file
+ <com.android.quickstep.views.LauncherRecentsView
+ android:id="@id/overview_panel"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:focusableInTouchMode="true"
+ android:theme="@style/HomeScreenElementTheme"
+ >
+
+ </com.android.quickstep.views.LauncherRecentsView>
+</com.android.quickstep.views.RecentsViewContainer>
\ No newline at end of file
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index c741913..0199cd9 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -45,4 +45,7 @@
<!-- Copied from framework resource:
docked_stack_divider_thickness - 2 * docked_stack_divider_insets -->
<dimen name="multi_window_task_divider_size">10dp</dimen>
+
+ <!-- Width of the space behind the last task in Overview. In the center of it, there is "Clear all" button. -->
+ <dimen name="clear_all_container_width">168dp</dimen>
</resources>
diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml
index bafa294..34cc0b7 100644
--- a/quickstep/res/values/strings.xml
+++ b/quickstep/res/values/strings.xml
@@ -35,4 +35,7 @@
<!-- Content description for the recent apps's accessibility option that closes it. [CHAR LIMIT=NONE] -->
<string name="accessibility_close_task">Close</string>
+
+ <!-- Recents: Title of a button that clears the task list, i.e. closes all tasks. [CHAR LIMIT=30] -->
+ <string name="recents_clear_all">Clear all</string>
</resources>
\ No newline at end of file
diff --git a/quickstep/src/com/android/launcher3/uioverrides/LandscapeEdgeSwipeController.java b/quickstep/src/com/android/launcher3/uioverrides/LandscapeEdgeSwipeController.java
index 3622fc4..a7cf545 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/LandscapeEdgeSwipeController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/LandscapeEdgeSwipeController.java
@@ -12,6 +12,7 @@
import com.android.launcher3.touch.AbstractStateChangeTouchController;
import com.android.launcher3.touch.SwipeDetector;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
+import com.android.quickstep.RecentsModel;
import com.android.quickstep.util.SysuiEventLogger;
/**
@@ -19,6 +20,8 @@
*/
public class LandscapeEdgeSwipeController extends AbstractStateChangeTouchController {
+ private static final String TAG = "LandscapeEdgeSwipeCtrl";
+
public LandscapeEdgeSwipeController(Launcher l) {
super(l, SwipeDetector.HORIZONTAL);
}
@@ -69,6 +72,7 @@
protected void onSwipeInteractionCompleted(LauncherState targetState, int logAction) {
super.onSwipeInteractionCompleted(targetState, logAction);
if (mFromState == NORMAL && targetState == OVERVIEW) {
+ RecentsModel.getInstance(mLauncher).onOverviewShown(true, TAG);
SysuiEventLogger.writeDummyRecentsTransition(0);
}
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java
index 9f21a95..2e95c04 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java
@@ -39,6 +39,7 @@
import com.android.launcher3.touch.SwipeDetector;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
+import com.android.quickstep.RecentsModel;
import com.android.quickstep.TouchInteractionService;
import com.android.quickstep.util.SysuiEventLogger;
import com.android.quickstep.views.RecentsView;
@@ -49,6 +50,8 @@
*/
public class PortraitStatesTouchController extends AbstractStateChangeTouchController {
+ private static final String TAG = "PortraitStatesTouchCtrl";
+
private static final float TOTAL_DISTANCE_MULTIPLIER = 3f;
private static final float LINEAR_SCALE_LIMIT = 1 / TOTAL_DISTANCE_MULTIPLIER;
@@ -284,6 +287,7 @@
protected void onSwipeInteractionCompleted(LauncherState targetState, int logAction) {
super.onSwipeInteractionCompleted(targetState, logAction);
if (mFromState == NORMAL && targetState == OVERVIEW) {
+ RecentsModel.getInstance(mLauncher).onOverviewShown(true, TAG);
SysuiEventLogger.writeDummyRecentsTransition(0);
}
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
index 124ec20..49d4931 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
@@ -20,7 +20,7 @@
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.quickstep.views.LauncherRecentsView.TRANSLATION_Y_FACTOR;
import static com.android.quickstep.views.RecentsView.ADJACENT_SCALE;
-import static com.android.quickstep.views.RecentsView.CONTENT_ALPHA;
+import static com.android.quickstep.views.RecentsViewContainer.CONTENT_ALPHA;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
@@ -33,21 +33,24 @@
import com.android.launcher3.anim.AnimatorSetBuilder;
import com.android.launcher3.anim.PropertySetter;
import com.android.quickstep.views.LauncherRecentsView;
+import com.android.quickstep.views.RecentsViewContainer;
@TargetApi(Build.VERSION_CODES.O)
public class RecentsViewStateController implements StateHandler {
private final Launcher mLauncher;
private final LauncherRecentsView mRecentsView;
+ private final RecentsViewContainer mRecentsViewContainer;
public RecentsViewStateController(Launcher launcher) {
mLauncher = launcher;
mRecentsView = launcher.getOverviewPanel();
+ mRecentsViewContainer = launcher.getOverviewPanelContainer();
}
@Override
public void setState(LauncherState state) {
- mRecentsView.setContentAlpha(state.overviewUi ? 1 : 0);
+ mRecentsViewContainer.setContentAlpha(state.overviewUi ? 1 : 0);
float[] scaleTranslationYFactor = state.getOverviewScaleAndTranslationYFactor(mLauncher);
mRecentsView.setAdjacentScale(scaleTranslationYFactor[0]);
mRecentsView.setTranslationYFactor(scaleTranslationYFactor[1]);
@@ -66,7 +69,7 @@
builder.getInterpolator(ANIM_OVERVIEW_TRANSLATION, LINEAR));
setter.setFloat(mRecentsView, TRANSLATION_Y_FACTOR, scaleTranslationYFactor[1],
builder.getInterpolator(ANIM_OVERVIEW_TRANSLATION, LINEAR));
- setter.setFloat(mRecentsView, CONTENT_ALPHA, toState.overviewUi ? 1 : 0,
+ setter.setFloat(mRecentsViewContainer, CONTENT_ALPHA, toState.overviewUi ? 1 : 0,
AGGRESSIVE_EASE_IN_OUT);
if (!toState.overviewUi) {
diff --git a/quickstep/src/com/android/quickstep/RecentsModel.java b/quickstep/src/com/android/quickstep/RecentsModel.java
index 4652f2d..70b0355 100644
--- a/quickstep/src/com/android/quickstep/RecentsModel.java
+++ b/quickstep/src/com/android/quickstep/RecentsModel.java
@@ -26,8 +26,10 @@
import android.os.Build;
import android.os.Bundle;
import android.os.Looper;
+import android.os.RemoteException;
import android.os.UserHandle;
import android.support.annotation.WorkerThread;
+import android.util.Log;
import android.util.LruCache;
import android.util.SparseArray;
import android.view.accessibility.AccessibilityManager;
@@ -234,6 +236,19 @@
mRecentsTaskLoader.onTrimMemory(level);
}
+ public void onOverviewShown(boolean fromHome, String tag) {
+ if (mSystemUiProxy == null) {
+ return;
+ }
+ try {
+ mSystemUiProxy.onOverviewShown(fromHome);
+ } catch (RemoteException e) {
+ Log.w(tag,
+ "Failed to notify SysUI of overview shown from " + (fromHome ? "home" : "app")
+ + ": ", e);
+ }
+ }
+
@WorkerThread
public void preloadAssistData(int taskId, Bundle data) {
mMainThreadExecutor.execute(() -> {
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 4f0187c..57f46b8 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -39,13 +39,12 @@
import android.view.Choreographer;
import android.view.MotionEvent;
import android.view.VelocityTracker;
-import android.view.View;
import android.view.ViewConfiguration;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.MainThreadExecutor;
-import com.android.launcher3.R;
import com.android.launcher3.util.TraceHelper;
+import com.android.launcher3.views.BaseDragLayer;
import com.android.quickstep.views.RecentsView;
import com.android.systemui.shared.recents.IOverviewProxy;
import com.android.systemui.shared.recents.ISystemUiProxy;
@@ -248,7 +247,7 @@
private final ActivityControlHelper<T> mActivityHelper;
private final T mActivity;
- private final View mTarget;
+ private final BaseDragLayer mTarget;
private final int[] mLocationOnScreen = new int[2];
private final PointF mDownPos = new PointF();
private final int mTouchSlop;
@@ -293,7 +292,6 @@
case ACTION_MOVE: {
float displacement = ev.getY() - mDownPos.y;
if (Math.abs(displacement) >= mTouchSlop) {
- mTrackingStarted = true;
mTarget.getLocationOnScreen(mLocationOnScreen);
// Send a down event only when mTouchSlop is crossed.
@@ -301,6 +299,7 @@
down.setAction(ACTION_DOWN);
sendEvent(down);
down.recycle();
+ mTrackingStarted = true;
}
}
}
@@ -319,7 +318,10 @@
int flags = ev.getEdgeFlags();
ev.setEdgeFlags(flags | EDGE_NAV_BAR);
ev.offsetLocation(-mLocationOnScreen[0], -mLocationOnScreen[1]);
- mTarget.dispatchTouchEvent(ev);
+ if (!mTrackingStarted) {
+ mTarget.onInterceptTouchEvent(ev);
+ }
+ mTarget.onTouchEvent(ev);
ev.offsetLocation(mLocationOnScreen[0], mLocationOnScreen[1]);
ev.setEdgeFlags(flags);
}
diff --git a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
index d456367..0944a7a 100644
--- a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -18,7 +18,9 @@
import static com.android.launcher3.BaseActivity.INVISIBLE_BY_STATE_HANDLER;
import static com.android.launcher3.Utilities.postAsyncCallback;
import static com.android.launcher3.anim.Interpolators.ACCEL_2;
+import static com.android.launcher3.anim.Interpolators.DEACCEL;
import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLATOR;
import static com.android.quickstep.QuickScrubController.QUICK_SCRUB_START_DURATION;
import static com.android.quickstep.TouchConsumer.INTERACTION_NORMAL;
import static com.android.quickstep.TouchConsumer.INTERACTION_QUICK_SCRUB;
@@ -55,7 +57,6 @@
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.AnimatorPlaybackController;
-import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.logging.UserEventDispatcher;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
@@ -129,10 +130,12 @@
"STATE_QUICK_SCRUB_END"
};
- private static final long MAX_SWIPE_DURATION = 200;
+ private static final long MAX_SWIPE_DURATION = 350;
private static final long MIN_SWIPE_DURATION = 80;
private static final float MIN_PROGRESS_FOR_OVERVIEW = 0.5f;
+ private static final float SWIPE_DURATION_MULTIPLIER =
+ Math.min(1 / MIN_PROGRESS_FOR_OVERVIEW, 1 / (1 - MIN_PROGRESS_FOR_OVERVIEW));
private final ClipAnimationHelper mClipAnimationHelper = new ClipAnimationHelper();
@@ -400,7 +403,7 @@
setStateOnUiThread(STATE_QUICK_SCRUB_START);
// Start the window animation without waiting for launcher.
- animateToProgress(1f, QUICK_SCRUB_START_DURATION);
+ animateToProgress(1f, QUICK_SCRUB_START_DURATION, TOUCH_RESPONSE_INTERPOLATOR);
}
@WorkerThread
@@ -558,12 +561,15 @@
public void onGestureEnded(float endVelocity) {
Resources res = mContext.getResources();
float flingThreshold = res.getDimension(R.dimen.quickstep_fling_threshold_velocity);
- boolean isFling = Math.abs(endVelocity) > flingThreshold;
+ boolean isFling = mGestureStarted && Math.abs(endVelocity) > flingThreshold;
long duration = MAX_SWIPE_DURATION;
final float endShift;
if (!isFling) {
- endShift = mCurrentShift.value >= MIN_PROGRESS_FOR_OVERVIEW ? 1 : 0;
+ endShift = mCurrentShift.value >= MIN_PROGRESS_FOR_OVERVIEW && mGestureStarted ? 1 : 0;
+ long expectedDuration = Math.abs(Math.round((endShift - mCurrentShift.value)
+ * MAX_SWIPE_DURATION * SWIPE_DURATION_MULTIPLIER));
+ duration = Math.min(MAX_SWIPE_DURATION, expectedDuration);
mLogAction = Touch.SWIPE;
} else {
endShift = endVelocity < 0 ? 1 : 0;
@@ -573,13 +579,14 @@
// we want the page's snap velocity to approximately match the velocity at
// which the user flings, so we scale the duration by a value near to the
- // derivative of the scroll interpolator at zero, ie. 5.
- duration = 5 * Math.round(1000 * Math.abs(distanceToTravel / endVelocity));
+ // derivative of the scroll interpolator at zero, ie. 2.
+ long baseDuration = Math.round(1000 * Math.abs(distanceToTravel / endVelocity));
+ duration = Math.min(MAX_SWIPE_DURATION, 2 * baseDuration);
}
mLogAction = Touch.FLING;
}
- animateToProgress(endShift, duration);
+ animateToProgress(endShift, duration, DEACCEL);
}
private void doLogGesture(boolean toLauncher) {
@@ -599,10 +606,10 @@
}
/** Animates to the given progress, where 0 is the current app and 1 is overview. */
- private void animateToProgress(float progress, long duration) {
+ private void animateToProgress(float progress, long duration, Interpolator interpolator) {
mIsGoingToHome = Float.compare(progress, 1) == 0;
ObjectAnimator anim = mCurrentShift.animateToValue(progress).setDuration(duration);
- anim.setInterpolator(Interpolators.SCROLL);
+ anim.setInterpolator(interpolator);
anim.addListener(new AnimationSuccessListener() {
@Override
public void onAnimationSuccess(Animator animator) {
@@ -691,6 +698,7 @@
// If we haven't posted the transition end runnable, run it now
finishTransitionRunnable.run();
}
+ RecentsModel.getInstance(mContext).onOverviewShown(false, TAG);
doLogGesture(true /* toLauncher */);
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 597e333..29d999d 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -87,21 +87,10 @@
public abstract class RecentsView<T extends BaseActivity>
extends PagedView implements OnSharedPreferenceChangeListener, Insettable {
+ public static final boolean DEBUG_SHOW_CLEAR_ALL_BUTTON = false;
+
private final Rect mTempRect = new Rect();
- public static final FloatProperty<RecentsView> CONTENT_ALPHA =
- new FloatProperty<RecentsView>("contentAlpha") {
- @Override
- public void setValue(RecentsView recentsView, float v) {
- recentsView.setContentAlpha(v);
- }
-
- @Override
- public Float get(RecentsView recentsView) {
- return recentsView.mContentAlpha;
- }
- };
-
public static final FloatProperty<RecentsView> ADJACENT_SCALE =
new FloatProperty<RecentsView>("adjacentScale") {
@Override
@@ -180,6 +169,8 @@
// Keeps track of task views whose visual state should not be reset
private ArraySet<TaskView> mIgnoreResetTaskViews = new ArraySet<>();
+ private RecentsViewContainer mContainerView;
+
// Variables for empty state
private final Drawable mEmptyIcon;
private final CharSequence mEmptyMessage;
@@ -320,12 +311,18 @@
@Override
public boolean onTouchEvent(MotionEvent ev) {
- super.onTouchEvent(ev);
+ if (DEBUG_SHOW_CLEAR_ALL_BUTTON && mTouchState == TOUCH_STATE_REST && mScroller.isFinished()
+ && getChildCount() != 0
+ && ev.getX() > getChildAt(getChildCount() - 1).getRight() - getScrollX()) {
+ // If nothing is in motion, allow events to the right of the last task to go to the
+ // Clear All button.
+ return false;
+ }
+
if (ev.getAction() == MotionEvent.ACTION_UP && mShowEmptyMessage) {
onAllTasksRemoved();
}
- // Do not let touch escape to siblings below this view.
- return true;
+ return super.onTouchEvent(ev);
}
private void applyLoadPlan(RecentsTaskLoadPlan loadPlan) {
@@ -424,6 +421,10 @@
protected abstract void getTaskSize(DeviceProfile dp, Rect outRect);
+ public void getTaskSize(Rect outRect) {
+ getTaskSize(mActivity.getDeviceProfile(), outRect);
+ }
+
@Override
protected boolean computeScrollHelper() {
boolean scrolling = super.computeScrollHelper();
@@ -844,11 +845,11 @@
snapToPageRelative(1);
}
- public void setContentAlpha(float alpha) {
- if (mContentAlpha == alpha) {
- return;
- }
+ public float getContentAlpha() {
+ return mContentAlpha;
+ }
+ public void setContentAlpha(float alpha) {
mContentAlpha = alpha;
for (int i = getChildCount() - 1; i >= 0; i--) {
TaskView child = getPageAt(i);
@@ -860,8 +861,6 @@
int alphaInt = Math.round(alpha * 255);
mEmptyMessagePaint.setAlpha(alphaInt);
mEmptyIcon.setAlpha(alphaInt);
-
- setVisibility(alpha > 0 ? VISIBLE : GONE);
}
public void setAdjacentScale(float adjacentScale) {
@@ -929,6 +928,9 @@
mShowEmptyMessage = isEmpty;
updateEmptyStateUi(hasSizeChanged);
invalidate();
+ if (mContainerView != null) {
+ mContainerView.onEmptyStateChanged(!DEBUG_SHOW_CLEAR_ALL_BUTTON || mShowEmptyMessage);
+ }
}
@Override
@@ -1095,4 +1097,30 @@
protected String getCurrentPageDescription() {
return "";
}
+
+ public void dismissAllTasks() {
+ for (int i = 0; i < getChildCount(); ++i) {
+ Task task = getPageAt(i).getTask();
+ if (task != null) {
+ ActivityManagerWrapper.getInstance().removeTask(task.key.id);
+ }
+ }
+ onAllTasksRemoved();
+ }
+
+ @Override
+ protected int computeMaxScrollX() {
+ if (!DEBUG_SHOW_CLEAR_ALL_BUTTON || getChildCount() == 0) {
+ return super.computeMaxScrollX();
+ }
+
+ // Allow a clear_all_container_width-sized gap after the last task.
+ return super.computeMaxScrollX() + (int) getResources().getDimension(
+ R.dimen.clear_all_container_width) - getPaddingEnd();
+ }
+
+ public void setContainerView(RecentsViewContainer containerView) {
+ mContainerView = containerView;
+ mContainerView.onEmptyStateChanged(!DEBUG_SHOW_CLEAR_ALL_BUTTON || mShowEmptyMessage);
+ }
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java b/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java
new file mode 100644
index 0000000..ece78c1
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java
@@ -0,0 +1,81 @@
+package com.android.quickstep.views;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.util.FloatProperty;
+import android.view.MotionEvent;
+import android.view.View;
+
+import com.android.launcher3.InsettableFrameLayout;
+import com.android.launcher3.R;
+
+public class RecentsViewContainer extends InsettableFrameLayout {
+ public static final FloatProperty<RecentsViewContainer> CONTENT_ALPHA =
+ new FloatProperty<RecentsViewContainer>("contentAlpha") {
+ @Override
+ public void setValue(RecentsViewContainer view, float v) {
+ view.setContentAlpha(v);
+ }
+
+ @Override
+ public Float get(RecentsViewContainer view) {
+ return view.mRecentsView.getContentAlpha();
+ }
+ };
+
+ private final Rect mTempRect = new Rect();
+
+ private RecentsView mRecentsView;
+ private View mClearAllButton;
+
+ public RecentsViewContainer(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+
+ mClearAllButton = findViewById(R.id.clear_all_button);
+ mClearAllButton.setOnClickListener((v) -> {
+ mRecentsView.dismissAllTasks();
+ });
+
+ mRecentsView = (RecentsView) findViewById(R.id.overview_panel);
+ mRecentsView.setContainerView(this);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+ mRecentsView.getTaskSize(mTempRect);
+
+ mClearAllButton.setTranslationX(
+ (mClearAllButton.getMeasuredWidth() - getResources().getDimension(
+ R.dimen.clear_all_container_width)) / 2);
+ mClearAllButton.setTranslationY(
+ mTempRect.top + (mTempRect.height() - mClearAllButton.getMeasuredHeight()) / 2);
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ super.onTouchEvent(ev);
+ // Do not let touch escape to siblings below this view. This prevents scrolling of the
+ // workspace while in Recents.
+ return true;
+ }
+
+ public void setContentAlpha(float alpha) {
+ if (alpha == mRecentsView.getContentAlpha()) {
+ return;
+ }
+ mRecentsView.setContentAlpha(alpha);
+ setVisibility(alpha > 0 ? VISIBLE : GONE);
+ }
+
+ public void onEmptyStateChanged(boolean isEmpty) {
+ mClearAllButton.setVisibility(isEmpty ? GONE : VISIBLE);
+ }
+}
\ No newline at end of file
diff --git a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
index 6473d16..2f7199b 100644
--- a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
@@ -148,20 +148,18 @@
}
int width = getMeasuredWidth();
int height = getMeasuredHeight();
- if (mClipBottom > 0 && !mTask.isLocked) {
- canvas.save();
- canvas.clipRect(0, 0, width, mClipBottom);
- canvas.drawRoundRect(0, 0, width, height, mCornerRadius, mCornerRadius, mPaint);
- canvas.restore();
- canvas.save();
- canvas.clipRect(0, mClipBottom, width, height);
- canvas.drawRoundRect(0, 0, width, height, mCornerRadius, mCornerRadius,
- mBackgroundPaint);
- canvas.restore();
- } else {
- canvas.drawRoundRect(0, 0, width, height, mCornerRadius,
- mCornerRadius, mTask.isLocked ? mBackgroundPaint : mPaint);
+ // Always draw the background since the snapshots may be translucent
+ canvas.drawRoundRect(0, 0, width, height, mCornerRadius, mCornerRadius, mBackgroundPaint);
+ if (!mTask.isLocked) {
+ if (mClipBottom > 0) {
+ canvas.save();
+ canvas.clipRect(0, 0, width, mClipBottom);
+ canvas.drawRoundRect(0, 0, width, height, mCornerRadius, mCornerRadius, mPaint);
+ canvas.restore();
+ } else {
+ canvas.drawRoundRect(0, 0, width, height, mCornerRadius, mCornerRadius, mPaint);
+ }
}
}
diff --git a/res/layout/launcher.xml b/res/layout/launcher.xml
index a4acf06..6556adf 100644
--- a/res/layout/launcher.xml
+++ b/res/layout/launcher.xml
@@ -40,7 +40,7 @@
launcher:pageIndicator="@+id/page_indicator" />
<include
- android:id="@+id/overview_panel"
+ android:id="@+id/overview_panel_container"
layout="@layout/overview_panel"
android:visibility="gone" />
diff --git a/res/values/config.xml b/res/values/config.xml
index a40afe1..9d1bb41 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -147,6 +147,7 @@
<item type="id" name="search_container_all_apps" />
<!-- Recents -->
+ <item type="id" name="overview_panel"/>
<integer name="config_recentsMaxThumbnailCacheSize">6</integer>
<integer name="config_recentsMaxIconCacheSize">12</integer>
diff --git a/src/com/android/launcher3/BaseActivity.java b/src/com/android/launcher3/BaseActivity.java
index f197921..a41edc0 100644
--- a/src/com/android/launcher3/BaseActivity.java
+++ b/src/com/android/launcher3/BaseActivity.java
@@ -144,7 +144,7 @@
@Override
protected void onStop() {
- mActivityFlags &= ~ACTIVITY_STATE_STARTED;
+ mActivityFlags &= ~ACTIVITY_STATE_STARTED & ~ACTIVITY_STATE_USER_ACTIVE;
mForceInvisible = 0;
super.onStop();
}
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 41bfcb7..fb7c0ce 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -65,27 +65,6 @@
private static final int[] STATE_PRESSED = new int[] {android.R.attr.state_pressed};
- private final BaseDraggingActivity mActivity;
- private Drawable mIcon;
- private final boolean mCenterVertically;
-
- private final CheckLongPressHelper mLongPressHelper;
- private final StylusEventHelper mStylusEventHelper;
- private final float mSlop;
-
- private final boolean mLayoutHorizontal;
- private final int mIconSize;
- @ViewDebug.ExportedProperty(category = "launcher")
- private int mTextColor;
- private boolean mIsIconVisible = true;
-
- private BadgeInfo mBadgeInfo;
- private BadgeRenderer mBadgeRenderer;
- private int mBadgeColor;
- private float mBadgeScale;
- private boolean mForceHideBadge;
- private Point mTempSpaceForBadgeOffset = new Point();
- private Rect mTempIconBounds = new Rect();
private static final Property<BubbleTextView, Float> BADGE_SCALE_PROPERTY
= new Property<BubbleTextView, Float>(Float.TYPE, "badgeScale") {
@@ -101,19 +80,45 @@
}
};
- public static final Property<BubbleTextView, Integer> TEXT_ALPHA_PROPERTY
- = new Property<BubbleTextView, Integer>(Integer.class, "textAlpha") {
+ public static final Property<BubbleTextView, Float> TEXT_ALPHA_PROPERTY
+ = new Property<BubbleTextView, Float>(Float.class, "textAlpha") {
@Override
- public Integer get(BubbleTextView bubbleTextView) {
- return bubbleTextView.getTextAlpha();
+ public Float get(BubbleTextView bubbleTextView) {
+ return bubbleTextView.mTextAlpha;
}
@Override
- public void set(BubbleTextView bubbleTextView, Integer alpha) {
+ public void set(BubbleTextView bubbleTextView, Float alpha) {
bubbleTextView.setTextAlpha(alpha);
}
};
+ private final BaseDraggingActivity mActivity;
+ private Drawable mIcon;
+ private final boolean mCenterVertically;
+
+ private final CheckLongPressHelper mLongPressHelper;
+ private final StylusEventHelper mStylusEventHelper;
+ private final float mSlop;
+
+ private final boolean mLayoutHorizontal;
+ private final int mIconSize;
+
+ @ViewDebug.ExportedProperty(category = "launcher")
+ private boolean mIsIconVisible = true;
+ @ViewDebug.ExportedProperty(category = "launcher")
+ private int mTextColor;
+ @ViewDebug.ExportedProperty(category = "launcher")
+ private float mTextAlpha = 1;
+
+ private BadgeInfo mBadgeInfo;
+ private BadgeRenderer mBadgeRenderer;
+ private int mBadgeColor;
+ private float mBadgeScale;
+ private boolean mForceHideBadge;
+ private Point mTempSpaceForBadgeOffset = new Point();
+ private Rect mTempIconBounds = new Rect();
+
@ViewDebug.ExportedProperty(category = "launcher")
private boolean mStayPressed;
@ViewDebug.ExportedProperty(category = "launcher")
@@ -166,7 +171,7 @@
setEllipsize(TruncateAt.END);
setAccessibilityDelegate(mActivity.getAccessibilityDelegate());
-
+ setTextAlpha(1f);
}
@Override
@@ -404,13 +409,17 @@
@Override
public void setTextColor(int color) {
mTextColor = color;
- super.setTextColor(color);
+ super.setTextColor(getModifiedColor());
}
@Override
public void setTextColor(ColorStateList colors) {
mTextColor = colors.getDefaultColor();
- super.setTextColor(colors);
+ if (Float.compare(mTextAlpha, 1) == 0) {
+ super.setTextColor(colors);
+ } else {
+ super.setTextColor(getModifiedColor());
+ }
}
public boolean shouldTextBeVisible() {
@@ -421,19 +430,21 @@
}
public void setTextVisibility(boolean visible) {
- if (visible) {
- super.setTextColor(mTextColor);
- } else {
- setTextAlpha(0);
+ setTextAlpha(visible ? 1 : 0);
+ }
+
+ private void setTextAlpha(float alpha) {
+ mTextAlpha = alpha;
+ super.setTextColor(getModifiedColor());
+ }
+
+ private int getModifiedColor() {
+ if (mTextAlpha == 0) {
+ // Special case to prevent text shadows in high contrast mode
+ return Color.TRANSPARENT;
}
- }
-
- public void setTextAlpha(int alpha) {
- super.setTextColor(ColorUtils.setAlphaComponent(mTextColor, alpha));
- }
-
- private int getTextAlpha() {
- return Color.alpha(getCurrentTextColor());
+ return ColorUtils.setAlphaComponent(
+ mTextColor, Math.round(Color.alpha(mTextColor) * mTextAlpha));
}
/**
@@ -441,8 +452,8 @@
* @param fadeIn Whether the text should fade in or fade out.
*/
public ObjectAnimator createTextAlphaAnimator(boolean fadeIn) {
- int toAlpha = shouldTextBeVisible() && fadeIn ? Color.alpha(mTextColor) : 0;
- return ObjectAnimator.ofInt(this, TEXT_ALPHA_PROPERTY, toAlpha);
+ float toAlpha = shouldTextBeVisible() && fadeIn ? 1 : 0;
+ return ObjectAnimator.ofFloat(this, TEXT_ALPHA_PROPERTY, toAlpha);
}
@Override
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 8840860..ec0a8ff 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -18,6 +18,7 @@
import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
+
import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_DELAY;
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.NORMAL;
@@ -205,6 +206,8 @@
// UI and state for the overview panel
private View mOverviewPanel;
+ private View mOverviewPanelContainer;
+
@Thunk boolean mWorkspaceLoading = true;
private OnResumeCallback mOnResumeCallback;
@@ -912,6 +915,7 @@
mWorkspace = mDragLayer.findViewById(R.id.workspace);
mWorkspace.initParentViews(mDragLayer);
mOverviewPanel = findViewById(R.id.overview_panel);
+ mOverviewPanelContainer = findViewById(R.id.overview_panel_container);
mHotseat = findViewById(R.id.hotseat);
mDragHandleIndicator = findViewById(R.id.drag_indicator);
mHotseatSearchBox = findViewById(R.id.search_container_hotseat);
@@ -1192,6 +1196,10 @@
return (T) mOverviewPanel;
}
+ public <T extends View> T getOverviewPanelContainer() {
+ return (T) mOverviewPanelContainer;
+ }
+
public DropTargetBar getDropTargetBar() {
return mDropTargetBar;
}
diff --git a/src/com/android/launcher3/compat/WallpaperManagerCompat.java b/src/com/android/launcher3/compat/WallpaperManagerCompat.java
index 00258c7..6605ace 100644
--- a/src/com/android/launcher3/compat/WallpaperManagerCompat.java
+++ b/src/com/android/launcher3/compat/WallpaperManagerCompat.java
@@ -31,7 +31,7 @@
if (sInstance == null) {
context = context.getApplicationContext();
- if (Utilities.ATLEAST_OREO) {
+ if (Utilities.ATLEAST_OREO_MR1) {
try {
sInstance = new WallpaperManagerCompatVOMR1(context);
} catch (Throwable e) {
diff --git a/src/com/android/launcher3/folder/FolderAnimationManager.java b/src/com/android/launcher3/folder/FolderAnimationManager.java
index ec448e9..9ae3775 100644
--- a/src/com/android/launcher3/folder/FolderAnimationManager.java
+++ b/src/com/android/launcher3/folder/FolderAnimationManager.java
@@ -16,6 +16,7 @@
package com.android.launcher3.folder;
+import static com.android.launcher3.BubbleTextView.TEXT_ALPHA_PROPERTY;
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.MAX_NUM_ITEMS_IN_PREVIEW;
@@ -172,9 +173,8 @@
AnimatorSet a = LauncherAnimUtils.createAnimatorSet();
// Initialize the Folder items' text.
- PropertyResetListener colorResetListener = new PropertyResetListener<>(
- BubbleTextView.TEXT_ALPHA_PROPERTY,
- Color.alpha(Themes.getAttrColor(mContext, android.R.attr.textColorSecondary)));
+ PropertyResetListener colorResetListener =
+ new PropertyResetListener<>(TEXT_ALPHA_PROPERTY, 1f);
for (BubbleTextView icon : mFolder.getItemsOnPage(mFolder.mContent.getCurrentPage())) {
if (mIsOpening) {
icon.setTextVisibility(false);
diff --git a/src/com/android/launcher3/notification/NotificationListener.java b/src/com/android/launcher3/notification/NotificationListener.java
index 117287b..b527b6a 100644
--- a/src/com/android/launcher3/notification/NotificationListener.java
+++ b/src/com/android/launcher3/notification/NotificationListener.java
@@ -150,22 +150,12 @@
public void onCreate() {
super.onCreate();
sIsCreated = true;
- mNotificationBadgingObserver = new SettingsObserver.Secure(getContentResolver()) {
- @Override
- public void onSettingChanged(boolean isNotificationBadgingEnabled) {
- if (!isNotificationBadgingEnabled) {
- requestUnbind();
- }
- }
- };
- mNotificationBadgingObserver.register(NOTIFICATION_BADGING);
}
@Override
public void onDestroy() {
super.onDestroy();
sIsCreated = false;
- mNotificationBadgingObserver.unregister();
}
public static @Nullable NotificationListener getInstanceIfConnected() {
@@ -203,6 +193,17 @@
public void onListenerConnected() {
super.onListenerConnected();
sIsConnected = true;
+
+ mNotificationBadgingObserver = new SettingsObserver.Secure(getContentResolver()) {
+ @Override
+ public void onSettingChanged(boolean isNotificationBadgingEnabled) {
+ if (!isNotificationBadgingEnabled) {
+ requestUnbind();
+ }
+ }
+ };
+ mNotificationBadgingObserver.register(NOTIFICATION_BADGING);
+
onNotificationFullRefresh();
}
@@ -214,6 +215,7 @@
public void onListenerDisconnected() {
super.onListenerDisconnected();
sIsConnected = false;
+ mNotificationBadgingObserver.unregister();
}
@Override