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

209 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 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_APPLICATION_OVERLAY;
import static com.android.systemui.shared.system.WindowManagerWrapper.ITYPE_BOTTOM_TAPPABLE_ELEMENT;
import static com.android.systemui.shared.system.WindowManagerWrapper.ITYPE_EXTRA_NAVIGATION_BAR;
import android.animation.Animator;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.view.Gravity;
import android.view.WindowManager;
import androidx.annotation.Nullable;
import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.QuickstepAppTransitionManagerImpl;
import com.android.launcher3.R;
import com.android.launcher3.anim.AlphaUpdateListener;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.states.StateAnimationConfig;
import com.android.quickstep.AnimatedFloat;
import com.android.systemui.shared.system.WindowManagerWrapper;
/**
* Interfaces with Launcher/WindowManager/SystemUI to determine what to show in TaskbarView.
*/
public class TaskbarController {
private static final String WINDOW_TITLE = "Taskbar";
private final TaskbarContainerView mTaskbarContainerView;
private final TaskbarView mTaskbarView;
private final BaseQuickstepLauncher mLauncher;
private final WindowManager mWindowManager;
// Layout width and height of the Taskbar in the default state.
private final Point mTaskbarSize;
private final TaskbarStateHandler mTaskbarStateHandler;
private final TaskbarVisibilityController mTaskbarVisibilityController;
// Initialized in init().
private WindowManager.LayoutParams mWindowLayoutParams;
public TaskbarController(BaseQuickstepLauncher launcher,
TaskbarContainerView taskbarContainerView) {
mLauncher = launcher;
mTaskbarContainerView = taskbarContainerView;
mTaskbarView = mTaskbarContainerView.findViewById(R.id.taskbar_view);
mWindowManager = mLauncher.getWindowManager();
mTaskbarSize = new Point(MATCH_PARENT,
mLauncher.getResources().getDimensionPixelSize(R.dimen.taskbar_size));
mTaskbarStateHandler = mLauncher.getTaskbarStateHandler();
mTaskbarVisibilityController = new TaskbarVisibilityController(mLauncher,
createTaskbarVisibilityControllerCallbacks());
}
private TaskbarVisibilityControllerCallbacks createTaskbarVisibilityControllerCallbacks() {
return new TaskbarVisibilityControllerCallbacks() {
@Override
public void updateTaskbarBackgroundAlpha(float alpha) {
mTaskbarView.setBackgroundAlpha(alpha);
}
@Override
public void updateTaskbarVisibilityAlpha(float alpha) {
mTaskbarContainerView.setAlpha(alpha);
AlphaUpdateListener.updateVisibility(mTaskbarContainerView);
}
};
}
/**
* Initializes the Taskbar, including adding it to the screen.
*/
public void init() {
addToWindowManager();
mTaskbarStateHandler.setTaskbarCallbacks(createTaskbarStateHandlerCallbacks());
mTaskbarVisibilityController.init();
}
private TaskbarStateHandlerCallbacks createTaskbarStateHandlerCallbacks() {
return new TaskbarStateHandlerCallbacks() {
@Override
public AnimatedFloat getAlphaTarget() {
return mTaskbarVisibilityController.getTaskbarVisibilityForLauncherState();
}
};
}
/**
* Removes the Taskbar from the screen, and removes any obsolete listeners etc.
*/
public void cleanup() {
removeFromWindowManager();
mTaskbarStateHandler.setTaskbarCallbacks(null);
mTaskbarVisibilityController.cleanup();
}
private void removeFromWindowManager() {
if (mTaskbarContainerView.isAttachedToWindow()) {
mWindowManager.removeViewImmediate(mTaskbarContainerView);
}
}
private void addToWindowManager() {
removeFromWindowManager();
final int gravity = Gravity.BOTTOM;
mWindowLayoutParams = new WindowManager.LayoutParams(
mTaskbarSize.x,
mTaskbarSize.y,
TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
mWindowLayoutParams.setTitle(WINDOW_TITLE);
mWindowLayoutParams.packageName = mLauncher.getPackageName();
mWindowLayoutParams.gravity = gravity;
mWindowLayoutParams.setFitInsetsTypes(0);
mWindowLayoutParams.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
mWindowLayoutParams.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
WindowManagerWrapper wmWrapper = WindowManagerWrapper.getInstance();
wmWrapper.setProvidesInsetsTypes(
mWindowLayoutParams,
new int[] { ITYPE_EXTRA_NAVIGATION_BAR, ITYPE_BOTTOM_TAPPABLE_ELEMENT }
);
TaskbarContainerView.LayoutParams taskbarLayoutParams =
new TaskbarContainerView.LayoutParams(mTaskbarSize.x, mTaskbarSize.y);
taskbarLayoutParams.gravity = gravity;
mTaskbarView.setLayoutParams(taskbarLayoutParams);
mWindowManager.addView(mTaskbarContainerView, mWindowLayoutParams);
}
/**
* Should be called from onResume() and onPause(), and animates the Taskbar accordingly.
*/
public void onLauncherResumedOrPaused(boolean isResumed) {
long duration = QuickstepAppTransitionManagerImpl.CONTENT_ALPHA_DURATION;
final Animator anim;
if (isResumed) {
anim = createAnimToLauncher(null, duration);
} else {
anim = createAnimToApp(duration);
}
anim.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.
*/
public Animator createAnimToLauncher(@Nullable LauncherState toState, long duration) {
PendingAnimation anim = new PendingAnimation(duration);
anim.add(mTaskbarVisibilityController.createAnimToBackgroundAlpha(0, duration));
if (toState != null) {
mTaskbarStateHandler.setStateWithAnimation(toState, new StateAnimationConfig(), anim);
}
return anim.buildAnim();
}
private Animator createAnimToApp(long duration) {
return mTaskbarVisibilityController.createAnimToBackgroundAlpha(1, duration);
}
/**
* Should be called when the IME visibility changes, so we can hide/show Taskbar accordingly.
*/
public void setIsImeVisible(boolean isImeVisible) {
mTaskbarVisibilityController.animateToVisibilityForIme(isImeVisible ? 0 : 1);
}
/**
* Contains methods that TaskbarStateHandler can call to interface with TaskbarController.
*/
protected interface TaskbarStateHandlerCallbacks {
AnimatedFloat getAlphaTarget();
}
/**
* Contains methods that TaskbarVisibilityController can call to interface with
* TaskbarController.
*/
protected interface TaskbarVisibilityControllerCallbacks {
void updateTaskbarBackgroundAlpha(float alpha);
void updateTaskbarVisibilityAlpha(float alpha);
}
}