Merge "Add taskbar icons unfold animation" into sc-v2-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
6b53e3101e
@@ -35,6 +35,8 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentSender;
|
||||
import android.content.ServiceConnection;
|
||||
import android.hardware.SensorManager;
|
||||
import android.hardware.devicestate.DeviceStateManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.CancellationSignal;
|
||||
import android.os.Handler;
|
||||
@@ -73,6 +75,8 @@ import com.android.quickstep.SystemUiProxy;
|
||||
import com.android.quickstep.TaskUtils;
|
||||
import com.android.quickstep.TouchInteractionService;
|
||||
import com.android.quickstep.TouchInteractionService.TISBinder;
|
||||
import com.android.quickstep.util.LauncherUnfoldAnimationController;
|
||||
import com.android.quickstep.util.ProxyScreenStatusProvider;
|
||||
import com.android.quickstep.util.RemoteAnimationProvider;
|
||||
import com.android.quickstep.util.RemoteFadeOutAnimationListener;
|
||||
import com.android.quickstep.util.SplitSelectStateController;
|
||||
@@ -82,6 +86,9 @@ import com.android.quickstep.views.SplitPlaceholderView;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
import com.android.systemui.shared.system.ActivityOptionsCompat;
|
||||
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||
import com.android.systemui.unfold.UnfoldTransitionFactory;
|
||||
import com.android.systemui.unfold.UnfoldTransitionProgressProvider;
|
||||
import com.android.systemui.unfold.config.UnfoldTransitionConfig;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
@@ -117,6 +124,7 @@ public abstract class BaseQuickstepLauncher extends Launcher
|
||||
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
|
||||
mTaskbarManager = ((TISBinder) iBinder).getTaskbarManager();
|
||||
mTaskbarManager.setLauncher(BaseQuickstepLauncher.this);
|
||||
|
||||
Log.d(TAG, "TIS service connected");
|
||||
resetServiceBindRetryState();
|
||||
|
||||
@@ -142,16 +150,41 @@ public abstract class BaseQuickstepLauncher extends Launcher
|
||||
private @Nullable DragOptions mNextWorkspaceDragOptions = null;
|
||||
private SplitPlaceholderView mSplitPlaceholderView;
|
||||
|
||||
private @Nullable UnfoldTransitionProgressProvider mUnfoldTransitionProgressProvider;
|
||||
private @Nullable LauncherUnfoldAnimationController mLauncherUnfoldAnimationController;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
SysUINavigationMode.INSTANCE.get(this).addModeChangeListener(this);
|
||||
addMultiWindowModeChangedListener(mDepthController);
|
||||
initUnfoldTransitionProgressProvider();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
if (mLauncherUnfoldAnimationController != null) {
|
||||
mLauncherUnfoldAnimationController.onResume();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
if (mLauncherUnfoldAnimationController != null) {
|
||||
mLauncherUnfoldAnimationController.onPause();
|
||||
}
|
||||
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
mAppTransitionManager.onActivityDestroyed();
|
||||
if (mUnfoldTransitionProgressProvider != null) {
|
||||
mUnfoldTransitionProgressProvider.destroy();
|
||||
}
|
||||
|
||||
SysUINavigationMode.INSTANCE.get(this).removeModeChangeListener(this);
|
||||
|
||||
@@ -160,6 +193,11 @@ public abstract class BaseQuickstepLauncher extends Launcher
|
||||
mTaskbarManager.clearLauncher(this);
|
||||
}
|
||||
resetServiceBindRetryState();
|
||||
|
||||
if (mLauncherUnfoldAnimationController != null) {
|
||||
mLauncherUnfoldAnimationController.onDestroy();
|
||||
}
|
||||
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@@ -334,6 +372,28 @@ public abstract class BaseQuickstepLauncher extends Launcher
|
||||
mConnectionAttempts = 0;
|
||||
}
|
||||
|
||||
private void initUnfoldTransitionProgressProvider() {
|
||||
final UnfoldTransitionConfig config = UnfoldTransitionFactory.createConfig(this);
|
||||
if (config.isEnabled()) {
|
||||
mUnfoldTransitionProgressProvider =
|
||||
UnfoldTransitionFactory.createUnfoldTransitionProgressProvider(
|
||||
this,
|
||||
config,
|
||||
ProxyScreenStatusProvider.INSTANCE,
|
||||
getSystemService(DeviceStateManager.class),
|
||||
getSystemService(SensorManager.class),
|
||||
getMainThreadHandler(),
|
||||
getMainExecutor()
|
||||
);
|
||||
|
||||
mLauncherUnfoldAnimationController = new LauncherUnfoldAnimationController(
|
||||
this,
|
||||
getWindowManager(),
|
||||
mUnfoldTransitionProgressProvider
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public void setTaskbarUIController(LauncherTaskbarUIController taskbarUIController) {
|
||||
mTaskbarUIController = taskbarUIController;
|
||||
}
|
||||
@@ -373,6 +433,11 @@ public abstract class BaseQuickstepLauncher extends Launcher
|
||||
return mTaskbarStateHandler;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public UnfoldTransitionProgressProvider getUnfoldTransitionProgressProvider() {
|
||||
return mUnfoldTransitionProgressProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsAdaptiveIconAnimation(View clickedView) {
|
||||
return mAppTransitionManager.hasControlRemoteAppTransitionPermission()
|
||||
|
||||
@@ -62,6 +62,7 @@ import com.android.launcher3.util.ViewCache;
|
||||
import com.android.launcher3.views.ActivityContext;
|
||||
import com.android.quickstep.SysUINavigationMode;
|
||||
import com.android.quickstep.SysUINavigationMode.Mode;
|
||||
import com.android.quickstep.util.ScopedUnfoldTransitionProgressProvider;
|
||||
import com.android.systemui.shared.recents.model.Task;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
import com.android.systemui.shared.system.WindowManagerWrapper;
|
||||
@@ -98,7 +99,8 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
|
||||
private boolean mIsDestroyed = false;
|
||||
|
||||
public TaskbarActivityContext(Context windowContext, DeviceProfile dp,
|
||||
TaskbarNavButtonController buttonController) {
|
||||
TaskbarNavButtonController buttonController, ScopedUnfoldTransitionProgressProvider
|
||||
unfoldTransitionProgressProvider) {
|
||||
super(windowContext, Themes.getActivityThemeRes(windowContext));
|
||||
mDeviceProfile = dp;
|
||||
|
||||
@@ -120,6 +122,14 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
|
||||
FrameLayout navButtonsView = mDragLayer.findViewById(R.id.navbuttons_view);
|
||||
StashedHandleView stashedHandleView = mDragLayer.findViewById(R.id.stashed_handle);
|
||||
|
||||
Display display = windowContext.getDisplay();
|
||||
Context c = display.getDisplayId() == Display.DEFAULT_DISPLAY
|
||||
? windowContext.getApplicationContext()
|
||||
: windowContext.getApplicationContext().createDisplayContext(display);
|
||||
mWindowManager = c.getSystemService(WindowManager.class);
|
||||
mLeftCorner = display.getRoundedCorner(RoundedCorner.POSITION_BOTTOM_LEFT);
|
||||
mRightCorner = display.getRoundedCorner(RoundedCorner.POSITION_BOTTOM_RIGHT);
|
||||
|
||||
// Construct controllers.
|
||||
mControllers = new TaskbarControllers(this,
|
||||
new TaskbarDragController(this),
|
||||
@@ -129,18 +139,12 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
|
||||
R.color.popup_color_primary_light),
|
||||
new TaskbarDragLayerController(this, mDragLayer),
|
||||
new TaskbarViewController(this, taskbarView),
|
||||
new TaskbarUnfoldAnimationController(unfoldTransitionProgressProvider,
|
||||
mWindowManager),
|
||||
new TaskbarKeyguardController(this),
|
||||
new StashedHandleViewController(this, stashedHandleView),
|
||||
new TaskbarStashController(this),
|
||||
new TaskbarEduController(this));
|
||||
|
||||
Display display = windowContext.getDisplay();
|
||||
Context c = display.getDisplayId() == Display.DEFAULT_DISPLAY
|
||||
? windowContext.getApplicationContext()
|
||||
: windowContext.getApplicationContext().createDisplayContext(display);
|
||||
mWindowManager = c.getSystemService(WindowManager.class);
|
||||
mLeftCorner = display.getRoundedCorner(RoundedCorner.POSITION_BOTTOM_LEFT);
|
||||
mRightCorner = display.getRoundedCorner(RoundedCorner.POSITION_BOTTOM_RIGHT);
|
||||
}
|
||||
|
||||
public void init() {
|
||||
|
||||
@@ -31,6 +31,7 @@ public class TaskbarControllers {
|
||||
public final RotationButtonController rotationButtonController;
|
||||
public final TaskbarDragLayerController taskbarDragLayerController;
|
||||
public final TaskbarViewController taskbarViewController;
|
||||
public final TaskbarUnfoldAnimationController taskbarUnfoldAnimationController;
|
||||
public final TaskbarKeyguardController taskbarKeyguardController;
|
||||
public final StashedHandleViewController stashedHandleViewController;
|
||||
public final TaskbarStashController taskbarStashController;
|
||||
@@ -46,6 +47,7 @@ public class TaskbarControllers {
|
||||
RotationButtonController rotationButtonController,
|
||||
TaskbarDragLayerController taskbarDragLayerController,
|
||||
TaskbarViewController taskbarViewController,
|
||||
TaskbarUnfoldAnimationController taskbarUnfoldAnimationController,
|
||||
TaskbarKeyguardController taskbarKeyguardController,
|
||||
StashedHandleViewController stashedHandleViewController,
|
||||
TaskbarStashController taskbarStashController,
|
||||
@@ -57,6 +59,7 @@ public class TaskbarControllers {
|
||||
this.rotationButtonController = rotationButtonController;
|
||||
this.taskbarDragLayerController = taskbarDragLayerController;
|
||||
this.taskbarViewController = taskbarViewController;
|
||||
this.taskbarUnfoldAnimationController = taskbarUnfoldAnimationController;
|
||||
this.taskbarKeyguardController = taskbarKeyguardController;
|
||||
this.stashedHandleViewController = stashedHandleViewController;
|
||||
this.taskbarStashController = taskbarStashController;
|
||||
@@ -75,6 +78,7 @@ public class TaskbarControllers {
|
||||
}
|
||||
taskbarDragLayerController.init(this);
|
||||
taskbarViewController.init(this);
|
||||
taskbarUnfoldAnimationController.init(this);
|
||||
taskbarKeyguardController.init(navbarButtonsViewController);
|
||||
stashedHandleViewController.init(this);
|
||||
taskbarStashController.init(this);
|
||||
@@ -89,6 +93,7 @@ public class TaskbarControllers {
|
||||
rotationButtonController.onDestroy();
|
||||
taskbarDragLayerController.onDestroy();
|
||||
taskbarKeyguardController.onDestroy();
|
||||
taskbarUnfoldAnimationController.onDestroy();
|
||||
taskbarViewController.onDestroy();
|
||||
stashedHandleViewController.onDestroy();
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ import com.android.quickstep.SysUINavigationMode;
|
||||
import com.android.quickstep.SysUINavigationMode.Mode;
|
||||
import com.android.quickstep.SystemUiProxy;
|
||||
import com.android.quickstep.TouchInteractionService;
|
||||
import com.android.quickstep.util.ScopedUnfoldTransitionProgressProvider;
|
||||
|
||||
/**
|
||||
* Class to manage taskbar lifecycle
|
||||
@@ -58,6 +59,10 @@ public class TaskbarManager implements DisplayController.DisplayInfoChangeListen
|
||||
private final TaskbarNavButtonController mNavButtonController;
|
||||
private final SettingsCache.OnChangeListener mUserSetupCompleteListener;
|
||||
|
||||
// The source for this provider is set when Launcher is available
|
||||
private final ScopedUnfoldTransitionProgressProvider mUnfoldProgressProvider =
|
||||
new ScopedUnfoldTransitionProgressProvider();
|
||||
|
||||
private TaskbarActivityContext mTaskbarActivityContext;
|
||||
private BaseQuickstepLauncher mLauncher;
|
||||
/**
|
||||
@@ -120,6 +125,9 @@ public class TaskbarManager implements DisplayController.DisplayInfoChangeListen
|
||||
*/
|
||||
public void setLauncher(@NonNull BaseQuickstepLauncher launcher) {
|
||||
mLauncher = launcher;
|
||||
mUnfoldProgressProvider.setSourceProvider(launcher
|
||||
.getUnfoldTransitionProgressProvider());
|
||||
|
||||
if (mTaskbarActivityContext != null) {
|
||||
mTaskbarActivityContext.setUIController(
|
||||
new LauncherTaskbarUIController(launcher, mTaskbarActivityContext));
|
||||
@@ -135,6 +143,7 @@ public class TaskbarManager implements DisplayController.DisplayInfoChangeListen
|
||||
if (mTaskbarActivityContext != null) {
|
||||
mTaskbarActivityContext.setUIController(TaskbarUIController.DEFAULT);
|
||||
}
|
||||
mUnfoldProgressProvider.setSourceProvider(null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,8 +162,8 @@ public class TaskbarManager implements DisplayController.DisplayInfoChangeListen
|
||||
return;
|
||||
}
|
||||
|
||||
mTaskbarActivityContext = new TaskbarActivityContext(
|
||||
mContext, dp.copy(mContext), mNavButtonController);
|
||||
mTaskbarActivityContext = new TaskbarActivityContext(mContext, dp.copy(mContext),
|
||||
mNavButtonController, mUnfoldProgressProvider);
|
||||
mTaskbarActivityContext.init();
|
||||
if (mLauncher != null) {
|
||||
mTaskbarActivityContext.setUIController(
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
package com.android.launcher3.taskbar;
|
||||
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.android.quickstep.util.LauncherViewsMoveFromCenterTranslationApplier;
|
||||
import com.android.quickstep.util.ScopedUnfoldTransitionProgressProvider;
|
||||
import com.android.systemui.shared.animation.UnfoldMoveFromCenterAnimator;
|
||||
import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener;
|
||||
|
||||
/**
|
||||
* Controls animation of taskbar icons when unfolding foldable devices
|
||||
*/
|
||||
public class TaskbarUnfoldAnimationController {
|
||||
|
||||
private final ScopedUnfoldTransitionProgressProvider mUnfoldTransitionProgressProvider;
|
||||
private final UnfoldMoveFromCenterAnimator mMoveFromCenterAnimator;
|
||||
private final TransitionListener mTransitionListener = new TransitionListener();
|
||||
private TaskbarViewController mTaskbarViewController;
|
||||
|
||||
public TaskbarUnfoldAnimationController(ScopedUnfoldTransitionProgressProvider
|
||||
unfoldTransitionProgressProvider, WindowManager windowManager) {
|
||||
mUnfoldTransitionProgressProvider = unfoldTransitionProgressProvider;
|
||||
mMoveFromCenterAnimator = new UnfoldMoveFromCenterAnimator(windowManager,
|
||||
new LauncherViewsMoveFromCenterTranslationApplier());
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the controller
|
||||
* @param taskbarControllers references to all other taskbar controllers
|
||||
*/
|
||||
public void init(TaskbarControllers taskbarControllers) {
|
||||
mTaskbarViewController = taskbarControllers.taskbarViewController;
|
||||
mTaskbarViewController.addOneTimePreDrawListener(() ->
|
||||
mUnfoldTransitionProgressProvider.setReadyToHandleTransition(true));
|
||||
mUnfoldTransitionProgressProvider.addCallback(mTransitionListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys the controller
|
||||
*/
|
||||
public void onDestroy() {
|
||||
mUnfoldTransitionProgressProvider.setReadyToHandleTransition(false);
|
||||
mUnfoldTransitionProgressProvider.removeCallback(mTransitionListener);
|
||||
}
|
||||
|
||||
private class TransitionListener implements TransitionProgressListener {
|
||||
|
||||
@Override
|
||||
public void onTransitionStarted() {
|
||||
mMoveFromCenterAnimator.updateDisplayProperties();
|
||||
View[] icons = mTaskbarViewController.getIconViews();
|
||||
for (View icon : icons) {
|
||||
// TODO(b/193794563) we should re-register views if they are re-bound/re-inflated
|
||||
// during the animation
|
||||
mMoveFromCenterAnimator.registerViewForAnimation(icon);
|
||||
}
|
||||
|
||||
mMoveFromCenterAnimator.onTransitionStarted();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransitionFinished() {
|
||||
mMoveFromCenterAnimator.onTransitionFinished();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransitionProgress(float progress) {
|
||||
mMoveFromCenterAnimator.onTransitionProgress(progress);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,20 +16,24 @@
|
||||
package com.android.launcher3.taskbar;
|
||||
|
||||
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
|
||||
import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X;
|
||||
import static com.android.launcher3.Utilities.squaredHypot;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.quickstep.AnimatedFloat.VALUE;
|
||||
|
||||
import android.graphics.Rect;
|
||||
import android.util.FloatProperty;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.view.ViewTreeObserver.OnPreDrawListener;
|
||||
|
||||
import com.android.launcher3.BubbleTextView;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.anim.PendingAnimation;
|
||||
import com.android.launcher3.folder.FolderIcon;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
import com.android.launcher3.util.MultiValueAlpha;
|
||||
import com.android.quickstep.AnimatedFloat;
|
||||
@@ -117,6 +121,25 @@ public class TaskbarViewController {
|
||||
mTaskbarView.setClickAndLongClickListenersForIcon(icon);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds one time pre draw listener to the taskbar view, it is called before
|
||||
* drawing a frame and invoked only once
|
||||
* @param listener callback that will be invoked before drawing the next frame
|
||||
*/
|
||||
public void addOneTimePreDrawListener(Runnable listener) {
|
||||
mTaskbarView.getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener() {
|
||||
@Override
|
||||
public boolean onPreDraw() {
|
||||
final ViewTreeObserver viewTreeObserver = mTaskbarView.getViewTreeObserver();
|
||||
if (viewTreeObserver.isAlive()) {
|
||||
listener.run();
|
||||
viewTreeObserver.removeOnPreDrawListener(this);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Rect getIconLayoutBounds() {
|
||||
return mTaskbarView.getIconLayoutBounds();
|
||||
}
|
||||
@@ -194,7 +217,7 @@ public class TaskbarViewController {
|
||||
float childCenter = (child.getLeft() + child.getRight()) / 2;
|
||||
float hotseatIconCenter = hotseatPadding.left + hotseatCellSize * info.screenId
|
||||
+ hotseatCellSize / 2;
|
||||
setter.setFloat(child, VIEW_TRANSLATE_X, hotseatIconCenter - childCenter, LINEAR);
|
||||
setter.setFloat(child, ICON_TRANSLATE_X, hotseatIconCenter - childCenter, LINEAR);
|
||||
}
|
||||
|
||||
AnimatorPlaybackController controller = setter.createPlaybackController();
|
||||
@@ -257,4 +280,30 @@ public class TaskbarViewController {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static final FloatProperty<View> ICON_TRANSLATE_X =
|
||||
new FloatProperty<View>("taskbarAligmentTranslateX") {
|
||||
|
||||
@Override
|
||||
public void setValue(View view, float v) {
|
||||
if (view instanceof BubbleTextView) {
|
||||
((BubbleTextView) view).setTranslationXForTaskbarAlignmentAnimation(v);
|
||||
} else if (view instanceof FolderIcon) {
|
||||
((FolderIcon) view).setTranslationForTaskbarAlignmentAnimation(v);
|
||||
} else {
|
||||
view.setTranslationX(v);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float get(View view) {
|
||||
if (view instanceof BubbleTextView) {
|
||||
return ((BubbleTextView) view)
|
||||
.getTranslationXForTaskbarAlignmentAnimation();
|
||||
} else if (view instanceof FolderIcon) {
|
||||
return ((FolderIcon) view).getTranslationXForTaskbarAlignmentAnimation();
|
||||
}
|
||||
return view.getTranslationX();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -36,13 +36,9 @@ import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SY
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Configuration;
|
||||
import android.hardware.SensorManager;
|
||||
import android.hardware.devicestate.DeviceStateManager;
|
||||
import android.view.HapticFeedbackConstants;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.BaseQuickstepLauncher;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.Launcher;
|
||||
@@ -79,14 +75,9 @@ import com.android.quickstep.SysUINavigationMode;
|
||||
import com.android.quickstep.SysUINavigationMode.Mode;
|
||||
import com.android.quickstep.SystemUiProxy;
|
||||
import com.android.quickstep.TaskUtils;
|
||||
import com.android.quickstep.util.LauncherUnfoldAnimationController;
|
||||
import com.android.quickstep.util.ProxyScreenStatusProvider;
|
||||
import com.android.quickstep.util.QuickstepOnboardingPrefs;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.quickstep.views.TaskView;
|
||||
import com.android.systemui.unfold.UnfoldTransitionFactory;
|
||||
import com.android.systemui.unfold.UnfoldTransitionProgressProvider;
|
||||
import com.android.systemui.unfold.config.UnfoldTransitionConfig;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
@@ -106,51 +97,10 @@ public class QuickstepLauncher extends BaseQuickstepLauncher {
|
||||
private FixedContainerItems mAllAppsPredictions;
|
||||
private HotseatPredictionController mHotseatPredictionController;
|
||||
|
||||
@Nullable
|
||||
private LauncherUnfoldAnimationController mLauncherUnfoldAnimationController;
|
||||
|
||||
@Override
|
||||
protected void setupViews() {
|
||||
super.setupViews();
|
||||
mHotseatPredictionController = new HotseatPredictionController(this);
|
||||
|
||||
final UnfoldTransitionConfig config = UnfoldTransitionFactory.createConfig(this);
|
||||
if (config.isEnabled()) {
|
||||
final UnfoldTransitionProgressProvider unfoldTransitionProgressProvider =
|
||||
UnfoldTransitionFactory.createUnfoldTransitionProgressProvider(
|
||||
this,
|
||||
config,
|
||||
ProxyScreenStatusProvider.INSTANCE,
|
||||
getSystemService(DeviceStateManager.class),
|
||||
getSystemService(SensorManager.class),
|
||||
getMainThreadHandler(),
|
||||
getMainExecutor()
|
||||
);
|
||||
|
||||
mLauncherUnfoldAnimationController = new LauncherUnfoldAnimationController(
|
||||
this,
|
||||
getWindowManager(),
|
||||
unfoldTransitionProgressProvider
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
if (mLauncherUnfoldAnimationController != null) {
|
||||
mLauncherUnfoldAnimationController.onResume();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
if (mLauncherUnfoldAnimationController != null) {
|
||||
mLauncherUnfoldAnimationController.onPause();
|
||||
}
|
||||
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -281,10 +231,6 @@ public class QuickstepLauncher extends BaseQuickstepLauncher {
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
mHotseatPredictionController.destroy();
|
||||
|
||||
if (mLauncherUnfoldAnimationController != null) {
|
||||
mLauncherUnfoldAnimationController.onDestroy();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -37,26 +37,23 @@ public class LauncherUnfoldAnimationController {
|
||||
private static final float MAX_WIDTH_INSET_FRACTION = 0.15f;
|
||||
|
||||
private final Launcher mLauncher;
|
||||
private final UnfoldTransitionProgressProvider mUnfoldTransitionProgressProvider;
|
||||
private final UnfoldMoveFromCenterWorkspaceAnimator mMoveFromCenterWorkspaceAnimation;
|
||||
|
||||
@Nullable
|
||||
private HorizontalInsettableView mQsbInsettable;
|
||||
|
||||
private final AnimationListener mAnimationListener = new AnimationListener();
|
||||
|
||||
private boolean mIsTransitionRunning = false;
|
||||
private boolean mIsReadyToPlayAnimation = false;
|
||||
private final ScopedUnfoldTransitionProgressProvider mProgressProvider;
|
||||
|
||||
public LauncherUnfoldAnimationController(
|
||||
Launcher launcher,
|
||||
WindowManager windowManager,
|
||||
UnfoldTransitionProgressProvider unfoldTransitionProgressProvider) {
|
||||
mLauncher = launcher;
|
||||
mUnfoldTransitionProgressProvider = unfoldTransitionProgressProvider;
|
||||
mMoveFromCenterWorkspaceAnimation = new UnfoldMoveFromCenterWorkspaceAnimator(launcher,
|
||||
windowManager);
|
||||
mUnfoldTransitionProgressProvider.addCallback(mAnimationListener);
|
||||
mProgressProvider = new ScopedUnfoldTransitionProgressProvider(
|
||||
unfoldTransitionProgressProvider);
|
||||
|
||||
mProgressProvider.addCallback(new UnfoldMoveFromCenterWorkspaceAnimator(launcher,
|
||||
windowManager));
|
||||
mProgressProvider.addCallback(new QsbAnimationListener());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,7 +70,7 @@ public class LauncherUnfoldAnimationController {
|
||||
@Override
|
||||
public boolean onPreDraw() {
|
||||
if (obs.isAlive()) {
|
||||
onPreDrawAfterResume();
|
||||
mProgressProvider.setReadyToHandleTransition(true);
|
||||
obs.removeOnPreDrawListener(this);
|
||||
}
|
||||
return true;
|
||||
@@ -85,12 +82,7 @@ public class LauncherUnfoldAnimationController {
|
||||
* Called when launcher activity is paused
|
||||
*/
|
||||
public void onPause() {
|
||||
if (mIsTransitionRunning) {
|
||||
mIsTransitionRunning = false;
|
||||
mAnimationListener.onTransitionFinished();
|
||||
}
|
||||
|
||||
mIsReadyToPlayAnimation = false;
|
||||
mProgressProvider.setReadyToHandleTransition(false);
|
||||
mQsbInsettable = null;
|
||||
}
|
||||
|
||||
@@ -98,48 +90,24 @@ public class LauncherUnfoldAnimationController {
|
||||
* Called when launcher activity is destroyed
|
||||
*/
|
||||
public void onDestroy() {
|
||||
mUnfoldTransitionProgressProvider.removeCallback(mAnimationListener);
|
||||
mProgressProvider.destroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called after performing layouting of the views after configuration change
|
||||
*/
|
||||
private void onPreDrawAfterResume() {
|
||||
mIsReadyToPlayAnimation = true;
|
||||
|
||||
if (mIsTransitionRunning) {
|
||||
mMoveFromCenterWorkspaceAnimation.onTransitionStarted();
|
||||
}
|
||||
}
|
||||
|
||||
private class AnimationListener implements TransitionProgressListener {
|
||||
private class QsbAnimationListener implements TransitionProgressListener {
|
||||
|
||||
@Override
|
||||
public void onTransitionStarted() {
|
||||
mIsTransitionRunning = true;
|
||||
|
||||
if (mIsReadyToPlayAnimation) {
|
||||
mMoveFromCenterWorkspaceAnimation.onTransitionStarted();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransitionFinished() {
|
||||
if (mIsReadyToPlayAnimation) {
|
||||
mMoveFromCenterWorkspaceAnimation.onTransitionFinished();
|
||||
|
||||
if (mQsbInsettable != null) {
|
||||
mQsbInsettable.setHorizontalInsets(0);
|
||||
}
|
||||
if (mQsbInsettable != null) {
|
||||
mQsbInsettable.setHorizontalInsets(0);
|
||||
}
|
||||
|
||||
mIsTransitionRunning = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransitionProgress(float progress) {
|
||||
mMoveFromCenterWorkspaceAnimation.onTransitionProgress(progress);
|
||||
|
||||
if (mQsbInsettable != null) {
|
||||
float insetPercentage = comp(progress) * MAX_WIDTH_INSET_FRACTION;
|
||||
mQsbInsettable.setHorizontalInsets(insetPercentage);
|
||||
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
package com.android.quickstep.util;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.launcher3.BubbleTextView;
|
||||
import com.android.launcher3.folder.FolderIcon;
|
||||
import com.android.launcher3.widget.NavigableAppWidgetHostView;
|
||||
import com.android.systemui.shared.animation.UnfoldMoveFromCenterAnimator.TranslationApplier;
|
||||
|
||||
/**
|
||||
* Class that allows to set translations for move from center animation independently
|
||||
* from other translations for certain launcher views
|
||||
*/
|
||||
public class LauncherViewsMoveFromCenterTranslationApplier implements TranslationApplier {
|
||||
|
||||
@Override
|
||||
public void apply(@NonNull View view, float x, float y) {
|
||||
if (view instanceof NavigableAppWidgetHostView) {
|
||||
((NavigableAppWidgetHostView) view).setTranslationForMoveFromCenterAnimation(x, y);
|
||||
} else if (view instanceof BubbleTextView) {
|
||||
((BubbleTextView) view).setTranslationForMoveFromCenterAnimation(x, y);
|
||||
} else if (view instanceof FolderIcon) {
|
||||
((FolderIcon) view).setTranslationForMoveFromCenterAnimation(x, y);
|
||||
} else {
|
||||
view.setTranslationX(x);
|
||||
view.setTranslationY(y);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
package com.android.quickstep.util;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
|
||||
import com.android.systemui.unfold.UnfoldTransitionProgressProvider;
|
||||
import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Manages progress listeners that can have smaller lifespan than the unfold animation.
|
||||
* Allows to limit getting transition updates to only when
|
||||
* {@link ScopedUnfoldTransitionProgressProvider#setReadyToHandleTransition} is called
|
||||
* with readyToHandleTransition = true
|
||||
*
|
||||
* If the transition has already started by the moment when the clients are ready to play
|
||||
* the transition then it will report transition started callback and current animation progress.
|
||||
*/
|
||||
public final class ScopedUnfoldTransitionProgressProvider implements
|
||||
UnfoldTransitionProgressProvider, TransitionProgressListener {
|
||||
|
||||
private static final float PROGRESS_UNSET = -1f;
|
||||
|
||||
@Nullable
|
||||
private UnfoldTransitionProgressProvider mSource;
|
||||
|
||||
private final List<TransitionProgressListener> mListeners = new ArrayList<>();
|
||||
|
||||
private boolean mIsReadyToHandleTransition;
|
||||
private boolean mIsTransitionRunning;
|
||||
private float mLastTransitionProgress = PROGRESS_UNSET;
|
||||
|
||||
public ScopedUnfoldTransitionProgressProvider() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public ScopedUnfoldTransitionProgressProvider(@Nullable UnfoldTransitionProgressProvider
|
||||
source) {
|
||||
setSourceProvider(source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the source for the unfold transition progress updates,
|
||||
* it replaces current provider if it is already set
|
||||
* @param provider transition provider that emits transition progress updates
|
||||
*/
|
||||
public void setSourceProvider(@Nullable UnfoldTransitionProgressProvider provider) {
|
||||
if (mSource != null) {
|
||||
mSource.removeCallback(this);
|
||||
}
|
||||
|
||||
if (provider != null) {
|
||||
mSource = provider;
|
||||
mSource.addCallback(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to notify this provide whether the listeners can play the transition or not.
|
||||
* Call this method with readyToHandleTransition = true when all listeners
|
||||
* are ready to consume the transition progress events.
|
||||
* Call it with readyToHandleTransition = false when listeners can't process the events.
|
||||
*/
|
||||
public void setReadyToHandleTransition(boolean isReadyToHandleTransition) {
|
||||
if (mIsTransitionRunning) {
|
||||
if (mIsReadyToHandleTransition) {
|
||||
mListeners.forEach(TransitionProgressListener::onTransitionStarted);
|
||||
|
||||
if (mLastTransitionProgress != PROGRESS_UNSET) {
|
||||
mListeners.forEach(listener ->
|
||||
listener.onTransitionProgress(mLastTransitionProgress));
|
||||
}
|
||||
} else {
|
||||
mIsTransitionRunning = false;
|
||||
mListeners.forEach(TransitionProgressListener::onTransitionFinished);
|
||||
}
|
||||
}
|
||||
|
||||
mIsReadyToHandleTransition = isReadyToHandleTransition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCallback(@NonNull TransitionProgressListener listener) {
|
||||
mListeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeCallback(@NonNull TransitionProgressListener listener) {
|
||||
mListeners.remove(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
mSource.removeCallback(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransitionStarted() {
|
||||
this.mIsTransitionRunning = true;
|
||||
if (mIsReadyToHandleTransition) {
|
||||
mListeners.forEach(TransitionProgressListener::onTransitionStarted);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransitionProgress(float progress) {
|
||||
if (mIsReadyToHandleTransition) {
|
||||
mListeners.forEach(listener -> listener.onTransitionProgress(progress));
|
||||
}
|
||||
|
||||
mLastTransitionProgress = progress;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransitionFinished() {
|
||||
if (mIsReadyToHandleTransition) {
|
||||
mListeners.forEach(TransitionProgressListener::onTransitionFinished);
|
||||
}
|
||||
|
||||
mIsTransitionRunning = false;
|
||||
mLastTransitionProgress = PROGRESS_UNSET;
|
||||
}
|
||||
}
|
||||
+1
-20
@@ -15,20 +15,16 @@
|
||||
*/
|
||||
package com.android.quickstep.util;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.android.launcher3.BubbleTextView;
|
||||
import com.android.launcher3.CellLayout;
|
||||
import com.android.launcher3.Hotseat;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.ShortcutAndWidgetContainer;
|
||||
import com.android.launcher3.Workspace;
|
||||
import com.android.launcher3.widget.NavigableAppWidgetHostView;
|
||||
import com.android.systemui.shared.animation.UnfoldMoveFromCenterAnimator;
|
||||
import com.android.systemui.shared.animation.UnfoldMoveFromCenterAnimator.TranslationApplier;
|
||||
import com.android.systemui.unfold.UnfoldTransitionProgressProvider;
|
||||
|
||||
import java.util.HashMap;
|
||||
@@ -49,7 +45,7 @@ public class UnfoldMoveFromCenterWorkspaceAnimator
|
||||
public UnfoldMoveFromCenterWorkspaceAnimator(Launcher launcher, WindowManager windowManager) {
|
||||
mLauncher = launcher;
|
||||
mMoveFromCenterAnimation = new UnfoldMoveFromCenterAnimator(windowManager,
|
||||
new WorkspaceViewsTranslationApplier());
|
||||
new LauncherViewsMoveFromCenterTranslationApplier());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -122,19 +118,4 @@ public class UnfoldMoveFromCenterWorkspaceAnimator
|
||||
view.setClipChildren(originalClipChildren);
|
||||
}
|
||||
}
|
||||
|
||||
private static class WorkspaceViewsTranslationApplier implements TranslationApplier {
|
||||
|
||||
@Override
|
||||
public void apply(@NonNull View view, float x, float y) {
|
||||
if (view instanceof NavigableAppWidgetHostView) {
|
||||
((NavigableAppWidgetHostView) view).setTranslationForMoveFromCenterAnimation(x, y);
|
||||
} else if (view instanceof BubbleTextView) {
|
||||
((BubbleTextView) view).setTranslationForMoveFromCenterAnimation(x, y);
|
||||
} else {
|
||||
view.setTranslationX(x);
|
||||
view.setTranslationY(y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,6 +90,8 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
|
||||
private final PointF mTranslationForReorderBounce = new PointF(0, 0);
|
||||
private final PointF mTranslationForReorderPreview = new PointF(0, 0);
|
||||
|
||||
private float mTranslationXForTaskbarAlignmentAnimation = 0f;
|
||||
|
||||
private final PointF mTranslationForMoveFromCenterAnimation = new PointF(0, 0);
|
||||
|
||||
private float mScaleForReorderBounce = 1f;
|
||||
@@ -825,7 +827,8 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
|
||||
|
||||
private void updateTranslation() {
|
||||
super.setTranslationX(mTranslationForReorderBounce.x + mTranslationForReorderPreview.x
|
||||
+ mTranslationForMoveFromCenterAnimation.x);
|
||||
+ mTranslationForMoveFromCenterAnimation.x
|
||||
+ mTranslationXForTaskbarAlignmentAnimation);
|
||||
super.setTranslationY(mTranslationForReorderBounce.y + mTranslationForReorderPreview.y
|
||||
+ mTranslationForMoveFromCenterAnimation.y);
|
||||
}
|
||||
@@ -860,11 +863,29 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
|
||||
return mScaleForReorderBounce;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets translation values for move from center animation
|
||||
*/
|
||||
public void setTranslationForMoveFromCenterAnimation(float x, float y) {
|
||||
mTranslationForMoveFromCenterAnimation.set(x, y);
|
||||
updateTranslation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets translationX for taskbar to launcher alignment animation
|
||||
*/
|
||||
public void setTranslationXForTaskbarAlignmentAnimation(float translationX) {
|
||||
mTranslationXForTaskbarAlignmentAnimation = translationX;
|
||||
updateTranslation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns translationX value for taskbar to launcher alignment animation
|
||||
*/
|
||||
public float getTranslationXForTaskbarAlignmentAnimation() {
|
||||
return mTranslationXForTaskbarAlignmentAnimation;
|
||||
}
|
||||
|
||||
public View getView() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -132,6 +132,9 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel
|
||||
|
||||
private Rect mTouchArea = new Rect();
|
||||
|
||||
private final PointF mTranslationForMoveFromCenterAnimation = new PointF(0, 0);
|
||||
private float mTranslationXForTaskbarAlignmentAnimation = 0f;
|
||||
|
||||
private final PointF mTranslationForReorderBounce = new PointF(0, 0);
|
||||
private final PointF mTranslationForReorderPreview = new PointF(0, 0);
|
||||
private float mScaleForReorderBounce = 1f;
|
||||
@@ -765,8 +768,11 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel
|
||||
}
|
||||
|
||||
private void updateTranslation() {
|
||||
super.setTranslationX(mTranslationForReorderBounce.x + mTranslationForReorderPreview.x);
|
||||
super.setTranslationY(mTranslationForReorderBounce.y + mTranslationForReorderPreview.y);
|
||||
super.setTranslationX(mTranslationForReorderBounce.x + mTranslationForReorderPreview.x
|
||||
+ mTranslationForMoveFromCenterAnimation.x
|
||||
+ mTranslationXForTaskbarAlignmentAnimation);
|
||||
super.setTranslationY(mTranslationForReorderBounce.y + mTranslationForReorderPreview.y
|
||||
+ mTranslationForMoveFromCenterAnimation.y);
|
||||
}
|
||||
|
||||
public void setReorderBounceOffset(float x, float y) {
|
||||
@@ -778,6 +784,29 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel
|
||||
offset.set(mTranslationForReorderBounce);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets translationX value for taskbar to launcher alignment animation
|
||||
*/
|
||||
public void setTranslationForTaskbarAlignmentAnimation(float translationX) {
|
||||
mTranslationXForTaskbarAlignmentAnimation = translationX;
|
||||
updateTranslation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns translation values for taskbar to launcher alignment animation
|
||||
*/
|
||||
public float getTranslationXForTaskbarAlignmentAnimation() {
|
||||
return mTranslationXForTaskbarAlignmentAnimation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets translation values for move from center animation
|
||||
*/
|
||||
public void setTranslationForMoveFromCenterAnimation(float x, float y) {
|
||||
mTranslationForMoveFromCenterAnimation.set(x, y);
|
||||
updateTranslation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReorderPreviewOffset(float x, float y) {
|
||||
mTranslationForReorderPreview.set(x, y);
|
||||
|
||||
Reference in New Issue
Block a user