Merge "Merge Android 12 QPR 3"

This commit is contained in:
Xin Li
2022-06-16 18:51:54 +00:00
committed by Gerrit Code Review
38 changed files with 493 additions and 216 deletions
@@ -39,6 +39,7 @@ import android.hardware.SensorManager;
import android.hardware.devicestate.DeviceStateManager;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.IBinder;
import android.view.View;
import android.view.WindowInsets;
import android.window.SplashScreen;
@@ -513,11 +514,26 @@ public abstract class BaseQuickstepLauncher extends Launcher
}
/**
* Adds a new launch cookie for the activity launch of the given {@param info} if supported.
* Adds a new launch cookie for the activity launch if supported.
*
* @param info the item info for the launch
* @param opts the options to set the launchCookie on.
*/
public void addLaunchCookie(ItemInfo info, ActivityOptions opts) {
IBinder launchCookie = getLaunchCookie(info);
if (launchCookie != null) {
opts.setLaunchCookie(launchCookie);
}
}
/**
* Return a new launch cookie for the activity launch if supported.
*
* @param info the item info for the launch
*/
public IBinder getLaunchCookie(ItemInfo info) {
if (info == null) {
return;
return null;
}
switch (info.container) {
case LauncherSettings.Favorites.CONTAINER_DESKTOP:
@@ -531,8 +547,7 @@ public abstract class BaseQuickstepLauncher extends Launcher
break;
}
// Reset any existing launch cookies associated with the cookie
opts.setLaunchCookie(ObjectWrapper.wrap(NO_MATCHING_ID));
return;
return ObjectWrapper.wrap(NO_MATCHING_ID);
}
switch (info.itemType) {
case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
@@ -543,10 +558,9 @@ public abstract class BaseQuickstepLauncher extends Launcher
break;
default:
// Reset any existing launch cookies associated with the cookie
opts.setLaunchCookie(ObjectWrapper.wrap(NO_MATCHING_ID));
return;
return ObjectWrapper.wrap(NO_MATCHING_ID);
}
opts.setLaunchCookie(ObjectWrapper.wrap(new Integer(info.id)));
return ObjectWrapper.wrap(new Integer(info.id));
}
public void setHintUserWillBeActive() {
@@ -44,6 +44,7 @@ import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_TRANSITIONS;
import static com.android.launcher3.model.data.ItemInfo.NO_MATCHING_ID;
import static com.android.launcher3.statehandlers.DepthController.DEPTH;
import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
import static com.android.launcher3.testing.TestProtocol.BAD_STATE;
import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATION;
import static com.android.launcher3.views.FloatingIconView.getFloatingIconView;
import static com.android.quickstep.TaskViewUtils.findTaskViewToLaunch;
@@ -75,6 +76,8 @@ import android.os.IBinder;
import android.os.Looper;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.Log;
import android.util.Pair;
import android.util.Size;
import android.view.SurfaceControl;
@@ -133,6 +136,7 @@ import com.android.systemui.shared.system.WindowManagerWrapper;
import com.android.wm.shell.startingsurface.IStartingWindowListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
@@ -609,9 +613,28 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
RecentsView overview = mLauncher.getOverviewPanel();
ObjectAnimator alpha = ObjectAnimator.ofFloat(overview,
RecentsView.CONTENT_ALPHA, alphas);
Log.d(BAD_STATE, "QTM composeViewContentAnimator alphas=" + Arrays.toString(alphas));
alpha.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
Log.d(BAD_STATE, "QTM composeViewContentAnimator onStart");
}
@Override
public void onAnimationCancel(Animator animation) {
float alpha = overview == null ? -1 : RecentsView.CONTENT_ALPHA.get(overview);
Log.d(BAD_STATE, "QTM composeViewContentAnimator onCancel, alpha=" + alpha);
}
@Override
public void onAnimationEnd(Animator animation) {
Log.d(BAD_STATE, "QTM composeViewContentAnimator onEnd");
}
});
alpha.setDuration(CONTENT_ALPHA_DURATION);
alpha.setInterpolator(LINEAR);
anim.play(alpha);
Log.d(BAD_STATE, "QTM composeViewContentAnimator setFreezeVisibility=true");
overview.setFreezeViewVisibility(true);
ObjectAnimator scaleAnim = ObjectAnimator.ofFloat(overview, SCALE_PROPERTY, scales);
@@ -620,6 +643,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
anim.play(scaleAnim);
return () -> {
Log.d(BAD_STATE, "QTM composeViewContentAnimator onEnd setFreezeVisibility=false");
overview.setFreezeViewVisibility(false);
SCALE_PROPERTY.set(overview, 1f);
mLauncher.getStateManager().reapplyState();
@@ -1274,8 +1298,8 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
}
}
return mLauncher.getFirstMatchForAppClose(launchCookieItemId,
packageName, UserHandle.of(runningTaskTarget.taskInfo.userId));
return mLauncher.getFirstMatchForAppClose(launchCookieItemId, packageName,
UserHandle.of(runningTaskTarget.taskInfo.userId), true /* supportsAllAppsState */);
}
private @NonNull RectF getDefaultWindowTargetRect() {
@@ -15,6 +15,7 @@
*/
package com.android.launcher3.taskbar;
import static android.view.InsetsState.ITYPE_BOTTOM_MANDATORY_GESTURES;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
@@ -90,11 +91,12 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
private static final String WINDOW_TITLE = "Taskbar";
private final DeviceProfile mDeviceProfile;
private final LayoutInflater mLayoutInflater;
private final TaskbarDragLayer mDragLayer;
private final TaskbarControllers mControllers;
private DeviceProfile mDeviceProfile;
private final WindowManager mWindowManager;
private final @Nullable RoundedCorner mLeftCorner, mRightCorner;
private final int mTaskbarHeightForIme;
@@ -125,10 +127,7 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE), 0);
final Resources resources = getResources();
float taskbarIconSize = resources.getDimension(R.dimen.taskbar_icon_size);
mDeviceProfile.updateIconSize(1, resources);
float iconScale = taskbarIconSize / mDeviceProfile.iconSizePx;
mDeviceProfile.updateIconSize(iconScale, resources);
updateIconSize(resources);
mTaskbarHeightForIme = resources.getDimensionPixelSize(R.dimen.taskbar_ime_size);
@@ -197,7 +196,8 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
WindowManagerWrapper wmWrapper = WindowManagerWrapper.getInstance();
wmWrapper.setProvidesInsetsTypes(
mWindowLayoutParams,
new int[] { ITYPE_EXTRA_NAVIGATION_BAR, ITYPE_BOTTOM_TAPPABLE_ELEMENT }
new int[] { ITYPE_EXTRA_NAVIGATION_BAR, ITYPE_BOTTOM_TAPPABLE_ELEMENT,
ITYPE_BOTTOM_MANDATORY_GESTURES }
);
// Adjust the frame by the rounded corners (ie. leaving just the bar as the inset) when
// the IME is showing
@@ -211,6 +211,19 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
mWindowManager.addView(mDragLayer, mWindowLayoutParams);
}
/** Updates the Device profile instance to the latest representation of the screen. */
public void updateDeviceProfile(DeviceProfile dp) {
mDeviceProfile = dp;
updateIconSize(getResources());
}
private void updateIconSize(Resources resources) {
float taskbarIconSize = resources.getDimension(R.dimen.taskbar_icon_size);
mDeviceProfile.updateIconSize(1, resources);
float iconScale = taskbarIconSize / mDeviceProfile.iconSizePx;
mDeviceProfile.updateIconSize(iconScale, resources);
}
public void onConfigurationChanged(@Config int configChanges) {
mControllers.onConfigurationChanged(configChanges);
}
@@ -145,7 +145,7 @@ public class TaskbarDragController extends DragController<TaskbarActivityContext
PopupContainerWithArrow<TaskbarActivityContext> popupContainer =
mControllers.taskbarPopupController.showForIcon(btv);
if (popupContainer != null) {
dragOptions.preDragCondition = popupContainer.createPreDragCondition();
dragOptions.preDragCondition = popupContainer.createPreDragCondition(false);
}
}
@@ -207,59 +207,10 @@ import java.util.function.Supplier;
private Animator onStateChangeApplied(int changedFlags, long duration, boolean start) {
AnimatorSet animatorSet = new AnimatorSet();
if (hasAnyFlag(changedFlags, FLAG_RESUMED)) {
boolean isResumed = isResumed();
ObjectAnimator anim = mIconAlignmentForResumedState
.animateToValue(isResumed && goingToUnstashedLauncherState()
? 1 : 0)
.setDuration(duration);
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mIsAnimatingToLauncherViaResume = false;
}
@Override
public void onAnimationStart(Animator animation) {
mIsAnimatingToLauncherViaResume = isResumed;
TaskbarStashController stashController = mControllers.taskbarStashController;
stashController.updateStateForFlag(FLAG_IN_APP, !isResumed);
stashController.applyState(duration);
}
});
animatorSet.play(anim);
}
if (hasAnyFlag(changedFlags, FLAG_RECENTS_ANIMATION_RUNNING)) {
boolean isRecentsAnimationRunning = isRecentsAnimationRunning();
Animator animator = mIconAlignmentForGestureState
.animateToValue(isRecentsAnimationRunning && goingToUnstashedLauncherState()
? 1 : 0);
if (isRecentsAnimationRunning) {
animator.setDuration(duration);
}
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mIsAnimatingToLauncherViaGesture = false;
}
@Override
public void onAnimationStart(Animator animation) {
mIsAnimatingToLauncherViaGesture = isRecentsAnimationRunning();
}
});
animatorSet.play(animator);
}
if (hasAnyFlag(changedFlags, FLAG_RESUMED | FLAG_RECENTS_ANIMATION_RUNNING)) {
boolean goingToLauncher = hasAnyFlag(FLAG_RESUMED | FLAG_RECENTS_ANIMATION_RUNNING);
animatorSet.play(mTaskbarBackgroundAlpha.animateToValue(goingToLauncher ? 0 : 1)
.setDuration(duration));
}
// Add the state animation first to ensure FLAG_IN_STASHED_LAUNCHER_STATE is set and we can
// determine whether goingToUnstashedLauncherStateChanged.
boolean wasGoingToUnstashedLauncherState = goingToUnstashedLauncherState();
if (hasAnyFlag(changedFlags, FLAG_TRANSITION_STATE_RUNNING)) {
boolean committed = !hasAnyFlag(FLAG_TRANSITION_STATE_RUNNING);
playStateTransitionAnim(animatorSet, duration, committed);
@@ -270,6 +221,76 @@ import java.util.function.Supplier;
applyState(0 /* duration */);
}
}
boolean goingToUnstashedLauncherStateChanged = wasGoingToUnstashedLauncherState
!= goingToUnstashedLauncherState();
boolean launcherStateChangedDuringAnimToResumeAlignment =
mIconAlignmentForResumedState.isAnimating() && goingToUnstashedLauncherStateChanged;
if (hasAnyFlag(changedFlags, FLAG_RESUMED)
|| launcherStateChangedDuringAnimToResumeAlignment) {
boolean isResumed = isResumed();
float toAlignmentForResumedState = isResumed && goingToUnstashedLauncherState() ? 1 : 0;
// If we're already animating to the value, just leave it be instead of restarting it.
if (!mIconAlignmentForResumedState.isAnimatingToValue(toAlignmentForResumedState)) {
ObjectAnimator resumeAlignAnim = mIconAlignmentForResumedState
.animateToValue(toAlignmentForResumedState)
.setDuration(duration);
resumeAlignAnim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mIsAnimatingToLauncherViaResume = false;
}
@Override
public void onAnimationStart(Animator animation) {
mIsAnimatingToLauncherViaResume = isResumed;
TaskbarStashController stashController =
mControllers.taskbarStashController;
stashController.updateStateForFlag(FLAG_IN_APP, !isResumed);
stashController.applyState(duration);
}
});
animatorSet.play(resumeAlignAnim);
}
}
boolean launcherStateChangedDuringAnimToGestureAlignment =
mIconAlignmentForGestureState.isAnimating() && goingToUnstashedLauncherStateChanged;
if (hasAnyFlag(changedFlags, FLAG_RECENTS_ANIMATION_RUNNING)
|| launcherStateChangedDuringAnimToGestureAlignment) {
boolean isRecentsAnimationRunning = isRecentsAnimationRunning();
float toAlignmentForGestureState = isRecentsAnimationRunning
&& goingToUnstashedLauncherState() ? 1 : 0;
// If we're already animating to the value, just leave it be instead of restarting it.
if (!mIconAlignmentForGestureState.isAnimatingToValue(toAlignmentForGestureState)) {
Animator gestureAlignAnim = mIconAlignmentForGestureState
.animateToValue(toAlignmentForGestureState);
if (isRecentsAnimationRunning) {
gestureAlignAnim.setDuration(duration);
}
gestureAlignAnim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mIsAnimatingToLauncherViaGesture = false;
}
@Override
public void onAnimationStart(Animator animation) {
mIsAnimatingToLauncherViaGesture = isRecentsAnimationRunning();
}
});
animatorSet.play(gestureAlignAnim);
}
}
if (hasAnyFlag(changedFlags, FLAG_RESUMED | FLAG_RECENTS_ANIMATION_RUNNING)) {
boolean goingToLauncher = hasAnyFlag(FLAG_RESUMED | FLAG_RECENTS_ANIMATION_RUNNING);
animatorSet.play(mTaskbarBackgroundAlpha.animateToValue(goingToLauncher ? 0 : 1)
.setDuration(duration));
}
if (start) {
animatorSet.start();
@@ -310,8 +331,11 @@ import java.util.function.Supplier;
animatorSet.play(stashAnimator);
}
animatorSet.play(mIconAlignmentForLauncherState.animateToValue(toAlignment)
.setDuration(duration));
// If we're already animating to the value, just leave it be instead of restarting it.
if (!mIconAlignmentForLauncherState.isAnimatingToValue(toAlignment)) {
animatorSet.play(mIconAlignmentForLauncherState.animateToValue(toAlignment)
.setDuration(duration));
}
}
private boolean isResumed() {
@@ -110,6 +110,13 @@ public class TaskbarManager implements DisplayController.DisplayInfoChangeListen
} else {
// Config change might be handled without re-creating the taskbar
if (mTaskbarActivityContext != null) {
DeviceProfile dp = mUserUnlocked
? LauncherAppState.getIDP(mContext).getDeviceProfile(mContext)
: null;
if (dp != null && dp.isTaskbarPresent) {
mTaskbarActivityContext.updateDeviceProfile(dp.copy(mContext));
}
mTaskbarActivityContext.onConfigurationChanged(configDiff);
}
}
@@ -26,12 +26,14 @@ import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SC
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_Y;
import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
import static com.android.launcher3.testing.TestProtocol.BAD_STATE;
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET;
import static com.android.quickstep.views.RecentsView.RECENTS_GRID_PROGRESS;
import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION;
import android.util.FloatProperty;
import android.util.Log;
import androidx.annotation.NonNull;
@@ -65,7 +67,10 @@ public abstract class BaseRecentsViewStateController<T extends RecentsView>
ADJACENT_PAGE_HORIZONTAL_OFFSET.set(mRecentsView, scaleAndOffset[1]);
TASK_SECONDARY_TRANSLATION.set(mRecentsView, 0f);
getContentAlphaProperty().set(mRecentsView, state.overviewUi ? 1f : 0);
float recentsAlpha = state.overviewUi ? 1f : 0;
Log.d(BAD_STATE, "BaseRecentsViewStateController setState state=" + state
+ ", alpha=" + recentsAlpha);
getContentAlphaProperty().set(mRecentsView, recentsAlpha);
getTaskModalnessProperty().set(mRecentsView, state.getOverviewModalness());
RECENTS_GRID_PROGRESS.set(mRecentsView,
state.displayOverviewTasksAsGrid(mLauncher.getDeviceProfile()) ? 1f : 0f);
@@ -74,6 +79,8 @@ public abstract class BaseRecentsViewStateController<T extends RecentsView>
@Override
public void setStateWithAnimation(LauncherState toState, StateAnimationConfig config,
PendingAnimation builder) {
Log.d(BAD_STATE, "BaseRecentsViewStateController setStateWithAnimation state=" + toState
+ ", config.skipOverview=" + config.hasAnimationFlag(SKIP_OVERVIEW));
if (config.hasAnimationFlag(SKIP_OVERVIEW)) {
return;
}
@@ -97,7 +104,10 @@ public abstract class BaseRecentsViewStateController<T extends RecentsView>
setter.setFloat(mRecentsView, TASK_SECONDARY_TRANSLATION, 0f,
config.getInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, LINEAR));
setter.setFloat(mRecentsView, getContentAlphaProperty(), toState.overviewUi ? 1 : 0,
float recentsAlpha = toState.overviewUi ? 1 : 0;
Log.d(BAD_STATE, "BaseRecentsViewStateController setStateWithAnimationInternal toState="
+ toState + ", alpha=" + recentsAlpha);
setter.setFloat(mRecentsView, getContentAlphaProperty(), recentsAlpha,
config.getInterpolator(ANIM_OVERVIEW_FADE, AGGRESSIVE_EASE_IN_OUT));
setter.setFloat(
@@ -21,6 +21,7 @@ import android.app.ActivityOptions;
import android.app.ActivityTaskManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.util.Pair;
@@ -58,6 +59,12 @@ class QuickstepInteractionHandler implements RemoteViews.InteractionHandler {
Pair<Intent, ActivityOptions> options = remoteResponse.getLaunchOptions(view);
ActivityOptionsWrapper activityOptions = mLauncher.getAppTransitionManager()
.getActivityLaunchOptions(hostView);
Object itemInfo = hostView.getTag();
IBinder launchCookie = null;
if (itemInfo instanceof ItemInfo) {
launchCookie = mLauncher.getLaunchCookie((ItemInfo) itemInfo);
activityOptions.options.setLaunchCookie(launchCookie);
}
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.
@@ -65,17 +72,14 @@ class QuickstepInteractionHandler implements RemoteViews.InteractionHandler {
ActivityTaskManager.getService()
.registerRemoteAnimationForNextActivityStart(
pendingIntent.getCreatorPackage(),
activityOptions.options.getRemoteAnimationAdapter());
activityOptions.options.getRemoteAnimationAdapter(),
launchCookie);
} catch (RemoteException e) {
// Do nothing.
}
}
activityOptions.options.setPendingIntentLaunchFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activityOptions.options.setSplashscreenStyle(SplashScreen.SPLASH_SCREEN_STYLE_EMPTY);
Object itemInfo = hostView.getTag();
if (itemInfo instanceof ItemInfo) {
mLauncher.addLaunchCookie((ItemInfo) itemInfo, activityOptions.options);
}
options = Pair.create(options.first, activityOptions.options);
if (pendingIntent.isActivity()) {
logAppLaunch(itemInfo);
@@ -38,6 +38,7 @@ import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_S
import static com.android.launcher3.states.StateAnimationConfig.SKIP_ALL_ANIMATIONS;
import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
import static com.android.launcher3.states.StateAnimationConfig.SKIP_SCRIM;
import static com.android.launcher3.testing.TestProtocol.BAD_STATE;
import static com.android.launcher3.touch.BothAxesSwipeDetector.DIRECTION_RIGHT;
import static com.android.launcher3.touch.BothAxesSwipeDetector.DIRECTION_UP;
import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
@@ -54,6 +55,7 @@ import android.animation.Animator.AnimatorListener;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.graphics.PointF;
import android.util.Log;
import android.view.MotionEvent;
import android.view.animation.Interpolator;
@@ -224,6 +226,7 @@ public class NoButtonQuickSwitchTouchController implements TouchController,
// Set RecentView's initial properties.
RECENTS_SCALE_PROPERTY.set(mRecentsView, fromState.getOverviewScaleAndOffset(mLauncher)[0]);
ADJACENT_PAGE_HORIZONTAL_OFFSET.set(mRecentsView, 1f);
Log.d(BAD_STATE, "NBQSTC setupOverviewAnimators setContentAlpha=1");
mRecentsView.setContentAlpha(1);
mRecentsView.setFullscreenProgress(fromState.getOverviewFullscreenProgress());
mLauncher.getActionsView().getVisibilityAlpha().setValue(
@@ -242,6 +245,24 @@ public class NoButtonQuickSwitchTouchController implements TouchController,
QUICK_SWITCH.getWorkspaceScrimColor(mLauncher), LINEAR);
if (mRecentsView.getTaskViewCount() == 0) {
xAnim.addFloat(mRecentsView, CONTENT_ALPHA, 0f, 1f, LINEAR);
Log.d(BAD_STATE, "NBQSTC setupOverviewAnimators from: 0 to: 1");
xAnim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
Log.d(BAD_STATE, "NBQSTC setupOverviewAnimators onStart");
}
@Override
public void onAnimationCancel(Animator animation) {
float alpha = mRecentsView == null ? -1 : CONTENT_ALPHA.get(mRecentsView);
Log.d(BAD_STATE, "NBQSTC setupOverviewAnimators onCancel, alpha=" + alpha);
}
@Override
public void onAnimationEnd(Animator animation) {
Log.d(BAD_STATE, "NBQSTC setupOverviewAnimators onEnd");
}
});
}
mXOverviewAnim = xAnim.createPlaybackController();
mXOverviewAnim.dispatchOnStart();
@@ -29,6 +29,7 @@ import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TR
import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PROGRESS;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_TRANSLATE;
import static com.android.launcher3.testing.TestProtocol.BAD_STATE;
import static com.android.launcher3.util.SystemUiController.UI_STATE_FULLSCREEN_TASK;
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET;
import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
@@ -36,6 +37,7 @@ import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHO
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
import android.util.Log;
import android.view.MotionEvent;
import com.android.launcher3.Launcher;
@@ -112,6 +114,7 @@ public class QuickSwitchTouchController extends AbstractStateChangeTouchControll
RECENTS_SCALE_PROPERTY.set(mOverviewPanel,
QUICK_SWITCH.getOverviewScaleAndOffset(mLauncher)[0] * 0.85f);
ADJACENT_PAGE_HORIZONTAL_OFFSET.set(mOverviewPanel, 1f);
Log.d(BAD_STATE, "QuickSwitchTouchController initCurrentAnimation setContentAlpha=1");
mOverviewPanel.setContentAlpha(1);
mCurrentAnimation = mLauncher.getStateManager()
@@ -249,6 +249,8 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
private RunningWindowAnim[] mRunningWindowAnim;
// Possible second animation running at the same time as mRunningWindowAnim
private Animator mParallelRunningAnim;
// Current running divider animation
private ValueAnimator mDividerAnimator;
private boolean mIsMotionPaused;
private boolean mHasMotionEverBeenPaused;
@@ -831,8 +833,8 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
// Notify when the animation starts
flushOnRecentsAnimationAndLauncherBound();
TaskViewUtils.setSplitAuxiliarySurfacesShown(mRecentsAnimationTargets.nonApps,
false /*shown*/, true /*animate*/);
// Start hiding the divider
setDividerShown(false, false /* immediate */);
// Only add the callback to enable the input consumer after we actually have the controller
mStateCallback.runOnceAtState(STATE_APP_CONTROLLER_RECEIVED | STATE_GESTURE_STARTED,
@@ -849,8 +851,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
mStateCallback.setStateOnUiThread(STATE_GESTURE_CANCELLED | STATE_HANDLER_INVALIDATED);
if (mRecentsAnimationTargets != null) {
TaskViewUtils.setSplitAuxiliarySurfacesShown(mRecentsAnimationTargets.nonApps,
true /*shown*/, true /*animate*/);
setDividerShown(true, false /* immediate */);
}
// Defer clearing the controller and the targets until after we've updated the state
@@ -1000,8 +1001,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
mStateCallback.setState(STATE_RESUME_LAST_TASK);
}
if (mRecentsAnimationTargets != null) {
TaskViewUtils.setSplitAuxiliarySurfacesShown(mRecentsAnimationTargets.nonApps,
true /*shown*/, false /*animate*/);
setDividerShown(true, true /* immediate */);
}
break;
}
@@ -1653,8 +1653,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
mActivityInterface.onTransitionCancelled(wasVisible, mGestureState.getEndTarget());
if (mRecentsAnimationTargets != null) {
TaskViewUtils.setSplitAuxiliarySurfacesShown(mRecentsAnimationTargets.nonApps,
true /*shown*/, false /*animate*/);
setDividerShown(true, true /* immediate */);
}
// Leave the pending invisible flag, as it may be used by wallpaper open animation.
@@ -1920,8 +1919,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
@Override
public void onRecentsAnimationFinished(RecentsAnimationController controller) {
if (!controller.getFinishTargetIsLauncher()) {
TaskViewUtils.setSplitAuxiliarySurfacesShown(mRecentsAnimationTargets.nonApps,
true /*shown*/, true /*animate*/);
setDividerShown(true, false /* immediate */);
}
mRecentsAnimationController = null;
mRecentsAnimationTargets = null;
@@ -2026,6 +2024,19 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
return scaleProgress;
}
private void setDividerShown(boolean shown, boolean immediate) {
if (mDividerAnimator != null) {
mDividerAnimator.cancel();
}
mDividerAnimator = TaskViewUtils.createSplitAuxiliarySurfacesAnimator(
mRecentsAnimationTargets.nonApps, shown, (dividerAnimator) -> {
dividerAnimator.start();
if (immediate) {
dividerAnimator.end();
}
});
}
/**
* Used for winscope tracing, see launcher_trace.proto
* @see com.android.systemui.shared.tracing.ProtoTraceable#writeToProto
@@ -42,6 +42,8 @@ public class AnimatedFloat {
private final Runnable mUpdateCallback;
private ObjectAnimator mValueAnimator;
// Only non-null when an animation is playing to this value.
private Float mEndValue;
public float value;
@@ -67,10 +69,18 @@ public class AnimatedFloat {
cancelAnimation();
mValueAnimator = ObjectAnimator.ofFloat(this, VALUE, start, end);
mValueAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animator) {
if (mValueAnimator == animator) {
mEndValue = end;
}
}
@Override
public void onAnimationEnd(Animator animator) {
if (mValueAnimator == animator) {
mValueAnimator = null;
mEndValue = null;
}
}
});
@@ -103,4 +113,15 @@ public class AnimatedFloat {
public ObjectAnimator getCurrentAnimation() {
return mValueAnimator;
}
public boolean isAnimating() {
return mValueAnimator != null;
}
/**
* Returns whether we are currently animating, and the animation's end value matches the given.
*/
public boolean isAnimatingToValue(float endValue) {
return isAnimating() && mEndValue != null && mEndValue == endValue;
}
}
@@ -246,7 +246,8 @@ public class LauncherSwipeHandlerV2 extends
return mActivity.getFirstMatchForAppClose(launchCookieItemId,
runningTaskView.getTask().key.getComponent().getPackageName(),
UserHandle.of(runningTaskView.getTask().key.userId));
UserHandle.of(runningTaskView.getTask().key.userId),
false /* supportsAllAppsState */);
}
@Override
@@ -24,6 +24,7 @@ import static com.android.launcher3.QuickstepTransitionManager.STATUS_BAR_TRANSI
import static com.android.launcher3.Utilities.createHomeIntent;
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
import static com.android.launcher3.graphics.SysUiScrim.SYSUI_PROGRESS;
import static com.android.launcher3.testing.TestProtocol.BAD_STATE;
import static com.android.launcher3.testing.TestProtocol.OVERVIEW_STATE_ORDINAL;
import static com.android.quickstep.TaskUtils.taskIsATargetWithMode;
import static com.android.quickstep.TaskViewUtils.createRecentsWindowAnimator;
@@ -38,6 +39,8 @@ import android.content.res.Configuration;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.Display;
import android.view.SurfaceControl.Transaction;
import android.view.View;
import android.window.SplashScreen;
@@ -308,6 +311,7 @@ public final class RecentsActivity extends StatefulActivity<RecentsState> {
protected void onStart() {
// Set the alpha to 1 before calling super, as it may get set back to 0 due to
// onActivityStart callback.
Log.d(BAD_STATE, "RecentsActivity onStart mFallbackRecentsView.setContentAlpha(1)");
mFallbackRecentsView.setContentAlpha(1);
super.onStart();
mFallbackRecentsView.updateLocusId();
@@ -554,15 +554,13 @@ public class RecentsAnimationDeviceState implements
/**
* @param ev An ACTION_DOWN motion event
* @param task Info for the currently running task
* @return whether the given motion event can trigger the assistant over the current task.
*/
public boolean canTriggerAssistantAction(MotionEvent ev, ActivityManager.RunningTaskInfo task) {
public boolean canTriggerAssistantAction(MotionEvent ev) {
return mAssistantAvailable
&& !QuickStepContract.isAssistantGestureDisabled(mSystemUiStateFlags)
&& mRotationTouchHelper.touchInAssistantRegion(ev)
&& !isLockToAppActive()
&& !isGestureBlockedActivity(task);
&& !isLockToAppActive();
}
/**
@@ -36,6 +36,8 @@ import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLAT
import static com.android.launcher3.anim.Interpolators.clampToProgress;
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
import static com.android.launcher3.statehandlers.DepthController.DEPTH;
import static com.android.launcher3.testing.TestProtocol.BAD_STATE;
import static com.android.quickstep.TaskAnimationManager.ENABLE_SHELL_TRANSITIONS;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING;
@@ -52,6 +54,7 @@ import android.graphics.Matrix.ScaleToFit;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Build;
import android.util.Log;
import android.view.SurfaceControl;
import android.view.View;
import android.window.TransitionInfo;
@@ -85,6 +88,7 @@ import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
/**
* Utility class for helpful methods related to {@link TaskView} objects and their tasks.
@@ -538,8 +542,16 @@ public final class TaskViewUtils {
nonAppTargets, depthController, pa);
if (launcherClosing) {
// TODO(b/182592057): differentiate between "restore split" vs "launch fullscreen app"
TaskViewUtils.setSplitAuxiliarySurfacesShown(nonAppTargets,
true /*shown*/, true /*animate*/, pa);
TaskViewUtils.createSplitAuxiliarySurfacesAnimator(nonAppTargets, true /*shown*/,
(dividerAnimator) -> {
// If split apps are launching, we want to delay showing the divider bar
// until the very end once the apps are mostly in place. This is because we
// aren't moving the divider leash in the relative position with the
// launching apps.
dividerAnimator.setStartDelay(pa.getDuration()
- SPLIT_DIVIDER_ANIM_DURATION);
pa.add(dividerAnimator);
});
}
Animator childStateAnimation = null;
@@ -552,6 +564,29 @@ public final class TaskViewUtils {
launcherAnim = dp.overviewShowAsGrid
? ObjectAnimator.ofFloat(recentsView, RecentsView.CONTENT_ALPHA, 0)
: recentsView.createAdjacentPageAnimForTaskLaunch(taskView);
if (dp.isTablet) {
Log.d(BAD_STATE, "TVU composeRecentsLaunchAnimator alpha=" + 0);
launcherAnim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
Log.d(BAD_STATE, "TVU composeRecentsLaunchAnimator onStart");
}
@Override
public void onAnimationCancel(Animator animation) {
float alpha = recentsView == null
? -1
: RecentsView.CONTENT_ALPHA.get(recentsView);
Log.d(BAD_STATE, "TVU composeRecentsLaunchAnimator onCancel, alpha="
+ alpha);
}
@Override
public void onAnimationEnd(Animator animation) {
Log.d(BAD_STATE, "TVU composeRecentsLaunchAnimator onEnd");
}
});
}
launcherAnim.setInterpolator(Interpolators.TOUCH_RESPONSE_INTERPOLATOR);
launcherAnim.setDuration(RECENTS_LAUNCH_DURATION);
@@ -594,16 +629,17 @@ public final class TaskViewUtils {
anim.addListener(windowAnimEndListener);
}
public static void setSplitAuxiliarySurfacesShown(RemoteAnimationTargetCompat[] nonApps,
boolean shown, boolean animate) {
setSplitAuxiliarySurfacesShown(nonApps, shown, animate,null);
}
private static void setSplitAuxiliarySurfacesShown(
@NonNull RemoteAnimationTargetCompat[] nonApps, boolean shown, boolean animate,
@Nullable PendingAnimation splitLaunchAnimation) {
/**
* Creates an animation to show/hide the auxiliary surfaces (aka. divider bar), only calling
* {@param animatorHandler} if there are valid surfaces to animate.
*
* @return the animator animating the surfaces
*/
public static ValueAnimator createSplitAuxiliarySurfacesAnimator(
RemoteAnimationTargetCompat[] nonApps, boolean shown,
Consumer<ValueAnimator> animatorHandler) {
if (nonApps == null || nonApps.length == 0) {
return;
return null;
}
SurfaceControl.Transaction t = new SurfaceControl.Transaction();
@@ -618,20 +654,7 @@ public final class TaskViewUtils {
}
}
if (!hasSurfaceToAnimate) {
return;
}
if (!animate) {
for (SurfaceControl leash : auxiliarySurfaces) {
t.setAlpha(leash, shown ? 1 : 0);
if (shown) {
t.show(leash);
} else {
t.hide(leash);
}
}
t.apply();
return;
return null;
}
ValueAnimator dockFadeAnimator = ValueAnimator.ofFloat(0f, 1f);
@@ -668,15 +691,7 @@ public final class TaskViewUtils {
}
});
dockFadeAnimator.setDuration(SPLIT_DIVIDER_ANIM_DURATION);
if (splitLaunchAnimation != null) {
// If split apps are launching, we want to delay showing the divider bar until the very
// end once the apps are mostly in place. This is because we aren't moving the divider
// leash in the relative position with the launching apps.
dockFadeAnimator.setStartDelay(
splitLaunchAnimation.getDuration() - SPLIT_DIVIDER_ANIM_DURATION);
splitLaunchAnimation.add(dockFadeAnimator);
} else {
dockFadeAnimator.start();
}
animatorHandler.accept(dockFadeAnimator);
return dockFadeAnimator;
}
}
@@ -37,7 +37,6 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_N
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_TRACING_ENABLED;
import android.annotation.TargetApi;
import android.app.ActivityManager;
import android.app.PendingIntent;
import android.app.RemoteAction;
import android.app.Service;
@@ -600,26 +599,14 @@ public class TouchInteractionService extends Service
ActiveGestureLog.INSTANCE.addLog("setInputConsumer: " + mConsumer.getName());
mUncheckedConsumer = mConsumer;
} else if (mDeviceState.isUserUnlocked() && mDeviceState.isFullyGesturalNavMode()) {
} else if (mDeviceState.isUserUnlocked() && mDeviceState.isFullyGesturalNavMode()
&& mDeviceState.canTriggerAssistantAction(event)) {
mGestureState = createGestureState(mGestureState);
ActivityManager.RunningTaskInfo runningTask = mGestureState.getRunningTask();
if (mDeviceState.canTriggerAssistantAction(event, runningTask)) {
// Do not change mConsumer as if there is an ongoing QuickSwitch gesture, we
// should not interrupt it. QuickSwitch assumes that interruption can only
// happen if the next gesture is also quick switch.
mUncheckedConsumer = new AssistantInputConsumer(
this,
mGestureState,
InputConsumer.NO_OP, mInputMonitorCompat,
mDeviceState,
event);
} else if (mDeviceState.canTriggerOneHandedAction(event)) {
// Consume gesture event for triggering one handed feature.
mUncheckedConsumer = new OneHandedModeInputConsumer(this, mDeviceState,
InputConsumer.NO_OP, mInputMonitorCompat);
} else {
mUncheckedConsumer = InputConsumer.NO_OP;
}
// Do not change mConsumer as if there is an ongoing QuickSwitch gesture, we
// should not interrupt it. QuickSwitch assumes that interruption can only
// happen if the next gesture is also quick switch.
mUncheckedConsumer = tryCreateAssistantInputConsumer(
InputConsumer.NO_OP, mGestureState, event);
} else if (mDeviceState.canTriggerOneHandedAction(event)) {
// Consume gesture event for triggering one handed feature.
mUncheckedConsumer = new OneHandedModeInputConsumer(this, mDeviceState,
@@ -666,6 +653,14 @@ public class TouchInteractionService extends Service
ProtoTracer.INSTANCE.get(this).scheduleFrameUpdate();
}
private InputConsumer tryCreateAssistantInputConsumer(InputConsumer base,
GestureState gestureState, MotionEvent motionEvent) {
return mDeviceState.isGestureBlockedActivity(gestureState.getRunningTask())
? base
: new AssistantInputConsumer(this, gestureState, base, mInputMonitorCompat,
mDeviceState, motionEvent);
}
public GestureState createGestureState(GestureState previousGestureState) {
GestureState gestureState = new GestureState(mOverviewComponentObserver,
ActiveGestureLog.INSTANCE.generateAndSetLogId());
@@ -711,9 +706,8 @@ public class TouchInteractionService extends Service
handleOrientationSetup(base);
}
if (mDeviceState.isFullyGesturalNavMode()) {
if (mDeviceState.canTriggerAssistantAction(event, newGestureState.getRunningTask())) {
base = new AssistantInputConsumer(this, newGestureState, base, mInputMonitorCompat,
mDeviceState, event);
if (mDeviceState.canTriggerAssistantAction(event)) {
base = tryCreateAssistantInputConsumer(base, newGestureState, event);
}
// If Taskbar is present, we listen for long press to unstash it.
@@ -15,6 +15,7 @@
*/
package com.android.quickstep.fallback;
import static com.android.launcher3.testing.TestProtocol.BAD_STATE;
import static com.android.quickstep.GestureState.GestureEndTarget.RECENTS;
import static com.android.quickstep.fallback.RecentsState.DEFAULT;
import static com.android.quickstep.fallback.RecentsState.HOME;
@@ -27,6 +28,7 @@ import android.app.ActivityManager.RunningTaskInfo;
import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import androidx.annotation.Nullable;
@@ -219,6 +221,7 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity, RecentsSta
setOverviewStateEnabled(true);
setOverviewGridEnabled(toState.displayOverviewTasksAsGrid(mActivity.getDeviceProfile()));
setOverviewFullscreenEnabled(toState.isFullScreen());
Log.d(BAD_STATE, "FRV onStateTransitionStart setFreezeVisibility=true, toState=" + toState);
setFreezeViewVisibility(true);
}
@@ -230,6 +233,8 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity, RecentsSta
}
boolean isOverlayEnabled = finalState == DEFAULT || finalState == MODAL_TASK;
setOverlayEnabled(isOverlayEnabled);
Log.d(BAD_STATE, "FRV onStateTransitionComplete setFreezeVisibility=false, finalState="
+ finalState);
setFreezeViewVisibility(false);
if (isOverlayEnabled) {
@@ -15,10 +15,13 @@
*/
package com.android.quickstep.util;
import static com.android.launcher3.testing.TestProtocol.BAD_STATE;
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.util.Log;
import androidx.dynamicanimation.animation.DynamicAnimation;
@@ -27,6 +30,8 @@ import com.android.launcher3.statemanager.StateManager.AtomicAnimationFactory;
import com.android.launcher3.statemanager.StatefulActivity;
import com.android.quickstep.views.RecentsView;
import java.util.Arrays;
public class RecentsAtomicAnimationFactory<ACTIVITY_TYPE extends StatefulActivity, STATE_TYPE>
extends AtomicAnimationFactory<STATE_TYPE> {
@@ -46,8 +51,30 @@ public class RecentsAtomicAnimationFactory<ACTIVITY_TYPE extends StatefulActivit
public Animator createStateElementAnimation(int index, float... values) {
switch (index) {
case INDEX_RECENTS_FADE_ANIM:
return ObjectAnimator.ofFloat(mActivity.getOverviewPanel(),
ObjectAnimator alpha = ObjectAnimator.ofFloat(mActivity.getOverviewPanel(),
RecentsView.CONTENT_ALPHA, values);
Log.d(BAD_STATE, "RAAF createStateElementAnimation alpha="
+ Arrays.toString(values));
alpha.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
Log.d(BAD_STATE, "RAAF createStateElementAnimation onStart");
}
@Override
public void onAnimationCancel(Animator animation) {
RecentsView recent = mActivity.getOverviewPanel();
float alpha = recent == null ? -1 : RecentsView.CONTENT_ALPHA.get(recent);
Log.d(BAD_STATE, "RAAF createStateElementAnimation onCancel, alpha="
+ alpha);
}
@Override
public void onAnimationEnd(Animator animation) {
Log.d(BAD_STATE, "RAAF createStateElementAnimation onEnd");
}
});
return alpha;
case INDEX_RECENTS_TRANSLATE_X_ANIM: {
RecentsView rv = mActivity.getOverviewPanel();
return new SpringAnimationBuilder(mActivity)
@@ -21,11 +21,13 @@ import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.LauncherState.OVERVIEW_MODAL_TASK;
import static com.android.launcher3.LauncherState.OVERVIEW_SPLIT_SELECT;
import static com.android.launcher3.LauncherState.SPRING_LOADED;
import static com.android.launcher3.testing.TestProtocol.BAD_STATE;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.Surface;
@@ -64,6 +66,7 @@ public class LauncherRecentsView extends RecentsView<BaseQuickstepLauncher, Laun
public void init(OverviewActionsView actionsView,
SplitSelectStateController splitPlaceholderView) {
super.init(actionsView, splitPlaceholderView);
Log.d(BAD_STATE, "LauncherRecentsView init setContentAlpha=0");
setContentAlpha(0);
}
@@ -96,6 +99,7 @@ public class LauncherRecentsView extends RecentsView<BaseQuickstepLauncher, Laun
setOverviewStateEnabled(toState.overviewUi);
setOverviewGridEnabled(toState.displayOverviewTasksAsGrid(mActivity.getDeviceProfile()));
setOverviewFullscreenEnabled(toState.getOverviewFullscreenProgress() == 1);
Log.d(BAD_STATE, "LRV onStateTransitionStart setFreezeVisibility=true, toState=" + toState);
setFreezeViewVisibility(true);
}
@@ -107,6 +111,8 @@ public class LauncherRecentsView extends RecentsView<BaseQuickstepLauncher, Laun
}
boolean isOverlayEnabled = finalState == OVERVIEW || finalState == OVERVIEW_MODAL_TASK;
setOverlayEnabled(isOverlayEnabled);
Log.d(BAD_STATE, "LRV onStateTransitionComplete setFreezeVisibility=false, finalState="
+ finalState);
setFreezeViewVisibility(false);
if (isOverlayEnabled) {
@@ -984,13 +984,17 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
*/
public void launchSideTaskInLiveTileModeForRestartedApp(int taskId) {
int runningTaskViewId = getTaskViewIdFromTaskId(taskId);
if (mRunningTaskViewId != -1 && mRunningTaskViewId == runningTaskViewId) {
TransformParams params = mRemoteTargetHandles[0].getTransformParams();
RemoteAnimationTargets targets = params.getTargetSet();
if (targets != null && targets.findTask(taskId) != null) {
launchSideTaskInLiveTileMode(taskId, targets.apps, targets.wallpapers,
targets.nonApps);
}
if (mRunningTaskViewId == -1 ||
mRunningTaskViewId != runningTaskViewId ||
mRemoteTargetHandles == null) {
return;
}
TransformParams params = mRemoteTargetHandles[0].getTransformParams();
RemoteAnimationTargets targets = params.getTargetSet();
if (targets != null && targets.findTask(taskId) != null) {
launchSideTaskInLiveTileMode(taskId, targets.apps, targets.wallpapers,
targets.nonApps);
}
}
@@ -4139,8 +4143,10 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
anim.play(ObjectAnimator.ofFloat(getPageAt(centerTaskIndex),
mOrientationHandler.getPrimaryViewTranslate(), primaryTranslation));
int runningTaskIndex = recentsView.getRunningTaskIndex();
if (ENABLE_QUICKSTEP_LIVE_TILE.get() && runningTaskIndex != -1
&& runningTaskIndex != taskIndex) {
if (ENABLE_QUICKSTEP_LIVE_TILE.get()
&& runningTaskIndex != -1
&& runningTaskIndex != taskIndex
&& recentsView.getRemoteTargetHandles() != null) {
for (RemoteTargetHandle remoteHandle : recentsView.getRemoteTargetHandles()) {
anim.play(ObjectAnimator.ofFloat(
remoteHandle.getTaskViewSimulator().taskPrimaryTranslation,
@@ -4235,9 +4241,12 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
if (isSuccess) {
if (tv.getTaskIds()[1] != -1) {
// TODO(b/194414938): make this part of the animations instead.
TaskViewUtils.setSplitAuxiliarySurfacesShown(mRemoteTargetHandles[0]
.getTransformParams().getTargetSet().nonApps,
true /*shown*/, false /*animate*/);
TaskViewUtils.createSplitAuxiliarySurfacesAnimator(
mRemoteTargetHandles[0].getTransformParams().getTargetSet().nonApps,
true /*shown*/, (dividerAnimator) -> {
dividerAnimator.start();
dividerAnimator.end();
});
}
if (ENABLE_QUICKSTEP_LIVE_TILE.get() && tv.isRunningTask()) {
finishRecentsAnimation(false /* toRecents */, null);
@@ -462,11 +462,15 @@ public class TaskView extends FrameLayout implements Reusable {
return getItemInfo(mTask);
}
protected WorkspaceItemInfo getItemInfo(Task task) {
ComponentKey componentKey = TaskUtils.getLaunchComponentKeyForTask(task.key);
protected WorkspaceItemInfo getItemInfo(@Nullable Task task) {
WorkspaceItemInfo stubInfo = new WorkspaceItemInfo();
stubInfo.itemType = LauncherSettings.Favorites.ITEM_TYPE_TASK;
stubInfo.container = LauncherSettings.Favorites.CONTAINER_TASKSWITCHER;
if (task == null) {
return stubInfo;
}
ComponentKey componentKey = TaskUtils.getLaunchComponentKeyForTask(task.key);
stubInfo.user = componentKey.user;
stubInfo.intent = new Intent().setComponent(componentKey.componentName);
stubInfo.title = task.title;
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@android:color/system_accent1_300"/>
</selector>
+4
View File
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#53BCAC"/>
</selector>
+4
View File
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@android:color/system_accent2_50"/>
</selector>
+4
View File
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#CDFAF1"/>
</selector>
+27 -14
View File
@@ -13,23 +13,36 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:enterFadeDuration="100">
<item
android:id="@+id/unselected"
android:state_selected="false">
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/accent_ripple_color">
<item android:id="@android:id/mask">
<shape android:shape="rectangle">
<corners android:radius="@dimen/all_apps_header_pill_corner_radius" />
<solid android:color="@color/all_apps_tabs_background" />
<solid android:color="@color/accent_ripple_color" />
</shape>
</item>
<item
android:id="@+id/selected"
android:state_selected="true">
<shape android:shape="rectangle">
<corners android:radius="@dimen/all_apps_header_pill_corner_radius" />
<solid android:color="@color/all_apps_tab_background_selected" />
</shape>
<item>
<selector android:enterFadeDuration="100">
<item
android:id="@+id/unselected"
android:state_selected="false">
<shape android:shape="rectangle">
<corners android:radius="@dimen/all_apps_header_pill_corner_radius" />
<solid android:color="@color/all_apps_tabs_background" />
</shape>
</item>
<item
android:id="@+id/selected"
android:state_selected="true">
<shape android:shape="rectangle">
<corners android:radius="@dimen/all_apps_header_pill_corner_radius" />
<solid android:color="@color/all_apps_tab_background_selected" />
</shape>
</item>
</selector>
</item>
</selector>
</ripple>
@@ -1,22 +0,0 @@
<?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>
@@ -35,6 +35,7 @@ import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.icu.text.MessageFormat;
import android.text.TextPaint;
import android.text.TextUtils;
import android.text.TextUtils.TruncateAt;
import android.util.AttributeSet;
import android.util.Property;
@@ -785,7 +786,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
invalidate();
}
}
if (itemInfo.contentDescription != null) {
if (!TextUtils.isEmpty(itemInfo.contentDescription)) {
if (itemInfo.isDisabled()) {
setContentDescription(getContext().getString(R.string.disabled_app_label,
itemInfo.contentDescription));
+33 -2
View File
@@ -57,6 +57,7 @@ import static com.android.launcher3.popup.SystemShortcut.INSTALL;
import static com.android.launcher3.popup.SystemShortcut.WIDGETS;
import static com.android.launcher3.states.RotationHelper.REQUEST_LOCK;
import static com.android.launcher3.states.RotationHelper.REQUEST_NONE;
import static com.android.launcher3.testing.TestProtocol.BAD_STATE;
import static com.android.launcher3.util.ItemInfoMatcher.forFolderMatch;
import android.animation.Animator;
@@ -493,6 +494,8 @@ public class Launcher extends StatefulActivity<LauncherState> implements Launche
if (!mModel.addCallbacksAndLoad(this)) {
if (!internalStateHandled) {
Log.d(BAD_STATE, "Launcher onCreate not binding sync, setting DragLayer alpha "
+ "ALPHA_INDEX_LAUNCHER_LOAD to 0");
// If we are not binding synchronously, show a fade in animation when
// the first page bind completes.
mDragLayer.getAlphaProperty(ALPHA_INDEX_LAUNCHER_LOAD).setValue(0);
@@ -986,6 +989,9 @@ public class Launcher extends StatefulActivity<LauncherState> implements Launche
DiscoveryBounce.showForHomeIfNeeded(this);
mAppWidgetHost.setActivityResumed(true);
// Temporary workaround for apps using SHOW_FORCED IME flag.
hideKeyboard();
}
private void logStopAndResume(boolean isResume) {
@@ -2626,6 +2632,28 @@ public class Launcher extends StatefulActivity<LauncherState> implements Launche
AlphaProperty property = mDragLayer.getAlphaProperty(ALPHA_INDEX_LAUNCHER_LOAD);
if (property.getValue() < 1) {
ObjectAnimator anim = ObjectAnimator.ofFloat(property, MultiValueAlpha.VALUE, 1);
Log.d(BAD_STATE, "Launcher onInitialBindComplete toAlpha=" + 1);
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
Log.d(BAD_STATE, "Launcher onInitialBindComplete onStart");
}
@Override
public void onAnimationCancel(Animator animation) {
float alpha = mDragLayer == null
? -1
: mDragLayer.getAlphaProperty(ALPHA_INDEX_LAUNCHER_LOAD).getValue();
Log.d(BAD_STATE, "Launcher onInitialBindComplete onCancel, alpha=" + alpha);
}
@Override
public void onAnimationEnd(Animator animation) {
Log.d(BAD_STATE, "Launcher onInitialBindComplete onEnd");
}
});
anim.addListener(AnimatorListeners.forEndCallback(executor::onLoadAnimationCompleted));
anim.start();
} else {
@@ -2688,8 +2716,11 @@ public class Launcher extends StatefulActivity<LauncherState> implements Launche
* @param preferredItemId The id of the preferred item to match to if it exists.
* @param packageName The package name of the app to match.
* @param user The user of the app to match.
* @param supportsAllAppsState If true and we are in All Apps state, looks for view in All Apps.
* Else we only looks on the workspace.
*/
public View getFirstMatchForAppClose(int preferredItemId, String packageName, UserHandle user) {
public View getFirstMatchForAppClose(int preferredItemId, String packageName, UserHandle user,
boolean supportsAllAppsState) {
final ItemInfoMatcher preferredItem = (info, cn) ->
info != null && info.id == preferredItemId;
final ItemInfoMatcher packageAndUserAndApp = (info, cn) ->
@@ -2700,7 +2731,7 @@ public class Launcher extends StatefulActivity<LauncherState> implements Launche
&& TextUtils.equals(info.getTargetComponent().getPackageName(),
packageName);
if (isInState(LauncherState.ALL_APPS)) {
if (supportsAllAppsState && isInState(LauncherState.ALL_APPS)) {
return getFirstMatch(Collections.singletonList(mAppsView.getActiveRecyclerView()),
preferredItem, packageAndUserAndApp);
} else {
+2 -1
View File
@@ -460,9 +460,10 @@ public final class Utilities {
* Trims the string, removing all whitespace at the beginning and end of the string.
* Non-breaking whitespaces are also removed.
*/
@NonNull
public static String trim(CharSequence s) {
if (s == null) {
return null;
return "";
}
// Just strip any sequence of whitespace or java space characters from the beginning and end
+3 -1
View File
@@ -30,6 +30,7 @@ import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_OVERLAY;
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SWIPELEFT;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SWIPERIGHT;
import static com.android.launcher3.testing.TestProtocol.BAD_STATE;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -1254,6 +1255,7 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
// different effects based on device performance. On at least one relatively high-end
// device I've tried, translating the launcher causes things to get quite laggy.
mLauncher.getDragLayer().setTranslationX(transX);
Log.d(BAD_STATE, "Workspace onOverlayScrollChanged DragLayer ALPHA_INDEX_OVERLAY=" + alpha);
mLauncher.getDragLayer().getAlphaProperty(ALPHA_INDEX_OVERLAY).setValue(alpha);
}
@@ -1686,7 +1688,7 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
PopupContainerWithArrow<Launcher> popupContainer = PopupContainerWithArrow
.showForIcon((BubbleTextView) child);
if (popupContainer != null) {
dragOptions.preDragCondition = popupContainer.createPreDragCondition();
dragOptions.preDragCondition = popupContainer.createPreDragCondition(true);
}
}
@@ -202,8 +202,7 @@ public class LoaderCursor extends CursorWrapper {
* Returns the title or empty string
*/
private String getTitle() {
String title = getString(titleIndex);
return TextUtils.isEmpty(title) ? "" : Utilities.trim(title);
return Utilities.trim(getString(titleIndex));
}
/**
@@ -396,7 +396,7 @@ public class PopupContainerWithArrow<T extends Context & ActivityContext>
* Current behavior:
* - Start the drag if the touch passes a certain distance from the original touch down.
*/
public DragOptions.PreDragCondition createPreDragCondition() {
public DragOptions.PreDragCondition createPreDragCondition(boolean updateIconUi) {
return new DragOptions.PreDragCondition() {
@Override
@@ -406,6 +406,9 @@ public class PopupContainerWithArrow<T extends Context & ActivityContext>
@Override
public void onPreDragStart(DropTarget.DragObject dragObject) {
if (!updateIconUi) {
return;
}
if (mIsAboveIcon) {
// Hide only the icon, keep the text visible.
mOriginalIcon.setIconVisible(false);
@@ -418,6 +421,9 @@ public class PopupContainerWithArrow<T extends Context & ActivityContext>
@Override
public void onPreDragEnd(DropTarget.DragObject dragObject, boolean dragStarted) {
if (!updateIconUi) {
return;
}
mOriginalIcon.setIconVisible(true);
if (dragStarted) {
// Make sure we keep the original icon hidden while it is being dragged.
@@ -480,6 +486,9 @@ public class PopupContainerWithArrow<T extends Context & ActivityContext>
@Override
protected void closeComplete() {
super.closeComplete();
if (mActivityContext.getDragController() != null) {
mActivityContext.getDragController().removeDragListener(this);
}
PopupContainerWithArrow openPopup = getOpen(mActivityContext);
if (openPopup == null || openPopup.mOriginalIcon != mOriginalIcon) {
mOriginalIcon.setTextVisibility(mOriginalIcon.shouldTextBeVisible());
@@ -125,4 +125,6 @@ public final class TestProtocol {
public static final String TASK_VIEW_ID_CRASH = "b/195430732";
public static final String NO_DROP_TARGET = "b/195031154";
public static final String NULL_INT_SET = "b/200572078";
public static final String BAD_STATE = "b/223498680";
}
@@ -40,6 +40,7 @@ import android.view.accessibility.AccessibilityEvent;
import android.widget.FrameLayout;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InsettableFrameLayout;
import com.android.launcher3.Utilities;
import com.android.launcher3.util.MultiValueAlpha;
@@ -545,8 +546,14 @@ public abstract class BaseDragLayer<T extends Context & ActivityContext>
public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) {
if (Utilities.ATLEAST_Q) {
Insets gestureInsets = insets.getMandatorySystemGestureInsets();
int gestureInsetBottom = gestureInsets.bottom;
DeviceProfile dp = mActivity.getDeviceProfile();
if (dp.isTaskbarPresent) {
// Ignore taskbar gesture insets to avoid interfering with TouchControllers.
gestureInsetBottom = Math.max(0, gestureInsetBottom - dp.taskbarSize);
}
mSystemGestureRegion.set(gestureInsets.left, gestureInsets.top,
gestureInsets.right, gestureInsets.bottom);
gestureInsets.right, gestureInsetBottom);
}
return super.dispatchApplyWindowInsets(insets);
}
@@ -564,6 +564,12 @@ public class FloatingIconView extends FrameLayout implements
launcher, parent);
view.recycle();
// Init properties before getting the drawable.
view.mIsVerticalBarLayout = launcher.getDeviceProfile().isVerticalBarLayout();
view.mIsOpening = isOpening;
view.mOriginalIcon = originalView;
view.mPositionOut = positionOut;
// Get the drawable on the background thread
boolean shouldLoadIcon = originalView.getTag() instanceof ItemInfo && hideOriginal;
if (shouldLoadIcon) {
@@ -577,11 +583,6 @@ public class FloatingIconView extends FrameLayout implements
}
sIconLoadResult = null;
view.mIsVerticalBarLayout = launcher.getDeviceProfile().isVerticalBarLayout();
view.mIsOpening = isOpening;
view.mOriginalIcon = originalView;
view.mPositionOut = positionOut;
// Match the position of the original view.
view.matchPositionOf(launcher, originalView, isOpening, positionOut);
@@ -639,6 +640,7 @@ public class FloatingIconView extends FrameLayout implements
mLoadIconSignal = null;
mEndRunnable = null;
mFinalDrawableBounds.setEmpty();
mIsOpening = false;
mPositionOut = null;
mListenerView.setListener(null);
mOriginalIcon = null;
@@ -159,7 +159,8 @@ public class FloatingSurfaceView extends AbstractFloatingView implements
return;
}
View icon = mLauncher.getFirstMatchForAppClose(-1,
mContract.componentName.getPackageName(), mContract.user);
mContract.componentName.getPackageName(), mContract.user,
false /* supportsAllAppsState */);
boolean iconChanged = mIcon != icon;
if (iconChanged) {