Snap for 8485725 from 15e9b89a37 to tm-qpr1-release

Change-Id: Ia976d27cb071f51168cc08998575f7ff4343c028
This commit is contained in:
Android Build Coastguard Worker
2022-04-22 03:08:59 +00:00
25 changed files with 438 additions and 199 deletions
+1 -3
View File
@@ -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;
+21 -4
View File
@@ -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>
+76
View File
@@ -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>
+2 -2
View File
@@ -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;
}
}