Merge "Reorganize taskbar controllers" into sc-v2-dev am: 51edca003c am: 3f0f5df8bf

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Launcher3/+/14923145

Change-Id: I56902c21fe4f1000cb528e6d0acfe5cf6805fc39
This commit is contained in:
Tony Wickham
2021-06-10 16:16:30 +00:00
committed by Automerger Merge Worker
10 changed files with 419 additions and 249 deletions
@@ -16,9 +16,12 @@
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;
@@ -30,6 +33,7 @@ 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;
@@ -47,7 +51,7 @@ public class LauncherTaskbarUIController extends TaskbarUIController {
final TaskbarDragLayer mTaskbarDragLayer;
final TaskbarView mTaskbarView;
private AnimatedFloat mTaskBarAlpha;
private AnimatedFloat mTaskbarBackgroundAlpha;
private AlphaProperty mIconAlphaForHome;
private @Nullable Animator mAnimator;
private boolean mIsAnimatingToLauncher;
@@ -66,11 +70,14 @@ public class LauncherTaskbarUIController extends TaskbarUIController {
}
@Override
protected void init(AnimatedFloat taskBarAlpha, AlphaProperty iconAlphaForLauncherState,
AlphaProperty iconAlphaForHome) {
mTaskBarAlpha = taskBarAlpha;
mIconAlphaForHome = iconAlphaForHome;
mTaskbarStateHandler.setAnimationController(iconAlphaForLauncherState);
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);
@@ -94,6 +101,18 @@ public class LauncherTaskbarUIController extends TaskbarUIController {
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.
*/
@@ -125,7 +144,7 @@ public class LauncherTaskbarUIController extends TaskbarUIController {
PendingAnimation anim = new PendingAnimation(duration);
mTaskbarStateHandler.setState(toState, anim);
anim.setFloat(mTaskBarAlpha, AnimatedFloat.VALUE, 0, LINEAR);
anim.setFloat(mTaskbarBackgroundAlpha, AnimatedFloat.VALUE, 0, LINEAR);
mTaskbarView.alignIconsWithLauncher(mLauncher.getDeviceProfile(), anim);
anim.addListener(new AnimatorListenerAdapter() {
@@ -146,7 +165,7 @@ public class LauncherTaskbarUIController extends TaskbarUIController {
private Animator createAnimToApp(long duration) {
PendingAnimation anim = new PendingAnimation(duration);
anim.setFloat(mTaskBarAlpha, AnimatedFloat.VALUE, 1, LINEAR);
anim.setFloat(mTaskbarBackgroundAlpha, AnimatedFloat.VALUE, 1, LINEAR);
anim.addListener(AnimatorListeners.forEndCallback(mTaskbarView.resetIconPosition(anim)));
anim.addListener(new AnimatorListenerAdapter() {
@Override
@@ -21,6 +21,7 @@ import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_BA
import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_HOME;
import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_IME_SWITCH;
import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_RECENTS;
import static com.android.launcher3.taskbar.TaskbarViewController.ALPHA_INDEX_IME;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING;
@@ -48,7 +49,6 @@ import com.android.launcher3.taskbar.TaskbarNavButtonController.TaskbarButton;
import com.android.launcher3.taskbar.contextual.RotationButton;
import com.android.launcher3.taskbar.contextual.RotationButtonController;
import com.android.launcher3.util.MultiValueAlpha;
import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
import com.android.quickstep.AnimatedFloat;
import java.util.ArrayList;
@@ -57,7 +57,7 @@ import java.util.function.IntPredicate;
/**
* Controller for managing nav bar buttons in taskbar
*/
public class NavbarButtonUIController {
public class NavbarButtonsViewController {
private final Rect mTempRect = new Rect();
@@ -74,48 +74,53 @@ public class NavbarButtonUIController {
private int mState;
private final TaskbarActivityContext mContext;
private View a11yButton;
private final FrameLayout mNavButtonsView;
private final ViewGroup mStartContainer;
private final ViewGroup mEndContainer;
// Initialized in init.
private TaskbarControllers mControllers;
private View mA11yButton;
private int mSysuiStateFlags;
public NavbarButtonUIController(TaskbarActivityContext context) {
public NavbarButtonsViewController(TaskbarActivityContext context, FrameLayout navButtonsView) {
mContext = context;
mNavButtonsView = navButtonsView;
mStartContainer = mNavButtonsView.findViewById(R.id.start_nav_buttons);
mEndContainer = mNavButtonsView.findViewById(R.id.end_nav_buttons);
}
/**
* Initializes the controller
*/
public void init(TaskbarDragLayer dragLayer,
TaskbarNavButtonController navButtonController,
RotationButtonController rotationButtonController,
AnimatedFloat taskbarBackgroundAlpha, AlphaProperty taskbarIconAlpha) {
FrameLayout buttonController = dragLayer.findViewById(R.id.navbuttons_view);
buttonController.getLayoutParams().height = mContext.getDeviceProfile().taskbarSize;
public void init(TaskbarControllers controllers) {
mControllers = controllers;
mNavButtonsView.getLayoutParams().height = mContext.getDeviceProfile().taskbarSize;
mA11yLongClickListener = view -> {
navButtonController.onButtonClick(BUTTON_A11Y_LONG_CLICK);
mControllers.navButtonController.onButtonClick(BUTTON_A11Y_LONG_CLICK);
return true;
};
if (mContext.canShowNavButtons()) {
ViewGroup startContainer = buttonController.findViewById(R.id.start_nav_buttons);
ViewGroup endContainer = buttonController.findViewById(R.id.end_nav_buttons);
initButtons(startContainer, endContainer, navButtonController);
initButtons(mStartContainer, mEndContainer, mControllers.navButtonController);
// Animate taskbar background when IME shows
mPropertyHolders.add(new StatePropertyHolder(taskbarBackgroundAlpha,
mPropertyHolders.add(new StatePropertyHolder(
mControllers.taskbarDragLayerController.getNavbarBackgroundAlpha(),
flags -> (flags & FLAG_IME_VISIBLE) == 0,
AnimatedFloat.VALUE, 0, 1));
mPropertyHolders.add(new StatePropertyHolder(
taskbarIconAlpha, flags -> (flags & FLAG_IME_VISIBLE) == 0,
MultiValueAlpha.VALUE, 1, 0));
mControllers.taskbarViewController.getTaskbarIconAlpha()
.getProperty(ALPHA_INDEX_IME),
flags -> (flags & FLAG_IME_VISIBLE) == 0, MultiValueAlpha.VALUE, 1, 0));
// Rotation button
RotationButton rotationButton = new RotationButtonImpl(addButton(endContainer));
RotationButton rotationButton = new RotationButtonImpl(addButton(mEndContainer));
rotationButton.hide();
rotationButtonController.setRotationButton(rotationButton);
mControllers.rotationButtonController.setRotationButton(rotationButton);
} else {
rotationButtonController.setRotationButton(new RotationButton() { });
mControllers.rotationButtonController.setRotationButton(new RotationButton() {});
}
applyState();
@@ -151,12 +156,12 @@ public class NavbarButtonUIController {
&& ((flags & FLAG_A11Y_VISIBLE) == 0)));
// A11y button
a11yButton = addButton(R.drawable.ic_sysbar_accessibility_button, BUTTON_A11Y,
mA11yButton = addButton(R.drawable.ic_sysbar_accessibility_button, BUTTON_A11Y,
endContainer, navButtonController);
mPropertyHolders.add(new StatePropertyHolder(a11yButton,
mPropertyHolders.add(new StatePropertyHolder(mA11yButton,
flags -> (flags & FLAG_A11Y_VISIBLE) != 0
&& (flags & FLAG_ROTATION_BUTTON_VISIBLE) == 0));
a11yButton.setOnLongClickListener(mA11yLongClickListener);
mA11yButton.setOnLongClickListener(mA11yLongClickListener);
}
public void updateStateForSysuiFlags(int systemUiStateFlags, boolean forceUpdate) {
@@ -174,7 +179,7 @@ public class NavbarButtonUIController {
updateStateForFlag(FLAG_IME_VISIBLE, isImeVisible);
updateStateForFlag(FLAG_SWITCHER_SUPPORTED, isImeSwitcherShowing);
updateStateForFlag(FLAG_A11Y_VISIBLE, a11yVisible);
a11yButton.setLongClickable(a11yLongClickable);
mA11yButton.setLongClickable(a11yLongClickable);
applyState();
}
@@ -38,6 +38,7 @@ import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.Toast;
import androidx.annotation.NonNull;
@@ -52,12 +53,10 @@ import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.taskbar.contextual.RotationButtonController;
import com.android.launcher3.touch.ItemClickHandler;
import com.android.launcher3.util.MultiValueAlpha;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.Themes;
import com.android.launcher3.util.TraceHelper;
import com.android.launcher3.views.ActivityContext;
import com.android.quickstep.AnimatedFloat;
import com.android.quickstep.SysUINavigationMode;
import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.systemui.shared.recents.model.Task;
@@ -77,16 +76,10 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
private static final String WINDOW_TITLE = "Taskbar";
private static final int ALPHA_INDEX_HOME = 0;
private static final int ALPHA_INDEX_LAUNCHER_STATE = 1;
private static final int ALPHA_INDEX_IME = 2;
private final DeviceProfile mDeviceProfile;
private final LayoutInflater mLayoutInflater;
private final TaskbarDragLayer mDragLayer;
private final TaskbarIconController mIconController;
private final TaskbarDragController mDragController;
private final NavbarButtonUIController mNavbarButtonUIController;
private final TaskbarControllers mControllers;
private final WindowManager mWindowManager;
private WindowManager.LayoutParams mWindowLayoutParams;
@@ -95,57 +88,46 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
private int mLastRequestedNonFullscreenHeight;
private final SysUINavigationMode.Mode mNavMode;
private final TaskbarNavButtonController mNavButtonController;
private final RotationButtonController mRotationButtonController;
private final boolean mIsSafeModeEnabled;
@NonNull
private TaskbarUIController mUIController = TaskbarUIController.DEFAULT;
private final View.OnClickListener mOnTaskbarIconClickListener;
private final View.OnLongClickListener mOnTaskbarIconLongClickListener;
// Alpha property for task bar
private final AnimatedFloat mBgTaskbar = new AnimatedFloat(this::updateBackgroundAlpha);
private final AnimatedFloat mBgNavbar = new AnimatedFloat(this::updateBackgroundAlpha);
private final MultiValueAlpha mTaskbarIconAlpha;
public TaskbarActivityContext(Context windowContext, DeviceProfile dp,
TaskbarNavButtonController buttonController) {
super(windowContext, Themes.getActivityThemeRes(windowContext));
mDeviceProfile = dp;
mNavButtonController = buttonController;
mNavMode = SysUINavigationMode.getMode(windowContext);
mIsSafeModeEnabled = TraceHelper.allowIpcs("isSafeMode",
() -> getPackageManager().isSafeMode());
mDragController = new TaskbarDragController(this);
mOnTaskbarIconLongClickListener = mDragController::startDragOnLongClick;
mOnTaskbarIconClickListener = this::onTaskbarIconClicked;
float taskbarIconSize = getResources().getDimension(R.dimen.taskbar_icon_size);
mDeviceProfile.updateIconSize(1, getResources());
float iconScale = taskbarIconSize / mDeviceProfile.iconSizePx;
mDeviceProfile.updateIconSize(iconScale, getResources());
mLayoutInflater = LayoutInflater.from(this).cloneInContext(this);
mDragLayer = (TaskbarDragLayer) mLayoutInflater
.inflate(R.layout.taskbar, null, false);
mRotationButtonController = new RotationButtonController(this,
R.color.popup_color_primary_light, R.color.popup_color_primary_light);
mNavbarButtonUIController = new NavbarButtonUIController(this);
mIconController = new TaskbarIconController(this, mDragLayer, mNavbarButtonUIController);
// Inflate views.
mDragLayer = (TaskbarDragLayer) mLayoutInflater.inflate(
R.layout.taskbar, null, false);
TaskbarView taskbarView = mDragLayer.findViewById(R.id.taskbar_view);
FrameLayout navButtonsView = mDragLayer.findViewById(R.id.navbuttons_view);
// Construct controllers.
mControllers = new TaskbarControllers(this,
new TaskbarDragController(this),
buttonController,
new NavbarButtonsViewController(this, navButtonsView),
new RotationButtonController(this, R.color.popup_color_primary_light,
R.color.popup_color_primary_light),
new TaskbarDragLayerController(this, mDragLayer),
new TaskbarViewController(this, taskbarView));
Display display = windowContext.getDisplay();
Context c = display.getDisplayId() == Display.DEFAULT_DISPLAY
? windowContext.getApplicationContext()
: windowContext.getApplicationContext().createDisplayContext(display);
mWindowManager = c.getSystemService(WindowManager.class);
mTaskbarIconAlpha = new MultiValueAlpha(mDragLayer.findViewById(R.id.taskbar_view), 3);
mTaskbarIconAlpha.setUpdateVisibility(true);
}
public void init() {
@@ -170,13 +152,10 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
new int[] { ITYPE_EXTRA_NAVIGATION_BAR, ITYPE_BOTTOM_TAPPABLE_ELEMENT }
);
mIconController.init(mOnTaskbarIconClickListener, mOnTaskbarIconLongClickListener);
mNavbarButtonUIController.init(mDragLayer, mNavButtonController, mRotationButtonController,
mBgNavbar, mTaskbarIconAlpha.getProperty(ALPHA_INDEX_IME));
// Initialize controllers after all are constructed.
mControllers.init();
mWindowManager.addView(mDragLayer, mWindowLayoutParams);
if (canShowNavButtons()) {
mRotationButtonController.init();
}
}
public boolean canShowNavButtons() {
@@ -200,23 +179,21 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
@Override
public Rect getFolderBoundingBox() {
return mDragLayer.getFolderBoundingBox();
return mControllers.taskbarDragLayerController.getFolderBoundingBox();
}
@Override
public TaskbarDragController getDragController() {
return mDragController;
return mControllers.taskbarDragController;
}
/**
* Sets a new data-source for this taskbar instance
*/
public void setUIController(@NonNull TaskbarUIController uiController) {
mUIController.onDestroy();
mUIController = uiController;
mIconController.setUIController(mUIController);
mUIController.init(mBgTaskbar, mTaskbarIconAlpha.getProperty(ALPHA_INDEX_LAUNCHER_STATE),
mTaskbarIconAlpha.getProperty(ALPHA_INDEX_HOME));
mControllers.uiController.onDestroy();
mControllers.uiController = uiController;
mControllers.uiController.init(mControllers);
}
/**
@@ -224,8 +201,7 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
*/
public void onDestroy() {
setUIController(TaskbarUIController.DEFAULT);
mIconController.onDestroy();
mRotationButtonController.onDestroy();
mControllers.onDestroy();
mWindowManager.removeViewImmediate(mDragLayer);
}
@@ -233,23 +209,25 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
if (!canShowNavButtons()) {
return;
}
mNavbarButtonUIController.updateStateForSysuiFlags(systemUiStateFlags, forceUpdate);
mIconController.setImeIsVisible(mNavbarButtonUIController.isImeVisible());
mControllers.navbarButtonsViewController.updateStateForSysuiFlags(
systemUiStateFlags, forceUpdate);
mControllers.taskbarViewController.setImeIsVisible(
mControllers.navbarButtonsViewController.isImeVisible());
}
public void onRotationProposal(int rotation, boolean isValid) {
mRotationButtonController.onRotationProposal(rotation, isValid);
mControllers.rotationButtonController.onRotationProposal(rotation, isValid);
}
public void disable(int displayId, int state1, int state2, boolean animate) {
if (displayId != getDisplayId()) {
return;
}
mRotationButtonController.onDisable2FlagChanged(state2);
mControllers.rotationButtonController.onDisable2FlagChanged(state2);
}
public void onSystemBarAttributesChanged(int displayId, int behavior) {
mRotationButtonController.onBehaviorChanged(displayId, behavior);
mControllers.rotationButtonController.onBehaviorChanged(displayId, behavior);
}
/**
@@ -296,8 +274,8 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
folder.animateOpen();
folder.iterateOverItems((itemInfo, itemView) -> {
itemView.setOnClickListener(mOnTaskbarIconClickListener);
itemView.setOnLongClickListener(mOnTaskbarIconLongClickListener);
mControllers.taskbarViewController
.setClickAndLongClickListenersForIcon(itemView);
// To play haptic when dragging, like other Taskbar items do.
itemView.setHapticFeedbackEnabled(true);
return false;
@@ -343,9 +321,4 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
AbstractFloatingView.closeAllOpenViews(this);
}
private void updateBackgroundAlpha() {
mDragLayer.setTaskbarBackgroundAlpha(Math.max(mBgNavbar.value, mBgTaskbar.value));
}
}
@@ -0,0 +1,76 @@
/*
* 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 androidx.annotation.NonNull;
import com.android.launcher3.taskbar.contextual.RotationButtonController;
/**
* Hosts various taskbar controllers to facilitate passing between one another.
*/
public class TaskbarControllers {
public final TaskbarActivityContext taskbarActivityContext;
public final TaskbarDragController taskbarDragController;
public final TaskbarNavButtonController navButtonController;
public final NavbarButtonsViewController navbarButtonsViewController;
public final RotationButtonController rotationButtonController;
public final TaskbarDragLayerController taskbarDragLayerController;
public final TaskbarViewController taskbarViewController;
/** Do not store this controller, as it may change at runtime. */
@NonNull public TaskbarUIController uiController = TaskbarUIController.DEFAULT;
public TaskbarControllers(TaskbarActivityContext taskbarActivityContext,
TaskbarDragController taskbarDragController,
TaskbarNavButtonController navButtonController,
NavbarButtonsViewController navbarButtonsViewController,
RotationButtonController rotationButtonController,
TaskbarDragLayerController taskbarDragLayerController,
TaskbarViewController taskbarViewController) {
this.taskbarActivityContext = taskbarActivityContext;
this.taskbarDragController = taskbarDragController;
this.navButtonController = navButtonController;
this.navbarButtonsViewController = navbarButtonsViewController;
this.rotationButtonController = rotationButtonController;
this.taskbarDragLayerController = taskbarDragLayerController;
this.taskbarViewController = taskbarViewController;
}
/**
* Initializes all controllers. Note that controllers can now reference each other through this
* TaskbarControllers instance, but should be careful to only access things that were created
* in constructors for now, as some controllers may still be waiting for init().
*/
public void init() {
navbarButtonsViewController.init(this);
if (taskbarActivityContext.canShowNavButtons()) {
rotationButtonController.init();
}
taskbarDragLayerController.init(this);
taskbarViewController.init(this);
}
/**
* Cleans up all controllers.
*/
public void onDestroy() {
uiController.onDestroy();
rotationButtonController.onDestroy();
taskbarDragLayerController.onDestroy();
}
}
@@ -18,7 +18,6 @@ package com.android.launcher3.taskbar;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
@@ -37,11 +36,9 @@ import com.android.systemui.shared.system.ViewTreeObserverWrapper.OnComputeInset
*/
public class TaskbarDragLayer extends BaseDragLayer<TaskbarActivityContext> {
private final int mFolderMargin;
private final Paint mTaskbarBackgroundPaint;
private TaskbarIconController.TaskbarDragLayerCallbacks mControllerCallbacks;
private TaskbarView mTaskbarView;
private TaskbarDragLayerController.TaskbarDragLayerCallbacks mControllerCallbacks;
private final OnComputeInsetsListener mTaskbarInsetsComputer = this::onComputeTaskbarInsets;
@@ -61,10 +58,13 @@ public class TaskbarDragLayer extends BaseDragLayer<TaskbarActivityContext> {
public TaskbarDragLayer(@NonNull Context context, @Nullable AttributeSet attrs,
int defStyleAttr, int defStyleRes) {
super(context, attrs, 1 /* alphaChannelCount */);
mFolderMargin = getResources().getDimensionPixelSize(R.dimen.taskbar_folder_margin);
mTaskbarBackgroundPaint = new Paint();
mTaskbarBackgroundPaint.setColor(getResources().getColor(R.color.taskbar_background));
mTaskbarBackgroundPaint.setAlpha(0);
}
public void init(TaskbarDragLayerController.TaskbarDragLayerCallbacks callbacks) {
mControllerCallbacks = callbacks;
recreateControllers();
}
@@ -73,15 +73,10 @@ public class TaskbarDragLayer extends BaseDragLayer<TaskbarActivityContext> {
mControllers = new TouchController[] {mActivity.getDragController()};
}
public void init(TaskbarIconController.TaskbarDragLayerCallbacks callbacks,
TaskbarView taskbarView) {
mControllerCallbacks = callbacks;
mTaskbarView = taskbarView;
}
private void onComputeTaskbarInsets(InsetsInfo insetsInfo) {
if (mControllerCallbacks != null) {
mControllerCallbacks.updateInsetsTouchability(insetsInfo);
mControllerCallbacks.updateContentInsets(insetsInfo.contentInsets);
}
}
@@ -120,20 +115,11 @@ public class TaskbarDragLayer extends BaseDragLayer<TaskbarActivityContext> {
@Override
protected void dispatchDraw(Canvas canvas) {
canvas.drawRect(0, canvas.getHeight() - mTaskbarView.getHeight(), canvas.getWidth(),
canvas.getHeight(), mTaskbarBackgroundPaint);
canvas.drawRect(0, canvas.getHeight() - mControllerCallbacks.getTaskbarBackgroundHeight(),
canvas.getWidth(), canvas.getHeight(), mTaskbarBackgroundPaint);
super.dispatchDraw(canvas);
}
/**
* @return Bounds (in our coordinates) where an opened Folder can display.
*/
protected Rect getFolderBoundingBox() {
Rect boundingBox = new Rect(0, 0, getWidth(), getHeight() - mTaskbarView.getHeight());
boundingBox.inset(mFolderMargin, mFolderMargin);
return boundingBox;
}
/**
* Sets the alpha of the background color behind all the Taskbar contents.
* @param alpha 0 is fully transparent, 1 is fully opaque.
@@ -0,0 +1,137 @@
/*
* 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.AbstractFloatingView.TYPE_ALL;
import static com.android.systemui.shared.system.ViewTreeObserverWrapper.InsetsInfo.TOUCHABLE_INSETS_FRAME;
import static com.android.systemui.shared.system.ViewTreeObserverWrapper.InsetsInfo.TOUCHABLE_INSETS_REGION;
import android.content.res.Resources;
import android.graphics.Rect;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.R;
import com.android.launcher3.anim.AlphaUpdateListener;
import com.android.quickstep.AnimatedFloat;
import com.android.systemui.shared.system.ViewTreeObserverWrapper.InsetsInfo;
/**
* Handles properties/data collection, then passes the results to TaskbarDragLayer to render.
*/
public class TaskbarDragLayerController {
private final TaskbarActivityContext mActivity;
private final TaskbarDragLayer mTaskbarDragLayer;
private final int mFolderMargin;
// Alpha properties for taskbar background.
private final AnimatedFloat mBgTaskbar = new AnimatedFloat(this::updateBackgroundAlpha);
private final AnimatedFloat mBgNavbar = new AnimatedFloat(this::updateBackgroundAlpha);
// Initialized in init.
private TaskbarControllers mControllers;
public TaskbarDragLayerController(TaskbarActivityContext activity,
TaskbarDragLayer taskbarDragLayer) {
mActivity = activity;
mTaskbarDragLayer = taskbarDragLayer;
final Resources resources = mTaskbarDragLayer.getResources();
mFolderMargin = resources.getDimensionPixelSize(R.dimen.taskbar_folder_margin);
}
public void init(TaskbarControllers controllers) {
mControllers = controllers;
mTaskbarDragLayer.init(new TaskbarDragLayerCallbacks());
}
public void onDestroy() {
mTaskbarDragLayer.onDestroy();
}
/**
* @return Bounds (in TaskbarDragLayer coordinates) where an opened Folder can display.
*/
public Rect getFolderBoundingBox() {
Rect boundingBox = new Rect(0, 0, mTaskbarDragLayer.getWidth(),
mTaskbarDragLayer.getHeight() - mActivity.getDeviceProfile().taskbarSize);
boundingBox.inset(mFolderMargin, mFolderMargin);
return boundingBox;
}
public AnimatedFloat getTaskbarBackgroundAlpha() {
return mBgTaskbar;
}
public AnimatedFloat getNavbarBackgroundAlpha() {
return mBgNavbar;
}
private void updateBackgroundAlpha() {
mTaskbarDragLayer.setTaskbarBackgroundAlpha(Math.max(mBgNavbar.value, mBgTaskbar.value));
}
/**
* Callbacks for {@link TaskbarDragLayer} to interact with its controller.
*/
public class TaskbarDragLayerCallbacks {
/**
* Called to update the touchable insets.
* @see InsetsInfo#setTouchableInsets(int)
*/
public void updateInsetsTouchability(InsetsInfo insetsInfo) {
insetsInfo.touchableRegion.setEmpty();
if (mTaskbarDragLayer.getAlpha() < AlphaUpdateListener.ALPHA_CUTOFF_THRESHOLD) {
// Let touches pass through us.
insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION);
} else if (mControllers.navbarButtonsViewController.isImeVisible()) {
insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_FRAME);
} else if (!mControllers.uiController.isTaskbarTouchable()) {
// Let touches pass through us.
insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION);
} else if (mControllers.taskbarViewController.areIconsVisible()) {
// Buttons are visible, take over the full taskbar area
insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_FRAME);
} else {
mControllers.navbarButtonsViewController.addVisibleButtonsRegion(
mTaskbarDragLayer, insetsInfo.touchableRegion);
insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION);
}
}
/**
* Called to update the {@link InsetsInfo#contentInsets}.
*/
public void updateContentInsets(Rect outContentInsets) {
mControllers.uiController.updateContentInsets(outContentInsets);
}
/**
* Called when a child is removed from TaskbarDragLayer.
*/
public void onDragLayerViewRemoved() {
if (AbstractFloatingView.getOpenView(mActivity, TYPE_ALL) == null) {
mActivity.setTaskbarWindowFullscreen(false);
}
}
/**
* Returns how tall the background should be drawn at the bottom of the screen.
*/
public int getTaskbarBackgroundHeight() {
return mActivity.getDeviceProfile().taskbarSize;
}
}
}
@@ -1,119 +0,0 @@
/*
* 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.AbstractFloatingView.TYPE_ALL;
import static com.android.systemui.shared.system.ViewTreeObserverWrapper.InsetsInfo.TOUCHABLE_INSETS_FRAME;
import static com.android.systemui.shared.system.ViewTreeObserverWrapper.InsetsInfo.TOUCHABLE_INSETS_REGION;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import androidx.annotation.NonNull;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.R;
import com.android.launcher3.anim.AlphaUpdateListener;
import com.android.systemui.shared.system.ViewTreeObserverWrapper.InsetsInfo;
/**
* Controller for taskbar icon UI
*/
public class TaskbarIconController {
private final TaskbarActivityContext mActivity;
private final TaskbarDragLayer mDragLayer;
private final NavbarButtonUIController mNavbarButtonUIController;
private final TaskbarView mTaskbarView;
@NonNull
private TaskbarUIController mUIController = TaskbarUIController.DEFAULT;
TaskbarIconController(TaskbarActivityContext activity, TaskbarDragLayer dragLayer,
NavbarButtonUIController navbarButtonUIController) {
mActivity = activity;
mDragLayer = dragLayer;
mNavbarButtonUIController = navbarButtonUIController;
mTaskbarView = mDragLayer.findViewById(R.id.taskbar_view);
}
public void init(OnClickListener clickListener, OnLongClickListener longClickListener) {
mTaskbarView.init(clickListener, longClickListener);
mTaskbarView.getLayoutParams().height = mActivity.getDeviceProfile().taskbarSize;
mDragLayer.init(new TaskbarDragLayerCallbacks(), mTaskbarView);
}
public void onDestroy() {
mDragLayer.onDestroy();
}
public void setUIController(@NonNull TaskbarUIController uiController) {
mUIController = uiController;
}
/**
* Should be called when the IME visibility changes, so we can hide/show Taskbar accordingly.
*/
public void setImeIsVisible(boolean isImeVisible) {
mTaskbarView.setTouchesEnabled(!isImeVisible);
}
/**
* Callbacks for {@link TaskbarDragLayer} to interact with the icon controller
*/
public class TaskbarDragLayerCallbacks {
/**
* Called to update the touchable insets
*/
public void updateInsetsTouchability(InsetsInfo insetsInfo) {
insetsInfo.touchableRegion.setEmpty();
if (mDragLayer.getAlpha() < AlphaUpdateListener.ALPHA_CUTOFF_THRESHOLD) {
// Let touches pass through us.
insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION);
} else if (mNavbarButtonUIController.isImeVisible()) {
insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_FRAME);
} else if (!mUIController.isTaskbarTouchable()) {
// Let touches pass through us.
insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION);
} else if (mTaskbarView.areIconsVisible()) {
// Buttons are visible, take over the full taskbar area
insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_FRAME);
} else {
mNavbarButtonUIController.addVisibleButtonsRegion(
mDragLayer, insetsInfo.touchableRegion);
insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION);
}
// TaskbarContainerView provides insets to other apps based on contentInsets. These
// insets should stay consistent even if we expand TaskbarContainerView'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.
insetsInfo.contentInsets.left = mTaskbarView.getLeft();
insetsInfo.contentInsets.top = mTaskbarView.getTop();
insetsInfo.contentInsets.right = mDragLayer.getWidth() - mTaskbarView.getRight();
insetsInfo.contentInsets.bottom = mDragLayer.getHeight() - mTaskbarView.getBottom();
}
public void onDragLayerViewRemoved() {
if (AbstractFloatingView.getOpenView(mActivity, TYPE_ALL) == null) {
mActivity.setTaskbarWindowFullscreen(false);
}
}
}
}
@@ -15,8 +15,7 @@
*/
package com.android.launcher3.taskbar;
import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
import com.android.quickstep.AnimatedFloat;
import android.graphics.Rect;
/**
* Base class for providing different taskbar UI
@@ -25,12 +24,13 @@ public class TaskbarUIController {
public static final TaskbarUIController DEFAULT = new TaskbarUIController();
protected void init(AnimatedFloat taskBarAlpha, AlphaProperty iconAlphaForLauncherState,
AlphaProperty iconAlphaForHome) { }
protected void init(TaskbarControllers taskbarControllers) { }
protected void onDestroy() { }
protected boolean isTaskbarTouchable() {
return true;
}
protected void updateContentInsets(Rect outContentInsets) { }
}
@@ -60,6 +60,7 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar
private final TaskbarActivityContext mActivityContext;
// Initialized in init.
private TaskbarViewController.TaskbarViewCallbacks mControllerCallbacks;
private View.OnClickListener mIconClickListener;
private View.OnLongClickListener mIconLongClickListener;
@@ -98,9 +99,10 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar
mItemPadding = (mIconTouchSize - actualIconSize) / 2;
}
protected void init(OnClickListener clickListener, OnLongClickListener longClickListener) {
mIconClickListener = clickListener;
mIconLongClickListener = longClickListener;
protected void init(TaskbarViewController.TaskbarViewCallbacks callbacks) {
mControllerCallbacks = callbacks;
mIconClickListener = mControllerCallbacks.getOnClickListener();
mIconLongClickListener = mControllerCallbacks.getOnLongClickListener();
int numHotseatIcons = mActivityContext.getDeviceProfile().numShownHotseatIcons;
updateHotseatItems(new ItemInfo[numHotseatIcons]);
@@ -200,11 +202,9 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar
&& hotseatItemInfo instanceof WorkspaceItemInfo) {
((BubbleTextView) hotseatView).applyFromWorkspaceItem(
(WorkspaceItemInfo) hotseatItemInfo);
hotseatView.setOnClickListener(mIconClickListener);
hotseatView.setOnLongClickListener(mIconLongClickListener);
setClickAndLongClickListenersForIcon(hotseatView);
} else if (isFolder) {
hotseatView.setOnClickListener(mIconClickListener);
hotseatView.setOnLongClickListener(mIconLongClickListener);
setClickAndLongClickListenersForIcon(hotseatView);
} else {
hotseatView.setOnClickListener(null);
hotseatView.setOnLongClickListener(null);
@@ -214,6 +214,14 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar
}
}
/**
* Sets OnClickListener and OnLongClickListener for the given view.
*/
public void setClickAndLongClickListenersForIcon(View icon) {
icon.setOnClickListener(mIconClickListener);
icon.setOnLongClickListener(mIconLongClickListener);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
int count = getChildCount();
@@ -0,0 +1,85 @@
/*
* 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 com.android.launcher3.util.MultiValueAlpha;
/**
* Handles properties/data collection, then passes the results to TaskbarView to render.
*/
public class TaskbarViewController {
public static final int ALPHA_INDEX_HOME = 0;
public static final int ALPHA_INDEX_LAUNCHER_STATE = 1;
public static final int ALPHA_INDEX_IME = 2;
private final TaskbarActivityContext mActivity;
private final TaskbarView mTaskbarView;
private final MultiValueAlpha mTaskbarIconAlpha;
// Initialized in init.
private TaskbarControllers mControllers;
public TaskbarViewController(TaskbarActivityContext activity, TaskbarView taskbarView) {
mActivity = activity;
mTaskbarView = taskbarView;
mTaskbarIconAlpha = new MultiValueAlpha(mTaskbarView, 3);
mTaskbarIconAlpha.setUpdateVisibility(true);
}
public void init(TaskbarControllers controllers) {
mControllers = controllers;
mTaskbarView.init(new TaskbarViewCallbacks());
mTaskbarView.getLayoutParams().height = mActivity.getDeviceProfile().taskbarSize;
}
public boolean areIconsVisible() {
return mTaskbarView.areIconsVisible();
}
public MultiValueAlpha getTaskbarIconAlpha() {
return mTaskbarIconAlpha;
}
/**
* Should be called when the IME visibility changes, so we can make Taskbar not steal touches.
*/
public void setImeIsVisible(boolean isImeVisible) {
mTaskbarView.setTouchesEnabled(!isImeVisible);
}
/**
* Sets OnClickListener and OnLongClickListener for the given view.
*/
public void setClickAndLongClickListenersForIcon(View icon) {
mTaskbarView.setClickAndLongClickListenersForIcon(icon);
}
/**
* Callbacks for {@link TaskbarView} to interact with its controller.
*/
public class TaskbarViewCallbacks {
public View.OnClickListener getOnClickListener() {
return mActivity::onTaskbarIconClicked;
}
public View.OnLongClickListener getOnLongClickListener() {
return mControllers.taskbarDragController::startDragOnLongClick;
}
}
}