Merge "Add WorkspaceRevealAnim, successor to StaggeredWorkspaceAnim." into sc-dev
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index c459472..7c9a2b8 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -39,6 +39,11 @@
<dimen name="overview_grid_focus_vertical_margin">90dp</dimen>
<dimen name="split_placeholder_size">110dp</dimen>
+ <!-- These speeds are in dp/s -->
+ <dimen name="max_task_dismiss_drag_velocity">2.25dp</dimen>
+ <dimen name="default_task_dismiss_drag_velocity">1.75dp</dimen>
+ <dimen name="default_task_dismiss_drag_velocity_grid">0.75dp</dimen>
+
<dimen name="recents_page_spacing">16dp</dimen>
<dimen name="recents_clear_all_deadzone_vertical_margin">70dp</dimen>
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java
index 0014b85..3a8de3c 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java
@@ -19,13 +19,13 @@
import android.app.ActivityTaskManager;
import android.app.PendingIntent;
import android.content.Intent;
-import android.os.Build;
import android.os.RemoteException;
import android.util.Log;
import android.util.Pair;
import android.view.View;
import android.widget.RemoteViews;
+import com.android.launcher3.Utilities;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.util.ActivityOptionsWrapper;
import com.android.launcher3.widget.LauncherAppWidgetHostView;
@@ -41,6 +41,7 @@
mLauncher = launcher;
}
+ @SuppressWarnings("NewApi")
@Override
public boolean onInteraction(View view, PendingIntent pendingIntent,
RemoteViews.RemoteResponse remoteResponse) {
@@ -53,7 +54,7 @@
Pair<Intent, ActivityOptions> options = remoteResponse.getLaunchOptions(hostView);
ActivityOptionsWrapper activityOptions = mLauncher.getAppTransitionManager()
.getActivityLaunchOptions(mLauncher, hostView);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && !pendingIntent.isActivity()) {
+ if (Utilities.ATLEAST_S && !pendingIntent.isActivity()) {
// In the event this pending intent eventually launches an activity, i.e. a trampoline,
// use the Quickstep transition animation.
try {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java b/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
index 77c2611..01c9e76 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
@@ -19,6 +19,7 @@
import android.content.Context;
import android.graphics.Color;
+import android.os.SystemProperties;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.DeviceProfile;
@@ -84,7 +85,8 @@
@Override
protected float getDepthUnchecked(Context context) {
- return 1f;
+ //TODO revert when b/178661709 is fixed
+ return SystemProperties.getBoolean("ro.launcher.depth.appLaunch", true) ? 1 : 0;
}
@Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
index 45791a3..8c128c8 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
@@ -20,6 +20,7 @@
import android.content.Context;
import android.graphics.Rect;
+import android.os.SystemProperties;
import android.view.View;
import com.android.launcher3.DeviceProfile;
@@ -127,7 +128,8 @@
@Override
protected float getDepthUnchecked(Context context) {
- return 1f;
+ //TODO revert when b/178661709 is fixed
+ return SystemProperties.getBoolean("ro.launcher.depth.overview", true) ? 1 : 0;
}
@Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java
index 70b3870..c6ea953 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java
@@ -28,6 +28,7 @@
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.LauncherAnimUtils;
+import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.Interpolators;
@@ -50,6 +51,10 @@
extends AnimatorListenerAdapter implements TouchController,
SingleAxisSwipeDetector.Listener {
+ private static final float ANIMATION_PROGRESS_FRACTION_MIDPOINT = 0.5f;
+ private static final long MIN_TASK_DISMISS_ANIMATION_DURATION = 300;
+ private static final long MAX_TASK_DISMISS_ANIMATION_DURATION = 600;
+
protected final T mActivity;
private final SingleAxisSwipeDetector mDetector;
private final RecentsView mRecentsView;
@@ -277,14 +282,32 @@
} else {
mFlingBlockCheck.onEvent();
}
- mCurrentAnimation.setPlayFraction(Utilities.boundToRange(
- totalDisplacement * mProgressMultiplier, 0, 1));
+
+ // Once halfway through task dismissal interpolation, switch from reversible dragging-task
+ // animation to playing the remaining task translation animations
+ if (mCurrentAnimation.getProgressFraction() < ANIMATION_PROGRESS_FRACTION_MIDPOINT) {
+ // Halve the value as we are animating the drag across the full length for only the
+ // first half of the progress
+ mCurrentAnimation.setPlayFraction(
+ Utilities.boundToRange(totalDisplacement * mProgressMultiplier / 2, 0, 1));
+ } else {
+ float dragVelocity = -mTaskBeingDragged.getResources().getDimension(
+ mRecentsView.showAsGrid() ? R.dimen.default_task_dismiss_drag_velocity_grid
+ : R.dimen.default_task_dismiss_drag_velocity);
+ onDragEnd(dragVelocity);
+ return true;
+ }
return true;
}
@Override
public void onDragEnd(float velocity) {
+ // Limit velocity, as very large scalar values make animations play too quickly
+ float maxTaskDismissDragVelocity = mTaskBeingDragged.getResources().getDimension(
+ R.dimen.max_task_dismiss_drag_velocity);
+ velocity = Utilities.boundToRange(velocity, -maxTaskDismissDragVelocity,
+ maxTaskDismissDragVelocity);
boolean fling = mDetector.isFling(velocity);
final boolean goingToEnd;
boolean blockedFling = fling && mFlingBlockCheck.isBlocked();
@@ -305,6 +328,11 @@
if (blockedFling && !goingToEnd) {
animationDuration *= LauncherAnimUtils.blockedFlingDurationFactor(velocity);
}
+ // Due to very high or low velocity dismissals, animation durations can be inconsistently
+ // long or short. Bound the duration for animation of task translations for a more
+ // standardized feel.
+ animationDuration = Utilities.boundToRange(animationDuration,
+ MIN_TASK_DISMISS_ANIMATION_DURATION, MAX_TASK_DISMISS_ANIMATION_DURATION);
mCurrentAnimation.setEndAction(this::clearState);
mCurrentAnimation.startWithVelocity(mActivity, goingToEnd,
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
index 6fb938a..acf9992 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.java
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -107,6 +107,17 @@
}
@Override
+ public void setHomeRotationEnabled(boolean enabled) {
+ if (mSystemUiProxy != null) {
+ try {
+ mSystemUiProxy.setHomeRotationEnabled(enabled);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed call onBackPressed", e);
+ }
+ }
+ }
+
+ @Override
public IBinder asBinder() {
// Do nothing
return null;
diff --git a/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java b/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java
index 76f43c9..6f681b3 100644
--- a/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java
+++ b/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java
@@ -45,8 +45,8 @@
private static final String LOG_TAG = "AllSetActivity";
private static final String URI_SYSTEM_NAVIGATION_SETTING =
"#Intent;action=com.android.settings.SEARCH_RESULT_TRAMPOLINE;S.:settings:fragment_args_key=gesture_system_navigation_input_summary;S.:settings:show_fragment=com.android.settings.gestures.SystemNavigationGestureSettings;end";
- private static final String EXTRA_ACCENT_COLOR_DARK_MODE = "accent_color_dark_mode";
- private static final String EXTRA_ACCENT_COLOR_LIGHT_MODE = "accent_color_light_mode";
+ private static final String EXTRA_ACCENT_COLOR_DARK_MODE = "suwColorAccentDark";
+ private static final String EXTRA_ACCENT_COLOR_LIGHT_MODE = "suwColorAccentLight";
private int mAccentColor;
diff --git a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
index e983f46..bfd9008 100644
--- a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
+++ b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
@@ -51,6 +51,7 @@
import com.android.launcher3.util.SettingsCache;
import com.android.launcher3.util.WindowBounds;
import com.android.quickstep.BaseActivityInterface;
+import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.views.TaskView;
import java.lang.annotation.Retention;
@@ -287,8 +288,9 @@
}
private void updateHomeRotationSetting() {
- setFlag(FLAG_HOME_ROTATION_ALLOWED_IN_PREFS,
- mSharedPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY, false));
+ boolean homeRotationEnabled = mSharedPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY, false);
+ setFlag(FLAG_HOME_ROTATION_ALLOWED_IN_PREFS, homeRotationEnabled);
+ SystemUiProxy.INSTANCE.get(mContext).setHomeRotationEnabled(homeRotationEnabled);
}
private void initFlags() {
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 7cd2a6a..4cdae27 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -32,11 +32,12 @@
import static com.android.launcher3.Utilities.squaredHypot;
import static com.android.launcher3.Utilities.squaredTouchSlop;
import static com.android.launcher3.anim.Interpolators.ACCEL;
+import static com.android.launcher3.anim.Interpolators.ACCEL_0_5;
import static com.android.launcher3.anim.Interpolators.ACCEL_0_75;
-import static com.android.launcher3.anim.Interpolators.ACCEL_2;
import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
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.Interpolators.clampToProgress;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_CLEAR_ALL;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_DISMISS_SWIPE_UP;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_LAUNCH_SWIPE_DOWN;
@@ -336,6 +337,11 @@
// OverScroll constants
private static final int OVERSCROLL_PAGE_SNAP_ANIMATION_DURATION = 270;
+ private static final int DISMISS_TASK_DURATION = 300;
+ private static final int ADDITION_TASK_DURATION = 200;
+ private static final float INITIAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET = 0.55f;
+ private static final float ADDITIONAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET = 0.05f;
+
protected final RecentsOrientedState mOrientationState;
protected final BaseActivityInterface<STATE_TYPE, ACTIVITY_TYPE> mSizeStrategy;
protected RecentsAnimationController mRecentsAnimationController;
@@ -358,10 +364,6 @@
private final List<OnScrollChangedListener> mScrollListeners = new ArrayList<>();
private float mFullscreenScale;
- private static final int DISMISS_TASK_DURATION = 300;
- private static final int DISMISS_TASK_TRANSLATION_DURATION = 200;
- private static final int ADDITIONAL_DISMISS_TASK_TRANSLATION_DURATION = 75;
- private static final int ADDITION_TASK_DURATION = 200;
// The threshold at which we update the SystemUI flags when animating from the task into the app
public static final float UPDATE_SYSUI_FLAGS_THRESHOLD = 0.85f;
@@ -1886,21 +1888,18 @@
* This method is used when no task dismissal has occurred.
*/
private void updateGridProperties() {
- updateGridProperties(null, -1);
+ updateGridProperties(false);
}
/**
* Updates TaskView and ClearAllButton scaling and translation required to turn into grid
* layout.
* This method only calculates the potential position and depends on {@link #setGridProgress} to
- * apply the actual scaling and translation. This adds task translation animations in the case
- * of task dismissals: e.g. when dismissedTask is not null.
+ * apply the actual scaling and translation.
*
- * @param dismissedTask the TaskView dismissed, possibly null
- * @param dismissedIndex the index at which the dismissedTask was prior to dismissal, if no
- * dismissal occurred, this is unused
+ * @param isTaskDismissal indicates if update was called due to task dismissal
*/
- private void updateGridProperties(TaskView dismissedTask, int dismissedIndex) {
+ private void updateGridProperties(boolean isTaskDismissal) {
int taskCount = getTaskViewCount();
if (taskCount == 0) {
return;
@@ -1940,10 +1939,6 @@
int snappedPage = getNextPage();
TaskView snappedTaskView = getTaskViewAtByAbsoluteIndex(snappedPage);
- boolean isTaskDismissal = dismissedTask != null;
- float dismissedTaskWidth =
- isTaskDismissal ? dismissedTask.getLayoutParams().width + mPageSpacing : 0;
-
if (!isTaskDismissal) {
mTopRowIdSet.clear();
}
@@ -2039,34 +2034,13 @@
snappedTaskGridTranslationX = gridTranslations[snappedPage - mTaskViewStartIndex];
}
- // Animate task dismissTranslationX for tasks with index >= dismissed index and in the
- // same row as the dismissed index, or if the dismissed task was the focused task. Offset
- // successive task dismissal durations for a staggered effect.
- ArrayList<Animator> gridTranslationAnimators = new ArrayList<>();
- boolean isFocusedTaskDismissed =
- isTaskDismissal && dismissedTask.getTask().key.id == mFocusedTaskId;
for (int i = 0; i < taskCount; i++) {
TaskView taskView = getTaskViewAt(i);
- if (isFocusedTaskDismissed || (i >= dismissedIndex && isSameGridRow(dismissedTask,
- taskView))) {
- Animator taskDismissAnimator = ObjectAnimator.ofFloat(taskView,
- taskView.getPrimaryDismissTranslationProperty(),
- mIsRtl ? -dismissedTaskWidth : dismissedTaskWidth, 0f);
- int additionalTranslationDuration =
- i >= dismissedIndex ? (ADDITIONAL_DISMISS_TASK_TRANSLATION_DURATION * (
- (i - dismissedIndex) / 2)) : 0;
- taskDismissAnimator.setDuration(
- DISMISS_TASK_TRANSLATION_DURATION + additionalTranslationDuration);
- gridTranslationAnimators.add(taskDismissAnimator);
- }
taskView.setGridTranslationX(gridTranslations[i] - snappedTaskGridTranslationX);
taskView.getPrimaryNonFullscreenTranslationProperty().set(taskView,
snappedTaskFullscreenScrollAdjustment);
taskView.getSecondaryNonFullscreenTranslationProperty().set(taskView, 0f);
}
- AnimatorSet gridTranslationAnimatorSet = new AnimatorSet();
- gridTranslationAnimatorSet.playTogether(gridTranslationAnimators);
- gridTranslationAnimatorSet.start();
// Use the accumulated translation of the row containing the last task.
float clearAllAccumulatedTranslation = topSet.contains(taskCount - 1)
@@ -2210,7 +2184,7 @@
PendingAnimation anim) {
// Use setFloat instead of setViewAlpha as we want to keep the view visible even when it's
// alpha is set to 0 so that it can be recycled in the view pool properly
- anim.setFloat(taskView, VIEW_ALPHA, 0, ACCEL_2);
+ anim.setFloat(taskView, VIEW_ALPHA, 0, clampToProgress(ACCEL, 0, 0.5f));
SplitSelectStateController splitController = mSplitPlaceholderView.getSplitController();
ResourceProvider rp = DynamicResource.provider(mActivity);
@@ -2246,8 +2220,10 @@
throw new IllegalStateException("Invalid split task translation: " + dir);
}
}
+ // Double translation distance so dismissal drag is the full height, as we only animate
+ // the drag for the first half of the progress.
anim.add(ObjectAnimator.ofFloat(taskView, dismissingTaskViewTranslate,
- positiveNegativeFactor * translateDistance).setDuration(duration), LINEAR, sp);
+ positiveNegativeFactor * translateDistance * 2).setDuration(duration), LINEAR, sp);
if (LIVE_TILE.get() && taskView.isRunningTask()) {
anim.addOnFrameCallback(() -> {
@@ -2283,6 +2259,11 @@
}
int draggedIndex = indexOfChild(taskView);
+ boolean isFocusedTaskDismissed = taskView.getTask().key.id == mFocusedTaskId;
+ if (isFocusedTaskDismissed && showAsGrid()) {
+ anim.setFloat(mActionsView, VIEW_ALPHA, 0, clampToProgress(ACCEL_0_5, 0, 0.5f));
+ }
+ float dismissedTaskWidth = taskView.getLayoutParams().width + mPageSpacing;
boolean needsCurveUpdates = false;
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
@@ -2291,7 +2272,7 @@
addDismissedTaskAnimations(taskView, duration, anim);
}
} else if (!showAsGrid()) {
- // For grid layout, don't animate other tasks when dismissing in grid for now.
+ // Compute scroll offsets from task dismissal for animation.
// If we just take newScroll - oldScroll, everything to the right of dragged task
// translates to the left. We need to offset this in some cases:
// - In RTL, add page offset to all pages, since we want pages to move to the right
@@ -2318,15 +2299,31 @@
? ((TaskView) child).getPrimaryDismissTranslationProperty()
: mOrientationHandler.getPrimaryViewTranslate();
- ResourceProvider rp = DynamicResource.provider(mActivity);
- SpringProperty sp = new SpringProperty(SpringProperty.FLAG_CAN_SPRING_ON_END)
- .setDampingRatio(
- rp.getFloat(R.dimen.dismiss_task_trans_x_damping_ratio))
- .setStiffness(rp.getFloat(R.dimen.dismiss_task_trans_x_stiffness));
- anim.add(ObjectAnimator.ofFloat(child, translationProperty, scrollDiff)
- .setDuration(duration), ACCEL, sp);
+ float additionalDismissDuration =
+ ADDITIONAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET * Math.abs(
+ i - draggedIndex);
+ anim.setFloat(child, translationProperty, scrollDiff, clampToProgress(LINEAR,
+ Utilities.boundToRange(INITIAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET
+ + additionalDismissDuration, 0f, 1f), 1));
needsCurveUpdates = true;
}
+ } else if (child instanceof TaskView) {
+ // Animate task with index >= dismissed index and in the same row as the
+ // dismissed index, or if the dismissed task was the focused task. Offset
+ // successive task dismissal durations for a staggered effect.
+ if (isFocusedTaskDismissed || (i >= draggedIndex && isSameGridRow((TaskView) child,
+ taskView))) {
+ FloatProperty translationProperty =
+ ((TaskView) child).getPrimaryDismissTranslationProperty();
+ float additionalDismissDuration =
+ ADDITIONAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET * Math.abs(
+ i - draggedIndex);
+ anim.setFloat(child, translationProperty,
+ !mIsRtl ? -dismissedTaskWidth : dismissedTaskWidth,
+ clampToProgress(LINEAR, Utilities.boundToRange(
+ INITIAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET
+ + additionalDismissDuration, 0f, 1f), 1));
+ }
}
}
@@ -2364,6 +2361,10 @@
}
}
+ // Reset task translations as they may have updated via animations in
+ // createTaskDismissAnimation
+ resetTaskVisuals();
+
int pageToSnapTo = mCurrentPage;
// Snap to start if focused task was dismissed, as after quick switch it could
// be at any page but the focused task always displays at the start.
@@ -2381,7 +2382,7 @@
} else {
snapToPageImmediately(pageToSnapTo);
// Grid got messed up, reapply.
- updateGridProperties(taskView, draggedIndex - mTaskViewStartIndex);
+ updateGridProperties(true);
if (showAsGrid() && getFocusedTaskView() == null
&& mActionsView.getVisibilityAlpha().getValue() == 1) {
animateActionsViewOut();
@@ -2391,9 +2392,6 @@
// immediately available.
onLayout(false /* changed */, getLeft(), getTop(), getRight(), getBottom());
}
- if (!showAsGrid()) {
- resetTaskVisuals();
- }
onDismissAnimationEnds();
mPendingAnimation = null;
}
@@ -2617,6 +2615,16 @@
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
+ if (LIVE_TILE.get()) {
+ switchToScreenshot(
+ () -> finishRecentsAnimation(true /* toRecents */,
+ this::onConfigurationChangedInternal));
+ } else {
+ onConfigurationChangedInternal();
+ }
+ }
+
+ private void onConfigurationChangedInternal() {
final int rotation = mActivity.getDisplay().getRotation();
if (mOrientationState.setRecentsRotation(rotation)) {
updateOrientationHandler();
@@ -3711,7 +3719,8 @@
return mColorTint;
}
- private boolean showAsGrid() {
+ /** Returns {@code true} if the overview tasks are displayed as a grid. */
+ public boolean showAsGrid() {
return mOverviewGridEnabled || (mCurrentGestureEndTarget != null
&& mSizeStrategy.stateFromGestureEndTarget(
mCurrentGestureEndTarget).displayOverviewTasksAsGrid(mActivity.getDeviceProfile()));
diff --git a/quickstep/src/com/android/quickstep/views/TaskMenuView.java b/quickstep/src/com/android/quickstep/views/TaskMenuView.java
index 32cd367..bff1013 100644
--- a/quickstep/src/com/android/quickstep/views/TaskMenuView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskMenuView.java
@@ -215,6 +215,7 @@
RecentsView recentsView = mTaskView.getRecentsView();
recentsView.switchToScreenshot(null,
() -> recentsView.finishRecentsAnimation(true /* toRecents */,
+ false /* shouldPip */,
() -> menuOption.onClick(view)));
} else {
menuOption.onClick(view);
diff --git a/res/drawable/bg_widgets_picker_handle.xml b/res/drawable/bg_widgets_picker_handle.xml
new file mode 100644
index 0000000..68681a6
--- /dev/null
+++ b/res/drawable/bg_widgets_picker_handle.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 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.
+-->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item>
+ <shape android:shape="rectangle">
+ <solid android:color="?android:attr/colorBackground" />
+ <padding android:top="16dp"/>
+ </shape>
+ </item>
+ <item android:gravity="center">
+ <shape android:shape="rectangle">
+ <solid android:color="?android:attr/textColorSecondary" />
+ <size android:width="48dp" android:height="2dp" />
+ </shape>
+ </item>
+</layer-list>
\ No newline at end of file
diff --git a/res/drawable/personal_work_tabs_ripple.xml b/res/drawable/personal_work_tabs_ripple.xml
new file mode 100644
index 0000000..2e57b80
--- /dev/null
+++ b/res/drawable/personal_work_tabs_ripple.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 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.
+-->
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+ android:color="?android:attr/colorControlHighlight">
+ <shape android:shape="rectangle">
+ <solid android:color="@android:color/transparent" />
+ <corners android:radius="@dimen/all_apps_header_pill_corner_radius" />
+ </shape>
+</ripple>
\ No newline at end of file
diff --git a/res/layout/all_apps_personal_work_tabs.xml b/res/layout/all_apps_personal_work_tabs.xml
index 750e101..31fa5cf 100644
--- a/res/layout/all_apps_personal_work_tabs.xml
+++ b/res/layout/all_apps_personal_work_tabs.xml
@@ -32,7 +32,7 @@
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
- android:background="?android:attr/selectableItemBackground"
+ android:background="@drawable/personal_work_tabs_ripple"
android:text="@string/all_apps_personal_tab"
android:textColor="@color/all_apps_tab_text"
android:textSize="16sp" />
@@ -42,7 +42,7 @@
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
- android:background="?android:attr/selectableItemBackground"
+ android:background="@drawable/personal_work_tabs_ripple"
android:text="@string/all_apps_work_tab"
android:textColor="@color/all_apps_tab_text"
android:textSize="16sp" />
diff --git a/res/layout/widgets_full_sheet_search_and_recommendations.xml b/res/layout/widgets_full_sheet_search_and_recommendations.xml
index ce7a682..a89f85f 100644
--- a/res/layout/widgets_full_sheet_search_and_recommendations.xml
+++ b/res/layout/widgets_full_sheet_search_and_recommendations.xml
@@ -18,35 +18,44 @@
android:id="@+id/search_and_recommendations_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingHorizontal="16dp"
android:layout_marginBottom="16dp"
- android:orientation="vertical"
- android:clipToPadding="false">
+ android:orientation="vertical">
+
<View
android:id="@+id/collapse_handle"
- android:layout_width="48dp"
- android:layout_height="2dp"
- android:layout_marginTop="16dp"
- android:elevation="2dp"
- android:layout_gravity="center_horizontal"
- android:background="?android:attr/textColorSecondary"/>
+ android:layout_width="match_parent"
+ android:layout_height="18dp"
+ android:elevation="0.1dp"
+ android:background="@drawable/bg_widgets_picker_handle"/>
+
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:textSize="24sp"
- android:layout_marginTop="16dp"
+ android:layout_marginTop="24dp"
android:textColor="?android:attr/textColorSecondary"
android:text="@string/widget_button_text"/>
- <include layout="@layout/widgets_search_bar"/>
+
+ <FrameLayout
+ android:id="@+id/search_bar_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:elevation="0.1dp"
+ android:background="?android:attr/colorBackground"
+ android:paddingBottom="8dp"
+ android:clipToPadding="false">
+ <include layout="@layout/widgets_search_bar" />
+ </FrameLayout>
<com.android.launcher3.widget.picker.WidgetsRecommendationTableLayout
android:id="@+id/recommended_widget_table"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_marginHorizontal="16dp"
+ android:layout_marginTop="8dp"
android:background="@drawable/widgets_recommendation_background"
android:paddingVertical="@dimen/recommended_widgets_table_vertical_padding"
- android:layout_marginTop="16dp"
- android:visibility="gone"/>
+ android:visibility="gone" />
</com.android.launcher3.widget.picker.SearchAndRecommendationsView>
diff --git a/res/layout/widgets_personal_work_tabs.xml b/res/layout/widgets_personal_work_tabs.xml
index f835b52..72d83e8 100644
--- a/res/layout/widgets_personal_work_tabs.xml
+++ b/res/layout/widgets_personal_work_tabs.xml
@@ -22,6 +22,7 @@
android:layout_height="@dimen/all_apps_header_pill_height"
android:layout_marginHorizontal="16dp"
android:orientation="horizontal"
+ android:background="@drawable/all_apps_tabs_background"
android:elevation="2dp"
style="@style/TextHeadline">
@@ -30,7 +31,7 @@
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
- android:background="?android:attr/selectableItemBackground"
+ android:background="@drawable/personal_work_tabs_ripple"
android:text="@string/widgets_full_sheet_personal_tab"
android:textColor="@color/all_apps_tab_text"
android:textSize="14sp" />
@@ -40,7 +41,7 @@
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
- android:background="?android:attr/selectableItemBackground"
+ android:background="@drawable/personal_work_tabs_ripple"
android:text="@string/widgets_full_sheet_work_tab"
android:textColor="@color/all_apps_tab_text"
android:textSize="14sp" />
diff --git a/res/layout/widgets_search_bar.xml b/res/layout/widgets_search_bar.xml
index 2467156..6a4bb4d 100644
--- a/res/layout/widgets_search_bar.xml
+++ b/res/layout/widgets_search_bar.xml
@@ -5,10 +5,9 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
- android:layout_marginTop="16dp"
- android:layout_marginBottom="1dp"
- android:background="@drawable/bg_widgets_searchbox"
- android:elevation="2dp">
+ android:layout_marginTop="24dp"
+ android:layout_marginHorizontal="16dp"
+ android:background="@drawable/bg_widgets_searchbox">
<com.android.launcher3.ExtendedEditText
android:id="@+id/widgets_search_bar_edit_text"
diff --git a/res/values/id.xml b/res/values/id.xml
index 39c49bd..1bd40ce 100644
--- a/res/values/id.xml
+++ b/res/values/id.xml
@@ -15,6 +15,7 @@
limitations under the License.
-->
<resources>
+ <item type="id" name="apps_list_view_work" />
<item type="id" name="view_type_widgets_list" />
<item type="id" name="view_type_widgets_header" />
<item type="id" name="view_type_widgets_search_header" />
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 3fdcea5..1620d08 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -30,11 +30,13 @@
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
+import android.os.Parcelable;
import android.os.Process;
import android.text.Selection;
import android.text.SpannableStringBuilder;
import android.util.AttributeSet;
import android.util.Log;
+import android.util.SparseArray;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
@@ -133,6 +135,7 @@
private int mHeaderColor;
+
public AllAppsContainerView(Context context) {
this(context, null);
}
@@ -169,6 +172,19 @@
mAllAppsStore.addUpdateListener(this::onAppsUpdated);
}
+ @Override
+ protected void dispatchRestoreInstanceState(SparseArray<Parcelable> sparseArray) {
+ try {
+ // Many slice view id is not properly assigned, and hence throws null
+ // pointer exception in the underneath method. Catching the exception
+ // simply doesn't restore these slice views. This doesn't have any
+ // user visible effect because because we query them again.
+ super.dispatchRestoreInstanceState(sparseArray);
+ } catch (Exception e) {
+ Log.e("AllAppsContainerView", "restoreInstanceState viewId = 0", e);
+ }
+ }
+
/**
* Sets the long click listener for icons
*/
@@ -436,6 +452,7 @@
setupWorkToggle();
mAH[AdapterHolder.MAIN].setup(mViewPager.getChildAt(0), mPersonalMatcher);
mAH[AdapterHolder.WORK].setup(mViewPager.getChildAt(1), mWorkMatcher);
+ mAH[AdapterHolder.WORK].recyclerView.setId(R.id.apps_list_view_work);
mViewPager.getPageIndicator().setActiveMarker(AdapterHolder.MAIN);
findViewById(R.id.tab_personal)
.setOnClickListener((View view) -> {
diff --git a/src/com/android/launcher3/anim/Interpolators.java b/src/com/android/launcher3/anim/Interpolators.java
index 9d73bba..1e7b224 100644
--- a/src/com/android/launcher3/anim/Interpolators.java
+++ b/src/com/android/launcher3/anim/Interpolators.java
@@ -35,6 +35,7 @@
public static final Interpolator LINEAR = new LinearInterpolator();
public static final Interpolator ACCEL = new AccelerateInterpolator();
+ public static final Interpolator ACCEL_0_5 = new AccelerateInterpolator(0.5f);
public static final Interpolator ACCEL_0_75 = new AccelerateInterpolator(0.75f);
public static final Interpolator ACCEL_1_5 = new AccelerateInterpolator(1.5f);
public static final Interpolator ACCEL_2 = new AccelerateInterpolator(2);
@@ -149,11 +150,15 @@
*/
public static Interpolator clampToProgress(Interpolator interpolator, float lowerBound,
float upperBound) {
- if (upperBound <= lowerBound) {
- throw new IllegalArgumentException(String.format(
- "lowerBound (%f) must be less than upperBound (%f)", lowerBound, upperBound));
+ if (upperBound < lowerBound) {
+ throw new IllegalArgumentException(
+ String.format("upperBound (%f) must be greater than lowerBound (%f)",
+ upperBound, lowerBound));
}
return t -> {
+ if (t == lowerBound && t == upperBound) {
+ return t == 0f ? 0 : 1;
+ }
if (t < lowerBound) {
return 0;
}
diff --git a/src/com/android/launcher3/widget/picker/SearchAndRecommendationsScrollController.java b/src/com/android/launcher3/widget/picker/SearchAndRecommendationsScrollController.java
index 317fd03..34346ab 100644
--- a/src/com/android/launcher3/widget/picker/SearchAndRecommendationsScrollController.java
+++ b/src/com/android/launcher3/widget/picker/SearchAndRecommendationsScrollController.java
@@ -101,7 +101,7 @@
mCurrentRecyclerView.setOnContentChangeListener(mOnContentChangeListener);
mViewHolder.mHeaderTitle.setTranslationY(0);
mViewHolder.mRecommendedWidgetsTable.setTranslationY(0);
- mViewHolder.mSearchBar.setTranslationY(0);
+ mViewHolder.mSearchBarContainer.setTranslationY(0);
if (mHasWorkProfile) {
mPrimaryWorkTabsView.setTranslationY(0);
@@ -120,7 +120,7 @@
mCollapsibleHeightForRecommendation =
measureHeightWithVerticalMargins(mViewHolder.mHeaderTitle)
+ measureHeightWithVerticalMargins(mViewHolder.mCollapseHandle)
- + measureHeightWithVerticalMargins((View) mViewHolder.mSearchBar)
+ + measureHeightWithVerticalMargins((View) mViewHolder.mSearchBarContainer)
+ measureHeightWithVerticalMargins(mViewHolder.mRecommendedWidgetsTable);
int topContainerHeight = measureHeightWithVerticalMargins(mViewHolder.mContainer);
@@ -243,7 +243,7 @@
if (mCollapsibleHeightForSearch > 0) {
int searchYDisplacement = Math.max(-recyclerViewYOffset, -mCollapsibleHeightForSearch);
- mViewHolder.mSearchBar.setTranslationY(searchYDisplacement);
+ mViewHolder.mSearchBarContainer.setTranslationY(searchYDisplacement);
}
if (mHasWorkProfile && mCollapsibleHeightForTabs > 0) {
@@ -255,7 +255,7 @@
/** Resets any previous view translation. */
public void reset() {
mViewHolder.mHeaderTitle.setTranslationY(0);
- mViewHolder.mSearchBar.setTranslationY(0);
+ mViewHolder.mSearchBarContainer.setTranslationY(0);
if (mHasWorkProfile) {
mPrimaryWorkTabsView.setTranslationY(0);
}
diff --git a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
index 0ea50e6..e44acc3 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
@@ -713,6 +713,7 @@
final class SearchAndRecommendationViewHolder {
final SearchAndRecommendationsView mContainer;
final View mCollapseHandle;
+ final View mSearchBarContainer;
final WidgetsSearchBar mSearchBar;
final TextView mHeaderTitle;
final WidgetsRecommendationTableLayout mRecommendedWidgetsTable;
@@ -721,6 +722,7 @@
SearchAndRecommendationsView searchAndRecommendationContainer) {
mContainer = searchAndRecommendationContainer;
mCollapseHandle = mContainer.findViewById(R.id.collapse_handle);
+ mSearchBarContainer = mContainer.findViewById(R.id.search_bar_container);
mSearchBar = mContainer.findViewById(R.id.widgets_search_bar);
mHeaderTitle = mContainer.findViewById(R.id.title);
mRecommendedWidgetsTable = mContainer.findViewById(R.id.recommended_widget_table);
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index ca463e6..cbd9480 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -247,12 +247,26 @@
return mDevice;
}
+ private boolean hasSystemUiObject(String resId) {
+ return mDevice.hasObject(By.res(SYSTEMUI_PACKAGE, resId));
+ }
+
@Before
public void setUp() throws Exception {
mLauncher.onTestStart();
- Assert.assertTrue("Keyguard is visible, which is likely caused by a crash in SysUI",
+ Log.d(TAG, "Before disabling battery defender");
+ mDevice.executeShellCommand("setprop vendor.battery.defender.disable 1");
+ Log.d(TAG, "Before enabling stay awake");
+ mDevice.executeShellCommand("settings put global stay_on_while_plugged_in 3");
+ for (int i = 0; i < 10 && hasSystemUiObject("keyguard_status_view"); ++i) {
+ Log.d(TAG, "Before unlocking the phone");
+ mDevice.executeShellCommand("input keyevent 82");
+ mDevice.waitForIdle();
+ }
+ Assert.assertTrue("Keyguard still visible",
TestHelpers.wait(
Until.gone(By.res(SYSTEMUI_PACKAGE, "keyguard_status_view")), 60000));
+ Log.d(TAG, "Keyguard is not visible");
final String launcherPackageName = mDevice.getLauncherPackageName();
try {