Merge "Widgets - Filter work widgets when Work Profile is paused." into tm-dev
diff --git a/Android.bp b/Android.bp
index f5a38b4..c980a2e 100644
--- a/Android.bp
+++ b/Android.bp
@@ -31,6 +31,7 @@
"androidx.test.uiautomator_uiautomator",
"androidx.preference_preference",
"SystemUISharedLib",
+ "SystemUIAnimationLib",
],
srcs: [
"tests/tapl/**/*.java",
@@ -196,6 +197,7 @@
"lottie",
"SystemUISharedLib",
"SystemUI-statsd",
+ "SystemUIAnimationLib",
],
manifest: "quickstep/AndroidManifest.xml",
min_sdk_version: "current",
@@ -287,6 +289,7 @@
"SystemUISharedLib",
"Launcher3CommonDepsLib",
"QuickstepResLib",
+ "SystemUIAnimationLib",
],
manifest: "quickstep/AndroidManifest.xml",
platform_apis: true,
diff --git a/protos/launcher_atom.proto b/protos/launcher_atom.proto
index c559988..a61e430 100644
--- a/protos/launcher_atom.proto
+++ b/protos/launcher_atom.proto
@@ -23,6 +23,8 @@
//
// ItemInfos
message ItemInfo {
+ reserved 8;
+
oneof Item {
Application application = 1;
Task task = 2;
@@ -42,7 +44,14 @@
optional ContainerInfo container_info = 7;
// Stores the origin of the Item
- optional Attribute attribute = 8;
+ repeated Attribute item_attributes = 12;
+}
+
+message LauncherAttributes{
+
+ // Integer value of item attribute enum
+ // (e.g. SUGGESTED_LABEL, ALL_APPS_SEARCH_RESULT_SETTING etc)
+ repeated int32 item_attributes = 1;
}
// Represents various launcher surface where items are placed.
@@ -156,6 +165,13 @@
ALL_APPS_SEARCH_RESULT_LEGACY_SHORTCUT = 30;
ALL_APPS_SEARCH_RESULT_ASSISTANT_MEMORY = 31;
+ // Suggestion Type provided by AGA
+ ONE_SEARCH_WEB_QUERY = 32;
+ ONE_SEARCH_WEB_TRENDING = 33;
+ ONE_SEARCH_WEB_ENTITY = 34;
+ ONE_SEARCH_WEB_ANSWER = 35;
+ ONE_SEARCH_WEB_PERSONAL = 36;
+
WIDGETS_BOTTOM_TRAY = 28;
WIDGETS_TRAY_PREDICTION = 29;
}
diff --git a/quickstep/protos_overrides/launcher_atom_extension.proto b/quickstep/protos_overrides/launcher_atom_extension.proto
index ff050ea..a1566f0 100644
--- a/quickstep/protos_overrides/launcher_atom_extension.proto
+++ b/quickstep/protos_overrides/launcher_atom_extension.proto
@@ -42,5 +42,18 @@
// True if the item's title/content is a direct match to the search query, false otherwise.
optional bool direct_match = 2;
+
+ // Entry point for this on-device search session
+ optional EntryState entry_state = 3;
+
+ enum EntryState{
+ ENTRY_STATE_UNKNOWN = 0;
+
+ // User entered using swipe-up gesture from homescreen and searchbox in AllApps drawer.
+ ALL_APPS = 1;
+
+ // User entered by tapping on QSB bar on homescreen.
+ QSB = 2;
+ }
}
}
diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
index cb6094b..8fb085d 100644
--- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
@@ -25,9 +25,11 @@
import static com.android.launcher3.model.data.ItemInfo.NO_MATCHING_ID;
import static com.android.launcher3.popup.QuickstepSystemShortcut.getSplitSelectShortcutByPosition;
import static com.android.launcher3.util.DisplayController.CHANGE_ACTIVE_SCREEN;
+import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE;
+import static com.android.launcher3.util.DisplayController.NavigationMode.NO_BUTTON;
+import static com.android.launcher3.util.DisplayController.NavigationMode.TWO_BUTTONS;
+import static com.android.launcher3.util.Executors.THREAD_POOL_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
-import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
-import static com.android.quickstep.SysUINavigationMode.Mode.TWO_BUTTONS;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY;
import android.animation.AnimatorSet;
@@ -64,6 +66,7 @@
import com.android.launcher3.uioverrides.RecentsViewStateController;
import com.android.launcher3.util.ActivityOptionsWrapper;
import com.android.launcher3.util.DisplayController;
+import com.android.launcher3.util.DisplayController.NavigationMode;
import com.android.launcher3.util.IntSet;
import com.android.launcher3.util.ObjectWrapper;
import com.android.launcher3.util.RunnableList;
@@ -71,9 +74,6 @@
import com.android.launcher3.util.UiThreadHelper;
import com.android.quickstep.OverviewCommandHelper;
import com.android.quickstep.RecentsModel;
-import com.android.quickstep.SysUINavigationMode;
-import com.android.quickstep.SysUINavigationMode.Mode;
-import com.android.quickstep.SysUINavigationMode.NavigationModeChangeListener;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.TaskUtils;
import com.android.quickstep.TouchInteractionService.TISBinder;
@@ -101,8 +101,7 @@
/**
* Extension of Launcher activity to provide quickstep specific functionality
*/
-public abstract class BaseQuickstepLauncher extends Launcher
- implements NavigationModeChangeListener {
+public abstract class BaseQuickstepLauncher extends Launcher {
private DepthController mDepthController = new DepthController(this);
private QuickstepTransitionManager mAppTransitionManager;
@@ -130,7 +129,6 @@
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- SysUINavigationMode.INSTANCE.get(this).addModeChangeListener(this);
addMultiWindowModeChangedListener(mDepthController);
initUnfoldTransitionProgressProvider();
}
@@ -160,8 +158,6 @@
mUnfoldTransitionProgressProvider.destroy();
}
- SysUINavigationMode.INSTANCE.get(this).removeModeChangeListener(this);
-
mTISBindHelper.onDestroy();
if (mTaskbarManager != null) {
mTaskbarManager.clearActivity(this);
@@ -188,14 +184,6 @@
}
@Override
- public void onNavigationModeChanged(Mode newMode) {
- getDragLayer().recreateControllers();
- if (mActionsView != null) {
- mActionsView.updateVerticalMargin(newMode);
- }
- }
-
- @Override
public void onEnterAnimationComplete() {
super.onEnterAnimationComplete();
// After the transition to home, enable the high-res thumbnail loader if it wasn't enabled
@@ -304,7 +292,6 @@
protected void setupViews() {
super.setupViews();
- SysUINavigationMode.INSTANCE.get(this).updateMode();
mActionsView = findViewById(R.id.overview_actions_view);
RecentsView overviewPanel = (RecentsView) getOverviewPanel();
SplitSelectStateController controller =
@@ -312,7 +299,7 @@
getStateManager(), getDepthController());
overviewPanel.init(mActionsView, controller);
mActionsView.setDp(getDeviceProfile());
- mActionsView.updateVerticalMargin(SysUINavigationMode.getMode(this));
+ mActionsView.updateVerticalMargin(DisplayController.getNavigationMode(this));
mAppTransitionManager = new QuickstepTransitionManager(this);
mAppTransitionManager.registerRemoteAnimations();
@@ -344,6 +331,7 @@
getSystemService(SensorManager.class),
getMainThreadHandler(),
getMainExecutor(),
+ /* backgroundExecutor= */ THREAD_POOL_EXECUTOR,
/* tracingTagPrefix= */ "launcher"
);
@@ -432,7 +420,7 @@
@Override
public float[] getNormalOverviewScaleAndOffset() {
- return SysUINavigationMode.getMode(this).hasGestures
+ return DisplayController.getNavigationMode(this).hasGestures
? new float[] {1, 1} : new float[] {1.1f, NO_OFFSET};
}
@@ -462,7 +450,7 @@
}
public boolean shouldBackButtonBeHidden(LauncherState toState) {
- Mode mode = SysUINavigationMode.getMode(this);
+ NavigationMode mode = DisplayController.getNavigationMode(this);
boolean shouldBackButtonBeHidden = mode.hasGestures
&& toState.hasFlag(FLAG_HIDE_BACK_BUTTON)
&& hasWindowFocus()
@@ -480,7 +468,7 @@
*/
private void onLauncherStateOrFocusChanged() {
boolean shouldBackButtonBeHidden = shouldBackButtonBeHidden(getStateManager().getState());
- if (SysUINavigationMode.getMode(this) == TWO_BUTTONS) {
+ if (DisplayController.getNavigationMode(this) == TWO_BUTTONS) {
UiThreadHelper.setBackButtonAlphaAsync(this, SET_BACK_BUTTON_ALPHA,
shouldBackButtonBeHidden ? 0f : 1f, true /* animate */);
}
@@ -610,6 +598,13 @@
if ((flags & CHANGE_ACTIVE_SCREEN) != 0) {
getStateManager().moveToRestState();
}
+
+ if ((flags & CHANGE_NAVIGATION_MODE) != 0) {
+ getDragLayer().recreateControllers();
+ if (mActionsView != null) {
+ mActionsView.updateVerticalMargin(info.navigationMode);
+ }
+ }
}
@Override
@@ -625,7 +620,7 @@
WindowInsets oldInsets) {
// Override the tappable insets to be 0 on the bottom for gesture nav (otherwise taskbar
// would count towards it). This is used for the bottom protection in All Apps for example.
- if (SysUINavigationMode.getMode(this) == NO_BUTTON) {
+ if (DisplayController.getNavigationMode(this) == NO_BUTTON) {
Insets oldTappableInsets = oldInsets.getInsets(WindowInsets.Type.tappableElement());
Insets newTappableInsets = Insets.of(oldTappableInsets.left, oldTappableInsets.top,
oldTappableInsets.right, 0);
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index c4a3fb5..803dee4 100644
--- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
@@ -579,8 +579,8 @@
}
}
- // Pause page indicator animations as they lead to layer trashing.
- mLauncher.getWorkspace().getPageIndicator().pauseAnimations();
+ // Pause expensive view updates as they can lead to layer thrashing and skipped frames.
+ mLauncher.pauseExpensiveViewUpdates();
endListener = () -> {
viewsToAnimate.forEach(view -> {
@@ -590,7 +590,7 @@
if (scrimEnabled) {
mLauncher.getScrimView().setBackgroundColor(Color.TRANSPARENT);
}
- mLauncher.getWorkspace().getPageIndicator().skipAnimationsToEnd();
+ mLauncher.resumeExpensiveViewUpdates();
};
}
diff --git a/quickstep/src/com/android/launcher3/statehandlers/BackButtonAlphaHandler.java b/quickstep/src/com/android/launcher3/statehandlers/BackButtonAlphaHandler.java
index 1f268cc..07d3a51 100644
--- a/quickstep/src/com/android/launcher3/statehandlers/BackButtonAlphaHandler.java
+++ b/quickstep/src/com/android/launcher3/statehandlers/BackButtonAlphaHandler.java
@@ -17,17 +17,17 @@
package com.android.launcher3.statehandlers;
import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.launcher3.util.DisplayController.NavigationMode.TWO_BUTTONS;
import static com.android.quickstep.AnimatedFloat.VALUE;
-import static com.android.quickstep.SysUINavigationMode.Mode.TWO_BUTTONS;
import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.statemanager.StateManager.StateHandler;
import com.android.launcher3.states.StateAnimationConfig;
+import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.UiThreadHelper;
import com.android.quickstep.AnimatedFloat;
-import com.android.quickstep.SysUINavigationMode;
import com.android.quickstep.SystemUiProxy;
/**
@@ -48,7 +48,7 @@
@Override
public void setStateWithAnimation(LauncherState toState, StateAnimationConfig config,
PendingAnimation animation) {
- if (SysUINavigationMode.getMode(mLauncher) != TWO_BUTTONS) {
+ if (DisplayController.getNavigationMode(mLauncher) != TWO_BUTTONS) {
return;
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
index af53ae2..768a348 100644
--- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
@@ -34,7 +34,6 @@
import com.android.launcher3.QuickstepTransitionManager;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
-import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.logging.InstanceId;
import com.android.launcher3.logging.InstanceIdSequence;
import com.android.launcher3.model.data.ItemInfo;
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index fa0a606..e949b23 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -22,6 +22,7 @@
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
import static com.android.launcher3.AbstractFloatingView.TYPE_ALL;
+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;
@@ -70,13 +71,13 @@
import com.android.launcher3.popup.PopupDataProvider;
import com.android.launcher3.taskbar.allapps.TaskbarAllAppsController;
import com.android.launcher3.touch.ItemClickHandler;
+import com.android.launcher3.util.DisplayController;
+import com.android.launcher3.util.DisplayController.NavigationMode;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.SettingsCache;
import com.android.launcher3.util.TraceHelper;
import com.android.launcher3.util.ViewCache;
import com.android.launcher3.views.ActivityContext;
-import com.android.quickstep.SysUINavigationMode;
-import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.rotation.RotationButtonController;
import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -92,6 +93,8 @@
*/
public class TaskbarActivityContext extends BaseTaskbarContext {
+ private static final String IME_DRAWS_IME_NAV_BAR_RES_NAME = "config_imeDrawsImeNavBar";
+
private static final boolean ENABLE_THREE_BUTTON_TASKBAR =
SystemProperties.getBoolean("persist.debug.taskbar_three_button", false);
private static final String TAG = "TaskbarActivityContext";
@@ -109,7 +112,7 @@
// The size we should return to when we call setTaskbarWindowFullscreen(false)
private int mLastRequestedNonFullscreenHeight;
- private final SysUINavigationMode.Mode mNavMode;
+ private final NavigationMode mNavMode;
private final boolean mImeDrawsImeNavBar;
private final ViewCache mViewCache = new ViewCache();
@@ -130,8 +133,10 @@
super(windowContext);
mDeviceProfile = dp;
- mNavMode = SysUINavigationMode.getMode(windowContext);
- mImeDrawsImeNavBar = SysUINavigationMode.getImeDrawsImeNavBar(windowContext);
+ final Resources resources = getResources();
+
+ mNavMode = DisplayController.getNavigationMode(windowContext);
+ mImeDrawsImeNavBar = getBoolByName(IME_DRAWS_IME_NAV_BAR_RES_NAME, resources, false);
mIsSafeModeEnabled = TraceHelper.allowIpcs("isSafeMode",
() -> getPackageManager().isSafeMode());
mIsUserSetupComplete = SettingsCache.INSTANCE.get(this).getValue(
@@ -141,9 +146,7 @@
mIsNavBarKidsMode = SettingsCache.INSTANCE.get(this).getValue(
Settings.Secure.getUriFor(Settings.Secure.NAV_BAR_KIDS_MODE), 0);
- final Resources resources = getResources();
updateIconSize(resources);
-
mTaskbarHeightForIme = resources.getDimensionPixelSize(R.dimen.taskbar_ime_size);
// Inflate views.
@@ -258,11 +261,11 @@
}
public boolean isThreeButtonNav() {
- return mNavMode == Mode.THREE_BUTTONS;
+ return mNavMode == NavigationMode.THREE_BUTTONS;
}
public boolean isGestureNav() {
- return mNavMode == Mode.NO_BUTTON;
+ return mNavMode == NavigationMode.NO_BUTTON;
}
public boolean imeDrawsImeNavBar() {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
index 24c5d0e..af98b7f 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
@@ -16,6 +16,7 @@
package com.android.launcher3.taskbar;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_ALL_APPS;
+import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -55,20 +56,20 @@
import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.dragndrop.DragView;
import com.android.launcher3.dragndrop.DraggableView;
-import com.android.launcher3.folder.FolderIcon;
import com.android.launcher3.graphics.DragPreviewProvider;
import com.android.launcher3.logging.StatsLogManager;
-import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.popup.PopupContainerWithArrow;
import com.android.launcher3.shortcuts.DeepShortcutView;
import com.android.launcher3.shortcuts.ShortcutDragPreviewProvider;
-import com.android.launcher3.util.LauncherBindableItemsContainer;
+import com.android.launcher3.util.IntSet;
+import com.android.launcher3.util.ItemInfoMatcher;
import com.android.systemui.shared.recents.model.Task;
import java.io.PrintWriter;
import java.util.Arrays;
+import java.util.Collections;
/**
* Handles long click on Taskbar items to start a system drag and drop operation.
@@ -422,23 +423,18 @@
ItemInfo item = (ItemInfo) tag;
TaskbarViewController taskbarViewController = mControllers.taskbarViewController;
if (item.container == CONTAINER_ALL_APPS) {
- // Since all apps closes when the drag starts, target the all apps button instead
+ // Since all apps closes when the drag starts, target the all apps button instead.
target = taskbarViewController.getAllAppsButtonView();
} else if (item.container >= 0) {
- // Since folders close when the drag starts, target the folder icon instead
- LauncherBindableItemsContainer.ItemOperator op = (info, v) -> {
- if (info instanceof FolderInfo && v instanceof FolderIcon) {
- FolderInfo fi = (FolderInfo) info;
- for (WorkspaceItemInfo si : fi.contents) {
- if (si.id == item.id) {
- // Found the parent
- return true;
- }
- }
- }
- return false;
- };
- target = taskbarViewController.mapOverItems(op);
+ // Since folders close when the drag starts, target the folder icon instead.
+ ItemInfoMatcher matcher = ItemInfoMatcher.forFolderMatch(
+ ItemInfoMatcher.ofItemIds(IntSet.wrap(item.id)));
+ target = taskbarViewController.getFirstIconMatch(matcher);
+ } else if (item.itemType == ITEM_TYPE_DEEP_SHORTCUT) {
+ // Find first icon with same package/user as the deep shortcut.
+ ItemInfoMatcher packageUserMatcher = ItemInfoMatcher.ofPackages(
+ Collections.singleton(item.getTargetPackage()), item.user);
+ target = taskbarViewController.getFirstIconMatch(packageUserMatcher);
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
index ebe6a04..ce468d0 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
@@ -29,6 +29,7 @@
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BaseQuickstepLauncher;
+import com.android.launcher3.DeviceProfile;
import com.android.launcher3.LauncherState;
import com.android.launcher3.statemanager.StateManager;
import com.android.launcher3.util.MultiValueAlpha;
@@ -36,6 +37,7 @@
import com.android.quickstep.RecentsAnimationCallbacks;
import com.android.quickstep.RecentsAnimationController;
import com.android.quickstep.views.RecentsView;
+import com.android.systemui.animation.ViewRootSync;
import com.android.systemui.shared.recents.model.ThumbnailData;
import java.util.HashMap;
@@ -76,6 +78,9 @@
private boolean mShouldDelayLauncherStateAnim;
+ // We skip any view synchronizations during init/destroy.
+ private boolean mCanSyncViews;
+
private final StateManager.StateListener<LauncherState> mStateListener =
new StateManager.StateListener<LauncherState>() {
@@ -102,6 +107,8 @@
};
public void init(TaskbarControllers controllers, BaseQuickstepLauncher launcher) {
+ mCanSyncViews = false;
+
mControllers = controllers;
mLauncher = launcher;
@@ -121,9 +128,13 @@
updateStateForFlag(FLAG_RESUMED, launcher.hasBeenResumed());
mLauncherState = launcher.getStateManager().getState();
applyState(0);
+
+ mCanSyncViews = true;
}
public void onDestroy() {
+ mCanSyncViews = false;
+
mIconAlignmentForResumedState.finishAnimation();
mIconAlignmentForGestureState.finishAnimation();
mIconAlignmentForLauncherState.finishAnimation();
@@ -131,6 +142,8 @@
mIconAlphaForHome.setConsumer(null);
mLauncher.getHotseat().setIconsAlpha(1f);
mLauncher.getStateManager().removeStateListener(mStateListener);
+
+ mCanSyncViews = true;
}
public Animator createAnimToLauncher(@NonNull LauncherState toState,
@@ -380,6 +393,27 @@
return;
}
float alignment = alignmentSupplier.get();
+ float currentValue = mIconAlphaForHome.getValue();
+ boolean taskbarWillBeVisible = alignment < 1;
+ boolean firstFrameVisChanged = (taskbarWillBeVisible && Float.compare(currentValue, 1) != 0)
+ || (!taskbarWillBeVisible && Float.compare(currentValue, 0) != 0);
+
+ // Sync the first frame where we swap taskbar and hotseat.
+ if (firstFrameVisChanged && mCanSyncViews) {
+ DeviceProfile dp = mLauncher.getDeviceProfile();
+
+ // Do all the heavy work before the sync.
+ mControllers.taskbarViewController.createIconAlignmentControllerIfNotExists(dp);
+
+ ViewRootSync.synchronizeNextDraw(mLauncher.getHotseat(),
+ mControllers.taskbarActivityContext.getDragLayer(),
+ () -> updateIconAlignment(alignment));
+ } else {
+ updateIconAlignment(alignment);
+ }
+ }
+
+ private void updateIconAlignment(float alignment) {
mControllers.taskbarViewController.setLauncherIconAlignment(
alignment, mLauncher.getDeviceProfile());
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
index 0f7abda..cc462c1 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
@@ -21,6 +21,7 @@
import static com.android.launcher3.util.DisplayController.CHANGE_ACTIVE_SCREEN;
import static com.android.launcher3.util.DisplayController.CHANGE_DENSITY;
+import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE;
import static com.android.launcher3.util.DisplayController.CHANGE_SUPPORTED_BOUNDS;
import android.content.ComponentCallbacks;
@@ -40,15 +41,12 @@
import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.statemanager.StatefulActivity;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.DisplayController.Info;
import com.android.launcher3.util.SettingsCache;
import com.android.launcher3.util.SimpleBroadcastReceiver;
import com.android.quickstep.RecentsActivity;
-import com.android.quickstep.SysUINavigationMode;
-import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.TouchInteractionService;
import com.android.systemui.unfold.UnfoldTransitionProgressProvider;
@@ -59,8 +57,7 @@
/**
* Class to manage taskbar lifecycle
*/
-public class TaskbarManager implements DisplayController.DisplayInfoChangeListener,
- SysUINavigationMode.NavigationModeChangeListener {
+public class TaskbarManager implements DisplayController.DisplayInfoChangeListener {
private static final Uri USER_SETUP_COMPLETE_URI = Settings.Secure.getUriFor(
Settings.Secure.USER_SETUP_COMPLETE);
@@ -70,7 +67,6 @@
private final Context mContext;
private final DisplayController mDisplayController;
- private final SysUINavigationMode mSysUINavigationMode;
private final TaskbarNavButtonController mNavButtonController;
private final SettingsCache.OnChangeListener mUserSetupCompleteListener;
private final SettingsCache.OnChangeListener mNavBarKidsModeListener;
@@ -89,14 +85,13 @@
*/
private final TaskbarSharedState mSharedState = new TaskbarSharedState();
- private static final int CHANGE_FLAGS =
- CHANGE_ACTIVE_SCREEN | CHANGE_DENSITY | CHANGE_SUPPORTED_BOUNDS;
+ private static final int CHANGE_FLAGS = CHANGE_ACTIVE_SCREEN | CHANGE_DENSITY
+ | CHANGE_SUPPORTED_BOUNDS | CHANGE_NAVIGATION_MODE;
private boolean mUserUnlocked = false;
public TaskbarManager(TouchInteractionService service) {
mDisplayController = DisplayController.INSTANCE.get(service);
- mSysUINavigationMode = SysUINavigationMode.INSTANCE.get(service);
Display display =
service.getSystemService(DisplayManager.class).getDisplay(DEFAULT_DISPLAY);
mContext = service.createWindowContext(display, TYPE_NAVIGATION_BAR_PANEL, null);
@@ -137,7 +132,6 @@
mShutdownReceiver = new SimpleBroadcastReceiver(i -> destroyExistingTaskbar());
mDisplayController.addChangeListener(this);
- mSysUINavigationMode.addModeChangeListener(this);
SettingsCache.INSTANCE.get(mContext).register(USER_SETUP_COMPLETE_URI,
mUserSetupCompleteListener);
SettingsCache.INSTANCE.get(mContext).register(NAV_BAR_KIDS_MODE,
@@ -149,11 +143,6 @@
}
@Override
- public void onNavigationModeChanged(Mode newMode) {
- recreateTaskbar();
- }
-
- @Override
public void onDisplayInfoChanged(Context context, Info info, int flags) {
if ((flags & CHANGE_FLAGS) != 0) {
recreateTaskbar();
@@ -301,7 +290,6 @@
public void destroy() {
destroyExistingTaskbar();
mDisplayController.removeChangeListener(this);
- mSysUINavigationMode.removeModeChangeListener(this);
SettingsCache.INSTANCE.get(mContext).unregister(USER_SETUP_COMPLETE_URI,
mUserSetupCompleteListener);
SettingsCache.INSTANCE.get(mContext).unregister(NAV_BAR_KIDS_MODE,
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
index 1d5fa4d..6bc4c0a 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
@@ -29,10 +29,12 @@
import android.content.SharedPreferences;
import android.view.ViewConfiguration;
+import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Utilities;
import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
import com.android.quickstep.AnimatedFloat;
import com.android.quickstep.SystemUiProxy;
+import com.android.systemui.shared.system.WindowManagerWrapper;
import java.io.PrintWriter;
import java.util.StringJoiner;
@@ -60,15 +62,16 @@
// If any of these flags are enabled, inset apps by our stashed height instead of our unstashed
// height. This way the reported insets are consistent even during transitions out of the app.
- // Currently any flag that causes us to stash in an app is included, except for IME since that
- // covers the underlying app anyway and thus the app shouldn't change insets.
+ // Currently any flag that causes us to stash in an app is included, except for IME or All Apps
+ // since those cover the underlying app anyway and thus the app shouldn't change insets.
private static final int FLAGS_REPORT_STASHED_INSETS_TO_APP = FLAGS_STASHED_IN_APP
- & ~FLAG_STASHED_IN_APP_IME;
+ & ~FLAG_STASHED_IN_APP_IME & ~FLAG_STASHED_IN_APP_ALL_APPS;
/**
* How long to stash/unstash when manually invoked via long press.
*/
- public static final long TASKBAR_STASH_DURATION = 300;
+ public static final long TASKBAR_STASH_DURATION =
+ WindowManagerWrapper.ANIMATION_DURATION_RESIZE;
/**
* How long to stash/unstash when keyboard is appearing/disappearing.
@@ -187,7 +190,7 @@
* Returns whether the taskbar can visually stash into a handle based on the current device
* state.
*/
- private boolean supportsVisualStashing() {
+ public boolean supportsVisualStashing() {
return !mActivity.isThreeButtonNav();
}
@@ -254,7 +257,14 @@
* Returns the height that taskbar will inset when inside apps.
*/
public int getContentHeightToReportToApps() {
- if (hasAnyFlag(FLAGS_REPORT_STASHED_INSETS_TO_APP)) {
+ if (supportsVisualStashing() && hasAnyFlag(FLAGS_REPORT_STASHED_INSETS_TO_APP)) {
+ DeviceProfile dp = mActivity.getDeviceProfile();
+ if (hasAnyFlag(FLAG_STASHED_IN_APP_SETUP) && dp.isTaskbarPresent && !dp.isLandscape) {
+ // We always show the back button in SUW but in portrait the SUW layout may not
+ // be wide enough to support overlapping the nav bar with its content. For now,
+ // just inset by the bar height.
+ return mUnstashedHeight;
+ }
boolean isAnimating = mAnimator != null && mAnimator.isStarted();
return mControllers.stashedHandleViewController.isStashedHandleVisible() || isAnimating
? mStashedHeight : 0;
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
index 07b851f..6bc2a93 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
@@ -68,4 +68,11 @@
public void setSystemGestureInProgress(boolean inProgress) {
mControllers.taskbarStashController.setSystemGestureInProgress(inProgress);
}
+
+ /**
+ * Manually closes the all apps window.
+ */
+ public void hideAllApps() {
+ mControllers.taskbarAllAppsController.hide();
+ }
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
index ade58a9..0b537e2 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
@@ -39,6 +39,7 @@
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.uioverrides.ApiWrapper;
+import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.util.LauncherBindableItemsContainer;
import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.views.AllAppsButton;
@@ -367,17 +368,36 @@
}
/**
- * Maps {@code op} over all the child views, returning the view that {@code op} evaluates
- * {@code true} for, or {@code null} if none satisfy {@code op}.
+ * Maps {@code op} over all the child views.
*/
- protected View mapOverItems(LauncherBindableItemsContainer.ItemOperator op) {
+ public void mapOverItems(LauncherBindableItemsContainer.ItemOperator op) {
// map over all the shortcuts on the taskbar
for (int i = 0; i < getChildCount(); i++) {
View item = getChildAt(i);
if (op.evaluate((ItemInfo) item.getTag(), item)) {
- return item;
+ return;
}
}
- return null;
+ }
+
+ /**
+ * Finds the first icon to match one of the given matchers, from highest to lowest priority.
+ * @return The first match, or All Apps button if no match was found.
+ */
+ public View getFirstMatch(ItemInfoMatcher... matchers) {
+ for (ItemInfoMatcher matcher : matchers) {
+ for (int i = 0; i < getChildCount(); i++) {
+ View item = getChildAt(i);
+ if (!(item.getTag() instanceof ItemInfo)) {
+ // Should only happen for All Apps button.
+ continue;
+ }
+ ItemInfo info = (ItemInfo) item.getTag();
+ if (matcher.matchesInfo(info)) {
+ return item;
+ }
+ }
+ }
+ return mAllAppsButton;
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
index 153ed14..f354b2c 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
@@ -37,6 +37,7 @@
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.folder.FolderIcon;
import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.util.LauncherBindableItemsContainer;
import com.android.launcher3.util.MultiValueAlpha;
import com.android.quickstep.AnimatedFloat;
@@ -191,15 +192,23 @@
}
/**
+ * Creates the icon alignment controller if it does not already exist.
+ * @param launcherDp Launcher device profile.
+ */
+ public void createIconAlignmentControllerIfNotExists(DeviceProfile launcherDp) {
+ if (mIconAlignControllerLazy == null) {
+ mIconAlignControllerLazy = createIconAlignmentController(launcherDp);
+ }
+ }
+
+ /**
* Sets the taskbar icon alignment relative to Launcher hotseat icons
* @param alignmentRatio [0, 1]
* 0 => not aligned
* 1 => fully aligned
*/
public void setLauncherIconAlignment(float alignmentRatio, DeviceProfile launcherDp) {
- if (mIconAlignControllerLazy == null) {
- mIconAlignControllerLazy = createIconAlignmentController(launcherDp);
- }
+ createIconAlignmentControllerIfNotExists(launcherDp);
mIconAlignControllerLazy.setPlayFraction(alignmentRatio);
if (alignmentRatio <= 0 || alignmentRatio >= 1) {
// Cleanup lazy controller so that it is created again in next animation
@@ -274,8 +283,22 @@
mTaskbarNavButtonTranslationY.updateValue(-deviceProfile.getTaskbarOffsetY());
}
- public View mapOverItems(LauncherBindableItemsContainer.ItemOperator op) {
- return mTaskbarView.mapOverItems(op);
+ /**
+ * Maps the given operator to all the top-level children of TaskbarView.
+ */
+ public void mapOverItems(LauncherBindableItemsContainer.ItemOperator op) {
+ mTaskbarView.mapOverItems(op);
+ }
+
+ /**
+ * Returns the first icon to match the given parameter, in priority from:
+ * 1) Icons directly on Taskbar
+ * 2) FolderIcon of the Folder containing the given icon
+ * 3) All Apps button
+ */
+ public View getFirstIconMatch(ItemInfoMatcher matcher) {
+ ItemInfoMatcher folderMatcher = ItemInfoMatcher.forFolderMatch(matcher);
+ return mTaskbarView.getFirstMatch(matcher, folderMatcher);
}
/**
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContext.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContext.java
index 7f3add3..a67ca70 100644
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContext.java
@@ -22,8 +22,10 @@
import static com.android.systemui.shared.system.ViewTreeObserverWrapper.InsetsInfo.TOUCHABLE_INSETS_REGION;
import android.content.Context;
+import android.graphics.Insets;
import android.view.KeyEvent;
import android.view.View;
+import android.view.WindowInsets;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.DeviceProfile;
@@ -59,6 +61,10 @@
private final TaskbarAllAppsDragLayer mDragLayer;
private final TaskbarAllAppsContainerView mAppsView;
+ // We automatically stash taskbar when all apps is opened in gesture navigation mode.
+ private final boolean mWillTaskbarBeVisuallyStashed;
+ private final int mStashedTaskbarHeight;
+
TaskbarAllAppsContext(
TaskbarActivityContext taskbarContext,
TaskbarAllAppsController windowController,
@@ -79,6 +85,9 @@
windowController,
taskbarStashController);
mAppsView = slideInView.getAppsView();
+
+ mWillTaskbarBeVisuallyStashed = taskbarStashController.supportsVisualStashing();
+ mStashedTaskbarHeight = taskbarStashController.getStashedHeight();
}
TaskbarAllAppsViewController getAllAppsViewController() {
@@ -189,5 +198,37 @@
inoutInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION);
}
}
+
+ @Override
+ public WindowInsets onApplyWindowInsets(WindowInsets insets) {
+ return updateInsetsDueToStashing(insets);
+ }
+
+ /**
+ * Taskbar automatically stashes when opening all apps, but we don't report the insets as
+ * changing to avoid moving the underlying app. But internally, the apps view should still
+ * layout according to the stashed insets rather than the unstashed insets. So this method
+ * does two things:
+ * 1) Sets navigationBars bottom inset to stashedHeight.
+ * 2) Sets tappableInsets bottom inset to 0.
+ */
+ private WindowInsets updateInsetsDueToStashing(WindowInsets oldInsets) {
+ if (!mActivity.mWillTaskbarBeVisuallyStashed) {
+ return oldInsets;
+ }
+ WindowInsets.Builder updatedInsetsBuilder = new WindowInsets.Builder(oldInsets);
+
+ Insets oldNavInsets = oldInsets.getInsets(WindowInsets.Type.navigationBars());
+ Insets newNavInsets = Insets.of(oldNavInsets.left, oldNavInsets.top, oldNavInsets.right,
+ mActivity.mStashedTaskbarHeight);
+ updatedInsetsBuilder.setInsets(WindowInsets.Type.navigationBars(), newNavInsets);
+
+ Insets oldTappableInsets = oldInsets.getInsets(WindowInsets.Type.tappableElement());
+ Insets newTappableInsets = Insets.of(oldTappableInsets.left, oldTappableInsets.top,
+ oldTappableInsets.right, 0);
+ updatedInsetsBuilder.setInsets(WindowInsets.Type.tappableElement(), newTappableInsets);
+
+ return updatedInsetsBuilder.build();
+ }
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java
index 87133fc..cf9d778 100644
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java
@@ -15,6 +15,7 @@
*/
package com.android.launcher3.taskbar.allapps;
+import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
import static com.android.launcher3.AbstractFloatingView.TYPE_ALL;
@@ -130,6 +131,11 @@
.setPredictedApps(mPredictedApps);
}
+ /** Closes the {@link TaskbarAllAppsContainerView}. */
+ public void hide() {
+ mProxyView.close(true);
+ }
+
/**
* Removes the all apps window from the hierarchy, if all floating views are closed and there is
* no system drag operation in progress.
@@ -158,6 +164,7 @@
layoutParams.gravity = Gravity.BOTTOM;
layoutParams.packageName = mTaskbarContext.getPackageName();
layoutParams.setFitInsetsTypes(0); // Handled by container view.
+ layoutParams.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
layoutParams.setSystemApplicationOverlay(true);
return layoutParams;
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java b/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java
index aa26645..9240fb8 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java
@@ -24,8 +24,8 @@
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
-import com.android.quickstep.SysUINavigationMode;
-import com.android.quickstep.SysUINavigationMode.Mode;
+import com.android.launcher3.util.DisplayController;
+import com.android.launcher3.util.DisplayController.NavigationMode;
public class ApiWrapper {
@@ -54,7 +54,7 @@
* Returns the minimum space that should be left empty at the end of hotseat
*/
public static int getHotseatEndOffset(Context context) {
- if (SysUINavigationMode.INSTANCE.get(context).getMode() == Mode.THREE_BUTTONS) {
+ if (DisplayController.getNavigationMode(context) == NavigationMode.THREE_BUTTONS) {
Resources res = context.getResources();
/*
* 3 nav buttons +
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index 1073d76..829accc 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -68,14 +68,14 @@
import com.android.launcher3.uioverrides.touchcontrollers.TaskViewTouchController;
import com.android.launcher3.uioverrides.touchcontrollers.TransposedQuickSwitchTouchController;
import com.android.launcher3.uioverrides.touchcontrollers.TwoButtonNavbarTouchController;
+import com.android.launcher3.util.DisplayController;
+import com.android.launcher3.util.DisplayController.NavigationMode;
import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.util.PendingRequestArgs;
import com.android.launcher3.util.TouchController;
import com.android.launcher3.util.UiThreadHelper;
import com.android.launcher3.util.UiThreadHelper.AsyncCommand;
import com.android.launcher3.widget.LauncherAppWidgetHost;
-import com.android.quickstep.SysUINavigationMode;
-import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.TaskUtils;
import com.android.quickstep.util.QuickstepOnboardingPrefs;
@@ -303,7 +303,7 @@
@Override
public TouchController[] createTouchControllers() {
- Mode mode = SysUINavigationMode.getMode(this);
+ NavigationMode mode = DisplayController.getNavigationMode(this);
ArrayList<TouchController> list = new ArrayList<>();
list.add(getDragController());
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
index bb13329..236454e 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
@@ -26,8 +26,8 @@
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.R;
+import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.Themes;
-import com.android.quickstep.SysUINavigationMode;
import com.android.quickstep.util.LayoutUtils;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
@@ -58,7 +58,7 @@
@Override
public int getTransitionDuration(Context context) {
// In gesture modes, overview comes in all the way from the side, so give it more time.
- return SysUINavigationMode.INSTANCE.get(context).getMode().hasGestures ? 380 : 250;
+ return DisplayController.getNavigationMode(context).hasGestures ? 380 : 250;
}
@Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
index bd7e5de..4d05349 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
@@ -60,7 +60,7 @@
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.uioverrides.QuickstepLauncher;
-import com.android.quickstep.SysUINavigationMode;
+import com.android.launcher3.util.DisplayController;
import com.android.quickstep.util.RecentsAtomicAnimationFactory;
import com.android.quickstep.views.RecentsView;
@@ -97,7 +97,7 @@
config.setInterpolator(ANIM_WORKSPACE_SCALE, DEACCEL);
config.setInterpolator(ANIM_WORKSPACE_FADE, ACCEL);
- if (SysUINavigationMode.getMode(mActivity).hasGestures
+ if (DisplayController.getNavigationMode(mActivity).hasGestures
&& overview.getTaskViewCount() > 0) {
// Overview is going offscreen, so keep it at its current scale and opacity.
config.setInterpolator(ANIM_OVERVIEW_SCALE, FINAL_FRAME);
@@ -139,7 +139,7 @@
}
} else if ((fromState == NORMAL || fromState == HINT_STATE
|| fromState == HINT_STATE_TWO_BUTTON) && toState == OVERVIEW) {
- if (SysUINavigationMode.getMode(mActivity).hasGestures) {
+ if (DisplayController.getNavigationMode(mActivity).hasGestures) {
config.setInterpolator(ANIM_WORKSPACE_SCALE,
fromState == NORMAL ? ACCEL : OVERSHOOT_1_2);
config.setInterpolator(ANIM_WORKSPACE_TRANSLATE, ACCEL);
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
index f0ef9cc..e5cd53a 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
@@ -44,8 +44,8 @@
import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.touch.AbstractStateChangeTouchController;
import com.android.launcher3.touch.SingleAxisSwipeDetector;
-import com.android.quickstep.SysUINavigationMode;
-import com.android.quickstep.SysUINavigationMode.Mode;
+import com.android.launcher3.util.DisplayController;
+import com.android.launcher3.util.DisplayController.NavigationMode;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.TaskUtils;
import com.android.quickstep.views.RecentsView;
@@ -125,7 +125,7 @@
private void setupInterpolators(StateAnimationConfig stateAnimationConfig) {
stateAnimationConfig.setInterpolator(ANIM_WORKSPACE_FADE, DEACCEL_2);
stateAnimationConfig.setInterpolator(ANIM_ALL_APPS_FADE, DEACCEL_2);
- if (SysUINavigationMode.getMode(mLauncher) == Mode.NO_BUTTON) {
+ if (DisplayController.getNavigationMode(mLauncher) == NavigationMode.NO_BUTTON) {
// Overview lives to the left of workspace, so translate down later than over
stateAnimationConfig.setInterpolator(ANIM_WORKSPACE_TRANSLATE, ACCEL_2);
stateAnimationConfig.setInterpolator(ANIM_VERTICAL_PROGRESS, ACCEL_2);
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java
index 308bca6..ca7f633 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java
@@ -38,10 +38,10 @@
import com.android.launcher3.touch.BaseSwipeDetector;
import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.launcher3.touch.SingleAxisSwipeDetector;
+import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.FlingBlockCheck;
import com.android.launcher3.util.TouchController;
import com.android.launcher3.views.BaseDragLayer;
-import com.android.quickstep.SysUINavigationMode;
import com.android.quickstep.util.VibratorWrapper;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
@@ -177,7 +177,7 @@
// - It's the focused task if in grid view
// - The task is snapped
mAllowGoingDown = i == mRecentsView.getCurrentPage()
- && SysUINavigationMode.getMode(mActivity).hasGestures
+ && DisplayController.getNavigationMode(mActivity).hasGestures
&& (!mRecentsView.showAsGrid() || mTaskBeingDragged.isFocusedTask())
&& mRecentsView.isTaskInExpectedScrollPosition(i);
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 2570e6c..253903c 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -1768,6 +1768,7 @@
private void maybeFinishSwipeToHome() {
if (mIsSwipingPipToHome && mSwipePipToHomeAnimators[0] != null) {
SystemUiProxy.INSTANCE.get(mContext).stopSwipePipToHome(
+ mSwipePipToHomeAnimator.getTaskId(),
mSwipePipToHomeAnimator.getComponentName(),
mSwipePipToHomeAnimator.getDestinationBounds(),
mSwipePipToHomeAnimator.getContentOverlay());
diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
index 0f707c0..6584f88 100644
--- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
@@ -19,9 +19,9 @@
import static com.android.launcher3.anim.Interpolators.ACCEL_2;
import static com.android.launcher3.anim.Interpolators.INSTANT;
import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.launcher3.util.DisplayController.getNavigationMode;
import static com.android.quickstep.AbsSwipeUpHandler.RECENTS_ATTACH_DURATION;
import static com.android.quickstep.GestureState.GestureEndTarget.RECENTS;
-import static com.android.quickstep.SysUINavigationMode.getMode;
import static com.android.quickstep.util.RecentsAtomicAnimationFactory.INDEX_RECENTS_FADE_ANIM;
import static com.android.quickstep.util.RecentsAtomicAnimationFactory.INDEX_RECENTS_TRANSLATE_X_ANIM;
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET;
@@ -55,9 +55,10 @@
import com.android.launcher3.statemanager.StatefulActivity;
import com.android.launcher3.taskbar.TaskbarUIController;
import com.android.launcher3.touch.PagedOrientationHandler;
+import com.android.launcher3.util.DisplayController;
+import com.android.launcher3.util.DisplayController.NavigationMode;
import com.android.launcher3.util.WindowBounds;
import com.android.launcher3.views.ScrimView;
-import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.quickstep.util.ActivityInitListener;
import com.android.quickstep.util.AnimatorControllerWithResistance;
import com.android.quickstep.util.SplitScreenBounds;
@@ -68,6 +69,7 @@
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
import java.util.HashMap;
+import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Predicate;
@@ -192,7 +194,12 @@
activity.getStateManager().moveToRestState();
}
- public void closeOverlay() { }
+ /**
+ * Closes any overlays.
+ */
+ public void closeOverlay() {
+ Optional.ofNullable(getTaskbarController()).ifPresent(TaskbarUIController::hideAllApps);
+ }
public void switchRunningTaskViewToScreenshot(HashMap<Integer, ThumbnailData> thumbnailDatas,
Runnable runnable) {
@@ -356,8 +363,8 @@
/** Gets the space that the overview actions will take, including bottom margin. */
private int getOverviewActionsHeight(Context context, DeviceProfile dp) {
Resources res = context.getResources();
- return OverviewActionsView.getOverviewActionsBottomMarginPx(getMode(context), dp)
- + OverviewActionsView.getOverviewActionsTopMarginPx(getMode(context), dp)
+ return OverviewActionsView.getOverviewActionsBottomMarginPx(getNavigationMode(context), dp)
+ + OverviewActionsView.getOverviewActionsTopMarginPx(getNavigationMode(context), dp)
+ res.getDimensionPixelSize(R.dimen.overview_actions_height);
}
@@ -480,7 +487,7 @@
// Creating the activity controller animation sometimes reapplies the launcher state
// (because we set the animation as the current state animation), so we reapply the
// attached state here as well to ensure recents is shown/hidden appropriately.
- if (SysUINavigationMode.getMode(mActivity) == Mode.NO_BUTTON) {
+ if (DisplayController.getNavigationMode(mActivity) == NavigationMode.NO_BUTTON) {
setRecentsAttachedToAppWindow(mIsAttachedToWindow, false);
}
}
diff --git a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
index ffdfa43..7feec2c 100644
--- a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
@@ -16,7 +16,7 @@
package com.android.quickstep;
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
-import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
+import static com.android.launcher3.util.DisplayController.NavigationMode.NO_BUTTON;
import static com.android.quickstep.fallback.RecentsState.BACKGROUND_APP;
import static com.android.quickstep.fallback.RecentsState.DEFAULT;
import static com.android.quickstep.fallback.RecentsState.HOME;
@@ -33,6 +33,7 @@
import com.android.launcher3.statemanager.StateManager;
import com.android.launcher3.taskbar.FallbackTaskbarUIController;
import com.android.launcher3.touch.PagedOrientationHandler;
+import com.android.launcher3.util.DisplayController;
import com.android.quickstep.GestureState.GestureEndTarget;
import com.android.quickstep.fallback.RecentsState;
import com.android.quickstep.util.ActivityInitListener;
@@ -62,8 +63,7 @@
public int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context, Rect outRect,
PagedOrientationHandler orientationHandler) {
calculateTaskSize(context, dp, outRect);
- if (dp.isVerticalBarLayout()
- && SysUINavigationMode.INSTANCE.get(context).getMode() != NO_BUTTON) {
+ if (dp.isVerticalBarLayout() && DisplayController.getNavigationMode(context) != NO_BUTTON) {
return dp.isSeascape() ? outRect.left : (dp.widthPx - outRect.right);
} else {
return dp.heightPx - outRect.bottom;
diff --git a/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java b/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
index a82137e..4eb190a 100644
--- a/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
@@ -56,6 +56,7 @@
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.anim.SpringAnimationBuilder;
+import com.android.launcher3.util.DisplayController;
import com.android.quickstep.fallback.FallbackRecentsView;
import com.android.quickstep.fallback.RecentsState;
import com.android.quickstep.util.RectFSpringAnim;
@@ -176,7 +177,7 @@
@Override
protected void notifyGestureAnimationStartToRecents() {
if (mRunningOverHome) {
- if (SysUINavigationMode.getMode(mContext).hasGestures) {
+ if (DisplayController.getNavigationMode(mContext).hasGestures) {
mRecentsView.onGestureAnimationStartOnHome(
new ActivityManager.RunningTaskInfo[]{mGestureState.getRunningTask()});
}
diff --git a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
index 38331a9..10a3a2e 100644
--- a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
@@ -44,8 +44,9 @@
import com.android.launcher3.statemanager.StateManager;
import com.android.launcher3.taskbar.LauncherTaskbarUIController;
import com.android.launcher3.touch.PagedOrientationHandler;
+import com.android.launcher3.util.DisplayController;
+import com.android.launcher3.util.DisplayController.NavigationMode;
import com.android.quickstep.GestureState.GestureEndTarget;
-import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.quickstep.util.ActivityInitListener;
import com.android.quickstep.util.AnimatorControllerWithResistance;
import com.android.quickstep.util.LayoutUtils;
@@ -72,7 +73,8 @@
public int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context, Rect outRect,
PagedOrientationHandler orientationHandler) {
calculateTaskSize(context, dp, outRect);
- if (dp.isVerticalBarLayout() && SysUINavigationMode.getMode(context) != Mode.NO_BUTTON) {
+ if (dp.isVerticalBarLayout()
+ && DisplayController.getNavigationMode(context) != NavigationMode.NO_BUTTON) {
return dp.isSeascape() ? outRect.left : (dp.widthPx - outRect.right);
} else {
return LayoutUtils.getShelfTrackingDistance(context, dp, orientationHandler);
@@ -278,6 +280,7 @@
@Override
public void closeOverlay() {
+ super.closeOverlay();
Launcher launcher = getCreatedActivity();
if (launcher == null) {
return;
diff --git a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
index 4d13253..e5c7b0e 100644
--- a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
+++ b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
@@ -34,6 +34,7 @@
import com.android.launcher3.R;
import com.android.launcher3.ResourceUtils;
import com.android.launcher3.util.DisplayController.Info;
+import com.android.launcher3.util.DisplayController.NavigationMode;
import java.io.PrintWriter;
import java.util.HashMap;
@@ -112,7 +113,7 @@
* mQuickstepStartingRotation only updates when device rotation matches touch rotation.
*/
private int mActiveTouchRotation;
- private SysUINavigationMode.Mode mMode;
+ private NavigationMode mMode;
private QuickStepContractInfo mContractInfo;
/**
@@ -135,7 +136,7 @@
}
- OrientationTouchTransformer(Resources resources, SysUINavigationMode.Mode mode,
+ OrientationTouchTransformer(Resources resources, NavigationMode mode,
QuickStepContractInfo contractInfo) {
mResources = resources;
mMode = mode;
@@ -155,7 +156,7 @@
resetSwipeRegions(info);
}
- void setNavigationMode(SysUINavigationMode.Mode newMode, Info info, Resources newRes) {
+ void setNavigationMode(NavigationMode newMode, Info info, Resources newRes) {
if (DEBUG) {
Log.d(TAG, "setNavigationMode new: " + newMode + " oldMode: " + mMode + " " + this);
}
@@ -212,8 +213,7 @@
* @param info The current displayInfo which will be the start of the quickswitch gesture
*/
void enableMultipleRegions(boolean enableMultipleRegions, Info info) {
- mEnableMultipleRegions = enableMultipleRegions &&
- mMode != SysUINavigationMode.Mode.TWO_BUTTONS;
+ mEnableMultipleRegions = enableMultipleRegions && mMode != NavigationMode.TWO_BUTTONS;
if (mEnableMultipleRegions) {
mQuickStepStartingRotation = info.rotation;
} else {
@@ -276,9 +276,8 @@
Point size = display.currentSize;
int rotation = display.rotation;
int touchHeight = mNavBarGesturalHeight;
- OrientationRectF orientationRectF =
- new OrientationRectF(0, 0, size.x, size.y, rotation);
- if (mMode == SysUINavigationMode.Mode.NO_BUTTON) {
+ OrientationRectF orientationRectF = new OrientationRectF(0, 0, size.x, size.y, rotation);
+ if (mMode == NavigationMode.NO_BUTTON) {
orientationRectF.top = orientationRectF.bottom - touchHeight;
updateAssistantRegions(orientationRectF);
} else {
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
index ad57683..f1ace49 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
@@ -21,12 +21,13 @@
import static android.view.Display.DEFAULT_DISPLAY;
import static com.android.launcher3.util.DisplayController.CHANGE_ALL;
+import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE;
import static com.android.launcher3.util.DisplayController.CHANGE_ROTATION;
+import static com.android.launcher3.util.DisplayController.NavigationMode.NO_BUTTON;
+import static com.android.launcher3.util.DisplayController.NavigationMode.THREE_BUTTONS;
+import static com.android.launcher3.util.DisplayController.NavigationMode.TWO_BUTTONS;
import static com.android.launcher3.util.SettingsCache.ONE_HANDED_ENABLED;
import static com.android.launcher3.util.SettingsCache.ONE_HANDED_SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED;
-import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
-import static com.android.quickstep.SysUINavigationMode.Mode.THREE_BUTTONS;
-import static com.android.quickstep.SysUINavigationMode.Mode.TWO_BUTTONS;
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_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY;
@@ -71,9 +72,8 @@
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener;
import com.android.launcher3.util.DisplayController.Info;
+import com.android.launcher3.util.DisplayController.NavigationMode;
import com.android.launcher3.util.SettingsCache;
-import com.android.quickstep.SysUINavigationMode.NavigationModeChangeListener;
-import com.android.quickstep.SysUINavigationMode.OneHandedModeChangeListener;
import com.android.quickstep.util.NavBarPosition;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.QuickStepContract;
@@ -89,15 +89,11 @@
/**
* Manages the state of the system during a swipe up gesture.
*/
-public class RecentsAnimationDeviceState implements
- NavigationModeChangeListener,
- DisplayInfoChangeListener,
- OneHandedModeChangeListener {
+public class RecentsAnimationDeviceState implements DisplayInfoChangeListener {
static final String SUPPORT_ONE_HANDED_MODE = "ro.support_one_handed_mode";
private final Context mContext;
- private final SysUINavigationMode mSysUiNavMode;
private final DisplayController mDisplayController;
private final int mDisplayId;
private final RotationTouchHelper mRotationTouchHelper;
@@ -110,7 +106,7 @@
private final ArrayList<Runnable> mOnDestroyActions = new ArrayList<>();
private @SystemUiStateFlags int mSystemUiStateFlags;
- private SysUINavigationMode.Mode mMode = THREE_BUTTONS;
+ private NavigationMode mMode = THREE_BUTTONS;
private NavBarPosition mNavBarPosition;
private final Region mDeferredGestureRegion = new Region();
@@ -148,10 +144,8 @@
public RecentsAnimationDeviceState(Context context, boolean isInstanceForTouches) {
mContext = context;
mDisplayController = DisplayController.INSTANCE.get(context);
- mSysUiNavMode = SysUINavigationMode.INSTANCE.get(context);
mDisplayId = DEFAULT_DISPLAY;
mIsOneHandedModeSupported = SystemProperties.getBoolean(SUPPORT_ONE_HANDED_MODE, false);
- runOnDestroy(() -> mDisplayController.removeChangeListener(this));
mRotationTouchHelper = RotationTouchHelper.INSTANCE.get(context);
if (isInstanceForTouches) {
// rotationTouchHelper doesn't get initialized after being destroyed, so only destroy
@@ -180,9 +174,10 @@
};
runOnDestroy(mExclusionListener::unregister);
- // Register for navigation mode changes
- onNavigationModeChanged(mSysUiNavMode.addModeChangeListener(this));
- runOnDestroy(() -> mSysUiNavMode.removeModeChangeListener(this));
+ // Register for display changes changes
+ mDisplayController.addChangeListener(this);
+ onDisplayInfoChanged(context, mDisplayController.getInfo(), CHANGE_ALL);
+ runOnDestroy(() -> mDisplayController.removeChangeListener(this));
// Add any blocked activities
String[] blockingActivities;
@@ -267,47 +262,36 @@
* Adds a listener for the nav mode change, guaranteed to be called after the device state's
* mode has changed.
*/
- public void addNavigationModeChangedCallback(NavigationModeChangeListener listener) {
- listener.onNavigationModeChanged(mSysUiNavMode.addModeChangeListener(listener));
- runOnDestroy(() -> mSysUiNavMode.removeModeChangeListener(listener));
- }
-
- @Override
- public void onNavigationModeChanged(SysUINavigationMode.Mode newMode) {
- mDisplayController.removeChangeListener(this);
- mDisplayController.addChangeListener(this);
- onDisplayInfoChanged(mContext, mDisplayController.getInfo(), CHANGE_ALL);
-
- if (newMode == NO_BUTTON) {
- mExclusionListener.register();
- } else {
- mExclusionListener.unregister();
- }
-
- mNavBarPosition = new NavBarPosition(newMode, mDisplayController.getInfo());
- mMode = newMode;
+ public void addNavigationModeChangedCallback(Runnable callback) {
+ DisplayController.DisplayInfoChangeListener listener = (context, info, flags) -> {
+ if ((flags & CHANGE_NAVIGATION_MODE) != 0) {
+ callback.run();
+ }
+ };
+ mDisplayController.addChangeListener(listener);
+ callback.run();
+ runOnDestroy(() -> mDisplayController.removeChangeListener(listener));
}
@Override
public void onDisplayInfoChanged(Context context, Info info, int flags) {
- if ((flags & CHANGE_ROTATION) != 0) {
+ if ((flags & (CHANGE_ROTATION | CHANGE_NAVIGATION_MODE)) != 0) {
+ mMode = info.navigationMode;
mNavBarPosition = new NavBarPosition(mMode, info);
+
+ if (mMode == NO_BUTTON) {
+ mExclusionListener.register();
+ } else {
+ mExclusionListener.unregister();
+ }
}
}
- @Override
public void onOneHandedModeChanged(int newGesturalHeight) {
mRotationTouchHelper.setGesturalHeight(newGesturalHeight);
}
/**
- * @return the current navigation mode for the device.
- */
- public SysUINavigationMode.Mode getNavMode() {
- return mMode;
- }
-
- /**
* @return the nav bar position for the current nav bar mode and display rotation.
*/
public NavBarPosition getNavBarPosition() {
diff --git a/quickstep/src/com/android/quickstep/RotationTouchHelper.java b/quickstep/src/com/android/quickstep/RotationTouchHelper.java
index 35efddf..dad5071 100644
--- a/quickstep/src/com/android/quickstep/RotationTouchHelper.java
+++ b/quickstep/src/com/android/quickstep/RotationTouchHelper.java
@@ -20,9 +20,10 @@
import static com.android.launcher3.util.DisplayController.CHANGE_ACTIVE_SCREEN;
import static com.android.launcher3.util.DisplayController.CHANGE_ALL;
+import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE;
import static com.android.launcher3.util.DisplayController.CHANGE_ROTATION;
+import static com.android.launcher3.util.DisplayController.NavigationMode.THREE_BUTTONS;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
-import static com.android.quickstep.SysUINavigationMode.Mode.THREE_BUTTONS;
import android.content.Context;
import android.content.res.Resources;
@@ -33,6 +34,7 @@
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener;
import com.android.launcher3.util.DisplayController.Info;
+import com.android.launcher3.util.DisplayController.NavigationMode;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.quickstep.util.RecentsOrientedState;
import com.android.systemui.shared.system.QuickStepContract;
@@ -42,22 +44,22 @@
import java.io.PrintWriter;
import java.util.ArrayList;
-public class RotationTouchHelper implements
- SysUINavigationMode.NavigationModeChangeListener,
- DisplayInfoChangeListener {
+/**
+ * Helper class for transforming touch events
+ */
+public class RotationTouchHelper implements DisplayInfoChangeListener {
public static final MainThreadInitializedObject<RotationTouchHelper> INSTANCE =
new MainThreadInitializedObject<>(RotationTouchHelper::new);
private OrientationTouchTransformer mOrientationTouchTransformer;
private DisplayController mDisplayController;
- private SysUINavigationMode mSysUiNavMode;
private int mDisplayId;
private int mDisplayRotation;
private final ArrayList<Runnable> mOnDestroyActions = new ArrayList<>();
- private SysUINavigationMode.Mode mMode = THREE_BUTTONS;
+ private NavigationMode mMode = THREE_BUTTONS;
private TaskStackChangeListener mFrozenTaskListener = new TaskStackChangeListener() {
@Override
@@ -144,16 +146,16 @@
}
mDisplayController = DisplayController.INSTANCE.get(mContext);
Resources resources = mContext.getResources();
- mSysUiNavMode = SysUINavigationMode.INSTANCE.get(mContext);
mDisplayId = DEFAULT_DISPLAY;
mOrientationTouchTransformer = new OrientationTouchTransformer(resources, mMode,
() -> QuickStepContract.getWindowCornerRadius(mContext));
// Register for navigation mode changes
- SysUINavigationMode.Mode newMode = mSysUiNavMode.addModeChangeListener(this);
- onNavModeChangedInternal(newMode, newMode.hasGestures);
- runOnDestroy(() -> mSysUiNavMode.removeModeChangeListener(this));
+ mDisplayController.addChangeListener(this);
+ DisplayController.Info info = mDisplayController.getInfo();
+ onDisplayInfoChangedInternal(info, CHANGE_ALL, info.navigationMode.hasGestures);
+ runOnDestroy(() -> mDisplayController.removeChangeListener(this));
mOrientationListener = new OrientationEventListener(mContext) {
@Override
@@ -242,66 +244,56 @@
event.getY(pointerIndex));
}
-
@Override
- public void onNavigationModeChanged(SysUINavigationMode.Mode newMode) {
- onNavModeChangedInternal(newMode, false);
+ public void onDisplayInfoChanged(Context context, Info info, int flags) {
+ onDisplayInfoChangedInternal(info, flags, false);
}
- /**
- * @param forceRegister if {@code true}, this will register {@link #mFrozenTaskListener} via
- * {@link #setupOrientationSwipeHandler()}
- */
- private void onNavModeChangedInternal(SysUINavigationMode.Mode newMode, boolean forceRegister) {
- mDisplayController.removeChangeListener(this);
- mDisplayController.addChangeListener(this);
- onDisplayInfoChanged(mContext, mDisplayController.getInfo(), CHANGE_ALL);
+ private void onDisplayInfoChangedInternal(Info info, int flags, boolean forceRegister) {
+ if ((flags & (CHANGE_ROTATION | CHANGE_ACTIVE_SCREEN | CHANGE_NAVIGATION_MODE)) != 0) {
+ mDisplayRotation = info.rotation;
- mOrientationTouchTransformer.setNavigationMode(newMode, mDisplayController.getInfo(),
- mContext.getResources());
+ if (mMode.hasGestures) {
+ updateGestureTouchRegions();
+ mOrientationTouchTransformer.createOrAddTouchRegion(info);
+ mCurrentAppRotation = mDisplayRotation;
- if (forceRegister || (!mMode.hasGestures && newMode.hasGestures)) {
- setupOrientationSwipeHandler();
- } else if (mMode.hasGestures && !newMode.hasGestures){
- destroyOrientationSwipeHandlerCallback();
+ /* Update nav bars on the following:
+ * a) if this is coming from an activity rotation OR
+ * aa) we launch an app in the orientation that user is already in
+ * b) We're not in overview, since overview will always be portrait (w/o home
+ * rotation)
+ * c) We're actively in quickswitch mode
+ */
+ if ((mPrioritizeDeviceRotation
+ || mCurrentAppRotation == mSensorRotation)
+ // switch to an app of orientation user is in
+ && !mInOverview
+ && mTaskListFrozen) {
+ toggleSecondaryNavBarsForRotation();
+ }
+ }
}
- mMode = newMode;
+ if ((flags & CHANGE_NAVIGATION_MODE) != 0) {
+ NavigationMode newMode = info.navigationMode;
+ mOrientationTouchTransformer.setNavigationMode(newMode, mDisplayController.getInfo(),
+ mContext.getResources());
+
+ if (forceRegister || (!mMode.hasGestures && newMode.hasGestures)) {
+ setupOrientationSwipeHandler();
+ } else if (mMode.hasGestures && !newMode.hasGestures) {
+ destroyOrientationSwipeHandlerCallback();
+ }
+
+ mMode = newMode;
+ }
}
public int getDisplayRotation() {
return mDisplayRotation;
}
- @Override
- public void onDisplayInfoChanged(Context context, Info info, int flags) {
- if ((flags & (CHANGE_ROTATION | CHANGE_ACTIVE_SCREEN)) == 0) {
- return;
- }
-
- mDisplayRotation = info.rotation;
-
- if (!mMode.hasGestures) {
- return;
- }
- updateGestureTouchRegions();
- mOrientationTouchTransformer.createOrAddTouchRegion(info);
- mCurrentAppRotation = mDisplayRotation;
-
- /* Update nav bars on the following:
- * a) if this is coming from an activity rotation OR
- * aa) we launch an app in the orientation that user is already in
- * b) We're not in overview, since overview will always be portrait (w/o home rotation)
- * c) We're actively in quickswitch mode
- */
- if ((mPrioritizeDeviceRotation
- || mCurrentAppRotation == mSensorRotation) // switch to an app of orientation user is in
- && !mInOverview
- && mTaskListFrozen) {
- toggleSecondaryNavBarsForRotation();
- }
- }
-
/**
* Sets the gestural height.
*/
diff --git a/quickstep/src/com/android/quickstep/SysUINavigationMode.java b/quickstep/src/com/android/quickstep/SysUINavigationMode.java
deleted file mode 100644
index 406414c..0000000
--- a/quickstep/src/com/android/quickstep/SysUINavigationMode.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (C) 2019 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.quickstep;
-
-import static com.android.launcher3.ResourceUtils.INVALID_RESOURCE_HANDLE;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NAVIGATION_MODE_2_BUTTON;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NAVIGATION_MODE_3_BUTTON;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NAVIGATION_MODE_GESTURE_BUTTON;
-import static com.android.launcher3.util.PackageManagerHelper.getPackageFilter;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.util.Log;
-
-import com.android.launcher3.ResourceUtils;
-import com.android.launcher3.logging.StatsLogManager.LauncherEvent;
-import com.android.launcher3.util.MainThreadInitializedObject;
-
-import java.io.PrintWriter;
-import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-/**
- * Observer for the resource config that specifies the navigation bar mode.
- */
-public class SysUINavigationMode {
-
- public enum Mode {
- THREE_BUTTONS(false, 0, LAUNCHER_NAVIGATION_MODE_3_BUTTON),
- TWO_BUTTONS(true, 1, LAUNCHER_NAVIGATION_MODE_2_BUTTON),
- NO_BUTTON(true, 2, LAUNCHER_NAVIGATION_MODE_GESTURE_BUTTON);
-
- public final boolean hasGestures;
- public final int resValue;
- public final LauncherEvent launcherEvent;
-
- Mode(boolean hasGestures, int resValue, LauncherEvent launcherEvent) {
- this.hasGestures = hasGestures;
- this.resValue = resValue;
- this.launcherEvent = launcherEvent;
- }
- }
-
- public static Mode getMode(Context context) {
- return INSTANCE.get(context).getMode();
- }
-
- public static boolean getImeDrawsImeNavBar(Context context) {
- return INSTANCE.get(context).getImeDrawsImeNavBar();
- }
-
- public static final MainThreadInitializedObject<SysUINavigationMode> INSTANCE =
- new MainThreadInitializedObject<>(SysUINavigationMode::new);
-
- private static final String TAG = "SysUINavigationMode";
- private static final String ACTION_OVERLAY_CHANGED = "android.intent.action.OVERLAY_CHANGED";
- private static final String NAV_BAR_INTERACTION_MODE_RES_NAME = "config_navBarInteractionMode";
- private static final String IME_DRAWS_IME_NAV_BAR_RES_NAME = "config_imeDrawsImeNavBar";
- private static final String TARGET_OVERLAY_PACKAGE = "android";
-
- private final Context mContext;
- private Mode mMode;
- private boolean mImeDrawsImeNavBar;
-
- private int mNavBarGesturalHeight;
- private int mNavBarLargerGesturalHeight;
-
- private final List<NavigationModeChangeListener> mChangeListeners =
- new CopyOnWriteArrayList<>();
-
- public SysUINavigationMode(Context context) {
- mContext = context;
- initializeMode();
-
- mContext.registerReceiver(new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- updateMode();
- updateGesturalHeight();
- }
- }, getPackageFilter(TARGET_OVERLAY_PACKAGE, ACTION_OVERLAY_CHANGED));
- }
-
- /** Updates navigation mode when needed. */
- public void updateMode() {
- Mode oldMode = mMode;
- initializeMode();
- if (mMode != oldMode) {
- dispatchModeChange();
- }
- }
-
- private void updateGesturalHeight() {
- int newGesturalHeight = ResourceUtils.getDimenByName(
- ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE, mContext.getResources(),
- INVALID_RESOURCE_HANDLE);
-
- if (newGesturalHeight == INVALID_RESOURCE_HANDLE) {
- Log.e(TAG, "Failed to get system resource ID. Incompatible framework version?");
- return;
- }
-
- if (mNavBarGesturalHeight != newGesturalHeight) {
- mNavBarGesturalHeight = newGesturalHeight;
- }
-
- int newLargerGesturalHeight = ResourceUtils.getDimenByName(
- ResourceUtils.NAVBAR_BOTTOM_GESTURE_LARGER_SIZE, mContext.getResources(),
- INVALID_RESOURCE_HANDLE);
- if (newLargerGesturalHeight == INVALID_RESOURCE_HANDLE) {
- Log.e(TAG, "Failed to get system resource ID. Incompatible framework version?");
- return;
- }
- if (mNavBarLargerGesturalHeight != newLargerGesturalHeight) {
- mNavBarLargerGesturalHeight = newLargerGesturalHeight;
- }
- }
-
- private void initializeMode() {
- int modeInt = ResourceUtils.getIntegerByName(NAV_BAR_INTERACTION_MODE_RES_NAME,
- mContext.getResources(), INVALID_RESOURCE_HANDLE);
- mNavBarGesturalHeight = ResourceUtils.getDimenByName(
- ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE, mContext.getResources(),
- INVALID_RESOURCE_HANDLE);
- mNavBarLargerGesturalHeight = ResourceUtils.getDimenByName(
- ResourceUtils.NAVBAR_BOTTOM_GESTURE_LARGER_SIZE, mContext.getResources(),
- mNavBarGesturalHeight);
- mImeDrawsImeNavBar = ResourceUtils.getBoolByName(IME_DRAWS_IME_NAV_BAR_RES_NAME,
- mContext.getResources(), false);
-
- if (modeInt == INVALID_RESOURCE_HANDLE) {
- Log.e(TAG, "Failed to get system resource ID. Incompatible framework version?");
- return;
- }
-
- for (Mode m : Mode.values()) {
- if (m.resValue == modeInt) {
- mMode = m;
- }
- }
- }
-
- private void dispatchModeChange() {
- for (NavigationModeChangeListener listener : mChangeListeners) {
- listener.onNavigationModeChanged(mMode);
- }
- }
-
- public Mode addModeChangeListener(NavigationModeChangeListener listener) {
- mChangeListeners.add(listener);
- return mMode;
- }
-
- public void removeModeChangeListener(NavigationModeChangeListener listener) {
- mChangeListeners.remove(listener);
- }
-
- public Mode getMode() {
- return mMode;
- }
-
- public boolean getImeDrawsImeNavBar() {
- return mImeDrawsImeNavBar;
- }
-
- public void dump(PrintWriter pw) {
- pw.println("SysUINavigationMode:");
- pw.println(" mode=" + mMode.name());
- pw.println(" mImeDrawsImeNavBar=:" + mImeDrawsImeNavBar);
- pw.println(" mNavBarGesturalHeight=:" + mNavBarGesturalHeight);
- }
-
- public interface NavigationModeChangeListener {
- void onNavigationModeChanged(Mode newMode);
- }
-
- public interface OneHandedModeChangeListener {
- void onOneHandedModeChanged(int newGesturalHeight);
- }
-}
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
index 8b00f45..667ea14 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.java
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -17,6 +17,7 @@
import static android.app.ActivityManager.RECENT_IGNORE_UNAVAILABLE;
+import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import android.app.PendingIntent;
@@ -39,6 +40,8 @@
import android.view.RemoteAnimationTarget;
import android.view.SurfaceControl;
+import com.android.launcher3.util.DisplayController;
+import com.android.launcher3.util.DisplayController.Info;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.SplitConfigurationOptions;
import com.android.systemui.shared.recents.ISystemUiProxy;
@@ -65,8 +68,7 @@
/**
* Holds the reference to SystemUI.
*/
-public class SystemUiProxy implements ISystemUiProxy,
- SysUINavigationMode.NavigationModeChangeListener {
+public class SystemUiProxy implements ISystemUiProxy, DisplayController.DisplayInfoChangeListener {
private static final String TAG = SystemUiProxy.class.getSimpleName();
public static final MainThreadInitializedObject<SystemUiProxy> INSTANCE =
@@ -107,13 +109,15 @@
private int mLastSystemUiStateFlags;
public SystemUiProxy(Context context) {
- SysUINavigationMode.INSTANCE.get(context).addModeChangeListener(this);
+ DisplayController.INSTANCE.get(context).addChangeListener(this);
}
@Override
- public void onNavigationModeChanged(SysUINavigationMode.Mode newMode) {
- // Whenever the nav mode changes, force reset the nav button alpha
- setNavBarButtonAlpha(1f, false);
+ public void onDisplayInfoChanged(Context context, Info info, int flags) {
+ if ((flags & CHANGE_NAVIGATION_MODE) != 0) {
+ // Whenever the nav mode changes, force reset the nav button alpha
+ setNavBarButtonAlpha(1f, false);
+ }
}
@Override
@@ -541,11 +545,16 @@
return null;
}
- public void stopSwipePipToHome(ComponentName componentName, Rect destinationBounds,
+ /**
+ * Notifies WM Shell that launcher has finished all the animation for swipe to home. WM Shell
+ * can choose to fade out the overlay when entering PIP is finished, and WM Shell should be
+ * responsible for cleaning up the overlay.
+ */
+ public void stopSwipePipToHome(int taskId, ComponentName componentName, Rect destinationBounds,
SurfaceControl overlay) {
if (mPip != null) {
try {
- mPip.stopSwipePipToHome(componentName, destinationBounds, overlay);
+ mPip.stopSwipePipToHome(taskId, componentName, destinationBounds, overlay);
} catch (RemoteException e) {
Log.w(TAG, "Failed call stopSwipePipToHome");
}
diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
index 5e298f4..57b42f8 100644
--- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java
+++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
@@ -44,14 +44,14 @@
import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.shared.system.TaskStackChangeListeners;
-import java.util.Arrays;
+import java.util.ArrayList;
import java.util.HashMap;
public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAnimationListener {
public static final boolean ENABLE_SHELL_TRANSITIONS =
- SystemProperties.getBoolean("persist.debug.shell_transit", false);
+ SystemProperties.getBoolean("persist.wm.debug.shell_transit", false);
public static final boolean SHELL_TRANSITIONS_ROTATION = ENABLE_SHELL_TRANSITIONS
- && SystemProperties.getBoolean("persist.debug.shell_transit_rotate", false);
+ && SystemProperties.getBoolean("persist.wm.debug.shell_transit_rotate", false);
private RecentsAnimationController mController;
private RecentsAnimationCallbacks mCallbacks;
@@ -156,12 +156,26 @@
RemoteAnimationTargetCompat appearedTaskTarget = appearedTaskTargets[0];
BaseActivityInterface activityInterface = mLastGestureState.getActivityInterface();
// Convert appTargets to type RemoteAnimationTarget for all apps except Home app
- RemoteAnimationTarget[] nonHomeApps = Arrays.stream(appearedTaskTargets)
- .filter(remoteAnimationTarget ->
- remoteAnimationTarget.activityType != ACTIVITY_TYPE_HOME)
+ final ArrayList<RemoteAnimationTargetCompat> tmpNonHomeApps = new ArrayList<>();
+ final ArrayList<RemoteAnimationTargetCompat> tmpHomeApps = new ArrayList<>();
+ for (RemoteAnimationTargetCompat compat : appearedTaskTargets) {
+ if (compat.activityType != ACTIVITY_TYPE_HOME) {
+ tmpNonHomeApps.add(compat);
+ } else {
+ tmpHomeApps.add(compat);
+ }
+ }
+ RemoteAnimationTarget[] nonHomeApps = tmpNonHomeApps.stream()
.map(RemoteAnimationTargetCompat::unwrap)
.toArray(RemoteAnimationTarget[]::new);
-
+ RemoteAnimationTarget[] homeApps = tmpHomeApps.stream()
+ .map(RemoteAnimationTargetCompat::unwrap)
+ .toArray(RemoteAnimationTarget[]::new);
+ if (homeApps.length > 0
+ && activityInterface.getCreatedActivity() instanceof RecentsActivity) {
+ ((RecentsActivity) activityInterface.getCreatedActivity()).startHome();
+ return;
+ }
RemoteAnimationTarget[] nonAppTargets =
SystemUiProxy.INSTANCE.getNoCreate()
.onGoingToRecentsLegacy(false, nonHomeApps);
@@ -198,8 +212,16 @@
RemoteTransitionCompat transition = new RemoteTransitionCompat(mCallbacks,
mController != null ? mController.getController() : null,
mCtx.getIApplicationThread());
- final ActivityOptions options = ActivityOptionsCompat.makeRemoteTransition(transition)
- .setTransientLaunch();
+ final ActivityOptions options = ActivityOptionsCompat.makeRemoteTransition(transition);
+ // Allowing to pause Home if Home is top activity and Recents is not Home. So when user
+ // start home when recents animation is playing, the home activity can be resumed again
+ // to let the transition controller collect Home activity.
+ ActivityManager.RunningTaskInfo rti = gestureState.getRunningTask();
+ boolean homeIsOnTop = rti != null && rti.topActivity != null
+ && rti.topActivity.equals(gestureState.getHomeIntent().getComponent());
+ if (!homeIsOnTop) {
+ options.setTransientLaunch();
+ }
options.setSourceInfo(ActivityOptions.SourceInfo.TYPE_RECENTS_ANIMATION, eventTime);
UI_HELPER_EXECUTOR.execute(() -> mCtx.startActivity(intent, options.toBundle()));
} else {
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index b224089..021048a 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -47,7 +47,6 @@
import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.drawable.Icon;
-import android.hardware.display.DisplayManager;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
@@ -77,6 +76,7 @@
import com.android.launcher3.tracing.LauncherTraceProto;
import com.android.launcher3.tracing.TouchInteractionServiceProto;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
+import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.OnboardingPrefs;
import com.android.launcher3.util.TraceHelper;
import com.android.launcher3.util.WindowBounds;
@@ -344,8 +344,6 @@
private InputMonitorCompat mInputMonitorCompat;
private InputEventReceiver mInputEventReceiver;
- private DisplayManager mDisplayManager;
-
private TaskbarManager mTaskbarManager;
private Function<GestureState, AnimatedFloat> mSwipeUpProxyProvider = i -> null;
@@ -357,7 +355,6 @@
mMainChoreographer = Choreographer.getInstance();
mAM = ActivityManagerWrapper.getInstance();
mDeviceState = new RecentsAnimationDeviceState(this, true);
- mDisplayManager = getSystemService(DisplayManager.class);
mTaskbarManager = new TaskbarManager(this);
mRotationTouchHelper = mDeviceState.getRotationTouchHelper();
@@ -399,7 +396,7 @@
/**
* Called when the navigation mode changes, guaranteed to be after the device state has updated.
*/
- private void onNavigationModeChanged(SysUINavigationMode.Mode mode) {
+ private void onNavigationModeChanged() {
initInputMonitor();
resetHomeBounceSeenOnQuickstepEnabledFirstTime();
}
@@ -948,7 +945,7 @@
pw.println("Input state:");
pw.println(" mInputMonitorCompat=" + mInputMonitorCompat);
pw.println(" mInputEventReceiver=" + mInputEventReceiver);
- SysUINavigationMode.INSTANCE.get(this).dump(pw);
+ DisplayController.INSTANCE.get(this).dump(pw);
pw.println("TouchState:");
BaseDraggingActivity createdOverviewActivity = mOverviewComponentObserver == null ? null
: mOverviewComponentObserver.getActivityInterface().getCreatedActivity();
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackNavBarTouchController.java b/quickstep/src/com/android/quickstep/fallback/FallbackNavBarTouchController.java
index 9d9ef94..3e01ed0 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackNavBarTouchController.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackNavBarTouchController.java
@@ -22,9 +22,9 @@
import com.android.launcher3.Utilities;
import com.android.launcher3.util.DisplayController;
+import com.android.launcher3.util.DisplayController.NavigationMode;
import com.android.launcher3.util.TouchController;
import com.android.quickstep.RecentsActivity;
-import com.android.quickstep.SysUINavigationMode;
import com.android.quickstep.util.NavBarPosition;
import com.android.quickstep.util.TriggerSwipeUpTouchTracker;
@@ -40,8 +40,8 @@
public FallbackNavBarTouchController(RecentsActivity activity) {
mActivity = activity;
- SysUINavigationMode.Mode sysUINavigationMode = SysUINavigationMode.getMode(mActivity);
- if (sysUINavigationMode == SysUINavigationMode.Mode.NO_BUTTON) {
+ NavigationMode sysUINavigationMode = DisplayController.getNavigationMode(mActivity);
+ if (sysUINavigationMode == NavigationMode.NO_BUTTON) {
NavBarPosition navBarPosition = new NavBarPosition(sysUINavigationMode,
DisplayController.INSTANCE.get(mActivity).getInfo());
mTriggerSwipeUpTracker = new TriggerSwipeUpTouchTracker(mActivity,
diff --git a/quickstep/src/com/android/quickstep/interaction/NavBarGestureHandler.java b/quickstep/src/com/android/quickstep/interaction/NavBarGestureHandler.java
index 851cccf..a8163af 100644
--- a/quickstep/src/com/android/quickstep/interaction/NavBarGestureHandler.java
+++ b/quickstep/src/com/android/quickstep/interaction/NavBarGestureHandler.java
@@ -47,7 +47,7 @@
import com.android.launcher3.R;
import com.android.launcher3.ResourceUtils;
import com.android.launcher3.anim.Interpolators;
-import com.android.quickstep.SysUINavigationMode.Mode;
+import com.android.launcher3.util.DisplayController.NavigationMode;
import com.android.quickstep.util.MotionPauseDetector;
import com.android.quickstep.util.NavBarPosition;
import com.android.quickstep.util.TriggerSwipeUpTouchTracker;
@@ -101,7 +101,7 @@
}
mSwipeUpTouchTracker =
new TriggerSwipeUpTouchTracker(context, true /*disableHorizontalSwipe*/,
- new NavBarPosition(Mode.NO_BUTTON, displayRotation),
+ new NavBarPosition(NavigationMode.NO_BUTTON, displayRotation),
null /*onInterceptTouch*/, this);
mMotionPauseDetector = new MotionPauseDetector(context);
diff --git a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
index 9a101b9..2db4c20 100644
--- a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
@@ -336,8 +336,7 @@
1f - SHAPE_PROGRESS_DURATION /* shapeProgressStart */,
radius, 255,
false, /* isOpening */
- mFakeIconView, mDp,
- false /* isVerticalBarLayout */);
+ mFakeIconView, mDp);
mFakeIconView.setAlpha(1);
mFakeTaskView.setAlpha(getWindowAlpha(progress));
mFakePreviousTaskView.setAlpha(getWindowAlpha(progress));
diff --git a/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java b/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java
index a0cd0d7..bd0250d 100644
--- a/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java
+++ b/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java
@@ -26,6 +26,7 @@
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_THEMED_ICON_ENABLED;
import static com.android.launcher3.model.DeviceGridState.KEY_WORKSPACE_SIZE;
import static com.android.launcher3.model.QuickstepModelDelegate.LAST_PREDICTION_ENABLED_STATE;
+import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE;
import static com.android.launcher3.util.SettingsCache.NOTIFICATION_BADGING_URI;
import static com.android.launcher3.util.Themes.KEY_THEMED_ICONS;
@@ -44,11 +45,11 @@
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.logging.StatsLogManager.StatsLogger;
import com.android.launcher3.model.DeviceGridState;
+import com.android.launcher3.util.DisplayController;
+import com.android.launcher3.util.DisplayController.Info;
+import com.android.launcher3.util.DisplayController.NavigationMode;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.SettingsCache;
-import com.android.quickstep.SysUINavigationMode;
-import com.android.quickstep.SysUINavigationMode.Mode;
-import com.android.quickstep.SysUINavigationMode.NavigationModeChangeListener;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -60,8 +61,8 @@
* Utility class to log launcher settings changes
*/
public class SettingsChangeLogger implements
- NavigationModeChangeListener, OnSharedPreferenceChangeListener {
-
+ DisplayController.DisplayInfoChangeListener, OnSharedPreferenceChangeListener {
+
/**
* Singleton instance
*/
@@ -76,7 +77,7 @@
private final ArrayMap<String, LoggablePref> mLoggablePrefs;
private final StatsLogManager mStatsLogManager;
- private Mode mNavMode;
+ private NavigationMode mNavMode;
private StatsLogManager.LauncherEvent mNotificationDotsEvent;
private StatsLogManager.LauncherEvent mHomeScreenSuggestionEvent;
@@ -84,7 +85,8 @@
mContext = context;
mStatsLogManager = StatsLogManager.newInstance(mContext);
mLoggablePrefs = loadPrefKeys(context);
- mNavMode = SysUINavigationMode.INSTANCE.get(context).addModeChangeListener(this);
+ DisplayController.INSTANCE.get(context).addChangeListener(this);
+ mNavMode = DisplayController.getNavigationMode(context);
getPrefs(context).registerOnSharedPreferenceChangeListener(this);
getDevicePrefs(context).registerOnSharedPreferenceChangeListener(this);
@@ -141,9 +143,11 @@
}
@Override
- public void onNavigationModeChanged(Mode newMode) {
- mNavMode = newMode;
- mStatsLogManager.logger().log(newMode.launcherEvent);
+ public void onDisplayInfoChanged(Context context, Info info, int flags) {
+ if ((flags & CHANGE_NAVIGATION_MODE) != 0) {
+ mNavMode = info.navigationMode;
+ mStatsLogManager.logger().log(mNavMode.launcherEvent);
+ }
}
@Override
diff --git a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
index 12a638a..d85515a 100644
--- a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
+++ b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
@@ -42,10 +42,12 @@
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.Utilities;
import com.android.launcher3.logger.LauncherAtom;
+import com.android.launcher3.logger.LauncherAtom.Attribute;
import com.android.launcher3.logger.LauncherAtom.ContainerInfo;
import com.android.launcher3.logger.LauncherAtom.FolderContainer.ParentContainerCase;
import com.android.launcher3.logger.LauncherAtom.FolderIcon;
import com.android.launcher3.logger.LauncherAtom.FromState;
+import com.android.launcher3.logger.LauncherAtom.LauncherAttributes;
import com.android.launcher3.logger.LauncherAtom.ToState;
import com.android.launcher3.logger.LauncherAtomExtensions.DeviceSearchResultContainer;
import com.android.launcher3.logger.LauncherAtomExtensions.DeviceSearchResultContainer.SearchAttributes;
@@ -88,13 +90,14 @@
private static final int FOLDER_HIERARCHY_OFFSET = 100;
private static final int SEARCH_RESULT_HIERARCHY_OFFSET = 200;
private static final int EXTENDED_CONTAINERS_HIERARCHY_OFFSET = 300;
- private static final int ATTRIBUTE_MULTIPLIER = 100;
/**
* Flags for converting SearchAttribute to integer value.
*/
- private static final int SEARCH_ATTRIBUTES_CORRECTED_QUERY = 1;
+ private static final int SEARCH_ATTRIBUTES_CORRECTED_QUERY = 1 << 0;
private static final int SEARCH_ATTRIBUTES_DIRECT_MATCH = 1 << 1;
+ private static final int SEARCH_ATTRIBUTES_ENTRY_STATE_ALL_APPS = 1 << 2;
+ private static final int SEARCH_ATTRIBUTES_ENTRY_STATE_QSB = 1 << 3;
public static final CopyOnWriteArrayList<StatsLogConsumer> LOGS_CONSUMER =
new CopyOnWriteArrayList<>();
@@ -110,6 +113,11 @@
return new StatsCompatLogger(mContext, mActivityContext);
}
+ @Override
+ protected StatsLatencyLogger createLatencyLogger() {
+ return new StatsCompatLatencyLogger(mContext, mActivityContext);
+ }
+
/**
* Synchronously writes an itemInfo to stats log
*/
@@ -123,8 +131,7 @@
}
SysUiStatsLog.write(SysUiStatsLog.LAUNCHER_SNAPSHOT,
LAUNCHER_WORKSPACE_SNAPSHOT.getId() /* event_id */,
- info.getAttribute().getNumber() * ATTRIBUTE_MULTIPLIER
- + info.getItemCase().getNumber() /* target_id */,
+ info.getItemCase().getNumber() /* target_id */,
instanceId.getId() /* instance_id */,
0 /* uid */,
getPackageName(info) /* package_name */,
@@ -137,11 +144,20 @@
getParentPageId(info) /* page_id_parent */,
getHierarchy(info) /* hierarchy */,
info.getIsWork() /* is_work_profile */,
- info.getAttribute().getNumber() /* origin */,
+ 0 /* origin */,
getCardinality(info) /* cardinality */,
info.getWidget().getSpanX(),
info.getWidget().getSpanY(),
- getFeatures(info));
+ getFeatures(info),
+ getAttributes(info) /* attributes */
+ );
+ }
+
+ private static byte[] getAttributes(LauncherAtom.ItemInfo itemInfo) {
+ LauncherAttributes.Builder responseBuilder = LauncherAttributes.newBuilder();
+ itemInfo.getItemAttributesList().stream().map(Attribute::getNumber).forEach(
+ responseBuilder::addItemAttributes);
+ return responseBuilder.build().toByteArray();
}
/**
@@ -153,8 +169,7 @@
return SysUiStatsLog.buildStatsEvent(
SysUiStatsLog.LAUNCHER_LAYOUT_SNAPSHOT, // atom ID,
LAUNCHER_WORKSPACE_SNAPSHOT.getId(), // event_id = 1;
- info.getAttribute().getNumber() * ATTRIBUTE_MULTIPLIER
- + info.getItemCase().getNumber(), // item_id = 2;
+ info.getItemCase().getNumber(), // item_id = 2;
instanceId == null ? 0 : instanceId.getId(), //instance_id = 3;
0, //uid = 4 [(is_uid) = true];
getPackageName(info), // package_name = 5;
@@ -167,10 +182,11 @@
getParentPageId(info), //page_id_parent = 12 [default = -2];
getHierarchy(info), // container_id = 13;
info.getIsWork(), // is_work_profile = 14;
- info.getAttribute().getNumber(), // attribute_id = 15;
+ 0, // attribute_id = 15;
getCardinality(info), // cardinality = 16;
info.getWidget().getSpanX(), // span_x = 17 [default = 1];
- info.getWidget().getSpanY() // span_y = 18 [default = 1];
+ info.getWidget().getSpanY(), // span_y = 18 [default = 1];
+ getAttributes(info) /* attributes */
);
}
@@ -393,8 +409,7 @@
null /* launcher extensions, deprecated */,
false /* quickstep_enabled, deprecated */,
event.getId() /* event_id */,
- atomInfo.getAttribute().getNumber() * ATTRIBUTE_MULTIPLIER
- + atomInfo.getItemCase().getNumber() /* target_id */,
+ atomInfo.getItemCase().getNumber() /* target_id */,
instanceId.getId() /* instance_id TODO */,
0 /* uid TODO */,
getPackageName(atomInfo) /* package_name */,
@@ -413,7 +428,70 @@
atomInfo.getFolderIcon().getLabelInfo() /* edittext */,
getCardinality(atomInfo) /* cardinality */,
getFeatures(atomInfo) /* features */,
- getSearchAttributes(atomInfo) /* searchAttributes */
+ getSearchAttributes(atomInfo) /* searchAttributes */,
+ getAttributes(atomInfo) /* attributes */
+ );
+ }
+ }
+
+ /**
+ * Helps to construct and log statsd compatible latency events.
+ */
+ private static class StatsCompatLatencyLogger implements StatsLatencyLogger {
+ private final Context mContext;
+ private final Optional<ActivityContext> mActivityContext;
+ private InstanceId mInstanceId = DEFAULT_INSTANCE_ID;
+ private LatencyType mType = LatencyType.UNKNOWN;
+ private int mPackageId = 0;
+ private long mLatencyInMillis;
+
+ StatsCompatLatencyLogger(Context context, ActivityContext activityContext) {
+ mContext = context;
+ mActivityContext = Optional.ofNullable(activityContext);
+ }
+
+ @Override
+ public StatsLatencyLogger withInstanceId(InstanceId instanceId) {
+ this.mInstanceId = instanceId;
+ return this;
+ }
+
+ @Override
+ public StatsLatencyLogger withType(LatencyType type) {
+ this.mType = type;
+ return this;
+ }
+
+ @Override
+ public StatsLatencyLogger withPackageId(int packageId) {
+ this.mPackageId = packageId;
+ return this;
+ }
+
+ @Override
+ public StatsLatencyLogger withLatency(long latencyInMillis) {
+ this.mLatencyInMillis = latencyInMillis;
+ return this;
+ }
+
+ @Override
+ public void log(EventEnum event) {
+ if (IS_VERBOSE) {
+ String name = (event instanceof Enum) ? ((Enum) event).name() :
+ event.getId() + "";
+
+ Log.d(TAG, mInstanceId == DEFAULT_INSTANCE_ID
+ ? String.format("\n%s = %dms\n", name, mLatencyInMillis)
+ : String.format("\n%s = %dms (InstanceId:%s)\n", name,
+ mLatencyInMillis, mInstanceId));
+ }
+
+ SysUiStatsLog.write(SysUiStatsLog.LAUNCHER_LATENCY,
+ event.getId(), // event_id
+ mInstanceId.getId(), // instance_id
+ mPackageId, // package_id
+ mLatencyInMillis, // latency_in_millis
+ mType.getId() //type
);
}
}
@@ -592,6 +670,12 @@
if (searchAttributes.getDirectMatch()) {
response = response | SEARCH_ATTRIBUTES_DIRECT_MATCH;
}
+ if (searchAttributes.getEntryState() == SearchAttributes.EntryState.ALL_APPS) {
+ response = response | SEARCH_ATTRIBUTES_ENTRY_STATE_ALL_APPS;
+ } else if (searchAttributes.getEntryState() == SearchAttributes.EntryState.QSB) {
+ response = response | SEARCH_ATTRIBUTES_ENTRY_STATE_QSB;
+ }
+
return response;
}
diff --git a/quickstep/src/com/android/quickstep/util/ImageActionUtils.java b/quickstep/src/com/android/quickstep/util/ImageActionUtils.java
index 51a9915..63d5b0d 100644
--- a/quickstep/src/com/android/quickstep/util/ImageActionUtils.java
+++ b/quickstep/src/com/android/quickstep/util/ImageActionUtils.java
@@ -48,10 +48,10 @@
import androidx.core.content.FileProvider;
import com.android.internal.app.ChooserActivity;
+import com.android.internal.util.ScreenshotHelper;
import com.android.launcher3.BuildConfig;
import com.android.quickstep.SystemUiProxy;
import com.android.systemui.shared.recents.model.Task;
-import com.android.systemui.shared.recents.utilities.BitmapUtil;
import java.io.File;
import java.io.FileOutputStream;
@@ -77,7 +77,8 @@
public static void saveScreenshot(SystemUiProxy systemUiProxy, Bitmap screenshot,
Rect screenshotBounds,
Insets visibleInsets, Task.TaskKey task) {
- systemUiProxy.handleImageBundleAsScreenshot(BitmapUtil.hardwareBitmapToBundle(screenshot),
+ systemUiProxy.handleImageBundleAsScreenshot(
+ ScreenshotHelper.HardwareBitmapBundler.hardwareBitmapToBundle(screenshot),
screenshotBounds, visibleInsets, task);
}
diff --git a/quickstep/src/com/android/quickstep/util/LayoutUtils.java b/quickstep/src/com/android/quickstep/util/LayoutUtils.java
index 302526d..d0856be 100644
--- a/quickstep/src/com/android/quickstep/util/LayoutUtils.java
+++ b/quickstep/src/com/android/quickstep/util/LayoutUtils.java
@@ -22,8 +22,9 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.touch.PagedOrientationHandler;
+import com.android.launcher3.util.DisplayController;
+import com.android.launcher3.util.DisplayController.NavigationMode;
import com.android.quickstep.LauncherActivityInterface;
-import com.android.quickstep.SysUINavigationMode;
public class LayoutUtils {
@@ -32,7 +33,7 @@
*/
public static float getDefaultSwipeHeight(Context context, DeviceProfile dp) {
float swipeHeight = dp.allAppsCellHeightPx - dp.allAppsIconTextSizePx;
- if (SysUINavigationMode.getMode(context) == SysUINavigationMode.Mode.NO_BUTTON) {
+ if (DisplayController.getNavigationMode(context) == NavigationMode.NO_BUTTON) {
swipeHeight -= dp.getInsets().bottom;
}
return swipeHeight;
diff --git a/quickstep/src/com/android/quickstep/util/NavBarPosition.java b/quickstep/src/com/android/quickstep/util/NavBarPosition.java
index 449dba8..527a6d2 100644
--- a/quickstep/src/com/android/quickstep/util/NavBarPosition.java
+++ b/quickstep/src/com/android/quickstep/util/NavBarPosition.java
@@ -15,27 +15,27 @@
*/
package com.android.quickstep.util;
-import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
+import static com.android.launcher3.util.DisplayController.NavigationMode.NO_BUTTON;
import android.view.Surface;
import com.android.launcher3.util.DisplayController.Info;
-import com.android.quickstep.SysUINavigationMode;
+import com.android.launcher3.util.DisplayController.NavigationMode;
/**
* Utility class to check nav bar position.
*/
public class NavBarPosition {
- private final SysUINavigationMode.Mode mMode;
+ private final NavigationMode mMode;
private final int mDisplayRotation;
- public NavBarPosition(SysUINavigationMode.Mode mode, Info info) {
+ public NavBarPosition(NavigationMode mode, Info info) {
mMode = mode;
mDisplayRotation = info.rotation;
}
- public NavBarPosition(SysUINavigationMode.Mode mode, int displayRotation) {
+ public NavBarPosition(NavigationMode mode, int displayRotation) {
mMode = mode;
mDisplayRotation = displayRotation;
}
diff --git a/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java b/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java
index 54642a2..fb32581 100644
--- a/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java
+++ b/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java
@@ -21,7 +21,7 @@
import static com.android.launcher3.LauncherState.HINT_STATE;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
-import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
+import static com.android.launcher3.util.DisplayController.NavigationMode.NO_BUTTON;
import android.content.SharedPreferences;
@@ -34,8 +34,8 @@
import com.android.launcher3.statemanager.StateManager;
import com.android.launcher3.statemanager.StateManager.StateListener;
import com.android.launcher3.uioverrides.QuickstepLauncher;
+import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.OnboardingPrefs;
-import com.android.quickstep.SysUINavigationMode;
import com.android.quickstep.views.AllAppsEduView;
/**
@@ -51,8 +51,8 @@
stateManager.addStateListener(new StateListener<LauncherState>() {
@Override
public void onStateTransitionComplete(LauncherState finalState) {
- boolean swipeUpEnabled = SysUINavigationMode.INSTANCE
- .get(mLauncher).getMode().hasGestures;
+ boolean swipeUpEnabled =
+ DisplayController.getNavigationMode(mLauncher).hasGestures;
LauncherState prevState = stateManager.getLastState();
if (((swipeUpEnabled && finalState == OVERVIEW) || (!swipeUpEnabled
@@ -88,7 +88,7 @@
});
}
- if (SysUINavigationMode.getMode(launcher) == NO_BUTTON
+ if (DisplayController.getNavigationMode(launcher) == NO_BUTTON
&& FeatureFlags.ENABLE_ALL_APPS_EDU.get()) {
stateManager.addStateListener(new StateListener<LauncherState>() {
private static final int MAX_NUM_SWIPES_TO_TRIGGER_EDU = 3;
diff --git a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
index 6a3286b..0fa2b24 100644
--- a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
+++ b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
@@ -16,7 +16,7 @@
package com.android.quickstep.views;
-import static com.android.quickstep.SysUINavigationMode.Mode.THREE_BUTTONS;
+import static com.android.launcher3.util.DisplayController.NavigationMode.THREE_BUTTONS;
import android.content.Context;
import android.content.res.Configuration;
@@ -36,10 +36,10 @@
import com.android.launcher3.Insettable;
import com.android.launcher3.R;
import com.android.launcher3.uioverrides.ApiWrapper;
+import com.android.launcher3.util.DisplayController;
+import com.android.launcher3.util.DisplayController.NavigationMode;
import com.android.launcher3.util.MultiValueAlpha;
import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
-import com.android.quickstep.SysUINavigationMode;
-import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.quickstep.TaskOverlayFactory.OverlayUICallbacks;
import com.android.quickstep.util.LayoutUtils;
@@ -148,13 +148,13 @@
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
- updateVerticalMargin(SysUINavigationMode.getMode(getContext()));
+ updateVerticalMargin(DisplayController.getNavigationMode(getContext()));
}
@Override
public void setInsets(Rect insets) {
mInsets.set(insets);
- updateVerticalMargin(SysUINavigationMode.getMode(getContext()));
+ updateVerticalMargin(DisplayController.getNavigationMode(getContext()));
updatePaddingAndTranslations();
}
@@ -204,7 +204,7 @@
*/
private void updatePaddingAndTranslations() {
boolean alignFor3ButtonTaskbar = mDp.isTaskbarPresent &&
- SysUINavigationMode.getMode(getContext()) == THREE_BUTTONS;
+ DisplayController.getNavigationMode(getContext()) == THREE_BUTTONS;
if (alignFor3ButtonTaskbar) {
// Add extra horizontal spacing
int additionalPadding = ApiWrapper.getHotseatEndOffset(getContext());
@@ -218,7 +218,7 @@
// the button nav top is.
View startActionView = findViewById(R.id.action_screenshot);
int marginBottom = getOverviewActionsBottomMarginPx(
- SysUINavigationMode.getMode(getContext()), mDp);
+ DisplayController.getNavigationMode(getContext()), mDp);
int actionsTop =
(mDp.heightPx - marginBottom - mInsets.bottom) - startActionView.getHeight();
int navTop = mDp.heightPx - (mDp.taskbarSize + mDp.getTaskbarOffsetY());
@@ -233,7 +233,7 @@
}
/** Updates vertical margins for different navigation mode or configuration changes. */
- public void updateVerticalMargin(Mode mode) {
+ public void updateVerticalMargin(NavigationMode mode) {
if (mDp == null) {
return;
}
@@ -249,7 +249,7 @@
*/
public void setDp(DeviceProfile dp) {
mDp = dp;
- updateVerticalMargin(SysUINavigationMode.getMode(getContext()));
+ updateVerticalMargin(DisplayController.getNavigationMode(getContext()));
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
dp.isVerticalBarLayout() ? 0 : dp.overviewActionsButtonSpacing,
@@ -274,14 +274,13 @@
}
/** Get the top margin associated with the action buttons in Overview. */
- public static int getOverviewActionsTopMarginPx(
- SysUINavigationMode.Mode mode, DeviceProfile dp) {
+ public static int getOverviewActionsTopMarginPx(NavigationMode mode, DeviceProfile dp) {
// In vertical bar, use the smaller task margin for the top regardless of mode
if (dp.isVerticalBarLayout()) {
return dp.overviewTaskMarginPx;
}
- if (mode == SysUINavigationMode.Mode.THREE_BUTTONS) {
+ if (mode == NavigationMode.THREE_BUTTONS) {
return dp.overviewActionsMarginThreeButtonPx;
}
@@ -289,8 +288,7 @@
}
/** Get the bottom margin associated with the action buttons in Overview. */
- public static int getOverviewActionsBottomMarginPx(
- SysUINavigationMode.Mode mode, DeviceProfile dp) {
+ public static int getOverviewActionsBottomMarginPx(NavigationMode mode, DeviceProfile dp) {
int inset = dp.getInsets().bottom;
if (dp.isVerticalBarLayout()) {
@@ -298,7 +296,7 @@
}
// Actions button will be aligned with nav buttons in updatePaddingAndTranslations().
- if (mode == SysUINavigationMode.Mode.THREE_BUTTONS) {
+ if (mode == NavigationMode.THREE_BUTTONS) {
return dp.overviewActionsMarginThreeButtonPx + inset;
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 984b0ef..1d621dc 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -725,7 +725,8 @@
TestLogging.recordEvent(
TestProtocol.SEQUENCE_MAIN, "startActivityFromRecentsAsync", mTask);
ActivityOptionsWrapper opts = mActivity.getActivityLaunchOptions(this, null);
- opts.options.setLaunchDisplayId(getRootViewDisplayId());
+ opts.options.setLaunchDisplayId(
+ getDisplay() == null ? DEFAULT_DISPLAY : getDisplay().getDisplayId());
if (ActivityManagerWrapper.getInstance()
.startActivityFromRecents(mTask.key, opts.options)) {
RecentsView recentsView = getRecentsView();
@@ -766,7 +767,8 @@
// Indicate success once the system has indicated that the transition has started
ActivityOptions opts = ActivityOptionsCompat.makeCustomAnimation(
getContext(), 0, 0, () -> callback.accept(true), MAIN_EXECUTOR.getHandler());
- opts.setLaunchDisplayId(getRootViewDisplayId());
+ opts.setLaunchDisplayId(
+ getDisplay() == null ? DEFAULT_DISPLAY : getDisplay().getDisplayId());
if (freezeTaskList) {
ActivityOptionsCompat.setFreezeRecentTasksList(opts);
}
diff --git a/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java b/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java
index fb7fda1..09f0858 100644
--- a/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java
+++ b/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java
@@ -36,7 +36,7 @@
*/
public abstract class AbstractQuickStepTest extends AbstractLauncherUiTest {
static final boolean ENABLE_SHELL_TRANSITIONS =
- SystemProperties.getBoolean("persist.debug.shell_transit", false);
+ SystemProperties.getBoolean("persist.wm.debug.shell_transit", false);
@Override
protected TestRule getRulesInsideActivityMonitor() {
return RuleChain.
diff --git a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
index 9a39b34..4529217 100644
--- a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
+++ b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
@@ -42,7 +42,6 @@
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.os.RemoteException;
-import android.platform.test.rule.CrashDetector;
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;
@@ -106,8 +105,7 @@
}
mOrderSensitiveRules = RuleChain
- .outerRule(new CrashDetector("com.android.systemui"))
- .around(new NavigationModeSwitchRule(mLauncher))
+ .outerRule(new NavigationModeSwitchRule(mLauncher))
.around(new FailureWatcher(mDevice, mLauncher));
mOtherLauncherActivity = context.getPackageManager().queryIntentActivities(
diff --git a/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java b/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java
index 1cb7529..e5e2cf3 100644
--- a/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java
+++ b/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java
@@ -33,6 +33,7 @@
import com.android.launcher3.tapl.LauncherInstrumentation;
import com.android.launcher3.tapl.TestHelpers;
import com.android.launcher3.ui.AbstractLauncherUiTest;
+import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.Wait;
import com.android.launcher3.util.rule.FailureWatcher;
import com.android.systemui.shared.system.QuickStepContract;
@@ -71,8 +72,8 @@
private final LauncherInstrumentation mLauncher;
- static final SysUINavigationMode SYS_UI_NAVIGATION_MODE =
- SysUINavigationMode.INSTANCE.get(getInstrumentation().getTargetContext());
+ static final DisplayController DISPLAY_CONTROLLER =
+ DisplayController.INSTANCE.get(getInstrumentation().getTargetContext());
public NavigationModeSwitchRule(LauncherInstrumentation launcher) {
mLauncher = launcher;
@@ -138,7 +139,7 @@
private static LauncherInstrumentation.NavigationModel currentSysUiNavigationMode() {
return LauncherInstrumentation.getNavigationModel(
- SysUINavigationMode.getMode(
+ DisplayController.getNavigationMode(
getInstrumentation().
getTargetContext()).
resValue);
@@ -159,18 +160,18 @@
if (currentSysUiNavigationMode() != expectedMode) {
final CountDownLatch latch = new CountDownLatch(1);
final Context targetContext = getInstrumentation().getTargetContext();
- final SysUINavigationMode.NavigationModeChangeListener listener =
- newMode -> {
- if (LauncherInstrumentation.getNavigationModel(newMode.resValue)
+ final DisplayController.DisplayInfoChangeListener listener =
+ (context, info, flags) -> {
+ if (LauncherInstrumentation.getNavigationModel(info.navigationMode.resValue)
== expectedMode) {
latch.countDown();
}
};
targetContext.getMainExecutor().execute(() ->
- SYS_UI_NAVIGATION_MODE.addModeChangeListener(listener));
+ DISPLAY_CONTROLLER.addChangeListener(listener));
latch.await(60, TimeUnit.SECONDS);
targetContext.getMainExecutor().execute(() ->
- SYS_UI_NAVIGATION_MODE.removeModeChangeListener(listener));
+ DISPLAY_CONTROLLER.removeChangeListener(listener));
assertTrue(launcher, "Navigation mode didn't change to " + expectedMode,
currentSysUiNavigationMode() == expectedMode, description);
diff --git a/quickstep/tests/src/com/android/quickstep/OrientationTouchTransformerTest.java b/quickstep/tests/src/com/android/quickstep/OrientationTouchTransformerTest.java
index 159a51f..6b3f699 100644
--- a/quickstep/tests/src/com/android/quickstep/OrientationTouchTransformerTest.java
+++ b/quickstep/tests/src/com/android/quickstep/OrientationTouchTransformerTest.java
@@ -21,7 +21,7 @@
import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
-import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
+import static com.android.launcher3.util.DisplayController.NavigationMode.NO_BUTTON;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
diff --git a/quickstep/tests/src/com/android/quickstep/util/TaskViewSimulatorTest.java b/quickstep/tests/src/com/android/quickstep/util/TaskViewSimulatorTest.java
index 9c5cfcd..6dc9f8d 100644
--- a/quickstep/tests/src/com/android/quickstep/util/TaskViewSimulatorTest.java
+++ b/quickstep/tests/src/com/android/quickstep/util/TaskViewSimulatorTest.java
@@ -39,7 +39,6 @@
import com.android.launcher3.util.LauncherModelHelper;
import com.android.launcher3.util.ReflectionHelpers;
import com.android.quickstep.FallbackActivityInterface;
-import com.android.quickstep.SysUINavigationMode;
import com.android.quickstep.SystemUiProxy;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;
@@ -143,7 +142,6 @@
LauncherModelHelper helper = new LauncherModelHelper();
try {
helper.sandboxContext.allow(SystemUiProxy.INSTANCE);
- helper.sandboxContext.allow(SysUINavigationMode.INSTANCE);
Display display = mock(Display.class);
doReturn(DEFAULT_DISPLAY).when(display).getDisplayId();
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 99a337e..620eb7b 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -152,6 +152,9 @@
<!-- numHotseatIcons defaults to numColumns, if not specified -->
<attr name="numHotseatIcons" format="integer" />
+ <!-- Number of icons to use when shrinking the hotseat size,
+ defaults to numHotseatIcons / 2 -->
+ <attr name="numShrunkenHotseatIcons" format="integer" />
<!-- Number of icons to use when extending the hotseat size,
defaults to 2 * numHotseatIcons -->
<attr name="numExtendedHotseatIcons" format="integer" />
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 97c0f38..cd9bbf7 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -34,7 +34,6 @@
import com.android.launcher3.CellLayout.ContainerType;
import com.android.launcher3.DevicePaddings.DevicePadding;
-import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.icons.DotRenderer;
import com.android.launcher3.icons.GraphicsUtils;
import com.android.launcher3.icons.IconNormalizer;
@@ -59,6 +58,7 @@
// Device properties
public final boolean isTablet;
+ public final boolean isLargeTablet;
public final boolean isPhone;
public final boolean transposeLayoutWithOrientation;
public final boolean isTwoPanels;
@@ -67,6 +67,7 @@
// Device properties in current orientation
public final boolean isLandscape;
public final boolean isMultiWindowMode;
+ public final boolean isGestureMode;
public final int windowX;
public final int windowY;
@@ -229,12 +230,13 @@
/** TODO: Once we fully migrate to staged split, remove "isMultiWindowMode" */
DeviceProfile(Context context, InvariantDeviceProfile inv, Info info, WindowBounds windowBounds,
boolean isMultiWindowMode, boolean transposeLayoutWithOrientation,
- boolean useTwoPanels) {
+ boolean useTwoPanels, boolean isGestureMode) {
this.inv = inv;
this.isLandscape = windowBounds.isLandscape();
this.isMultiWindowMode = isMultiWindowMode;
this.transposeLayoutWithOrientation = transposeLayoutWithOrientation;
+ this.isGestureMode = isGestureMode;
windowX = windowBounds.bounds.left;
windowY = windowBounds.bounds.top;
@@ -243,6 +245,7 @@
// Determine device posture.
mInfo = info;
isTablet = info.isTablet(windowBounds);
+ isLargeTablet = info.isLargeTablet(windowBounds);
isPhone = !isTablet;
isTwoPanels = isTablet && useTwoPanels;
isTaskbarPresent = isTablet && ApiWrapper.TASKBAR_DRAWN_IN_PROCESS;
@@ -343,9 +346,15 @@
workspaceCellPaddingXPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_cell_padding_x);
hotseatQsbHeight = res.getDimensionPixelSize(R.dimen.qsb_widget_height);
- isQsbInline = isTablet && isLandscape && !isTwoPanels && hotseatQsbHeight > 0;
- numShownHotseatIcons =
- isTwoPanels ? inv.numDatabaseHotseatIcons : inv.numShownHotseatIcons;
+ isQsbInline = isLargeTablet && isLandscape && hotseatQsbHeight > 0;
+
+ if (isTaskbarPresent && !isGestureMode && isQsbInline) {
+ numShownHotseatIcons = inv.numShrunkenHotseatIcons;
+ } else {
+ numShownHotseatIcons =
+ isTwoPanels ? inv.numDatabaseHotseatIcons : inv.numShownHotseatIcons;
+ }
+
numShownAllAppsColumns =
isTwoPanels ? inv.numDatabaseAllAppsColumns : inv.numAllAppsColumns;
hotseatBarSizeExtraSpacePx = 0;
@@ -540,7 +549,8 @@
return new Builder(context, inv, mInfo)
.setWindowBounds(bounds)
.setUseTwoPanels(isTwoPanels)
- .setMultiWindowMode(isMultiWindowMode);
+ .setMultiWindowMode(isMultiWindowMode)
+ .setGestureMode(isGestureMode);
}
public DeviceProfile copy(Context context) {
@@ -1081,9 +1091,11 @@
writer.println(prefix + "\t1 dp = " + mMetrics.density + " px");
writer.println(prefix + "\tisTablet:" + isTablet);
+ writer.println(prefix + "\tisLargeTablet:" + isLargeTablet);
writer.println(prefix + "\tisPhone:" + isPhone);
writer.println(prefix + "\ttransposeLayoutWithOrientation:"
+ transposeLayoutWithOrientation);
+ writer.println(prefix + "\tisGestureMode:" + isGestureMode);
writer.println(prefix + "\tisLandscape:" + isLandscape);
writer.println(prefix + "\tisMultiWindowMode:" + isMultiWindowMode);
@@ -1266,6 +1278,7 @@
private boolean mIsMultiWindowMode = false;
private Boolean mTransposeLayoutWithOrientation;
+ private Boolean mIsGestureMode;
public Builder(Context context, InvariantDeviceProfile inv, Info info) {
mContext = context;
@@ -1294,6 +1307,11 @@
return this;
}
+ public Builder setGestureMode(boolean isGestureMode) {
+ mIsGestureMode = isGestureMode;
+ return this;
+ }
+
public DeviceProfile build() {
if (mWindowBounds == null) {
throw new IllegalArgumentException("Window bounds not set");
@@ -1301,8 +1319,11 @@
if (mTransposeLayoutWithOrientation == null) {
mTransposeLayoutWithOrientation = !mInfo.isTablet(mWindowBounds);
}
- return new DeviceProfile(mContext, mInv, mInfo, mWindowBounds,
- mIsMultiWindowMode, mTransposeLayoutWithOrientation, mUseTwoPanels);
+ if (mIsGestureMode == null) {
+ mIsGestureMode = DisplayController.getNavigationMode(mContext).hasGestures;
+ }
+ return new DeviceProfile(mContext, mInv, mInfo, mWindowBounds, mIsMultiWindowMode,
+ mTransposeLayoutWithOrientation, mUseTwoPanels, mIsGestureMode);
}
}
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index dfe4bb0..886c657 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -19,6 +19,7 @@
import static com.android.launcher3.Utilities.dpiFromPx;
import static com.android.launcher3.config.FeatureFlags.ENABLE_TWO_PANEL_HOME;
import static com.android.launcher3.util.DisplayController.CHANGE_DENSITY;
+import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE;
import static com.android.launcher3.util.DisplayController.CHANGE_SUPPORTED_BOUNDS;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
@@ -138,6 +139,11 @@
public int numShownHotseatIcons;
/**
+ * Number of icons inside the hotseat area when using 3 buttons navigation.
+ */
+ public int numShrunkenHotseatIcons;
+
+ /**
* Number of icons inside the hotseat area that is stored in the database. This is greater than
* or equal to numnShownHotseatIcons, allowing for a seamless transition between two hotseat
* sizes that share the same DB.
@@ -188,7 +194,8 @@
DisplayController.INSTANCE.get(context).setPriorityListener(
(displayContext, info, flags) -> {
- if ((flags & (CHANGE_DENSITY | CHANGE_SUPPORTED_BOUNDS)) != 0) {
+ if ((flags & (CHANGE_DENSITY | CHANGE_SUPPORTED_BOUNDS
+ | CHANGE_NAVIGATION_MODE)) != 0) {
onConfigChanged(displayContext);
}
});
@@ -336,6 +343,7 @@
horizontalMargin = displayOption.horizontalMargin;
numShownHotseatIcons = closestProfile.numHotseatIcons;
+ numShrunkenHotseatIcons = closestProfile.numShrunkenHotseatIcons;
numDatabaseHotseatIcons = deviceType == TYPE_MULTI_DISPLAY
? closestProfile.numDatabaseHotseatIcons : closestProfile.numHotseatIcons;
hotseatBorderSpaces = displayOption.hotseatBorderSpaces;
@@ -365,7 +373,8 @@
for (WindowBounds bounds : displayInfo.supportedBounds) {
localSupportedProfiles.add(new DeviceProfile.Builder(context, this, displayInfo)
.setUseTwoPanels(deviceType == TYPE_MULTI_DISPLAY)
- .setWindowBounds(bounds).build());
+ .setWindowBounds(bounds)
+ .build());
// Wallpaper size should be the maximum of the all possible sizes Launcher expects
int displayWidth = bounds.bounds.width();
@@ -691,6 +700,7 @@
private final int numAllAppsColumns;
private final int numDatabaseAllAppsColumns;
private final int numHotseatIcons;
+ private final int numShrunkenHotseatIcons;
private final int numDatabaseHotseatIcons;
private final String dbFile;
@@ -727,6 +737,8 @@
numHotseatIcons = a.getInt(
R.styleable.GridDisplayOption_numHotseatIcons, numColumns);
+ numShrunkenHotseatIcons = a.getInt(
+ R.styleable.GridDisplayOption_numShrunkenHotseatIcons, numHotseatIcons / 2);
numDatabaseHotseatIcons = a.getInt(
R.styleable.GridDisplayOption_numExtendedHotseatIcons, 2 * numHotseatIcons);
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 8fb2f53..5c5aee5 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -3192,4 +3192,15 @@
public ArrowPopup<?> getOptionsPopup() {
return findViewById(R.id.popup_container);
}
+
+ /** 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.
+ getWorkspace().getPageIndicator().pauseAnimations();
+ }
+
+ /** Resumes view updates at the end of the app launch animation. */
+ public void resumeExpensiveViewUpdates() {
+ getWorkspace().getPageIndicator().skipAnimationsToEnd();
+ }
}
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 3458ed1..278bcf2 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -103,6 +103,9 @@
"USE_FALLBACK_APP_SEARCH", false,
"Use fallback launcher app search results instead of AiAi app results");
+ public static final BooleanFlag ENABLE_QUICK_SEARCH = new DeviceFlag("ENABLE_QUICK_SEARCH",
+ true, "Use quick search behavior.");
+
public static final BooleanFlag COLLECT_SEARCH_HISTORY = new DeviceFlag(
"COLLECT_SEARCH_HISTORY", false, "Allow launcher to collect search history for log");
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index 0d2bc37..0c1ba8b 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -562,7 +562,7 @@
}
/**
- * Helps to construct and write the log message.
+ * Helps to construct and log launcher event.
*/
public interface StatsLogger {
@@ -662,6 +662,64 @@
}
/**
+ * Helps to construct and log latency event.
+ */
+ public interface StatsLatencyLogger {
+
+ enum LatencyType {
+ UNKNOWN(0),
+ COLD(1),
+ HOT(2);
+
+ private final int mId;
+
+ LatencyType(int id) {
+ this.mId = id;
+ }
+
+ public int getId() {
+ return mId;
+ }
+
+ }
+
+ /**
+ * Sets {@link InstanceId} of log message.
+ */
+ default StatsLatencyLogger withInstanceId(InstanceId instanceId) {
+ return this;
+ }
+
+
+ /**
+ * Sets latency of the event.
+ */
+ default StatsLatencyLogger withLatency(long latencyInMillis) {
+ return this;
+ }
+
+ /**
+ * Sets {@link LatencyType} of log message.
+ */
+ default StatsLatencyLogger withType(LatencyType type) {
+ return this;
+ }
+
+ /**
+ * Sets packageId of log message.
+ */
+ default StatsLatencyLogger withPackageId(int packageId) {
+ return this;
+ }
+
+ /**
+ * Builds the final message and logs it as {@link EventEnum}.
+ */
+ default void log(EventEnum event) {
+ }
+ }
+
+ /**
* Returns new logger object.
*/
public StatsLogger logger() {
@@ -672,11 +730,27 @@
return logger;
}
+ /**
+ * Returns new latency logger object.
+ */
+ public StatsLatencyLogger latencyLogger() {
+ StatsLatencyLogger logger = createLatencyLogger();
+ if (mInstanceId != null) {
+ logger.withInstanceId(mInstanceId);
+ }
+ return logger;
+ }
+
protected StatsLogger createLogger() {
return new StatsLogger() {
};
}
+ protected StatsLatencyLogger createLatencyLogger() {
+ return new StatsLatencyLogger() {
+ };
+ }
+
/**
* Sets InstanceId to every new {@link StatsLogger} object returned by {@link #logger()} when
* not-null.
diff --git a/src/com/android/launcher3/model/data/FolderInfo.java b/src/com/android/launcher3/model/data/FolderInfo.java
index cd2ef35..efebce3 100644
--- a/src/com/android/launcher3/model/data/FolderInfo.java
+++ b/src/com/android/launcher3/model/data/FolderInfo.java
@@ -217,7 +217,7 @@
return getDefaultItemInfoBuilder()
.setFolderIcon(folderIcon)
.setRank(rank)
- .setAttribute(getLabelState().mLogAttribute)
+ .addItemAttributes(getLabelState().mLogAttribute)
.setContainerInfo(getContainerInfo())
.build();
}
diff --git a/src/com/android/launcher3/model/data/LauncherAppWidgetInfo.java b/src/com/android/launcher3/model/data/LauncherAppWidgetInfo.java
index 0283d5f..e57a895 100644
--- a/src/com/android/launcher3/model/data/LauncherAppWidgetInfo.java
+++ b/src/com/android/launcher3/model/data/LauncherAppWidgetInfo.java
@@ -288,7 +288,7 @@
LauncherAtom.ItemInfo info = super.buildProto(folderInfo);
return info.toBuilder()
.setWidget(info.getWidget().toBuilder().setWidgetFeatures(widgetFeatures))
- .setAttribute(getAttribute(sourceContainer))
+ .addItemAttributes(getAttribute(sourceContainer))
.build();
}
}
diff --git a/src/com/android/launcher3/util/DisplayController.java b/src/com/android/launcher3/util/DisplayController.java
index 7963401..f944d3c 100644
--- a/src/com/android/launcher3/util/DisplayController.java
+++ b/src/com/android/launcher3/util/DisplayController.java
@@ -15,11 +15,18 @@
*/
package com.android.launcher3.util;
+import static android.content.Intent.ACTION_CONFIGURATION_CHANGED;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
+import static com.android.launcher3.ResourceUtils.INVALID_RESOURCE_HANDLE;
import static com.android.launcher3.Utilities.dpiFromPx;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NAVIGATION_MODE_2_BUTTON;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NAVIGATION_MODE_3_BUTTON;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NAVIGATION_MODE_GESTURE_BUTTON;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import static com.android.launcher3.util.PackageManagerHelper.getPackageFilter;
+import static com.android.launcher3.util.WindowManagerCompat.MIN_LARGE_TABLET_WIDTH;
import static com.android.launcher3.util.WindowManagerCompat.MIN_TABLET_WIDTH;
import static java.util.Collections.emptyMap;
@@ -29,7 +36,6 @@
import android.content.ComponentCallbacks;
import android.content.Context;
import android.content.Intent;
-import android.content.IntentFilter;
import android.content.res.Configuration;
import android.graphics.Point;
import android.hardware.display.DisplayManager;
@@ -43,9 +49,12 @@
import androidx.annotation.AnyThread;
import androidx.annotation.UiThread;
+import com.android.launcher3.ResourceUtils;
import com.android.launcher3.Utilities;
+import com.android.launcher3.logging.StatsLogManager.LauncherEvent;
import com.android.launcher3.uioverrides.ApiWrapper;
+import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Map;
import java.util.Objects;
@@ -66,9 +75,14 @@
public static final int CHANGE_ROTATION = 1 << 1;
public static final int CHANGE_DENSITY = 1 << 2;
public static final int CHANGE_SUPPORTED_BOUNDS = 1 << 3;
+ public static final int CHANGE_NAVIGATION_MODE = 1 << 4;
public static final int CHANGE_ALL = CHANGE_ACTIVE_SCREEN | CHANGE_ROTATION
- | CHANGE_DENSITY | CHANGE_SUPPORTED_BOUNDS;
+ | CHANGE_DENSITY | CHANGE_SUPPORTED_BOUNDS | CHANGE_NAVIGATION_MODE;
+
+ private static final String ACTION_OVERLAY_CHANGED = "android.intent.action.OVERLAY_CHANGED";
+ private static final String NAV_BAR_INTERACTION_MODE_RES_NAME = "config_navBarInteractionMode";
+ private static final String TARGET_OVERLAY_PACKAGE = "android";
private final Context mContext;
private final DisplayManager mDM;
@@ -79,6 +93,8 @@
private DisplayInfoChangeListener mPriorityListener;
private final ArrayList<DisplayInfoChangeListener> mListeners = new ArrayList<>();
+ private final SimpleBroadcastReceiver mReceiver = new SimpleBroadcastReceiver(this::onIntent);
+
private Info mInfo;
private boolean mDestroyed = false;
@@ -92,11 +108,13 @@
mWindowContext.registerComponentCallbacks(this);
} else {
mWindowContext = null;
- SimpleBroadcastReceiver configChangeReceiver =
- new SimpleBroadcastReceiver(this::onConfigChanged);
- mContext.registerReceiver(configChangeReceiver,
- new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED));
+ mReceiver.register(mContext, ACTION_CONFIGURATION_CHANGED);
}
+
+ // Initialize navigation mode change listener
+ mContext.registerReceiver(mReceiver,
+ getPackageFilter(TARGET_OVERLAY_PACKAGE, ACTION_OVERLAY_CHANGED));
+
mInfo = new Info(getDisplayInfoContext(display), display,
getInternalDisplays(mDM), emptyMap());
}
@@ -116,6 +134,13 @@
return internalDisplays;
}
+ /**
+ * Returns the current navigation mode
+ */
+ public static NavigationMode getNavigationMode(Context context) {
+ return INSTANCE.get(context).getInfo().navigationMode;
+ }
+
@Override
public void close() {
mDestroyed = true;
@@ -140,15 +165,20 @@
void onDisplayInfoChanged(Context context, Info info, int flags);
}
- /**
- * Only used for pre-S
- */
- private void onConfigChanged(Intent intent) {
+ private void onIntent(Intent intent) {
if (mDestroyed) {
return;
}
- Configuration config = mContext.getResources().getConfiguration();
- if (mInfo.fontScale != config.fontScale || mInfo.densityDpi != config.densityDpi) {
+ boolean reconfigure = false;
+ if (ACTION_OVERLAY_CHANGED.equals(intent.getAction())) {
+ reconfigure = true;
+ } else if (ACTION_CONFIGURATION_CHANGED.equals(intent.getAction())) {
+ Configuration config = mContext.getResources().getConfiguration();
+ reconfigure = mInfo.fontScale != config.fontScale
+ || mInfo.densityDpi != config.densityDpi;
+ }
+
+ if (reconfigure) {
Log.d(TAG, "Configuration changed, notifying listeners");
Display display = mDM.getDisplay(DEFAULT_DISPLAY);
if (display != null) {
@@ -202,7 +232,8 @@
Info newInfo = new Info(displayContext, display,
oldInfo.mInternalDisplays, oldInfo.mPerDisplayBounds);
- if (newInfo.densityDpi != oldInfo.densityDpi || newInfo.fontScale != oldInfo.fontScale) {
+ if (newInfo.densityDpi != oldInfo.densityDpi || newInfo.fontScale != oldInfo.fontScale
+ || newInfo.navigationMode != oldInfo.navigationMode) {
// Cache may not be valid anymore, recreate without cache
newInfo = new Info(displayContext, display, getInternalDisplays(mDM), emptyMap());
}
@@ -217,6 +248,9 @@
if (newInfo.densityDpi != oldInfo.densityDpi || newInfo.fontScale != oldInfo.fontScale) {
change |= CHANGE_DENSITY;
}
+ if (newInfo.navigationMode != oldInfo.navigationMode) {
+ change |= CHANGE_NAVIGATION_MODE;
+ }
if (!newInfo.supportedBounds.equals(oldInfo.supportedBounds)) {
change |= CHANGE_SUPPORTED_BOUNDS;
@@ -247,7 +281,9 @@
if (mPriorityListener != null) {
mPriorityListener.onDisplayInfoChanged(context, mInfo, flags);
}
- for (int i = mListeners.size() - 1; i >= 0; i--) {
+
+ int count = mListeners.size();
+ for (int i = 0; i < count; i++) {
mListeners.get(i).onDisplayInfoChanged(context, mInfo, flags);
}
}
@@ -258,6 +294,7 @@
public final int rotation;
public final float fontScale;
public final int densityDpi;
+ public final NavigationMode navigationMode;
private final PortraitSize mScreenSizeDp;
@@ -282,6 +319,7 @@
fontScale = config.fontScale;
densityDpi = config.densityDpi;
mScreenSizeDp = new PortraitSize(config.screenHeightDp, config.screenWidthDp);
+ navigationMode = parseNavigationMode(context);
currentSize = new Point();
display.getRealSize(currentSize);
@@ -332,12 +370,35 @@
}
/**
- * Returns true if the bounds represent a tablet
+ * Returns {@code true} if the bounds represent a tablet.
*/
public boolean isTablet(WindowBounds bounds) {
return dpiFromPx(Math.min(bounds.bounds.width(), bounds.bounds.height()),
densityDpi) >= MIN_TABLET_WIDTH;
}
+
+ /**
+ * Returns {@code true} if the bounds represent a large tablet.
+ */
+ public boolean isLargeTablet(WindowBounds bounds) {
+ return dpiFromPx(Math.min(bounds.bounds.width(), bounds.bounds.height()),
+ densityDpi) >= MIN_LARGE_TABLET_WIDTH;
+ }
+ }
+
+ /**
+ * Dumps the current state information
+ */
+ public void dump(PrintWriter pw) {
+ Info info = mInfo;
+ pw.println("DisplayController.Info:");
+ pw.println(" id=" + info.displayId);
+ pw.println(" rotation=" + info.rotation);
+ pw.println(" fontScale=" + info.fontScale);
+ pw.println(" densityDpi=" + info.displayId);
+ pw.println(" navigationMode=" + info.navigationMode.name());
+ pw.println(" currentSize=" + info.currentSize);
+ pw.println(" supportedBounds=" + info.supportedBounds);
}
/**
@@ -364,4 +425,36 @@
return Objects.hash(width, height);
}
}
+
+ public enum NavigationMode {
+ THREE_BUTTONS(false, 0, LAUNCHER_NAVIGATION_MODE_3_BUTTON),
+ TWO_BUTTONS(true, 1, LAUNCHER_NAVIGATION_MODE_2_BUTTON),
+ NO_BUTTON(true, 2, LAUNCHER_NAVIGATION_MODE_GESTURE_BUTTON);
+
+ public final boolean hasGestures;
+ public final int resValue;
+ public final LauncherEvent launcherEvent;
+
+ NavigationMode(boolean hasGestures, int resValue, LauncherEvent launcherEvent) {
+ this.hasGestures = hasGestures;
+ this.resValue = resValue;
+ this.launcherEvent = launcherEvent;
+ }
+ }
+
+ private static NavigationMode parseNavigationMode(Context context) {
+ int modeInt = ResourceUtils.getIntegerByName(NAV_BAR_INTERACTION_MODE_RES_NAME,
+ context.getResources(), INVALID_RESOURCE_HANDLE);
+
+ if (modeInt == INVALID_RESOURCE_HANDLE) {
+ Log.e(TAG, "Failed to get system resource ID. Incompatible framework version?");
+ } else {
+ for (NavigationMode m : NavigationMode.values()) {
+ if (m.resValue == modeInt) {
+ return m;
+ }
+ }
+ }
+ return Utilities.ATLEAST_S ? NavigationMode.NO_BUTTON : NavigationMode.THREE_BUTTONS;
+ }
}
diff --git a/src/com/android/launcher3/util/WindowManagerCompat.java b/src/com/android/launcher3/util/WindowManagerCompat.java
index e1b9478..873a518 100644
--- a/src/com/android/launcher3/util/WindowManagerCompat.java
+++ b/src/com/android/launcher3/util/WindowManagerCompat.java
@@ -45,6 +45,7 @@
public class WindowManagerCompat {
public static final int MIN_TABLET_WIDTH = 600;
+ public static final int MIN_LARGE_TABLET_WIDTH = 720;
/**
* Returns a set of supported render sizes for a internal display.
diff --git a/src/com/android/launcher3/views/BubbleTextHolder.java b/src/com/android/launcher3/views/BubbleTextHolder.java
index 1cb27e1..76c465c 100644
--- a/src/com/android/launcher3/views/BubbleTextHolder.java
+++ b/src/com/android/launcher3/views/BubbleTextHolder.java
@@ -22,7 +22,7 @@
/**
* Views that contain {@link BubbleTextView} should implement this interface.
*/
-public interface BubbleTextHolder {
+public interface BubbleTextHolder extends IconLabelDotView {
BubbleTextView getBubbleText();
/**
@@ -32,4 +32,14 @@
*/
default void onItemInfoUpdated(ItemInfoWithIcon itemInfo) {
}
+
+ @Override
+ default void setIconVisible(boolean visible) {
+ getBubbleText().setIconVisible(visible);
+ }
+
+ @Override
+ default void setForceHideDot(boolean hide) {
+ getBubbleText().setForceHideDot(hide);
+ }
}
diff --git a/src/com/android/launcher3/views/ClipIconView.java b/src/com/android/launcher3/views/ClipIconView.java
index a66b3f9..d1f90e9 100644
--- a/src/com/android/launcher3/views/ClipIconView.java
+++ b/src/com/android/launcher3/views/ClipIconView.java
@@ -147,8 +147,7 @@
* Update the icon UI to match the provided parameters during an animation frame
*/
public void update(RectF rect, float progress, float shapeProgressStart, float cornerRadius,
- int fgIconAlpha, boolean isOpening, View container, DeviceProfile dp,
- boolean isVerticalBarLayout) {
+ int fgIconAlpha, boolean isOpening, View container, DeviceProfile dp) {
MarginLayoutParams lp = (MarginLayoutParams) container.getLayoutParams();
float dX = mIsRtl
@@ -169,7 +168,7 @@
}
update(rect, progress, shapeProgressStart, cornerRadius, fgIconAlpha, isOpening, scale,
- minSize, lp, isVerticalBarLayout, dp);
+ minSize, lp, dp);
container.setPivotX(0);
container.setPivotY(0);
@@ -181,7 +180,7 @@
private void update(RectF rect, float progress, float shapeProgressStart, float cornerRadius,
int fgIconAlpha, boolean isOpening, float scale, float minSize,
- MarginLayoutParams parentLp, boolean isVerticalBarLayout, DeviceProfile dp) {
+ MarginLayoutParams parentLp, DeviceProfile dp) {
float dX = mIsRtl
? rect.left - (dp.widthPx - parentLp.getMarginStart() - parentLp.width)
: rect.left - parentLp.getMarginStart();
@@ -193,7 +192,7 @@
float shapeRevealProgress = boundToRange(mapToRange(max(shapeProgressStart, progress),
shapeProgressStart, 1f, 0, toMax, LINEAR), 0, 1);
- if (isVerticalBarLayout) {
+ if (dp.isLandscape) {
mOutline.right = (int) (rect.width() / scale);
} else {
mOutline.bottom = (int) (rect.height() / scale);
@@ -218,16 +217,16 @@
mRevealAnimator.setCurrentFraction(shapeRevealProgress);
}
- float drawableScale = (isVerticalBarLayout ? mOutline.width() : mOutline.height())
+ float drawableScale = (dp.isLandscape ? mOutline.width() : mOutline.height())
/ minSize;
- setBackgroundDrawableBounds(drawableScale, isVerticalBarLayout);
+ setBackgroundDrawableBounds(drawableScale, dp.isLandscape);
if (isOpening) {
// Center align foreground
int height = mFinalDrawableBounds.height();
int width = mFinalDrawableBounds.width();
- int diffY = isVerticalBarLayout ? 0
+ int diffY = dp.isLandscape ? 0
: (int) (((height * drawableScale) - height) / 2);
- int diffX = isVerticalBarLayout ? (int) (((width * drawableScale) - width) / 2)
+ int diffX = dp.isLandscape ? (int) (((width * drawableScale) - width) / 2)
: 0;
sTmpRect.set(mFinalDrawableBounds);
sTmpRect.offset(diffX, diffY);
@@ -247,11 +246,11 @@
invalidateOutline();
}
- private void setBackgroundDrawableBounds(float scale, boolean isVerticalBarLayout) {
+ private void setBackgroundDrawableBounds(float scale, boolean isLandscape) {
sTmpRect.set(mFinalDrawableBounds);
Utilities.scaleRectAboutCenter(sTmpRect, scale);
// Since the drawable is at the top of the view, we need to offset to keep it centered.
- if (isVerticalBarLayout) {
+ if (isLandscape) {
sTmpRect.offsetTo((int) (mFinalDrawableBounds.left * scale), sTmpRect.top);
} else {
sTmpRect.offsetTo(sTmpRect.left, (int) (mFinalDrawableBounds.top * scale));
@@ -269,7 +268,7 @@
* Sets the icon for this view as part of initial setup
*/
public void setIcon(@Nullable Drawable drawable, int iconOffset, MarginLayoutParams lp,
- boolean isOpening, boolean isVerticalBarLayout, DeviceProfile dp) {
+ boolean isOpening, DeviceProfile dp) {
mIsAdaptiveIcon = drawable instanceof AdaptiveIconDrawable;
if (mIsAdaptiveIcon) {
boolean isFolderIcon = drawable instanceof FolderAdaptiveIcon;
@@ -304,7 +303,7 @@
Utilities.scaleRectAboutCenter(mStartRevealRect, IconShape.getNormalizationScale());
}
- if (isVerticalBarLayout) {
+ if (dp.isLandscape) {
lp.width = (int) Math.max(lp.width, lp.height * dp.aspectRatio);
} else {
lp.height = (int) Math.max(lp.height, lp.width * dp.aspectRatio);
@@ -325,7 +324,7 @@
bgDrawableStartScale = scale;
mOutline.set(0, 0, lp.width, lp.height);
}
- setBackgroundDrawableBounds(bgDrawableStartScale, isVerticalBarLayout);
+ setBackgroundDrawableBounds(bgDrawableStartScale, dp.isLandscape);
mEndRevealRect.set(0, 0, lp.width, lp.height);
setOutlineProvider(new ViewOutlineProvider() {
@Override
diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java
index 0f69530..56a1d37 100644
--- a/src/com/android/launcher3/views/FloatingIconView.java
+++ b/src/com/android/launcher3/views/FloatingIconView.java
@@ -43,6 +43,7 @@
import androidx.annotation.WorkerThread;
import com.android.launcher3.BubbleTextView;
+import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InsettableFrameLayout;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
@@ -82,7 +83,6 @@
private final Launcher mLauncher;
private final boolean mIsRtl;
- private boolean mIsVerticalBarLayout = false;
private boolean mIsOpening;
private IconLoadResult mIconLoadResult;
@@ -150,7 +150,7 @@
float shapeProgressStart, float cornerRadius, boolean isOpening) {
setAlpha(alpha);
mClipIconView.update(rect, progress, shapeProgressStart, cornerRadius, fgIconAlpha,
- isOpening, this, mLauncher.getDeviceProfile(), mIsVerticalBarLayout);
+ isOpening, this, mLauncher.getDeviceProfile());
}
@Override
@@ -320,11 +320,11 @@
@UiThread
private void setIcon(@Nullable Drawable drawable, @Nullable Drawable badge,
@Nullable Drawable btvIcon, int iconOffset) {
+ final DeviceProfile dp = mLauncher.getDeviceProfile();
final InsettableFrameLayout.LayoutParams lp =
(InsettableFrameLayout.LayoutParams) getLayoutParams();
mBadge = badge;
- mClipIconView.setIcon(drawable, iconOffset, lp, mIsOpening, mIsVerticalBarLayout,
- mLauncher.getDeviceProfile());
+ mClipIconView.setIcon(drawable, iconOffset, lp, mIsOpening, dp);
if (drawable instanceof AdaptiveIconDrawable) {
final int originalHeight = lp.height;
final int originalWidth = lp.width;
@@ -332,7 +332,7 @@
mFinalDrawableBounds.set(0, 0, originalWidth, originalHeight);
float aspectRatio = mLauncher.getDeviceProfile().aspectRatio;
- if (mIsVerticalBarLayout) {
+ if (dp.isLandscape) {
lp.width = (int) Math.max(lp.width, lp.height * aspectRatio);
} else {
lp.height = (int) Math.max(lp.height, lp.width * aspectRatio);
@@ -565,7 +565,6 @@
view.recycle();
// Init properties before getting the drawable.
- view.mIsVerticalBarLayout = launcher.getDeviceProfile().isVerticalBarLayout();
view.mIsOpening = isOpening;
view.mOriginalIcon = originalView;
view.mPositionOut = positionOut;
@@ -587,7 +586,7 @@
view.matchPositionOf(launcher, originalView, isOpening, positionOut);
// We need to add it to the overlay, but keep it invisible until animation starts..
- view.setVisibility(INVISIBLE);
+ setIconAndDotVisible(view, false);
parent.addView(view);
dragLayer.addView(view.mListenerView);
view.mListenerView.setListener(view::fastFinish);
@@ -596,16 +595,8 @@
view.mEndRunnable = null;
if (hideOriginal) {
- if (isOpening) {
- setIconAndDotVisible(originalView, true);
- view.finish(dragLayer);
- } else {
- originalView.setVisibility(VISIBLE);
- if (originalView instanceof IconLabelDotView) {
- setIconAndDotVisible(originalView, true);
- }
- view.finish(dragLayer);
- }
+ setIconAndDotVisible(originalView, true);
+ view.finish(dragLayer);
} else {
view.finish(dragLayer);
}
diff --git a/src/com/android/launcher3/widget/PendingAddWidgetInfo.java b/src/com/android/launcher3/widget/PendingAddWidgetInfo.java
index cbec642..470a800 100644
--- a/src/com/android/launcher3/widget/PendingAddWidgetInfo.java
+++ b/src/com/android/launcher3/widget/PendingAddWidgetInfo.java
@@ -70,7 +70,7 @@
public LauncherAtom.ItemInfo buildProto(FolderInfo folderInfo) {
LauncherAtom.ItemInfo info = super.buildProto(folderInfo);
return info.toBuilder()
- .setAttribute(LauncherAppWidgetInfo.getAttribute(sourceContainer))
+ .addItemAttributes(LauncherAppWidgetInfo.getAttribute(sourceContainer))
.build();
}
}
diff --git a/tests/src/com/android/launcher3/DeviceProfileTest.kt b/tests/src/com/android/launcher3/DeviceProfileTest.kt
index 6c99a21..60046a0 100644
--- a/tests/src/com/android/launcher3/DeviceProfileTest.kt
+++ b/tests/src/com/android/launcher3/DeviceProfileTest.kt
@@ -39,6 +39,7 @@
private var isMultiWindowMode: Boolean = false
private var transposeLayoutWithOrientation: Boolean = false
private var useTwoPanels: Boolean = false
+ private var isGestureMode: Boolean = true
@Before
fun setUp() {
@@ -58,7 +59,8 @@
windowBounds,
isMultiWindowMode,
transposeLayoutWithOrientation,
- useTwoPanels
+ useTwoPanels,
+ isGestureMode
)
assertThat(dp.isQsbInline).isFalse()
@@ -67,7 +69,7 @@
@Test
fun qsbWidth_is_match_parent_for_tablet_portrait() {
- initializeVarsForTablet()
+ initializeVarsForLargeTablet()
val dp = DeviceProfile(
context,
@@ -76,7 +78,8 @@
windowBounds,
isMultiWindowMode,
transposeLayoutWithOrientation,
- useTwoPanels
+ useTwoPanels,
+ isGestureMode
)
assertThat(dp.isQsbInline).isFalse()
@@ -84,8 +87,8 @@
}
@Test
- fun qsbWidth_has_size_for_tablet_landscape() {
- initializeVarsForTablet(true)
+ fun qsbWidth_has_size_for_large_tablet_landscape() {
+ initializeVarsForLargeTablet(true)
val dp = DeviceProfile(
context,
@@ -94,7 +97,8 @@
windowBounds,
isMultiWindowMode,
transposeLayoutWithOrientation,
- useTwoPanels
+ useTwoPanels,
+ isGestureMode
)
if (dp.hotseatQsbHeight > 0) {
@@ -110,8 +114,8 @@
* This test is to make sure that two panels don't inline the QSB as tablets do
*/
@Test
- fun qsbWidth_is_match_parent_for_two_panel_landscape() {
- initializeVarsForTablet(true)
+ fun qsbWidth_is_match_parent_for_small_two_panel_landscape() {
+ initializeVarsForSmallTablet(true)
useTwoPanels = true
val dp = DeviceProfile(
@@ -121,7 +125,8 @@
windowBounds,
isMultiWindowMode,
transposeLayoutWithOrientation,
- useTwoPanels
+ useTwoPanels,
+ isGestureMode
)
assertThat(dp.isQsbInline).isFalse()
@@ -137,11 +142,12 @@
windowBounds = WindowBounds(x, y, x, y - 100)
`when`(info.isTablet(any())).thenReturn(false)
+ `when`(info.isLargeTablet(any())).thenReturn(false)
scalableInvariantDeviceProfile()
}
- private fun initializeVarsForTablet(isLandscape: Boolean = false) {
+ private fun initializeVarsForSmallTablet(isLandscape: Boolean = false) {
val (x, y) = if (isLandscape)
Pair(2560, 1600)
else
@@ -150,6 +156,21 @@
windowBounds = WindowBounds(x, y, x, y - 100)
`when`(info.isTablet(any())).thenReturn(true)
+ `when`(info.isLargeTablet(any())).thenReturn(false)
+
+ scalableInvariantDeviceProfile()
+ }
+
+ private fun initializeVarsForLargeTablet(isLandscape: Boolean = false) {
+ val (x, y) = if (isLandscape)
+ Pair(2560, 1600)
+ else
+ Pair(1600, 2560)
+
+ windowBounds = WindowBounds(x, y, x, y - 100)
+
+ `when`(info.isTablet(any())).thenReturn(true)
+ `when`(info.isLargeTablet(any())).thenReturn(true)
scalableInvariantDeviceProfile()
}
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index 5abdcd3..c99c4f1 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -33,12 +33,12 @@
import android.content.pm.LauncherApps;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.graphics.Point;
import android.os.Debug;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
-import android.platform.test.rule.CrashDetector;
import android.system.OsConstants;
import android.util.Log;
@@ -55,6 +55,8 @@
import com.android.launcher3.Utilities;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.statemanager.StateManager;
+import com.android.launcher3.tapl.HomeAllApps;
+import com.android.launcher3.tapl.HomeAppIcon;
import com.android.launcher3.tapl.LauncherInstrumentation;
import com.android.launcher3.tapl.LauncherInstrumentation.ContainerType;
import com.android.launcher3.tapl.TestHelpers;
@@ -226,7 +228,6 @@
@Rule
public TestRule mOrderSensitiveRules = RuleChain
.outerRule(new TestStabilityRule())
- .around(new CrashDetector("com.android.systemui"))
.around(mActivityMonitor)
.around(getRulesInsideActivityMonitor());
@@ -602,4 +603,26 @@
protected void onLauncherActivityClose(Launcher launcher) {
}
+
+ protected HomeAppIcon createShortcutInCenterIfNotExist(String name) {
+ Point dimension = mLauncher.getWorkspace().getIconGridDimensions();
+ return createShortcutIfNotExist(name, dimension.x / 2, dimension.y / 2);
+ }
+
+ protected HomeAppIcon createShortcutIfNotExist(String name, int cellX, int cellY) {
+ HomeAppIcon homeAppIcon = mLauncher.getWorkspace().tryGetWorkspaceAppIcon(name);
+ if (homeAppIcon == null) {
+ HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
+ allApps.freeze();
+ try {
+ allApps.getAppIcon(name).dragToWorkspace(cellX, cellY);
+ } finally {
+ allApps.unfreeze();
+ }
+ homeAppIcon = mLauncher.getWorkspace().getWorkspaceAppIcon(name);
+ }
+ return homeAppIcon;
+ }
+
+
}
diff --git a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
index da8bf6e..61ec8bd 100644
--- a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
+++ b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
@@ -365,27 +365,11 @@
}
}
- private HomeAppIcon createShortcutIfNotExist(String name) {
- HomeAppIcon homeAppIcon = mLauncher.getWorkspace().tryGetWorkspaceAppIcon(name);
- if (homeAppIcon == null) {
- HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
- allApps.freeze();
- try {
- allApps.getAppIcon(name).dragToWorkspace(false, false);
- } finally {
- allApps.unfreeze();
- }
- homeAppIcon = mLauncher.getWorkspace().getWorkspaceAppIcon(name);
- }
- return homeAppIcon;
- }
-
- @Ignore("b/205014516")
@Test
@PortraitLandscape
public void testDragToFolder() throws Exception {
- final HomeAppIcon playStoreIcon = createShortcutIfNotExist("Play Store");
- final HomeAppIcon gmailIcon = createShortcutIfNotExist("Gmail");
+ final HomeAppIcon playStoreIcon = createShortcutIfNotExist("Play Store", 0, 1);
+ final HomeAppIcon gmailIcon = createShortcutIfNotExist("Gmail", 1, 1);
FolderIcon folderIcon = gmailIcon.dragToIcon(playStoreIcon);
@@ -399,7 +383,7 @@
assertNull("Play Store should be moved to a folder.",
workspace.tryGetWorkspaceAppIcon("Play Store"));
- final HomeAppIcon youTubeIcon = createShortcutIfNotExist("YouTube");
+ final HomeAppIcon youTubeIcon = createShortcutInCenterIfNotExist("YouTube");
folderIcon = youTubeIcon.dragToIcon(folderIcon);
folder = folderIcon.open();
@@ -433,8 +417,8 @@
@PortraitLandscape
public void testDeleteFromWorkspace() throws Exception {
// test delete both built-in apps and user-installed app from workspace
- for (String appName : new String[] {"Gmail", "Play Store", APP_NAME}) {
- final HomeAppIcon homeAppIcon = createShortcutIfNotExist(appName);
+ for (String appName : new String[]{"Gmail", "Play Store", APP_NAME}) {
+ final HomeAppIcon homeAppIcon = createShortcutInCenterIfNotExist(appName);
Workspace workspace = mLauncher.getWorkspace().deleteAppIcon(homeAppIcon);
assertNull(appName + " app was found after being deleted from workspace",
workspace.tryGetWorkspaceAppIcon(appName));
@@ -458,7 +442,7 @@
TestUtil.installDummyApp();
try {
verifyAppUninstalledFromAllApps(
- createShortcutIfNotExist(DUMMY_APP_NAME).uninstall(), DUMMY_APP_NAME);
+ createShortcutInCenterIfNotExist(DUMMY_APP_NAME).uninstall(), DUMMY_APP_NAME);
} finally {
TestUtil.uninstallDummyApp();
}
@@ -509,7 +493,7 @@
}
// test to move a shortcut to other cell.
- final HomeAppIcon launcherTestAppIcon = createShortcutIfNotExist(APP_NAME);
+ final HomeAppIcon launcherTestAppIcon = createShortcutInCenterIfNotExist(APP_NAME);
for (Point target : targets) {
launcherTestAppIcon.dragToWorkspace(target.x, target.y);
}
diff --git a/tests/tapl/com/android/launcher3/tapl/HomeAppIcon.java b/tests/tapl/com/android/launcher3/tapl/HomeAppIcon.java
index 4b36dc0..baabe12 100644
--- a/tests/tapl/com/android/launcher3/tapl/HomeAppIcon.java
+++ b/tests/tapl/com/android/launcher3/tapl/HomeAppIcon.java
@@ -115,7 +115,7 @@
String.format("want to drag the icon to cell(%d, %d)", cellX, cellY))
) {
final Supplier<Point> dest = () -> Workspace.getCellCenter(mLauncher, cellX, cellY);
- Workspace.dragIconToWorkspace(mLauncher, this, dest, true, getLongPressIndicator(),
+ Workspace.dragIconToWorkspace(mLauncher, this, dest, getLongPressIndicator(),
() -> addExpectedEventsForLongClick(), null);
try (LauncherInstrumentation.Closable ignore = mLauncher.addContextLayer("dragged")) {
WorkspaceAppIcon appIcon =
diff --git a/tests/tapl/com/android/launcher3/tapl/Launchable.java b/tests/tapl/com/android/launcher3/tapl/Launchable.java
index 02a6b91..a28eac6 100644
--- a/tests/tapl/com/android/launcher3/tapl/Launchable.java
+++ b/tests/tapl/com/android/launcher3/tapl/Launchable.java
@@ -139,7 +139,7 @@
mLauncher.waitForLauncherObject(longPressIndicator);
LauncherInstrumentation.log("movePointerForStartDrag: indicator");
mLauncher.movePointer(iconCenter, dragStartCenter, DEFAULT_DRAG_STEPS, false,
- downTime, true, LauncherInstrumentation.GestureScope.INSIDE);
+ downTime, downTime, true, LauncherInstrumentation.GestureScope.INSIDE);
}
private int getStartDragThreshold() {
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index f063191..bbfbc55 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -1107,11 +1107,13 @@
}
}
- @NonNull UiObject2 waitForObjectInContainer(UiObject2 container, BySelector selector) {
+ @NonNull
+ UiObject2 waitForObjectInContainer(UiObject2 container, BySelector selector) {
return waitForObjectsInContainer(container, selector).get(0);
}
- @NonNull List<UiObject2> waitForObjectsInContainer(
+ @NonNull
+ List<UiObject2> waitForObjectsInContainer(
UiObject2 container, BySelector selector) {
try {
final List<UiObject2> objects = container.wait(
@@ -1406,13 +1408,13 @@
final Point end = new Point(endX, endY);
sendPointer(downTime, downTime, MotionEvent.ACTION_DOWN, start, gestureScope);
final long endTime = movePointer(
- start, end, steps, false, downTime, slowDown, gestureScope);
+ start, end, steps, false, downTime, downTime, slowDown, gestureScope);
sendPointer(downTime, endTime, MotionEvent.ACTION_UP, end, gestureScope);
}
- long movePointer(Point start, Point end, int steps, boolean isDecelerating,
- long downTime, boolean slowDown, GestureScope gestureScope) {
- long endTime = movePointer(downTime, downTime, steps * GESTURE_STEP_MS,
+ long movePointer(Point start, Point end, int steps, boolean isDecelerating, long downTime,
+ long startTime, boolean slowDown, GestureScope gestureScope) {
+ long endTime = movePointer(downTime, startTime, steps * GESTURE_STEP_MS,
isDecelerating, start, end, gestureScope);
if (slowDown) {
endTime = movePointer(downTime, endTime + GESTURE_STEP_MS, 5 * GESTURE_STEP_MS, end,
diff --git a/tests/tapl/com/android/launcher3/tapl/Workspace.java b/tests/tapl/com/android/launcher3/tapl/Workspace.java
index 4f4ce30..3bc5389 100644
--- a/tests/tapl/com/android/launcher3/tapl/Workspace.java
+++ b/tests/tapl/com/android/launcher3/tapl/Workspace.java
@@ -178,10 +178,10 @@
* pageDelta: 3, the latest page that can be created is 2) the icon will be dragged onto the
* page that can be created and is closest to the target page.
*
- * @param homeAppIcon - icon to drag.
- * @param pageDelta - how many pages should the icon be dragged from the current page.
- * It can be a negative value. currentPage + pageDelta should be greater
- * than or equal to 0.
+ * @param homeAppIcon - icon to drag.
+ * @param pageDelta - how many pages should the icon be dragged from the current page.
+ * It can be a negative value. currentPage + pageDelta should be greater
+ * than or equal to 0.
*/
public void dragIcon(HomeAppIcon homeAppIcon, int pageDelta) {
if (mHotseat.getVisibleBounds().height() > mHotseat.getVisibleBounds().width()) {
@@ -246,7 +246,6 @@
dragIconToWorkspace(
mLauncher, homeAppIcon,
() -> getDropPointFromDropTargetBar(mLauncher, DELETE_TARGET_TEXT_ID),
- true, /* decelerating */
homeAppIcon.getLongPressIndicator(),
() -> mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, LONG_CLICK_EVENT),
null);
@@ -261,8 +260,9 @@
/**
* Uninstall the appIcon by dragging it to the 'uninstall' drop point of the drop_target_bar.
*
- * @param launcher the root TAPL instrumentation object of {@link LauncherInstrumentation} type.
- * @param homeAppIcon to be uninstalled.
+ * @param launcher the root TAPL instrumentation object of {@link
+ * LauncherInstrumentation} type.
+ * @param homeAppIcon to be uninstalled.
* @param launcher the root TAPL instrumentation object of {@link
* LauncherInstrumentation} type.
* @param homeAppIcon to be uninstalled.
@@ -276,7 +276,6 @@
dragIconToWorkspace(
launcher, homeAppIcon,
() -> getDropPointFromDropTargetBar(launcher, UNINSTALL_TARGET_TEXT_ID),
- true, /* decelerating */
homeAppIcon.getLongPressIndicator(),
expectLongClickEvents,
null);
@@ -353,23 +352,24 @@
expectDropEvents = () -> launcher.expectEvent(TestProtocol.SEQUENCE_MAIN,
LauncherInstrumentation.EVENT_START);
}
- dragIconToWorkspace(launcher, launchable, () -> dest, false, longPressIndicator,
+ dragIconToWorkspace(launcher, launchable, () -> dest, longPressIndicator,
expectLongClickEvents, expectDropEvents);
}
/**
- * Drag icon in workspace to else where.
+ * Drag icon in workspace to else where and drop it immediately.
+ * (There is no slow down time before drop event)
* This function expects the launchable is inside the workspace and there is no drop event.
*/
static void dragIconToWorkspace(LauncherInstrumentation launcher, Launchable launchable,
Supplier<Point> destSupplier, String longPressIndicator) {
- dragIconToWorkspace(launcher, launchable, destSupplier, false, longPressIndicator,
+ dragIconToWorkspace(launcher, launchable, destSupplier, longPressIndicator,
() -> launcher.expectEvent(TestProtocol.SEQUENCE_MAIN, LONG_CLICK_EVENT), null);
}
static void dragIconToWorkspace(
LauncherInstrumentation launcher, Launchable launchable, Supplier<Point> dest,
- boolean isDecelerating, String longPressIndicator, Runnable expectLongClickEvents,
+ String longPressIndicator, Runnable expectLongClickEvents,
@Nullable Runnable expectDropEvents) {
try (LauncherInstrumentation.Closable ignored = launcher.addContextLayer(
"want to drag icon to workspace")) {
@@ -391,7 +391,7 @@
Point finalDragStart = dragStart;
executeAndWaitForPageScroll(launcher,
() -> launcher.movePointer(finalDragStart, screenEdge, DEFAULT_DRAG_STEPS,
- isDecelerating, downTime, true,
+ true, downTime, downTime, true,
LauncherInstrumentation.GestureScope.INSIDE));
targetDest.x += displayX * (targetDest.x > 0 ? -1 : 1);
dragStart = screenEdge;
@@ -399,8 +399,9 @@
// targetDest.x is now between 0 and displayX so we found the target page,
// we just have to put move the icon to the destination and drop it
- launcher.movePointer(dragStart, targetDest, DEFAULT_DRAG_STEPS, isDecelerating,
- downTime, true, LauncherInstrumentation.GestureScope.INSIDE);
+ launcher.movePointer(dragStart, targetDest, DEFAULT_DRAG_STEPS, true,
+ downTime, SystemClock.uptimeMillis(), false,
+ LauncherInstrumentation.GestureScope.INSIDE);
dropDraggedIcon(launcher, targetDest, downTime, expectDropEvents);
}
}
@@ -488,4 +489,4 @@
return widget != null ? new Widget(mLauncher, widget) : null;
}
}
-}
\ No newline at end of file
+}