Snap for 8485725 from 15e9b89a37 to tm-qpr1-release
Change-Id: Ia976d27cb071f51168cc08998575f7ff4343c028
This commit is contained in:
+1
-3
@@ -228,7 +228,7 @@ filegroup {
|
||||
],
|
||||
}
|
||||
|
||||
// Common source files used to build go launcher
|
||||
// Common source files used to build go launcher except go/src files
|
||||
filegroup {
|
||||
name: "launcher-go-src-no-build-config",
|
||||
srcs: [
|
||||
@@ -236,8 +236,6 @@ filegroup {
|
||||
"src/**/*.kt",
|
||||
"quickstep/src/**/*.java",
|
||||
"quickstep/src/**/*.kt",
|
||||
"go/src/**/*.java",
|
||||
"go/src/**/*.kt",
|
||||
"go/quickstep/src/**/*.java",
|
||||
"go/quickstep/src/**/*.kt",
|
||||
],
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.util;
|
||||
|
||||
/**
|
||||
* Defines method to find the next vacant cell on a grid.
|
||||
* This uses the default top-down, left-right approach and can be over-written through
|
||||
* code swaps in different launchers.
|
||||
*/
|
||||
public abstract class AbsGridOccupancy {
|
||||
|
||||
/**
|
||||
* Find the first vacant cell, if there is one.
|
||||
*
|
||||
* @param vacantOut Holds the x and y coordinate of the vacant cell
|
||||
* @param spanX Horizontal cell span.
|
||||
* @param spanY Vertical cell span.
|
||||
*
|
||||
* @return true if a vacant cell was found
|
||||
*/
|
||||
protected boolean findVacantCell(int[] vacantOut, boolean[][] cells, int countX, int countY,
|
||||
int spanX, int spanY) {
|
||||
for (int y = 0; (y + spanY) <= countY; y++) {
|
||||
for (int x = 0; (x + spanX) <= countX; x++) {
|
||||
boolean available = !cells[x][y];
|
||||
out:
|
||||
for (int i = x; i < x + spanX; i++) {
|
||||
for (int j = y; j < y + spanY; j++) {
|
||||
available = available && !cells[i][j];
|
||||
if (!available) break out;
|
||||
}
|
||||
}
|
||||
if (available) {
|
||||
vacantOut[0] = x;
|
||||
vacantOut[1] = y;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1161,7 +1161,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
|
||||
new LauncherAnimationRunner(mHandler, mWallpaperOpenTransitionRunner,
|
||||
false /* startAtFrontOfQueue */), mLauncher.getIApplicationThread());
|
||||
mLauncherOpenTransition.addHomeOpenCheck(mLauncher.getComponentName());
|
||||
SystemUiProxy.INSTANCE.getNoCreate().registerRemoteTransition(mLauncherOpenTransition);
|
||||
SystemUiProxy.INSTANCE.get(mLauncher).registerRemoteTransition(mLauncherOpenTransition);
|
||||
}
|
||||
if (mBackAnimationController != null) {
|
||||
mBackAnimationController.registerBackCallbacks(mHandler);
|
||||
@@ -1172,7 +1172,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
|
||||
unregisterRemoteAnimations();
|
||||
unregisterRemoteTransitions();
|
||||
mStartingWindowListener.setTransitionManager(null);
|
||||
SystemUiProxy.INSTANCE.getNoCreate().setStartingWindowListener(null);
|
||||
SystemUiProxy.INSTANCE.get(mLauncher).setStartingWindowListener(null);
|
||||
}
|
||||
|
||||
private void unregisterRemoteAnimations() {
|
||||
@@ -1196,7 +1196,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
|
||||
}
|
||||
if (hasControlRemoteAppTransitionPermission()) {
|
||||
if (mLauncherOpenTransition == null) return;
|
||||
SystemUiProxy.INSTANCE.getNoCreate().unregisterRemoteTransition(
|
||||
SystemUiProxy.INSTANCE.get(mLauncher).unregisterRemoteTransition(
|
||||
mLauncherOpenTransition);
|
||||
mLauncherOpenTransition = null;
|
||||
mWallpaperOpenTransitionRunner = null;
|
||||
|
||||
@@ -210,7 +210,7 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT
|
||||
0, 1));
|
||||
// Center nav buttons in new height for IME.
|
||||
float transForIme = (mContext.getDeviceProfile().taskbarSize
|
||||
- mContext.getTaskbarHeightForIme()) / 2f;
|
||||
- mControllers.taskbarInsetsController.getTaskbarHeightForIme()) / 2f;
|
||||
// For gesture nav, nav buttons only show for IME anyway so keep them translated down.
|
||||
float defaultButtonTransY = alwaysShowButtons ? 0 : transForIme;
|
||||
mPropertyHolders.add(new StatePropertyHolder(mTaskbarNavButtonTranslationYForIme,
|
||||
|
||||
@@ -27,9 +27,6 @@ import static com.android.launcher3.ResourceUtils.getBoolByName;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_OPEN;
|
||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED;
|
||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
|
||||
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 static com.android.systemui.shared.system.WindowManagerWrapper.ITYPE_SIZE;
|
||||
|
||||
import android.animation.AnimatorSet;
|
||||
import android.app.ActivityOptions;
|
||||
@@ -39,7 +36,6 @@ import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo.Config;
|
||||
import android.content.pm.LauncherApps;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Insets;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Process;
|
||||
@@ -88,7 +84,6 @@ import com.android.launcher3.views.ActivityContext;
|
||||
import com.android.systemui.shared.recents.model.Task;
|
||||
import com.android.systemui.shared.rotation.RotationButtonController;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
import com.android.systemui.shared.system.WindowManagerWrapper;
|
||||
import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
@@ -113,7 +108,6 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
|
||||
|
||||
private final WindowManager mWindowManager;
|
||||
private final @Nullable RoundedCorner mLeftCorner, mRightCorner;
|
||||
private final int mTaskbarHeightForIme;
|
||||
private WindowManager.LayoutParams mWindowLayoutParams;
|
||||
private boolean mIsFullscreen;
|
||||
// The size we should return to when we call setTaskbarWindowFullscreen(false)
|
||||
@@ -154,7 +148,6 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
|
||||
Settings.Secure.getUriFor(Settings.Secure.NAV_BAR_KIDS_MODE), 0);
|
||||
|
||||
updateIconSize(resources);
|
||||
mTaskbarHeightForIme = resources.getDimensionPixelSize(R.dimen.taskbar_ime_size);
|
||||
|
||||
// Get display and corners first, as views might use them in constructor.
|
||||
Display display = windowContext.getDisplay();
|
||||
@@ -202,29 +195,14 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
|
||||
new TaskbarAutohideSuspendController(this),
|
||||
new TaskbarPopupController(this),
|
||||
new TaskbarForceVisibleImmersiveController(this),
|
||||
new TaskbarAllAppsController(this));
|
||||
new TaskbarAllAppsController(this),
|
||||
new TaskbarInsetsController(this));
|
||||
}
|
||||
|
||||
public void init(TaskbarSharedState sharedState) {
|
||||
mLastRequestedNonFullscreenHeight = getDefaultTaskbarWindowHeight();
|
||||
mWindowLayoutParams = createDefaultWindowLayoutParams();
|
||||
|
||||
WindowManagerWrapper wmWrapper = WindowManagerWrapper.getInstance();
|
||||
wmWrapper.setProvidesInsetsTypes(
|
||||
mWindowLayoutParams,
|
||||
new int[] { ITYPE_EXTRA_NAVIGATION_BAR, ITYPE_BOTTOM_TAPPABLE_ELEMENT }
|
||||
);
|
||||
// Adjust the frame by the rounded corners (ie. leaving just the bar as the inset) when
|
||||
// the IME is showing
|
||||
mWindowLayoutParams.providedInternalImeInsets = new Insets[ITYPE_SIZE];
|
||||
final Insets reducingSize = Insets.of(0,
|
||||
getDefaultTaskbarWindowHeight() - mTaskbarHeightForIme, 0, 0);
|
||||
mWindowLayoutParams.providedInternalImeInsets[ITYPE_EXTRA_NAVIGATION_BAR] = reducingSize;
|
||||
mWindowLayoutParams.providedInternalImeInsets[ITYPE_BOTTOM_TAPPABLE_ELEMENT] =
|
||||
reducingSize;
|
||||
|
||||
mWindowLayoutParams.insetsRoundedCornerFrame = true;
|
||||
|
||||
// Initialize controllers after all are constructed.
|
||||
mControllers.init(sharedState);
|
||||
updateSysuiStateFlags(sharedState.sysuiStateFlags, true /* fromInit */);
|
||||
@@ -304,6 +282,10 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
|
||||
return mRightCorner == null ? 0 : mRightCorner.getRadius();
|
||||
}
|
||||
|
||||
public WindowManager.LayoutParams getWindowLayoutParams() {
|
||||
return mWindowLayoutParams;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskbarDragLayer getDragLayer() {
|
||||
return mDragLayer;
|
||||
@@ -577,14 +559,7 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
|
||||
}
|
||||
}
|
||||
mWindowLayoutParams.height = height;
|
||||
final Insets reducingSize =
|
||||
Insets.of(0, height - mTaskbarHeightForIme, 0, 0);
|
||||
if (mWindowLayoutParams.providedInternalImeInsets == null) {
|
||||
mWindowLayoutParams.providedInternalImeInsets = new Insets[ITYPE_SIZE];
|
||||
}
|
||||
mWindowLayoutParams.providedInternalImeInsets[ITYPE_EXTRA_NAVIGATION_BAR] = reducingSize;
|
||||
mWindowLayoutParams.providedInternalImeInsets[ITYPE_BOTTOM_TAPPABLE_ELEMENT] =
|
||||
reducingSize;
|
||||
mControllers.taskbarInsetsController.onTaskbarWindowHeightChanged();
|
||||
mWindowManager.updateViewLayout(mDragLayer, mWindowLayoutParams);
|
||||
}
|
||||
|
||||
@@ -595,13 +570,6 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
|
||||
return mDeviceProfile.taskbarSize + Math.max(getLeftCornerRadius(), getRightCornerRadius());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bottom insets taskbar provides to the IME when IME is visible.
|
||||
*/
|
||||
public int getTaskbarHeightForIme() {
|
||||
return mTaskbarHeightForIme;
|
||||
}
|
||||
|
||||
/**
|
||||
* Either adds or removes {@link WindowManager.LayoutParams#FLAG_NOT_FOCUSABLE} on the taskbar
|
||||
* window.
|
||||
|
||||
@@ -51,6 +51,7 @@ public class TaskbarControllers {
|
||||
public final TaskbarPopupController taskbarPopupController;
|
||||
public final TaskbarForceVisibleImmersiveController taskbarForceVisibleImmersiveController;
|
||||
public final TaskbarAllAppsController taskbarAllAppsController;
|
||||
public final TaskbarInsetsController taskbarInsetsController;
|
||||
|
||||
@Nullable private LoggableTaskbarController[] mControllersToLog = null;
|
||||
|
||||
@@ -76,7 +77,8 @@ public class TaskbarControllers {
|
||||
TaskbarAutohideSuspendController taskbarAutoHideSuspendController,
|
||||
TaskbarPopupController taskbarPopupController,
|
||||
TaskbarForceVisibleImmersiveController taskbarForceVisibleImmersiveController,
|
||||
TaskbarAllAppsController taskbarAllAppsController) {
|
||||
TaskbarAllAppsController taskbarAllAppsController,
|
||||
TaskbarInsetsController taskbarInsetsController) {
|
||||
this.taskbarActivityContext = taskbarActivityContext;
|
||||
this.taskbarDragController = taskbarDragController;
|
||||
this.navButtonController = navButtonController;
|
||||
@@ -94,6 +96,7 @@ public class TaskbarControllers {
|
||||
this.taskbarPopupController = taskbarPopupController;
|
||||
this.taskbarForceVisibleImmersiveController = taskbarForceVisibleImmersiveController;
|
||||
this.taskbarAllAppsController = taskbarAllAppsController;
|
||||
this.taskbarInsetsController = taskbarInsetsController;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -119,13 +122,14 @@ public class TaskbarControllers {
|
||||
taskbarForceVisibleImmersiveController.init(this);
|
||||
taskbarAllAppsController.init(this, sharedState);
|
||||
navButtonController.init(this);
|
||||
taskbarInsetsController.init(this);
|
||||
|
||||
mControllersToLog = new LoggableTaskbarController[] {
|
||||
taskbarDragController, navButtonController, navbarButtonsViewController,
|
||||
taskbarDragLayerController, taskbarScrimViewController, taskbarViewController,
|
||||
taskbarUnfoldAnimationController, taskbarKeyguardController,
|
||||
stashedHandleViewController, taskbarStashController, taskbarEduController,
|
||||
taskbarAutohideSuspendController, taskbarPopupController
|
||||
taskbarAutohideSuspendController, taskbarPopupController, taskbarInsetsController
|
||||
};
|
||||
|
||||
mAreAllControllersInitialized = true;
|
||||
|
||||
@@ -15,18 +15,10 @@
|
||||
*/
|
||||
package com.android.launcher3.taskbar;
|
||||
|
||||
import static com.android.launcher3.AbstractFloatingView.TYPE_ALL;
|
||||
import static com.android.launcher3.AbstractFloatingView.TYPE_TASKBAR_ALL_APPS;
|
||||
import static com.android.systemui.shared.system.ViewTreeObserverWrapper.InsetsInfo.TOUCHABLE_INSETS_CONTENT;
|
||||
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.launcher3.util.TouchController;
|
||||
import com.android.quickstep.AnimatedFloat;
|
||||
import com.android.systemui.shared.system.ViewTreeObserverWrapper.InsetsInfo;
|
||||
@@ -168,37 +160,7 @@ public class TaskbarDragLayerController implements TaskbarControllers.LoggableTa
|
||||
* @see InsetsInfo#setTouchableInsets(int)
|
||||
*/
|
||||
public void updateInsetsTouchability(InsetsInfo insetsInfo) {
|
||||
insetsInfo.touchableRegion.setEmpty();
|
||||
// Always have nav buttons be touchable
|
||||
mControllers.navbarButtonsViewController.addVisibleButtonsRegion(
|
||||
mTaskbarDragLayer, insetsInfo.touchableRegion);
|
||||
boolean insetsIsTouchableRegion = true;
|
||||
|
||||
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_REGION);
|
||||
} else if (!mControllers.uiController.isTaskbarTouchable()) {
|
||||
// Let touches pass through us.
|
||||
insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION);
|
||||
} else if (mControllers.taskbarDragController.isSystemDragInProgress()) {
|
||||
// Let touches pass through us.
|
||||
insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION);
|
||||
} else if (AbstractFloatingView.getOpenView(mActivity, TYPE_TASKBAR_ALL_APPS) != null) {
|
||||
// Let touches pass through us.
|
||||
insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION);
|
||||
} else if (mControllers.taskbarViewController.areIconsVisible()
|
||||
|| AbstractFloatingView.getOpenView(mActivity, TYPE_ALL) != null
|
||||
|| mActivity.isNavBarKidsModeActive()) {
|
||||
// Taskbar has some touchable elements, take over the full taskbar area
|
||||
insetsInfo.setTouchableInsets(mActivity.isTaskbarWindowFullscreen()
|
||||
? TOUCHABLE_INSETS_FRAME : TOUCHABLE_INSETS_CONTENT);
|
||||
insetsIsTouchableRegion = false;
|
||||
} else {
|
||||
insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION);
|
||||
}
|
||||
mActivity.excludeFromMagnificationRegion(insetsIsTouchableRegion);
|
||||
mControllers.taskbarInsetsController.updateInsetsTouchability(insetsInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.graphics.Insets
|
||||
import android.view.WindowManager
|
||||
import com.android.launcher3.AbstractFloatingView
|
||||
import com.android.launcher3.R
|
||||
import com.android.launcher3.anim.AlphaUpdateListener
|
||||
import com.android.launcher3.taskbar.TaskbarControllers.LoggableTaskbarController
|
||||
import com.android.quickstep.KtR
|
||||
import com.android.systemui.shared.system.ViewTreeObserverWrapper.InsetsInfo
|
||||
import com.android.systemui.shared.system.WindowManagerWrapper
|
||||
import com.android.systemui.shared.system.WindowManagerWrapper.*
|
||||
import java.io.PrintWriter
|
||||
|
||||
/**
|
||||
* Handles the insets that Taskbar provides to underlying apps and the IME.
|
||||
*/
|
||||
class TaskbarInsetsController(val context: TaskbarActivityContext): LoggableTaskbarController {
|
||||
|
||||
/** The bottom insets taskbar provides to the IME when IME is visible. */
|
||||
val taskbarHeightForIme: Int = context.resources.getDimensionPixelSize(
|
||||
KtR.dimen.taskbar_ime_size)
|
||||
|
||||
// Initialized in init.
|
||||
private lateinit var controllers: TaskbarControllers
|
||||
private lateinit var windowLayoutParams: WindowManager.LayoutParams
|
||||
|
||||
fun init(controllers: TaskbarControllers) {
|
||||
this.controllers = controllers
|
||||
windowLayoutParams = context.windowLayoutParams
|
||||
|
||||
val wmWrapper: WindowManagerWrapper = getInstance()
|
||||
wmWrapper.setProvidesInsetsTypes(
|
||||
windowLayoutParams,
|
||||
intArrayOf(
|
||||
ITYPE_EXTRA_NAVIGATION_BAR,
|
||||
ITYPE_BOTTOM_TAPPABLE_ELEMENT
|
||||
)
|
||||
)
|
||||
|
||||
windowLayoutParams.providedInternalImeInsets = arrayOfNulls<Insets>(ITYPE_SIZE)
|
||||
|
||||
onTaskbarWindowHeightChanged()
|
||||
|
||||
windowLayoutParams.insetsRoundedCornerFrame = true
|
||||
}
|
||||
|
||||
fun onTaskbarWindowHeightChanged() {
|
||||
val reducingSize = Insets.of(0, windowLayoutParams.height - taskbarHeightForIme, 0, 0)
|
||||
windowLayoutParams.providedInternalImeInsets[ITYPE_EXTRA_NAVIGATION_BAR] = reducingSize
|
||||
windowLayoutParams.providedInternalImeInsets[ITYPE_BOTTOM_TAPPABLE_ELEMENT] = reducingSize
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to update the touchable insets.
|
||||
* @see InsetsInfo.setTouchableInsets
|
||||
*/
|
||||
fun updateInsetsTouchability(insetsInfo: InsetsInfo) {
|
||||
insetsInfo.touchableRegion.setEmpty()
|
||||
// Always have nav buttons be touchable
|
||||
controllers.navbarButtonsViewController.addVisibleButtonsRegion(
|
||||
context.dragLayer, insetsInfo.touchableRegion
|
||||
)
|
||||
var insetsIsTouchableRegion = true
|
||||
if (context.dragLayer.alpha < AlphaUpdateListener.ALPHA_CUTOFF_THRESHOLD) {
|
||||
// Let touches pass through us.
|
||||
insetsInfo.setTouchableInsets(InsetsInfo.TOUCHABLE_INSETS_REGION)
|
||||
} else if (controllers.navbarButtonsViewController.isImeVisible) {
|
||||
insetsInfo.setTouchableInsets(InsetsInfo.TOUCHABLE_INSETS_REGION)
|
||||
} else if (!controllers.uiController.isTaskbarTouchable) {
|
||||
// Let touches pass through us.
|
||||
insetsInfo.setTouchableInsets(InsetsInfo.TOUCHABLE_INSETS_REGION)
|
||||
} else if (controllers.taskbarDragController.isSystemDragInProgress) {
|
||||
// Let touches pass through us.
|
||||
insetsInfo.setTouchableInsets(InsetsInfo.TOUCHABLE_INSETS_REGION)
|
||||
} else if (AbstractFloatingView.getOpenView<AbstractFloatingView?>(
|
||||
context,
|
||||
AbstractFloatingView.TYPE_TASKBAR_ALL_APPS
|
||||
) != null
|
||||
) {
|
||||
// Let touches pass through us.
|
||||
insetsInfo.setTouchableInsets(InsetsInfo.TOUCHABLE_INSETS_REGION)
|
||||
} else if (controllers.taskbarViewController.areIconsVisible()
|
||||
|| AbstractFloatingView.getOpenView<AbstractFloatingView?>(
|
||||
context,
|
||||
AbstractFloatingView.TYPE_ALL
|
||||
) != null
|
||||
|| context.isNavBarKidsModeActive
|
||||
) {
|
||||
// Taskbar has some touchable elements, take over the full taskbar area
|
||||
insetsInfo.setTouchableInsets(
|
||||
if (context.isTaskbarWindowFullscreen) {
|
||||
InsetsInfo.TOUCHABLE_INSETS_FRAME
|
||||
} else {
|
||||
InsetsInfo.TOUCHABLE_INSETS_CONTENT
|
||||
}
|
||||
)
|
||||
insetsIsTouchableRegion = false
|
||||
} else {
|
||||
insetsInfo.setTouchableInsets(InsetsInfo.TOUCHABLE_INSETS_REGION)
|
||||
}
|
||||
context.excludeFromMagnificationRegion(insetsIsTouchableRegion)
|
||||
}
|
||||
|
||||
override fun dumpLogs(prefix: String, pw: PrintWriter) {
|
||||
pw.println(prefix + "TaskbarInsetsController:")
|
||||
pw.println("$prefix\twindowHeight=${windowLayoutParams.height}")
|
||||
pw.println("$prefix\tprovidedInternalImeInsets[ITYPE_EXTRA_NAVIGATION_BAR]=" +
|
||||
"${windowLayoutParams.providedInternalImeInsets[ITYPE_EXTRA_NAVIGATION_BAR]}")
|
||||
pw.println("$prefix\tprovidedInternalImeInsets[ITYPE_BOTTOM_TAPPABLE_ELEMENT]=" +
|
||||
"${windowLayoutParams.providedInternalImeInsets[ITYPE_BOTTOM_TAPPABLE_ELEMENT]}")
|
||||
}
|
||||
}
|
||||
@@ -312,8 +312,8 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar
|
||||
if (!mTouchEnabled) {
|
||||
return true;
|
||||
}
|
||||
if (mIconLayoutBounds.contains((int) event.getX(), (int) event.getY())) {
|
||||
// Don't allow long pressing between icons.
|
||||
if (mIconLayoutBounds.left <= event.getX() && event.getX() <= mIconLayoutBounds.right) {
|
||||
// Don't allow long pressing between icons, or above/below them.
|
||||
return true;
|
||||
}
|
||||
if (mControllerCallbacks.onTouchEvent(event)) {
|
||||
|
||||
@@ -770,7 +770,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
// We will handle the sysui flags based on the centermost task view.
|
||||
mRecentsAnimationController.setUseLauncherSystemBarFlags(swipeUpThresholdPassed
|
||||
|| (quickswitchThresholdPassed && centermostTaskFlags != 0));
|
||||
mRecentsAnimationController.setSplitScreenMinimized(swipeUpThresholdPassed);
|
||||
mRecentsAnimationController.setSplitScreenMinimized(mContext, swipeUpThresholdPassed);
|
||||
// Provide a hint to WM the direction that we will be settling in case the animation
|
||||
// needs to be canceled
|
||||
mRecentsAnimationController.setWillFinishToHome(swipeUpThresholdPassed);
|
||||
|
||||
@@ -31,6 +31,7 @@ public class KtR {
|
||||
public static final class dimen {
|
||||
public static int task_menu_spacing = R.dimen.task_menu_spacing;
|
||||
public static int task_menu_horizontal_padding = R.dimen.task_menu_horizontal_padding;
|
||||
public static int taskbar_ime_size = R.dimen.taskbar_ime_size;
|
||||
}
|
||||
|
||||
public static final class layout {
|
||||
|
||||
@@ -29,7 +29,6 @@ import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.os.Handler;
|
||||
import android.util.Log;
|
||||
import android.util.MathUtils;
|
||||
import android.util.Pair;
|
||||
import android.view.RemoteAnimationTarget;
|
||||
@@ -55,7 +54,7 @@ import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
|
||||
* the app window and plays the rest of app close transitions in one go.
|
||||
*
|
||||
* This animation is used only for apps that enable back dispatching via
|
||||
* {@link android.view.OnBackInvokedDispatcher}. The controller registers
|
||||
* {@link android.window.OnBackInvokedDispatcher}. The controller registers
|
||||
* an {@link IOnBackInvokedCallback} with WM Shell and receives back dispatches when a back
|
||||
* navigation to launcher starts.
|
||||
*
|
||||
@@ -66,7 +65,6 @@ import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
|
||||
public class LauncherBackAnimationController {
|
||||
private static final int CANCEL_TRANSITION_DURATION = 233;
|
||||
private static final float MIN_WINDOW_SCALE = 0.7f;
|
||||
private static final String TAG = "LauncherBackAnimationController";
|
||||
private final QuickstepTransitionManager mQuickstepTransitionManager;
|
||||
private final Matrix mTransformMatrix = new Matrix();
|
||||
/** The window position at the beginning of the back animation. */
|
||||
@@ -115,12 +113,7 @@ public class LauncherBackAnimationController {
|
||||
* @param handler Handler to the thread to run the animations on.
|
||||
*/
|
||||
public void registerBackCallbacks(Handler handler) {
|
||||
SystemUiProxy systemUiProxy = SystemUiProxy.INSTANCE.getNoCreate();
|
||||
if (systemUiProxy == null) {
|
||||
Log.e(TAG, "SystemUiProxy is null. Skip registering back invocation callbacks");
|
||||
return;
|
||||
}
|
||||
systemUiProxy.setBackToLauncherCallback(
|
||||
SystemUiProxy.INSTANCE.get(mLauncher).setBackToLauncherCallback(
|
||||
new IOnBackInvokedCallback.Stub() {
|
||||
@Override
|
||||
public void onBackCancelled() {
|
||||
@@ -170,10 +163,7 @@ public class LauncherBackAnimationController {
|
||||
|
||||
/** Unregisters the back to launcher callback in shell. */
|
||||
public void unregisterBackCallbacks() {
|
||||
SystemUiProxy systemUiProxy = SystemUiProxy.INSTANCE.getNoCreate();
|
||||
if (systemUiProxy != null) {
|
||||
systemUiProxy.clearBackToLauncherCallback();
|
||||
}
|
||||
SystemUiProxy.INSTANCE.get(mLauncher).clearBackToLauncherCallback();
|
||||
}
|
||||
|
||||
private void startBack(BackEvent backEvent) {
|
||||
@@ -298,10 +288,7 @@ public class LauncherBackAnimationController {
|
||||
mInitialTouchPos.set(0, 0);
|
||||
mAnimatorSetInProgress = false;
|
||||
mSpringAnimationInProgress = false;
|
||||
SystemUiProxy systemUiProxy = SystemUiProxy.INSTANCE.getNoCreate();
|
||||
if (systemUiProxy != null) {
|
||||
SystemUiProxy.INSTANCE.getNoCreate().onBackToLauncherAnimationFinished();
|
||||
}
|
||||
SystemUiProxy.INSTANCE.get(mLauncher).onBackToLauncherAnimationFinished();
|
||||
}
|
||||
|
||||
private void startTransitionAnimations(RectFSpringAnim springAnim, AnimatorSet anim) {
|
||||
|
||||
@@ -19,6 +19,7 @@ import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
||||
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
|
||||
import static com.android.quickstep.TaskAnimationManager.ENABLE_SHELL_TRANSITIONS;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
import android.view.IRecentsAnimationController;
|
||||
@@ -97,24 +98,20 @@ public class RecentsAnimationController {
|
||||
* Indicates that the gesture has crossed the window boundary threshold and we should minimize
|
||||
* if we are in splitscreen.
|
||||
*/
|
||||
public void setSplitScreenMinimized(boolean splitScreenMinimized) {
|
||||
public void setSplitScreenMinimized(Context context, boolean splitScreenMinimized) {
|
||||
if (!mAllowMinimizeSplitScreen) {
|
||||
return;
|
||||
}
|
||||
if (mSplitScreenMinimized != splitScreenMinimized) {
|
||||
mSplitScreenMinimized = splitScreenMinimized;
|
||||
UI_HELPER_EXECUTOR.execute(() -> {
|
||||
SystemUiProxy p = SystemUiProxy.INSTANCE.getNoCreate();
|
||||
if (p != null) {
|
||||
p.setSplitScreenMinimized(splitScreenMinimized);
|
||||
}
|
||||
});
|
||||
UI_HELPER_EXECUTOR.execute(() -> SystemUiProxy.INSTANCE.get(context)
|
||||
.setSplitScreenMinimized(splitScreenMinimized));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove task remote animation target from
|
||||
* {@link RecentsAnimationCallbacks#onTaskAppeared(RemoteAnimationTargetCompat)}}.
|
||||
* {@link RecentsAnimationCallbacks#onTasksAppeared}}.
|
||||
*/
|
||||
@UiThread
|
||||
public void removeTaskTarget(@NonNull RemoteAnimationTargetCompat target) {
|
||||
|
||||
@@ -177,9 +177,8 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
|
||||
((RecentsActivity) activityInterface.getCreatedActivity()).startHome();
|
||||
return;
|
||||
}
|
||||
RemoteAnimationTarget[] nonAppTargets =
|
||||
SystemUiProxy.INSTANCE.getNoCreate()
|
||||
.onGoingToRecentsLegacy(false, nonHomeApps);
|
||||
RemoteAnimationTarget[] nonAppTargets = SystemUiProxy.INSTANCE.get(mCtx)
|
||||
.onGoingToRecentsLegacy(false, nonHomeApps);
|
||||
|
||||
if (ENABLE_QUICKSTEP_LIVE_TILE.get() && activityInterface.isInLiveTileMode()
|
||||
&& activityInterface.getCreatedActivity() != null) {
|
||||
|
||||
@@ -26,6 +26,7 @@ import com.android.quickstep.util.CancellableTask;
|
||||
import com.android.quickstep.util.RecentsOrientedState;
|
||||
import com.android.systemui.shared.recents.model.Task;
|
||||
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||
import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.function.Consumer;
|
||||
@@ -171,8 +172,14 @@ public class GroupedTaskView extends TaskView {
|
||||
RunnableList endCallback = new RunnableList();
|
||||
RecentsView recentsView = getRecentsView();
|
||||
// Callbacks run from remote animation when recents animation not currently running
|
||||
InteractionJankMonitorWrapper.begin(this,
|
||||
InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER, "Enter form GroupedTaskView");
|
||||
recentsView.getSplitPlaceholder().launchTasks(this /*groupedTaskView*/,
|
||||
success -> endCallback.executeAllAndDestroy(),
|
||||
success -> {
|
||||
endCallback.executeAllAndDestroy();
|
||||
InteractionJankMonitorWrapper.end(
|
||||
InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER);
|
||||
},
|
||||
false /* freezeTaskList */);
|
||||
|
||||
// Callbacks get run from recentsView for case when recents animation already running
|
||||
|
||||
@@ -175,6 +175,7 @@ import com.android.systemui.plugins.ResourceProvider;
|
||||
import com.android.systemui.shared.recents.model.Task;
|
||||
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
|
||||
import com.android.systemui.shared.system.PackageManagerWrapper;
|
||||
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;
|
||||
@@ -2744,9 +2745,16 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
mFirstFloatingTaskView.addAnimation(anim, startingTaskRect,
|
||||
mTempRect, true /* fadeWithThumbnail */, true /* isStagedTask */);
|
||||
}
|
||||
InteractionJankMonitorWrapper.begin(this,
|
||||
InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER, "First tile selected");
|
||||
anim.addEndListener(success -> {
|
||||
if (success) {
|
||||
mSplitToast.show();
|
||||
InteractionJankMonitorWrapper.end(
|
||||
InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER);
|
||||
} else {
|
||||
InteractionJankMonitorWrapper.cancel(
|
||||
InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -4040,9 +4048,11 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
mSecondFloatingTaskView.setAlpha(1);
|
||||
mSecondFloatingTaskView.addAnimation(pendingAnimation, secondTaskStartingBounds,
|
||||
secondTaskEndingBounds, true /* fadeWithThumbnail */, false /* isStagedTask */);
|
||||
pendingAnimation.addEndListener(aBoolean ->
|
||||
mSplitSelectStateController.launchSplitTasks(
|
||||
aBoolean1 -> RecentsView.this.resetFromSplitSelectionState()));
|
||||
pendingAnimation.addEndListener(aBoolean -> {
|
||||
mSplitSelectStateController.launchSplitTasks(
|
||||
aBoolean1 -> RecentsView.this.resetFromSplitSelectionState());
|
||||
InteractionJankMonitorWrapper.end(InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER);
|
||||
});
|
||||
if (containerTaskView.containsMultipleTasks()) {
|
||||
// If we are launching from a child task, then only hide the thumbnail itself
|
||||
mSecondSplitHiddenView = thumbnailView;
|
||||
@@ -4050,6 +4060,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
mSecondSplitHiddenView = containerTaskView;
|
||||
}
|
||||
mSecondSplitHiddenView.setVisibility(INVISIBLE);
|
||||
InteractionJankMonitorWrapper.begin(this,
|
||||
InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER, "Second tile selected");
|
||||
pendingAnimation.buildAnim().start();
|
||||
return true;
|
||||
}
|
||||
@@ -4486,10 +4498,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
// Reset the minimized state since we force-toggled the minimized state when entering
|
||||
// overview, but never actually finished the recents animation. This is a catch all for
|
||||
// cases where we haven't already reset it.
|
||||
SystemUiProxy p = SystemUiProxy.INSTANCE.getNoCreate();
|
||||
if (p != null) {
|
||||
p.setSplitScreenMinimized(false);
|
||||
}
|
||||
SystemUiProxy.INSTANCE.get(getContext()).setSplitScreenMinimized(false);
|
||||
}
|
||||
|
||||
if (mRecentsAnimationController == null) {
|
||||
|
||||
@@ -20,7 +20,6 @@ import static android.view.Display.DEFAULT_DISPLAY;
|
||||
import static android.widget.Toast.LENGTH_SHORT;
|
||||
|
||||
import static com.android.launcher3.AbstractFloatingView.TYPE_TASK_MENU;
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW_SPLIT_SELECT;
|
||||
import static com.android.launcher3.Utilities.comp;
|
||||
import static com.android.launcher3.Utilities.getDescendantCoordRelativeToAncestor;
|
||||
import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
|
||||
@@ -628,10 +627,7 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
|
||||
// Reset the minimized state since we force-toggled the minimized state when entering
|
||||
// overview, but never actually finished the recents animation
|
||||
SystemUiProxy p = SystemUiProxy.INSTANCE.getNoCreate();
|
||||
if (p != null) {
|
||||
p.setSplitScreenMinimized(false);
|
||||
}
|
||||
SystemUiProxy.INSTANCE.get(getContext()).setSplitScreenMinimized(false);
|
||||
|
||||
mIsClickableAsLiveTile = false;
|
||||
RemoteAnimationTargets targets;
|
||||
|
||||
@@ -145,6 +145,8 @@
|
||||
launcher:numFolderColumns="3"
|
||||
launcher:numHotseatIcons="6"
|
||||
launcher:numAllAppsColumns="6"
|
||||
launcher:isScalable="true"
|
||||
launcher:devicePaddingId="@xml/paddings_6x5"
|
||||
launcher:dbFile="launcher_6_by_5.db"
|
||||
launcher:defaultLayoutId="@xml/default_workspace_6x5"
|
||||
launcher:deviceCategory="tablet" >
|
||||
@@ -153,14 +155,29 @@
|
||||
launcher:name="Tablet"
|
||||
launcher:minWidthDps="900"
|
||||
launcher:minHeightDps="820"
|
||||
launcher:minCellHeight="104"
|
||||
launcher:minCellWidth="80"
|
||||
launcher:minCellHeight="120"
|
||||
launcher:minCellWidth="102"
|
||||
launcher:minCellHeightLandscape="104"
|
||||
launcher:minCellWidthLandscape="120"
|
||||
launcher:iconImageSize="60"
|
||||
launcher:iconTextSize="14"
|
||||
launcher:borderSpace="16"
|
||||
launcher:borderSpaceHorizontal="16"
|
||||
launcher:borderSpaceVertical="64"
|
||||
launcher:borderSpaceLandscapeHorizontal="64"
|
||||
launcher:borderSpaceLandscapeVertical="16"
|
||||
launcher:horizontalMargin="54"
|
||||
launcher:horizontalMarginLandscape="120"
|
||||
launcher:allAppsCellWidth="96"
|
||||
launcher:allAppsCellHeight="142"
|
||||
launcher:allAppsCellWidthLandscape="126"
|
||||
launcher:allAppsCellHeightLandscape="126"
|
||||
launcher:allAppsIconSize="60"
|
||||
launcher:allAppsIconTextSize="14"
|
||||
launcher:allAppsBorderSpace="16"
|
||||
launcher:allAppsBorderSpaceHorizontal="8"
|
||||
launcher:allAppsBorderSpaceVertical="16"
|
||||
launcher:allAppsBorderSpaceLandscape="16"
|
||||
launcher:hotseatBorderSpace="58"
|
||||
launcher:hotseatBorderSpaceLandscape="50.4"
|
||||
launcher:canBeDefault="true" />
|
||||
|
||||
</grid-option>
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2022 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.
|
||||
-->
|
||||
|
||||
<device-paddings xmlns:launcher="http://schemas.android.com/apk/res-auto" >
|
||||
|
||||
<!-- Some non default screen sizes -->
|
||||
<device-padding
|
||||
launcher:maxEmptySpace="30dp">
|
||||
<workspaceTopPadding
|
||||
launcher:a="0.34"
|
||||
launcher:b="0"/>
|
||||
<workspaceBottomPadding
|
||||
launcher:a="0.26"
|
||||
launcher:b="0"/>
|
||||
<hotseatBottomPadding
|
||||
launcher:a="0.4"
|
||||
launcher:b="0"/>
|
||||
</device-padding>
|
||||
|
||||
<device-padding
|
||||
launcher:maxEmptySpace="80dp">
|
||||
<workspaceTopPadding
|
||||
launcher:a="0"
|
||||
launcher:b="20dp"/>
|
||||
<workspaceBottomPadding
|
||||
launcher:a="0.4"
|
||||
launcher:b="0"
|
||||
launcher:c="20dp"/>
|
||||
<hotseatBottomPadding
|
||||
launcher:a="0.6"
|
||||
launcher:b="0"
|
||||
launcher:c="20dp"/>
|
||||
</device-padding>
|
||||
|
||||
<device-padding
|
||||
launcher:maxEmptySpace="280dp">
|
||||
<workspaceTopPadding
|
||||
launcher:a="0"
|
||||
launcher:b="112dp"/>
|
||||
<workspaceBottomPadding
|
||||
launcher:a="0.4"
|
||||
launcher:b="0"
|
||||
launcher:c="112dp"/>
|
||||
<hotseatBottomPadding
|
||||
launcher:a="0.6"
|
||||
launcher:b="0"
|
||||
launcher:c="112dp"/>
|
||||
</device-padding>
|
||||
|
||||
<device-padding
|
||||
launcher:maxEmptySpace="9999dp">
|
||||
<workspaceTopPadding
|
||||
launcher:a="0.40"
|
||||
launcher:c="36dp"/>
|
||||
<workspaceBottomPadding
|
||||
launcher:a="0.60"
|
||||
launcher:c="36dp"/>
|
||||
<hotseatBottomPadding
|
||||
launcher:a="0"
|
||||
launcher:b="36dp"/>
|
||||
</device-padding>
|
||||
</device-paddings>
|
||||
@@ -3235,12 +3235,12 @@ public class Launcher extends StatefulActivity<LauncherState>
|
||||
/** Pauses view updates that should not be run during the app launch animation. */
|
||||
public void pauseExpensiveViewUpdates() {
|
||||
// Pause page indicator animations as they lead to layer trashing.
|
||||
mWorkspace.getPageIndicator().pauseAnimations();
|
||||
getWorkspace().getPageIndicator().pauseAnimations();
|
||||
}
|
||||
|
||||
/** Resumes view updates at the end of the app launch animation. */
|
||||
public void resumeExpensiveViewUpdates() {
|
||||
mWorkspace.getPageIndicator().skipAnimationsToEnd();
|
||||
getWorkspace().getPageIndicator().skipAnimationsToEnd();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ import static android.view.View.VISIBLE;
|
||||
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION;
|
||||
import static com.android.launcher3.model.ModelUtils.filterCurrentWorkspaceItems;
|
||||
import static com.android.launcher3.model.ModelUtils.getMissingHotseatRanks;
|
||||
import static com.android.launcher3.model.ModelUtils.sortWorkspaceItemsSpatially;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Fragment;
|
||||
@@ -420,8 +419,6 @@ public class LauncherPreviewRenderer extends ContextWrapper
|
||||
currentWorkspaceItems, otherWorkspaceItems);
|
||||
filterCurrentWorkspaceItems(currentScreenIds, dataModel.appWidgets, currentAppWidgets,
|
||||
otherAppWidgets);
|
||||
|
||||
sortWorkspaceItemsSpatially(mIdp, currentWorkspaceItems);
|
||||
for (ItemInfo itemInfo : currentWorkspaceItems) {
|
||||
switch (itemInfo.itemType) {
|
||||
case Favorites.ITEM_TYPE_APPLICATION:
|
||||
|
||||
@@ -18,7 +18,6 @@ package com.android.launcher3.model;
|
||||
|
||||
import static com.android.launcher3.model.ItemInstallQueue.FLAG_LOADER_RUNNING;
|
||||
import static com.android.launcher3.model.ModelUtils.filterCurrentWorkspaceItems;
|
||||
import static com.android.launcher3.model.ModelUtils.sortWorkspaceItemsSpatially;
|
||||
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
|
||||
|
||||
import android.os.Process;
|
||||
@@ -27,6 +26,8 @@ import android.util.Log;
|
||||
import com.android.launcher3.InvariantDeviceProfile;
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.LauncherModel.CallbackTask;
|
||||
import com.android.launcher3.LauncherSettings;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.model.BgDataModel.Callbacks;
|
||||
import com.android.launcher3.model.BgDataModel.FixedContainerItems;
|
||||
import com.android.launcher3.model.data.AppInfo;
|
||||
@@ -110,6 +111,42 @@ public abstract class BaseLoaderResults {
|
||||
|
||||
public abstract void bindWidgets();
|
||||
|
||||
/**
|
||||
* Sorts the set of items by hotseat, workspace (spatially from top to bottom, left to right)
|
||||
*/
|
||||
protected void sortWorkspaceItemsSpatially(InvariantDeviceProfile profile,
|
||||
ArrayList<ItemInfo> workspaceItems) {
|
||||
final int screenCols = profile.numColumns;
|
||||
final int screenCellCount = profile.numColumns * profile.numRows;
|
||||
Collections.sort(workspaceItems, (lhs, rhs) -> {
|
||||
if (lhs.container == rhs.container) {
|
||||
// Within containers, order by their spatial position in that container
|
||||
switch (lhs.container) {
|
||||
case LauncherSettings.Favorites.CONTAINER_DESKTOP: {
|
||||
int lr = (lhs.screenId * screenCellCount + lhs.cellY * screenCols
|
||||
+ lhs.cellX);
|
||||
int rr = (rhs.screenId * screenCellCount + +rhs.cellY * screenCols
|
||||
+ rhs.cellX);
|
||||
return Integer.compare(lr, rr);
|
||||
}
|
||||
case LauncherSettings.Favorites.CONTAINER_HOTSEAT: {
|
||||
// We currently use the screen id as the rank
|
||||
return Integer.compare(lhs.screenId, rhs.screenId);
|
||||
}
|
||||
default:
|
||||
if (FeatureFlags.IS_STUDIO_BUILD) {
|
||||
throw new RuntimeException(
|
||||
"Unexpected container type when sorting workspace items.");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
// Between containers, order by hotseat, desktop
|
||||
return Integer.compare(lhs.container, rhs.container);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void executeCallbacksTask(CallbackTask task, Executor executor) {
|
||||
executor.execute(() -> {
|
||||
if (mMyBindingId != mBgDataModel.lastBindId) {
|
||||
@@ -131,7 +168,7 @@ public abstract class BaseLoaderResults {
|
||||
return idleLock;
|
||||
}
|
||||
|
||||
private static class WorkspaceBinder {
|
||||
private class WorkspaceBinder {
|
||||
|
||||
private final Executor mUiExecutor;
|
||||
private final Callbacks mCallbacks;
|
||||
|
||||
@@ -23,10 +23,8 @@ import android.graphics.Bitmap;
|
||||
import android.os.Process;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.launcher3.InvariantDeviceProfile;
|
||||
import com.android.launcher3.LauncherSettings;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.icons.BitmapInfo;
|
||||
import com.android.launcher3.icons.LauncherIcons;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
@@ -91,42 +89,6 @@ public class ModelUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the set of items by hotseat, workspace (spatially from top to bottom, left to right)
|
||||
*/
|
||||
public static void sortWorkspaceItemsSpatially(InvariantDeviceProfile profile,
|
||||
ArrayList<ItemInfo> workspaceItems) {
|
||||
final int screenCols = profile.numColumns;
|
||||
final int screenCellCount = profile.numColumns * profile.numRows;
|
||||
Collections.sort(workspaceItems, (lhs, rhs) -> {
|
||||
if (lhs.container == rhs.container) {
|
||||
// Within containers, order by their spatial position in that container
|
||||
switch (lhs.container) {
|
||||
case LauncherSettings.Favorites.CONTAINER_DESKTOP: {
|
||||
int lr = (lhs.screenId * screenCellCount + lhs.cellY * screenCols
|
||||
+ lhs.cellX);
|
||||
int rr = (rhs.screenId * screenCellCount + +rhs.cellY * screenCols
|
||||
+ rhs.cellX);
|
||||
return Integer.compare(lr, rr);
|
||||
}
|
||||
case LauncherSettings.Favorites.CONTAINER_HOTSEAT: {
|
||||
// We currently use the screen id as the rank
|
||||
return Integer.compare(lhs.screenId, rhs.screenId);
|
||||
}
|
||||
default:
|
||||
if (FeatureFlags.IS_STUDIO_BUILD) {
|
||||
throw new RuntimeException(
|
||||
"Unexpected container type when sorting workspace items.");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
// Between containers, order by hotseat, desktop
|
||||
return Integer.compare(lhs.container, rhs.container);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates though current workspace items and returns available hotseat ranks for prediction.
|
||||
*/
|
||||
|
||||
@@ -7,7 +7,7 @@ import com.android.launcher3.model.data.ItemInfo;
|
||||
/**
|
||||
* Utility object to manage the occupancy in a grid.
|
||||
*/
|
||||
public class GridOccupancy {
|
||||
public class GridOccupancy extends AbsGridOccupancy {
|
||||
|
||||
private final int mCountX;
|
||||
private final int mCountY;
|
||||
@@ -30,24 +30,7 @@ public class GridOccupancy {
|
||||
* @return true if a vacant cell was found
|
||||
*/
|
||||
public boolean findVacantCell(int[] vacantOut, int spanX, int spanY) {
|
||||
for (int y = 0; (y + spanY) <= mCountY; y++) {
|
||||
for (int x = 0; (x + spanX) <= mCountX; x++) {
|
||||
boolean available = !cells[x][y];
|
||||
out:
|
||||
for (int i = x; i < x + spanX; i++) {
|
||||
for (int j = y; j < y + spanY; j++) {
|
||||
available = available && !cells[i][j];
|
||||
if (!available) break out;
|
||||
}
|
||||
}
|
||||
if (available) {
|
||||
vacantOut[0] = x;
|
||||
vacantOut[1] = y;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return super.findVacantCell(vacantOut, cells, mCountX, mCountY, spanX, spanY);
|
||||
}
|
||||
|
||||
public void copyTo(GridOccupancy dest) {
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.util;
|
||||
|
||||
/**
|
||||
* Defines method to find the next vacant cell on a grid.
|
||||
* This uses the default top-down, left-right approach and can be over-written through
|
||||
* code swaps in different launchers.
|
||||
*/
|
||||
public abstract class AbsGridOccupancy {
|
||||
/**
|
||||
* Find the first vacant cell, if there is one.
|
||||
*
|
||||
* @param vacantOut Holds the x and y coordinate of the vacant cell
|
||||
* @param spanX Horizontal cell span.
|
||||
* @param spanY Vertical cell span.
|
||||
*
|
||||
* @return true if a vacant cell was found
|
||||
*/
|
||||
protected boolean findVacantCell(int[] vacantOut, boolean[][] cells, int countX, int countY,
|
||||
int spanX, int spanY) {
|
||||
for (int y = 0; (y + spanY) <= countY; y++) {
|
||||
for (int x = 0; (x + spanX) <= countX; x++) {
|
||||
boolean available = !cells[x][y];
|
||||
out:
|
||||
for (int i = x; i < x + spanX; i++) {
|
||||
for (int j = y; j < y + spanY; j++) {
|
||||
available = available && !cells[i][j];
|
||||
if (!available) break out;
|
||||
}
|
||||
}
|
||||
if (available) {
|
||||
vacantOut[0] = x;
|
||||
vacantOut[1] = y;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user