Files
lawnchair/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java

214 lines
8.0 KiB
Java
Raw Normal View History

/*
* 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 static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.taskbar.TaskbarViewController.ALPHA_INDEX_HOME;
import static com.android.launcher3.taskbar.TaskbarViewController.ALPHA_INDEX_LAUNCHER_STATE;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.graphics.Rect;
import android.view.MotionEvent;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.QuickstepTransitionManager;
import com.android.launcher3.R;
import com.android.launcher3.anim.AnimatorListeners;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.util.MultiValueAlpha;
import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
import com.android.quickstep.AnimatedFloat;
/**
* A data source which integrates with a Launcher instance
*/
public class LauncherTaskbarUIController extends TaskbarUIController {
private final BaseQuickstepLauncher mLauncher;
private final TaskbarStateHandler mTaskbarStateHandler;
private final TaskbarHotseatController mHotseatController;
private final TaskbarActivityContext mContext;
final TaskbarDragLayer mTaskbarDragLayer;
final TaskbarView mTaskbarView;
private AnimatedFloat mTaskbarBackgroundAlpha;
private AlphaProperty mIconAlphaForHome;
private @Nullable Animator mAnimator;
private boolean mIsAnimatingToLauncher;
private TaskbarKeyguardController mKeyguardController;
public LauncherTaskbarUIController(
BaseQuickstepLauncher launcher, TaskbarActivityContext context) {
mContext = context;
mTaskbarDragLayer = context.getDragLayer();
mTaskbarView = mTaskbarDragLayer.findViewById(R.id.taskbar_view);
mLauncher = launcher;
mTaskbarStateHandler = mLauncher.getTaskbarStateHandler();
mHotseatController = new TaskbarHotseatController(
mLauncher, mTaskbarView::updateHotseatItems);
}
@Override
protected void init(TaskbarControllers taskbarControllers) {
mTaskbarBackgroundAlpha = taskbarControllers.taskbarDragLayerController
.getTaskbarBackgroundAlpha();
MultiValueAlpha taskbarIconAlpha = taskbarControllers.taskbarViewController
.getTaskbarIconAlpha();
mIconAlphaForHome = taskbarIconAlpha.getProperty(ALPHA_INDEX_HOME);
mTaskbarStateHandler.setAnimationController(taskbarIconAlpha.getProperty(
ALPHA_INDEX_LAUNCHER_STATE));
mHotseatController.init();
setTaskbarViewVisible(!mLauncher.hasBeenResumed());
mLauncher.setTaskbarUIController(this);
mKeyguardController = taskbarControllers.taskbarKeyguardController;
}
@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);
mHotseatController.cleanup();
setTaskbarViewVisible(true);
mLauncher.getHotseat().setIconsAlpha(1f);
mLauncher.setTaskbarUIController(null);
}
@Override
protected boolean isTaskbarTouchable() {
return !mIsAnimatingToLauncher;
}
@Override
protected void updateContentInsets(Rect outContentInsets) {
// TaskbarDragLayer provides insets to other apps based on contentInsets. These
// insets should stay consistent even if we expand TaskbarDragLayer's bounds, e.g.
// to show a floating view like Folder. Thus, we set the contentInsets to be where
// mTaskbarView is, since its position never changes and insets rather than overlays.
outContentInsets.left = mTaskbarView.getLeft();
outContentInsets.top = mTaskbarView.getTop();
outContentInsets.right = mTaskbarDragLayer.getWidth() - mTaskbarView.getRight();
outContentInsets.bottom = mTaskbarDragLayer.getHeight() - mTaskbarView.getBottom();
}
/**
* Should be called from onResume() and onPause(), and animates the Taskbar accordingly.
*/
public void onLauncherResumedOrPaused(boolean isResumed) {
if (mKeyguardController.isScreenOff()) {
if (!isResumed) {
return;
} else {
// Resuming implicitly means device unlocked
mKeyguardController.setScreenOn();
}
}
long duration = QuickstepTransitionManager.CONTENT_ALPHA_DURATION;
if (mAnimator != null) {
mAnimator.cancel();
}
if (isResumed) {
mAnimator = createAnimToLauncher(mLauncher.getStateManager().getState(), duration);
} else {
mAnimator = createAnimToApp(duration);
}
mAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mAnimator = null;
}
});
mAnimator.start();
}
/**
* Create Taskbar animation when going from an app to Launcher.
* @param toState If known, the state we will end up in when reaching Launcher.
* TODO: Move this and createAnimToApp to TaskbarStateHandler using the BACKGROUND state
*/
public Animator createAnimToLauncher(@NonNull LauncherState toState, long duration) {
PendingAnimation anim = new PendingAnimation(duration);
mTaskbarStateHandler.setState(toState, anim);
anim.setFloat(mTaskbarBackgroundAlpha, AnimatedFloat.VALUE, 0, LINEAR);
mTaskbarView.alignIconsWithLauncher(mLauncher.getDeviceProfile(), anim);
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
mIsAnimatingToLauncher = true;
}
@Override
public void onAnimationEnd(Animator animation) {
mIsAnimatingToLauncher = false;
setTaskbarViewVisible(false);
}
});
return anim.buildAnim();
}
private Animator createAnimToApp(long duration) {
PendingAnimation anim = new PendingAnimation(duration);
anim.setFloat(mTaskbarBackgroundAlpha, AnimatedFloat.VALUE, 1, LINEAR);
anim.addListener(AnimatorListeners.forEndCallback(mTaskbarView.resetIconPosition(anim)));
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
setTaskbarViewVisible(true);
}
});
return anim.buildAnim();
}
/**
* Should be called when one or more items in the Hotseat have changed.
*/
public void onHotseatUpdated() {
mHotseatController.onHotseatUpdated();
}
/**
* @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) {
return mTaskbarView.isEventOverAnyItem(ev);
}
public boolean isDraggingItem() {
return mContext.getDragController().isDragging();
}
void setTaskbarViewVisible(boolean isVisible) {
mIconAlphaForHome.setValue(isVisible ? 1 : 0);
mLauncher.getHotseat().setIconsAlpha(isVisible ? 0f : 1f);
}
}