2020-12-22 12:40:09 -06:00
|
|
|
/*
|
|
|
|
|
* 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;
|
|
|
|
|
|
2020-12-23 16:12:18 -06:00
|
|
|
import android.animation.Animator;
|
2021-03-03 17:33:28 -08:00
|
|
|
import android.animation.AnimatorListenerAdapter;
|
2021-03-02 12:28:25 -08:00
|
|
|
import android.graphics.Rect;
|
2021-05-20 20:18:47 +00:00
|
|
|
import android.graphics.RectF;
|
2021-01-22 18:45:04 -08:00
|
|
|
import android.view.MotionEvent;
|
2020-12-22 12:40:09 -06:00
|
|
|
|
2020-12-23 16:12:18 -06:00
|
|
|
import androidx.annotation.Nullable;
|
|
|
|
|
|
2020-12-22 12:40:09 -06:00
|
|
|
import com.android.launcher3.BaseQuickstepLauncher;
|
2021-03-09 17:27:53 -08:00
|
|
|
import com.android.launcher3.DeviceProfile;
|
2020-12-23 16:12:18 -06:00
|
|
|
import com.android.launcher3.LauncherState;
|
2021-03-07 15:09:11 -08:00
|
|
|
import com.android.launcher3.QuickstepTransitionManager;
|
2020-12-22 12:40:09 -06:00
|
|
|
import com.android.launcher3.R;
|
2021-05-20 20:18:47 +00:00
|
|
|
import com.android.launcher3.Utilities;
|
2020-12-23 16:12:18 -06:00
|
|
|
import com.android.launcher3.anim.PendingAnimation;
|
|
|
|
|
import com.android.launcher3.states.StateAnimationConfig;
|
2021-05-20 20:18:47 +00:00
|
|
|
|
2020-12-22 12:40:09 -06:00
|
|
|
|
|
|
|
|
/**
|
2021-05-20 20:18:47 +00:00
|
|
|
* A data source which integrates with a Launcher instance
|
|
|
|
|
* TODO: Rename to have Launcher prefix
|
2020-12-22 12:40:09 -06:00
|
|
|
*/
|
|
|
|
|
|
2021-05-20 20:18:47 +00:00
|
|
|
public class TaskbarController extends TaskbarUIController {
|
2021-04-16 12:50:22 -07:00
|
|
|
|
2020-12-22 12:40:09 -06:00
|
|
|
private final BaseQuickstepLauncher mLauncher;
|
2020-12-23 16:12:18 -06:00
|
|
|
private final TaskbarStateHandler mTaskbarStateHandler;
|
2021-03-22 17:32:50 -07:00
|
|
|
private final TaskbarAnimationController mTaskbarAnimationController;
|
2021-01-11 14:54:23 -06:00
|
|
|
private final TaskbarHotseatController mHotseatController;
|
2020-12-22 12:40:09 -06:00
|
|
|
|
2021-05-20 20:18:47 +00:00
|
|
|
private final TaskbarActivityContext mContext;
|
|
|
|
|
final TaskbarContainerView mTaskbarContainerView;
|
|
|
|
|
final TaskbarView mTaskbarView;
|
2020-12-22 12:40:09 -06:00
|
|
|
|
2021-03-08 10:14:10 -08:00
|
|
|
private @Nullable Animator mAnimator;
|
2021-03-03 17:33:28 -08:00
|
|
|
private boolean mIsAnimatingToLauncher;
|
|
|
|
|
|
2021-05-20 20:18:47 +00:00
|
|
|
public TaskbarController(BaseQuickstepLauncher launcher, TaskbarActivityContext context) {
|
|
|
|
|
mContext = context;
|
|
|
|
|
mTaskbarContainerView = context.getDragLayer();
|
|
|
|
|
mTaskbarView = mTaskbarContainerView.findViewById(R.id.taskbar_view);
|
|
|
|
|
|
2020-12-22 12:40:09 -06:00
|
|
|
mLauncher = launcher;
|
2020-12-23 16:12:18 -06:00
|
|
|
mTaskbarStateHandler = mLauncher.getTaskbarStateHandler();
|
2021-03-22 17:32:50 -07:00
|
|
|
mTaskbarAnimationController = new TaskbarAnimationController(mLauncher,
|
|
|
|
|
createTaskbarAnimationControllerCallbacks());
|
2021-05-20 20:18:47 +00:00
|
|
|
mHotseatController = new TaskbarHotseatController(
|
|
|
|
|
mLauncher, mTaskbarView::updateHotseatItems);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
protected void onCreate() {
|
|
|
|
|
mTaskbarStateHandler.setAnimationController(mTaskbarAnimationController);
|
|
|
|
|
mTaskbarAnimationController.init();
|
|
|
|
|
mHotseatController.init();
|
|
|
|
|
setTaskbarViewVisible(!mLauncher.hasBeenResumed());
|
|
|
|
|
alignRealHotseatWithTaskbar();
|
|
|
|
|
mLauncher.setTaskbarController(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
protected void onDestroy() {
|
|
|
|
|
if (mAnimator != null) {
|
|
|
|
|
// End this first, in case it relies on properties that are about to be cleaned up.
|
|
|
|
|
mAnimator.end();
|
|
|
|
|
}
|
|
|
|
|
mTaskbarStateHandler.setAnimationController(null);
|
|
|
|
|
mTaskbarAnimationController.cleanup();
|
|
|
|
|
mHotseatController.cleanup();
|
|
|
|
|
setTaskbarViewVisible(true);
|
|
|
|
|
mLauncher.getHotseat().setIconsAlpha(1f);
|
|
|
|
|
mLauncher.setTaskbarController(null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
protected boolean isTaskbarTouchable() {
|
|
|
|
|
return !mIsAnimatingToLauncher;
|
2020-12-23 16:12:18 -06:00
|
|
|
}
|
|
|
|
|
|
2021-03-22 17:32:50 -07:00
|
|
|
private TaskbarAnimationControllerCallbacks createTaskbarAnimationControllerCallbacks() {
|
|
|
|
|
return new TaskbarAnimationControllerCallbacks() {
|
2020-12-23 16:12:18 -06:00
|
|
|
@Override
|
|
|
|
|
public void updateTaskbarBackgroundAlpha(float alpha) {
|
2021-04-07 11:06:40 -07:00
|
|
|
mTaskbarContainerView.setTaskbarBackgroundAlpha(alpha);
|
2020-12-23 16:12:18 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void updateTaskbarVisibilityAlpha(float alpha) {
|
2021-05-20 20:18:47 +00:00
|
|
|
mTaskbarView.setAlpha(alpha);
|
2020-12-23 16:12:18 -06:00
|
|
|
}
|
2021-03-22 17:32:50 -07:00
|
|
|
|
2021-04-16 12:50:22 -07:00
|
|
|
@Override
|
|
|
|
|
public void updateImeBarVisibilityAlpha(float alpha) {
|
2021-05-20 20:18:47 +00:00
|
|
|
mTaskbarContainerView.updateImeBarVisibilityAlpha(alpha);
|
2021-04-16 12:50:22 -07:00
|
|
|
}
|
|
|
|
|
|
2021-03-22 17:32:50 -07:00
|
|
|
@Override
|
|
|
|
|
public void updateTaskbarScale(float scale) {
|
2021-05-20 20:18:47 +00:00
|
|
|
mTaskbarView.setScaleX(scale);
|
|
|
|
|
mTaskbarView.setScaleY(scale);
|
2021-03-22 17:32:50 -07:00
|
|
|
}
|
2021-04-07 11:06:40 -07:00
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void updateTaskbarTranslationY(float translationY) {
|
|
|
|
|
if (translationY < 0) {
|
|
|
|
|
// Resize to accommodate the max translation we'll reach.
|
2021-05-20 20:18:47 +00:00
|
|
|
mContext.setTaskbarWindowHeight(mContext.getDeviceProfile().taskbarSize
|
2021-04-07 11:06:40 -07:00
|
|
|
+ mLauncher.getHotseat().getTaskbarOffsetY());
|
|
|
|
|
} else {
|
2021-05-20 20:18:47 +00:00
|
|
|
mContext.setTaskbarWindowHeight(mContext.getDeviceProfile().taskbarSize);
|
2021-02-02 17:12:08 -08:00
|
|
|
}
|
2021-05-20 20:18:47 +00:00
|
|
|
mTaskbarView.setTranslationY(translationY);
|
2021-01-11 14:54:23 -06:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-23 16:12:18 -06:00
|
|
|
/**
|
|
|
|
|
* Should be called from onResume() and onPause(), and animates the Taskbar accordingly.
|
|
|
|
|
*/
|
|
|
|
|
public void onLauncherResumedOrPaused(boolean isResumed) {
|
2021-03-07 15:09:11 -08:00
|
|
|
long duration = QuickstepTransitionManager.CONTENT_ALPHA_DURATION;
|
2021-03-08 10:14:10 -08:00
|
|
|
if (mAnimator != null) {
|
|
|
|
|
mAnimator.cancel();
|
|
|
|
|
}
|
2020-12-23 16:12:18 -06:00
|
|
|
if (isResumed) {
|
2021-03-08 10:14:10 -08:00
|
|
|
mAnimator = createAnimToLauncher(null, duration);
|
2020-12-23 16:12:18 -06:00
|
|
|
} else {
|
2021-03-08 10:14:10 -08:00
|
|
|
mAnimator = createAnimToApp(duration);
|
2020-12-23 16:12:18 -06:00
|
|
|
}
|
2021-03-08 10:14:10 -08:00
|
|
|
mAnimator.addListener(new AnimatorListenerAdapter() {
|
|
|
|
|
@Override
|
|
|
|
|
public void onAnimationEnd(Animator animation) {
|
|
|
|
|
mAnimator = null;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
mAnimator.start();
|
2020-12-23 16:12:18 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Create Taskbar animation when going from an app to Launcher.
|
|
|
|
|
* @param toState If known, the state we will end up in when reaching Launcher.
|
|
|
|
|
*/
|
|
|
|
|
public Animator createAnimToLauncher(@Nullable LauncherState toState, long duration) {
|
|
|
|
|
PendingAnimation anim = new PendingAnimation(duration);
|
2021-03-22 17:32:50 -07:00
|
|
|
anim.add(mTaskbarAnimationController.createAnimToBackgroundAlpha(0, duration));
|
2020-12-23 16:12:18 -06:00
|
|
|
if (toState != null) {
|
|
|
|
|
mTaskbarStateHandler.setStateWithAnimation(toState, new StateAnimationConfig(), anim);
|
|
|
|
|
}
|
2021-03-03 17:33:28 -08:00
|
|
|
|
|
|
|
|
anim.addListener(new AnimatorListenerAdapter() {
|
|
|
|
|
@Override
|
|
|
|
|
public void onAnimationStart(Animator animation) {
|
|
|
|
|
mIsAnimatingToLauncher = true;
|
2021-05-20 20:18:47 +00:00
|
|
|
mTaskbarView.setHolesAllowedInLayout(true);
|
|
|
|
|
mTaskbarView.updateHotseatItemsVisibility();
|
2021-03-03 17:33:28 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onAnimationEnd(Animator animation) {
|
|
|
|
|
mIsAnimatingToLauncher = false;
|
2021-05-20 20:18:47 +00:00
|
|
|
setTaskbarViewVisible(false);
|
2021-03-03 17:33:28 -08:00
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2020-12-23 16:12:18 -06:00
|
|
|
return anim.buildAnim();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Animator createAnimToApp(long duration) {
|
2021-03-02 12:28:25 -08:00
|
|
|
PendingAnimation anim = new PendingAnimation(duration);
|
2021-03-22 17:32:50 -07:00
|
|
|
anim.add(mTaskbarAnimationController.createAnimToBackgroundAlpha(1, duration));
|
2021-03-03 17:33:28 -08:00
|
|
|
anim.addListener(new AnimatorListenerAdapter() {
|
|
|
|
|
@Override
|
|
|
|
|
public void onAnimationStart(Animator animation) {
|
2021-05-20 20:18:47 +00:00
|
|
|
mTaskbarView.updateHotseatItemsVisibility();
|
|
|
|
|
setTaskbarViewVisible(true);
|
2021-03-22 14:43:58 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onAnimationEnd(Animator animation) {
|
2021-05-20 20:18:47 +00:00
|
|
|
mTaskbarView.setHolesAllowedInLayout(false);
|
2021-03-03 17:33:28 -08:00
|
|
|
}
|
|
|
|
|
});
|
2021-03-02 12:28:25 -08:00
|
|
|
return anim.buildAnim();
|
2020-12-23 16:12:18 -06:00
|
|
|
}
|
|
|
|
|
|
2021-05-20 20:18:47 +00:00
|
|
|
@Override
|
|
|
|
|
protected void onImeVisible(TaskbarContainerView containerView, boolean isVisible) {
|
|
|
|
|
mTaskbarAnimationController.animateToVisibilityForIme(isVisible ? 0 : 1);
|
2020-12-23 16:12:18 -06:00
|
|
|
}
|
|
|
|
|
|
2021-01-11 14:54:23 -06:00
|
|
|
/**
|
|
|
|
|
* Should be called when one or more items in the Hotseat have changed.
|
|
|
|
|
*/
|
|
|
|
|
public void onHotseatUpdated() {
|
|
|
|
|
mHotseatController.onHotseatUpdated();
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-22 18:45:04 -08:00
|
|
|
/**
|
|
|
|
|
* @param ev MotionEvent in screen coordinates.
|
|
|
|
|
* @return Whether any Taskbar item could handle the given MotionEvent if given the chance.
|
|
|
|
|
*/
|
|
|
|
|
public boolean isEventOverAnyTaskbarItem(MotionEvent ev) {
|
2021-05-20 20:18:47 +00:00
|
|
|
return mTaskbarView.isEventOverAnyItem(ev);
|
2021-01-22 18:45:04 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public boolean isDraggingItem() {
|
2021-05-20 20:18:47 +00:00
|
|
|
return mTaskbarView.isDraggingItem();
|
2021-01-11 14:54:23 -06:00
|
|
|
}
|
|
|
|
|
|
2021-03-02 12:28:25 -08:00
|
|
|
/**
|
|
|
|
|
* Pads the Hotseat to line up exactly with Taskbar's copy of the Hotseat.
|
|
|
|
|
*/
|
2021-05-20 20:18:47 +00:00
|
|
|
@Override
|
2021-03-02 12:28:25 -08:00
|
|
|
public void alignRealHotseatWithTaskbar() {
|
|
|
|
|
Rect hotseatBounds = new Rect();
|
2021-03-09 17:27:53 -08:00
|
|
|
DeviceProfile grid = mLauncher.getDeviceProfile();
|
2021-03-18 13:57:20 -07:00
|
|
|
int hotseatHeight = grid.workspacePadding.bottom + grid.taskbarSize;
|
2021-04-07 11:06:40 -07:00
|
|
|
int taskbarOffset = mLauncher.getHotseat().getTaskbarOffsetY();
|
|
|
|
|
int hotseatTopDiff = hotseatHeight - grid.taskbarSize - taskbarOffset;
|
|
|
|
|
int hotseatBottomDiff = taskbarOffset;
|
2021-03-09 17:27:53 -08:00
|
|
|
|
2021-05-20 20:18:47 +00:00
|
|
|
RectF hotseatBoundsF = mTaskbarView.getHotseatBounds();
|
|
|
|
|
Utilities.scaleRectFAboutPivot(hotseatBoundsF, getTaskbarScaleOnHome(),
|
|
|
|
|
mTaskbarView.getPivotX(), mTaskbarView.getPivotY());
|
|
|
|
|
hotseatBoundsF.round(hotseatBounds);
|
2021-03-22 14:43:58 -07:00
|
|
|
mLauncher.getHotseat().setPadding(hotseatBounds.left,
|
|
|
|
|
hotseatBounds.top + hotseatTopDiff,
|
2021-05-20 20:18:47 +00:00
|
|
|
mTaskbarView.getWidth() - hotseatBounds.right,
|
|
|
|
|
mTaskbarView.getHeight() - hotseatBounds.bottom + hotseatBottomDiff);
|
2021-04-16 12:50:22 -07:00
|
|
|
}
|
|
|
|
|
|
2021-03-22 14:43:58 -07:00
|
|
|
/**
|
|
|
|
|
* Returns the ratio of the taskbar icon size on home vs in an app.
|
|
|
|
|
*/
|
|
|
|
|
public float getTaskbarScaleOnHome() {
|
2021-05-20 20:18:47 +00:00
|
|
|
DeviceProfile inAppDp = mContext.getDeviceProfile();
|
|
|
|
|
DeviceProfile onHomeDp = mLauncher.getDeviceProfile();
|
2021-03-22 14:43:58 -07:00
|
|
|
return (float) onHomeDp.cellWidthPx / inAppDp.cellWidthPx;
|
2021-03-02 12:28:25 -08:00
|
|
|
}
|
|
|
|
|
|
2021-05-20 20:18:47 +00:00
|
|
|
void setTaskbarViewVisible(boolean isVisible) {
|
|
|
|
|
mTaskbarView.setIconsVisibility(isVisible);
|
|
|
|
|
mLauncher.getHotseat().setIconsAlpha(isVisible ? 0f : 1f);
|
2020-12-23 16:12:18 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2021-03-22 17:32:50 -07:00
|
|
|
* Contains methods that TaskbarAnimationController can call to interface with
|
2020-12-23 16:12:18 -06:00
|
|
|
* TaskbarController.
|
|
|
|
|
*/
|
2021-03-22 17:32:50 -07:00
|
|
|
protected interface TaskbarAnimationControllerCallbacks {
|
2020-12-23 16:12:18 -06:00
|
|
|
void updateTaskbarBackgroundAlpha(float alpha);
|
|
|
|
|
void updateTaskbarVisibilityAlpha(float alpha);
|
2021-04-16 12:50:22 -07:00
|
|
|
void updateImeBarVisibilityAlpha(float alpha);
|
2021-03-22 17:32:50 -07:00
|
|
|
void updateTaskbarScale(float scale);
|
2021-04-07 11:06:40 -07:00
|
|
|
void updateTaskbarTranslationY(float translationY);
|
2020-12-23 16:12:18 -06:00
|
|
|
}
|
2020-12-22 12:40:09 -06:00
|
|
|
}
|