Inlining BaseQuickstepLauncher to QuickstepLauncher
Bug: 243022799
Test: Presubmit
Change-Id: I3706fc1f10d88ea73bd873c7e94c3e78795791eb
diff --git a/quickstep/ext_tests/src/com/android/quickstep/DebugQuickstepTestInformationHandler.java b/quickstep/ext_tests/src/com/android/quickstep/DebugQuickstepTestInformationHandler.java
index 84b907f..2ffb28e 100644
--- a/quickstep/ext_tests/src/com/android/quickstep/DebugQuickstepTestInformationHandler.java
+++ b/quickstep/ext_tests/src/com/android/quickstep/DebugQuickstepTestInformationHandler.java
@@ -23,12 +23,12 @@
import androidx.annotation.Nullable;
-import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.taskbar.LauncherTaskbarUIController;
import com.android.launcher3.testing.DebugTestInformationHandler;
import com.android.launcher3.testing.shared.TestProtocol;
+import com.android.launcher3.uioverrides.QuickstepLauncher;
import java.util.concurrent.ExecutionException;
@@ -64,7 +64,7 @@
runOnUIThread(l -> {
enableManualTaskbarStashing(l, true);
- BaseQuickstepLauncher quickstepLauncher = (BaseQuickstepLauncher) l;
+ QuickstepLauncher quickstepLauncher = (QuickstepLauncher) l;
LauncherTaskbarUIController taskbarUIController =
quickstepLauncher.getTaskbarUIController();
@@ -90,7 +90,7 @@
}
private void enableManualTaskbarStashing(Launcher launcher, boolean enable) {
- BaseQuickstepLauncher quickstepLauncher = (BaseQuickstepLauncher) launcher;
+ QuickstepLauncher quickstepLauncher = (QuickstepLauncher) launcher;
LauncherTaskbarUIController taskbarUIController =
quickstepLauncher.getTaskbarUIController();
diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
deleted file mode 100644
index c2e8658..0000000
--- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
+++ /dev/null
@@ -1,708 +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.launcher3;
-
-import static com.android.launcher3.AbstractFloatingView.TYPE_ALL;
-import static com.android.launcher3.AbstractFloatingView.TYPE_HIDE_BACK_BUTTON;
-import static com.android.launcher3.LauncherState.FLAG_HIDE_BACK_BUTTON;
-import static com.android.launcher3.LauncherState.NORMAL;
-import static com.android.launcher3.LauncherState.NO_OFFSET;
-import static com.android.launcher3.LauncherState.OVERVIEW;
-import static com.android.launcher3.LauncherState.OVERVIEW_SPLIT_SELECT;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_SPLIT_FROM_WORKSPACE;
-import static com.android.launcher3.model.data.ItemInfo.NO_MATCHING_ID;
-import static com.android.launcher3.popup.QuickstepSystemShortcut.getSplitSelectShortcutByPosition;
-import static com.android.launcher3.taskbar.LauncherTaskbarUIController.ALL_APPS_PAGE_PROGRESS_INDEX;
-import static com.android.launcher3.taskbar.LauncherTaskbarUIController.MINUS_ONE_PAGE_PROGRESS_INDEX;
-import static com.android.launcher3.taskbar.LauncherTaskbarUIController.WIDGETS_PAGE_PROGRESS_INDEX;
-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.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.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY;
-
-import android.animation.AnimatorSet;
-import android.animation.ValueAnimator;
-import android.app.ActivityManager;
-import android.app.ActivityOptions;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentSender;
-import android.hardware.SensorManager;
-import android.hardware.devicestate.DeviceStateManager;
-import android.os.Bundle;
-import android.os.CancellationSignal;
-import android.os.IBinder;
-import android.view.Display;
-import android.view.View;
-import android.window.SplashScreen;
-
-import androidx.annotation.Nullable;
-
-import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.dragndrop.DragOptions;
-import com.android.launcher3.model.WellbeingModel;
-import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.popup.SystemShortcut;
-import com.android.launcher3.proxy.ProxyActivityStarter;
-import com.android.launcher3.proxy.StartActivityParams;
-import com.android.launcher3.statehandlers.BackButtonAlphaHandler;
-import com.android.launcher3.statehandlers.DepthController;
-import com.android.launcher3.statemanager.StateManager.StateHandler;
-import com.android.launcher3.taskbar.LauncherTaskbarUIController;
-import com.android.launcher3.taskbar.TaskbarManager;
-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.PendingSplitSelectInfo;
-import com.android.launcher3.util.RunnableList;
-import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
-import com.android.launcher3.util.UiThreadHelper;
-import com.android.quickstep.OverviewCommandHelper;
-import com.android.quickstep.RecentsModel;
-import com.android.quickstep.SystemUiProxy;
-import com.android.quickstep.TaskUtils;
-import com.android.quickstep.TouchInteractionService.TISBinder;
-import com.android.quickstep.util.LauncherUnfoldAnimationController;
-import com.android.quickstep.util.ProxyScreenStatusProvider;
-import com.android.quickstep.util.RemoteAnimationProvider;
-import com.android.quickstep.util.RemoteFadeOutAnimationListener;
-import com.android.quickstep.util.SplitSelectStateController;
-import com.android.quickstep.util.TISBindHelper;
-import com.android.quickstep.views.OverviewActionsView;
-import com.android.quickstep.views.RecentsView;
-import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.shared.system.ActivityOptionsCompat;
-import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
-import com.android.systemui.unfold.UnfoldTransitionFactory;
-import com.android.systemui.unfold.UnfoldTransitionProgressProvider;
-import com.android.systemui.unfold.config.ResourceUnfoldTransitionConfig;
-import com.android.systemui.unfold.config.UnfoldTransitionConfig;
-import com.android.systemui.unfold.system.ActivityManagerActivityTypeProvider;
-import com.android.systemui.unfold.system.DeviceStateManagerFoldProvider;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Stream;
-
-/**
- * Extension of Launcher activity to provide quickstep specific functionality
- */
-public abstract class BaseQuickstepLauncher extends Launcher {
-
- private DepthController mDepthController;
- private QuickstepTransitionManager mAppTransitionManager;
-
- /**
- * Reusable command for applying the back button alpha on the background thread.
- */
- public static final UiThreadHelper.AsyncCommand SET_BACK_BUTTON_ALPHA =
- (context, arg1, arg2) -> SystemUiProxy.INSTANCE.get(context).setNavBarButtonAlpha(
- Float.intBitsToFloat(arg1), arg2 != 0);
-
- private OverviewActionsView mActionsView;
-
- private TISBindHelper mTISBindHelper;
- private @Nullable TaskbarManager mTaskbarManager;
- private @Nullable OverviewCommandHelper mOverviewCommandHelper;
- private @Nullable LauncherTaskbarUIController mTaskbarUIController;
-
- // Will be updated when dragging from taskbar.
- private @Nullable DragOptions mNextWorkspaceDragOptions = null;
-
- private @Nullable UnfoldTransitionProgressProvider mUnfoldTransitionProgressProvider;
- private @Nullable LauncherUnfoldAnimationController mLauncherUnfoldAnimationController;
-
- /**
- * If Launcher restarted while in the middle of an Overview split select, it needs this data to
- * recover. In all other cases this will remain null.
- */
- private PendingSplitSelectInfo mPendingSplitSelectInfo = null;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- if (savedInstanceState != null) {
- mPendingSplitSelectInfo = ObjectWrapper.unwrap(
- savedInstanceState.getIBinder(PENDING_SPLIT_SELECT_INFO));
- }
- addMultiWindowModeChangedListener(mDepthController);
- initUnfoldTransitionProgressProvider();
- }
-
- @Override
- protected void onResume() {
- super.onResume();
-
- if (mLauncherUnfoldAnimationController != null) {
- mLauncherUnfoldAnimationController.onResume();
- }
- }
-
- @Override
- protected void onPause() {
- if (mLauncherUnfoldAnimationController != null) {
- mLauncherUnfoldAnimationController.onPause();
- }
-
- super.onPause();
- }
-
- @Override
- public void onDestroy() {
- mAppTransitionManager.onActivityDestroyed();
- if (mUnfoldTransitionProgressProvider != null) {
- mUnfoldTransitionProgressProvider.destroy();
- }
-
- mTISBindHelper.onDestroy();
- if (mTaskbarManager != null) {
- mTaskbarManager.clearActivity(this);
- }
-
- if (mLauncherUnfoldAnimationController != null) {
- mLauncherUnfoldAnimationController.onDestroy();
- }
-
- super.onDestroy();
- }
-
- @Override
- protected void onNewIntent(Intent intent) {
- super.onNewIntent(intent);
-
- if (mOverviewCommandHelper != null) {
- mOverviewCommandHelper.clearPendingCommands();
- }
- }
-
- public QuickstepTransitionManager getAppTransitionManager() {
- return mAppTransitionManager;
- }
-
- @Override
- public void onEnterAnimationComplete() {
- super.onEnterAnimationComplete();
- // After the transition to home, enable the high-res thumbnail loader if it wasn't enabled
- // as a part of quickstep, so that high-res thumbnails can load the next time we enter
- // overview
- RecentsModel.INSTANCE.get(this).getThumbnailCache()
- .getHighResLoadingState().setVisible(true);
- }
-
- @Override
- protected void handleGestureContract(Intent intent) {
- if (FeatureFlags.SEPARATE_RECENTS_ACTIVITY.get()) {
- super.handleGestureContract(intent);
- }
- }
-
- @Override
- public void onTrimMemory(int level) {
- super.onTrimMemory(level);
- RecentsModel.INSTANCE.get(this).onTrimMemory(level);
- }
-
- @Override
- public void onUiChangedWhileSleeping() {
- // Remove the snapshot because the content view may have obvious changes.
- UI_HELPER_EXECUTOR.execute(
- () -> ActivityManagerWrapper.getInstance().invalidateHomeTaskSnapshot(this));
- }
-
- @Override
- protected void onScreenOff() {
- super.onScreenOff();
- if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
- RecentsView recentsView = getOverviewPanel();
- recentsView.finishRecentsAnimation(true /* toRecents */, null);
- }
- }
-
- /**
- * {@code LauncherOverlayCallbacks} scroll amount.
- * Indicates transition progress to -1 screen.
- * @param progress From 0 to 1.
- */
- @Override
- public void onScrollChanged(float progress) {
- super.onScrollChanged(progress);
- onTaskbarInAppDisplayProgressUpdate(progress, MINUS_ONE_PAGE_PROGRESS_INDEX);
- }
-
- @Override
- public void onAllAppsTransition(float progress) {
- super.onAllAppsTransition(progress);
- onTaskbarInAppDisplayProgressUpdate(progress, ALL_APPS_PAGE_PROGRESS_INDEX);
- }
-
- @Override
- public void onWidgetsTransition(float progress) {
- super.onWidgetsTransition(progress);
- onTaskbarInAppDisplayProgressUpdate(progress, WIDGETS_PAGE_PROGRESS_INDEX);
- }
-
- private void onTaskbarInAppDisplayProgressUpdate(float progress, int flag) {
- if (mTaskbarManager == null
- || mTaskbarManager.getCurrentActivityContext() == null
- || mTaskbarUIController == null) {
- return;
- }
- mTaskbarUIController.onTaskbarInAppDisplayProgressUpdate(progress, flag);
- }
-
- @Override
- public void startIntentSenderForResult(IntentSender intent, int requestCode,
- Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, Bundle options) {
- if (requestCode != -1) {
- mPendingActivityRequestCode = requestCode;
- StartActivityParams params = new StartActivityParams(this, requestCode);
- params.intentSender = intent;
- params.fillInIntent = fillInIntent;
- params.flagsMask = flagsMask;
- params.flagsValues = flagsValues;
- params.extraFlags = extraFlags;
- params.options = options;
- startActivity(ProxyActivityStarter.getLaunchIntent(this, params));
- } else {
- super.startIntentSenderForResult(intent, requestCode, fillInIntent, flagsMask,
- flagsValues, extraFlags, options);
- }
- }
-
- @Override
- public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
- if (requestCode != -1) {
- mPendingActivityRequestCode = requestCode;
- StartActivityParams params = new StartActivityParams(this, requestCode);
- params.intent = intent;
- params.options = options;
- startActivity(ProxyActivityStarter.getLaunchIntent(this, params));
- } else {
- super.startActivityForResult(intent, requestCode, options);
- }
- }
-
- @Override
- protected void onDeferredResumed() {
- super.onDeferredResumed();
- handlePendingActivityRequest();
- }
-
- @Override
- public void onStateSetEnd(LauncherState state) {
- super.onStateSetEnd(state);
- handlePendingActivityRequest();
- }
-
- private void handlePendingActivityRequest() {
- if (mPendingActivityRequestCode != -1 && isInState(NORMAL)
- && ((getActivityFlags() & ACTIVITY_STATE_DEFERRED_RESUMED) != 0)) {
- // Remove any active ProxyActivityStarter task and send RESULT_CANCELED to Launcher.
- onActivityResult(mPendingActivityRequestCode, RESULT_CANCELED, null);
- // ProxyActivityStarter is started with clear task to reset the task after which it
- // removes the task itself.
- startActivity(ProxyActivityStarter.getLaunchIntent(this, null));
- }
- }
-
- @Override
- protected void setupViews() {
- super.setupViews();
-
- mActionsView = findViewById(R.id.overview_actions_view);
- RecentsView overviewPanel = (RecentsView) getOverviewPanel();
- SplitSelectStateController controller =
- new SplitSelectStateController(this, mHandler, getStateManager(),
- getDepthController());
- overviewPanel.init(mActionsView, controller);
- mActionsView.updateDimension(getDeviceProfile(), overviewPanel.getLastComputedTaskSize());
- mActionsView.updateVerticalMargin(DisplayController.getNavigationMode(this));
-
- mAppTransitionManager = new QuickstepTransitionManager(this);
- mAppTransitionManager.registerRemoteAnimations();
- mAppTransitionManager.registerRemoteTransitions();
-
- mTISBindHelper = new TISBindHelper(this, this::onTISConnected);
- mDepthController = new DepthController(this);
- }
-
- private void onTISConnected(TISBinder binder) {
- mTaskbarManager = binder.getTaskbarManager();
- mTaskbarManager.setActivity(this);
- mOverviewCommandHelper = binder.getOverviewCommandHelper();
- }
-
- @Override
- public void runOnBindToTouchInteractionService(Runnable r) {
- mTISBindHelper.runOnBindToTouchInteractionService(r);
- }
-
- private void initUnfoldTransitionProgressProvider() {
- final UnfoldTransitionConfig config = new ResourceUnfoldTransitionConfig();
- if (config.isEnabled()) {
- mUnfoldTransitionProgressProvider =
- UnfoldTransitionFactory.createUnfoldTransitionProgressProvider(
- /* context= */ this,
- config,
- ProxyScreenStatusProvider.INSTANCE,
- new DeviceStateManagerFoldProvider(
- getSystemService(DeviceStateManager.class), /* context */this),
- new ActivityManagerActivityTypeProvider(
- getSystemService(ActivityManager.class)),
- getSystemService(SensorManager.class),
- getMainThreadHandler(),
- getMainExecutor(),
- /* backgroundExecutor= */ THREAD_POOL_EXECUTOR,
- /* tracingTagPrefix= */ "launcher"
- );
-
- mLauncherUnfoldAnimationController = new LauncherUnfoldAnimationController(
- this,
- getWindowManager(),
- mUnfoldTransitionProgressProvider
- );
- }
- }
-
- public void setTaskbarUIController(LauncherTaskbarUIController taskbarUIController) {
- mTaskbarUIController = taskbarUIController;
- }
-
- public @Nullable LauncherTaskbarUIController getTaskbarUIController() {
- return mTaskbarUIController;
- }
-
- public <T extends OverviewActionsView> T getActionsView() {
- return (T) mActionsView;
- }
-
- @Override
- protected void closeOpenViews(boolean animate) {
- super.closeOpenViews(animate);
- TaskUtils.closeSystemWindowsAsync(CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY);
- }
-
- @Override
- protected void collectStateHandlers(List<StateHandler> out) {
- super.collectStateHandlers(out);
- out.add(getDepthController());
- out.add(new RecentsViewStateController(this));
- out.add(new BackButtonAlphaHandler(this));
- }
-
- public DepthController getDepthController() {
- return mDepthController;
- }
-
- @Nullable
- public UnfoldTransitionProgressProvider getUnfoldTransitionProgressProvider() {
- return mUnfoldTransitionProgressProvider;
- }
-
- @Override
- public boolean supportsAdaptiveIconAnimation(View clickedView) {
- return mAppTransitionManager.hasControlRemoteAppTransitionPermission();
- }
-
- @Override
- public DragOptions getDefaultWorkspaceDragOptions() {
- if (mNextWorkspaceDragOptions != null) {
- DragOptions options = mNextWorkspaceDragOptions;
- mNextWorkspaceDragOptions = null;
- return options;
- }
- return super.getDefaultWorkspaceDragOptions();
- }
-
- public void setNextWorkspaceDragOptions(DragOptions dragOptions) {
- mNextWorkspaceDragOptions = dragOptions;
- }
-
- @Override
- public void useFadeOutAnimationForLauncherStart(CancellationSignal signal) {
- QuickstepTransitionManager appTransitionManager = getAppTransitionManager();
- appTransitionManager.setRemoteAnimationProvider(new RemoteAnimationProvider() {
- @Override
- public AnimatorSet createWindowAnimation(RemoteAnimationTargetCompat[] appTargets,
- RemoteAnimationTargetCompat[] wallpaperTargets) {
-
- // On the first call clear the reference.
- signal.cancel();
-
- ValueAnimator fadeAnimation = ValueAnimator.ofFloat(1, 0);
- fadeAnimation.addUpdateListener(new RemoteFadeOutAnimationListener(appTargets,
- wallpaperTargets));
- AnimatorSet anim = new AnimatorSet();
- anim.play(fadeAnimation);
- return anim;
- }
- }, signal);
- }
-
- @Override
- public float[] getNormalOverviewScaleAndOffset() {
- return DisplayController.getNavigationMode(this).hasGestures
- ? new float[] {1, 1} : new float[] {1.1f, NO_OFFSET};
- }
-
- @Override
- public void onDragLayerHierarchyChanged() {
- onLauncherStateOrFocusChanged();
- }
-
- @Override
- protected void onActivityFlagsChanged(int changeBits) {
- if ((changeBits
- & (ACTIVITY_STATE_WINDOW_FOCUSED | ACTIVITY_STATE_TRANSITION_ACTIVE)) != 0) {
- onLauncherStateOrFocusChanged();
- }
-
- if ((changeBits & ACTIVITY_STATE_STARTED) != 0) {
- mDepthController.setActivityStarted(isStarted());
- }
-
- if ((changeBits & ACTIVITY_STATE_RESUMED) != 0) {
- if (mTaskbarUIController != null) {
- mTaskbarUIController.onLauncherResumedOrPaused(hasBeenResumed());
- }
- }
-
- super.onActivityFlagsChanged(changeBits);
- }
-
- public boolean shouldBackButtonBeHidden(LauncherState toState) {
- NavigationMode mode = DisplayController.getNavigationMode(this);
- boolean shouldBackButtonBeHidden = mode.hasGestures
- && toState.hasFlag(FLAG_HIDE_BACK_BUTTON)
- && hasWindowFocus()
- && (getActivityFlags() & ACTIVITY_STATE_TRANSITION_ACTIVE) == 0;
- if (shouldBackButtonBeHidden) {
- // Show the back button if there is a floating view visible.
- shouldBackButtonBeHidden = AbstractFloatingView.getTopOpenViewWithType(this,
- TYPE_ALL & ~TYPE_HIDE_BACK_BUTTON) == null;
- }
- return shouldBackButtonBeHidden;
- }
-
- /**
- * Sets the back button visibility based on the current state/window focus.
- */
- private void onLauncherStateOrFocusChanged() {
- boolean shouldBackButtonBeHidden = shouldBackButtonBeHidden(getStateManager().getState());
- if (DisplayController.getNavigationMode(this) == TWO_BUTTONS) {
- UiThreadHelper.setBackButtonAlphaAsync(this, SET_BACK_BUTTON_ALPHA,
- shouldBackButtonBeHidden ? 0f : 1f, true /* animate */);
- }
- if (getDragLayer() != null) {
- getRootView().setDisallowBackGesture(shouldBackButtonBeHidden);
- }
- }
-
- @Override
- public void finishBindingItems(IntSet pagesBoundFirst) {
- super.finishBindingItems(pagesBoundFirst);
- // Instantiate and initialize WellbeingModel now that its loading won't interfere with
- // populating workspace.
- // TODO: Find a better place for this
- WellbeingModel.INSTANCE.get(this);
- }
-
- @Override
- public void onInitialBindComplete(IntSet boundPages, RunnableList pendingTasks) {
- pendingTasks.add(() -> {
- // This is added in pending task as we need to wait for views to be positioned
- // correctly before registering them for the animation.
- if (mLauncherUnfoldAnimationController != null) {
- // This is needed in case items are rebound while the unfold animation is in
- // progress.
- mLauncherUnfoldAnimationController.updateRegisteredViewsIfNeeded();
- }
- });
- super.onInitialBindComplete(boundPages, pendingTasks);
- }
-
- @Override
- public Stream<SystemShortcut.Factory> getSupportedShortcuts() {
- Stream<SystemShortcut.Factory> base = Stream.of(WellbeingModel.SHORTCUT_FACTORY);
- if (ENABLE_SPLIT_FROM_WORKSPACE.get() && mDeviceProfile.isTablet) {
- RecentsView recentsView = getOverviewPanel();
- // TODO: Pull it out of PagedOrentationHandler for split from workspace.
- List<SplitPositionOption> positions =
- recentsView.getPagedOrientationHandler().getSplitPositionOptions(
- mDeviceProfile);
- List<SystemShortcut.Factory<BaseQuickstepLauncher>> splitShortcuts = new ArrayList<>();
- for (SplitPositionOption position : positions) {
- splitShortcuts.add(getSplitSelectShortcutByPosition(position));
- }
- base = Stream.concat(base, splitShortcuts.stream());
- }
- return Stream.concat(base, super.getSupportedShortcuts());
- }
-
- @Override
- public ActivityOptionsWrapper getActivityLaunchOptions(View v, @Nullable ItemInfo item) {
- ActivityOptionsWrapper activityOptions =
- mAppTransitionManager.hasControlRemoteAppTransitionPermission()
- ? mAppTransitionManager.getActivityLaunchOptions(v)
- : super.getActivityLaunchOptions(v, item);
- if (mLastTouchUpTime > 0) {
- ActivityOptionsCompat.setLauncherSourceInfo(
- activityOptions.options, mLastTouchUpTime);
- }
- activityOptions.options.setSplashScreenStyle(SplashScreen.SPLASH_SCREEN_STYLE_ICON);
- activityOptions.options.setLaunchDisplayId(
- (v != null && v.getDisplay() != null) ? v.getDisplay().getDisplayId()
- : Display.DEFAULT_DISPLAY);
- addLaunchCookie(item, activityOptions.options);
- return activityOptions;
- }
-
- /**
- * Adds a new launch cookie for the activity launch if supported.
- *
- * @param info the item info for the launch
- * @param opts the options to set the launchCookie on.
- */
- public void addLaunchCookie(ItemInfo info, ActivityOptions opts) {
- IBinder launchCookie = getLaunchCookie(info);
- if (launchCookie != null) {
- opts.setLaunchCookie(launchCookie);
- }
- }
-
- /**
- * Return a new launch cookie for the activity launch if supported.
- *
- * @param info the item info for the launch
- */
- public IBinder getLaunchCookie(ItemInfo info) {
- if (info == null) {
- return null;
- }
- switch (info.container) {
- case LauncherSettings.Favorites.CONTAINER_DESKTOP:
- case LauncherSettings.Favorites.CONTAINER_HOTSEAT:
- // Fall through and continue it's on the workspace (we don't support swiping back
- // to other containers like all apps or the hotseat predictions (which can change)
- break;
- default:
- if (info.container >= 0) {
- // Also allow swiping to folders
- break;
- }
- // Reset any existing launch cookies associated with the cookie
- return ObjectWrapper.wrap(NO_MATCHING_ID);
- }
- switch (info.itemType) {
- case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
- case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
- case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT:
- case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
- // Fall through and continue if it's an app, shortcut, or widget
- break;
- default:
- // Reset any existing launch cookies associated with the cookie
- return ObjectWrapper.wrap(NO_MATCHING_ID);
- }
- return ObjectWrapper.wrap(new Integer(info.id));
- }
-
- public void setHintUserWillBeActive() {
- addActivityFlags(ACTIVITY_STATE_USER_WILL_BE_ACTIVE);
- }
-
- @Override
- public void onDisplayInfoChanged(Context context, DisplayController.Info info, int flags) {
- super.onDisplayInfoChanged(context, info, flags);
- // When changing screens, force moving to rest state similar to StatefulActivity.onStop, as
- // StatefulActivity isn't called consistently.
- if ((flags & CHANGE_ACTIVE_SCREEN) != 0) {
- getStateManager().moveToRestState();
- }
-
- if ((flags & CHANGE_NAVIGATION_MODE) != 0) {
- getDragLayer().recreateControllers();
- if (mActionsView != null) {
- mActionsView.updateVerticalMargin(info.navigationMode);
- }
- }
- }
-
- @Override
- public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
- super.dump(prefix, fd, writer, args);
- if (mDepthController != null) {
- mDepthController.dump(prefix, writer);
- }
- }
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
-
- // If Launcher shuts downs during split select, we save some extra data in the recovery
- // bundle to allow graceful recovery. The normal LauncherState restore mechanism doesn't
- // work in this case because restoring straight to OverviewSplitSelect without staging data,
- // or before the tasks themselves have loaded into Overview, causes a crash. So we tell
- // Launcher to first restore into Overview state, wait for the relevant tasks and icons to
- // load in, and then proceed to OverviewSplitSelect.
- if (isInState(OVERVIEW_SPLIT_SELECT)) {
- SplitSelectStateController splitSelectStateController =
- ((RecentsView) getOverviewPanel()).getSplitPlaceholder();
- // Launcher will restart in Overview and then transition to OverviewSplitSelect.
- outState.putIBinder(PENDING_SPLIT_SELECT_INFO, ObjectWrapper.wrap(
- new PendingSplitSelectInfo(
- splitSelectStateController.getInitialTaskId(),
- splitSelectStateController.getActiveSplitStagePosition()
- )
- ));
- outState.putInt(RUNTIME_STATE, OVERVIEW.ordinal);
- }
- }
-
- /**
- * When Launcher restarts, it sometimes needs to recover to a split selection state.
- * This function checks if such a recovery is needed.
- * @return a boolean representing whether the launcher is waiting to recover to
- * OverviewSplitSelect state.
- */
- public boolean hasPendingSplitSelectInfo() {
- return mPendingSplitSelectInfo != null;
- }
-
- /**
- * See {@link #hasPendingSplitSelectInfo()}
- */
- public @Nullable PendingSplitSelectInfo getPendingSplitSelectInfo() {
- return mPendingSplitSelectInfo;
- }
-
- /**
- * When the launcher has successfully recovered to OverviewSplitSelect state, this function
- * deletes the recovery data, returning it to a null state.
- */
- public void finishSplitSelectRecovery() {
- mPendingSplitSelectInfo = null;
- }
-}
diff --git a/quickstep/src/com/android/launcher3/LauncherInitListener.java b/quickstep/src/com/android/launcher3/LauncherInitListener.java
index 35151f1..c4e85f6 100644
--- a/quickstep/src/com/android/launcher3/LauncherInitListener.java
+++ b/quickstep/src/com/android/launcher3/LauncherInitListener.java
@@ -20,6 +20,7 @@
import android.os.Build;
import android.os.CancellationSignal;
+import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.quickstep.util.ActivityInitListener;
import com.android.quickstep.util.RemoteAnimationProvider;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
@@ -44,7 +45,7 @@
public boolean handleInit(Launcher launcher, boolean alreadyOnHome) {
if (mRemoteAnimationProvider != null) {
QuickstepTransitionManager appTransitionManager =
- ((BaseQuickstepLauncher) launcher).getAppTransitionManager();
+ ((QuickstepLauncher) launcher).getAppTransitionManager();
// Set a one-time animation provider. After the first call, this will get cleared.
// TODO: Probably also check the intended target id.
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index d348cc3..521b3fe 100644
--- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
@@ -102,6 +102,7 @@
import com.android.launcher3.taskbar.LauncherTaskbarUIController;
import com.android.launcher3.testing.shared.ResourceUtils;
import com.android.launcher3.touch.PagedOrientationHandler;
+import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.ActivityOptionsWrapper;
import com.android.launcher3.util.DynamicResource;
import com.android.launcher3.util.ObjectWrapper;
@@ -193,7 +194,7 @@
// Cross-fade duration between App Widget and App
private static final int WIDGET_CROSSFADE_DURATION_MILLIS = 125;
- protected final BaseQuickstepLauncher mLauncher;
+ protected final QuickstepLauncher mLauncher;
private final DragLayer mDragLayer;
final Handler mHandler;
diff --git a/quickstep/src/com/android/launcher3/popup/QuickstepSystemShortcut.java b/quickstep/src/com/android/launcher3/popup/QuickstepSystemShortcut.java
index 89c07f2..a0cf6cb 100644
--- a/quickstep/src/com/android/launcher3/popup/QuickstepSystemShortcut.java
+++ b/quickstep/src/com/android/launcher3/popup/QuickstepSystemShortcut.java
@@ -23,9 +23,9 @@
import android.util.Log;
import android.view.View;
-import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
+import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
import com.android.quickstep.views.RecentsView;
@@ -33,18 +33,18 @@
String TAG = QuickstepSystemShortcut.class.getSimpleName();
- static SystemShortcut.Factory<BaseQuickstepLauncher> getSplitSelectShortcutByPosition(
+ static SystemShortcut.Factory<QuickstepLauncher> getSplitSelectShortcutByPosition(
SplitPositionOption position) {
return (activity, itemInfo, originalView) ->
new QuickstepSystemShortcut.SplitSelectSystemShortcut(activity, itemInfo,
originalView, position);
}
- class SplitSelectSystemShortcut extends SystemShortcut<BaseQuickstepLauncher> {
+ class SplitSelectSystemShortcut extends SystemShortcut<QuickstepLauncher> {
private final SplitPositionOption mPosition;
- public SplitSelectSystemShortcut(BaseQuickstepLauncher launcher, ItemInfo itemInfo,
+ public SplitSelectSystemShortcut(QuickstepLauncher launcher, ItemInfo itemInfo,
View originalView, SplitPositionOption position) {
super(position.iconResId, position.textResId, launcher, itemInfo, originalView);
diff --git a/quickstep/src/com/android/launcher3/statehandlers/BackButtonAlphaHandler.java b/quickstep/src/com/android/launcher3/statehandlers/BackButtonAlphaHandler.java
index 07d3a51..8c11081 100644
--- a/quickstep/src/com/android/launcher3/statehandlers/BackButtonAlphaHandler.java
+++ b/quickstep/src/com/android/launcher3/statehandlers/BackButtonAlphaHandler.java
@@ -20,11 +20,11 @@
import static com.android.launcher3.util.DisplayController.NavigationMode.TWO_BUTTONS;
import static com.android.quickstep.AnimatedFloat.VALUE;
-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.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.UiThreadHelper;
import com.android.quickstep.AnimatedFloat;
@@ -35,10 +35,10 @@
*/
public class BackButtonAlphaHandler implements StateHandler<LauncherState> {
- private final BaseQuickstepLauncher mLauncher;
+ private final QuickstepLauncher mLauncher;
private final AnimatedFloat mBackAlpha = new AnimatedFloat(this::updateBackAlpha);
- public BackButtonAlphaHandler(BaseQuickstepLauncher launcher) {
+ public BackButtonAlphaHandler(QuickstepLauncher launcher) {
mLauncher = launcher;
}
@@ -59,6 +59,6 @@
private void updateBackAlpha() {
UiThreadHelper.setBackButtonAlphaAsync(mLauncher,
- BaseQuickstepLauncher.SET_BACK_BUTTON_ALPHA, mBackAlpha.value, false /* animate */);
+ QuickstepLauncher.SET_BACK_BUTTON_ALPHA, mBackAlpha.value, false /* animate */);
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/DesktopTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/DesktopTaskbarUIController.java
index 3c76e8e..d69b8d2 100644
--- a/quickstep/src/com/android/launcher3/taskbar/DesktopTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/DesktopTaskbarUIController.java
@@ -16,7 +16,7 @@
package com.android.launcher3.taskbar;
-import com.android.launcher3.BaseQuickstepLauncher;
+import com.android.launcher3.uioverrides.QuickstepLauncher;
/**
* A data source which integrates with a Launcher instance, used specifically for a
@@ -24,9 +24,9 @@
*/
public class DesktopTaskbarUIController extends TaskbarUIController {
- private final BaseQuickstepLauncher mLauncher;
+ private final QuickstepLauncher mLauncher;
- public DesktopTaskbarUIController(BaseQuickstepLauncher launcher) {
+ public DesktopTaskbarUIController(QuickstepLauncher launcher) {
mLauncher = launcher;
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
index 62a11d4..6c740ba 100644
--- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
@@ -32,7 +32,6 @@
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
-import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.LauncherState;
import com.android.launcher3.QuickstepTransitionManager;
@@ -42,6 +41,7 @@
import com.android.launcher3.logging.InstanceIdSequence;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.ItemInfoWithIcon;
+import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.OnboardingPrefs;
import com.android.quickstep.AnimatedFloat;
import com.android.quickstep.RecentsAnimationCallbacks;
@@ -65,7 +65,7 @@
private final SparseArray<Float> mTaskbarInAppDisplayProgress = new SparseArray<>(4);
- private final BaseQuickstepLauncher mLauncher;
+ private final QuickstepLauncher mLauncher;
private final DeviceProfile.OnDeviceProfileChangeListener mOnDeviceProfileChangeListener =
dp -> {
@@ -81,7 +81,7 @@
private final TaskbarLauncherStateController
mTaskbarLauncherStateController = new TaskbarLauncherStateController();
- public LauncherTaskbarUIController(BaseQuickstepLauncher launcher) {
+ public LauncherTaskbarUIController(QuickstepLauncher launcher) {
mLauncher = launcher;
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
index 0bda3cd..ee94e8c 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
@@ -31,13 +31,13 @@
import androidx.annotation.Nullable;
import com.android.launcher3.AbstractFloatingView;
-import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.LauncherState;
import com.android.launcher3.QuickstepTransitionManager;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatorListeners;
import com.android.launcher3.statemanager.StateManager;
+import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.MultiValueAlpha;
import com.android.quickstep.AnimatedFloat;
import com.android.quickstep.RecentsAnimationCallbacks;
@@ -78,7 +78,7 @@
private TaskbarControllers mControllers;
private AnimatedFloat mTaskbarBackgroundAlpha;
private MultiValueAlpha.AlphaProperty mIconAlphaForHome;
- private BaseQuickstepLauncher mLauncher;
+ private QuickstepLauncher mLauncher;
private Integer mPrevState;
private int mState;
@@ -132,7 +132,7 @@
}
};
- public void init(TaskbarControllers controllers, BaseQuickstepLauncher launcher) {
+ public void init(TaskbarControllers controllers, QuickstepLauncher launcher) {
mCanSyncViews = false;
mControllers = controllers;
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
index 1212c61..35c5b96 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
@@ -37,12 +37,12 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.statemanager.StatefulActivity;
import com.android.launcher3.taskbar.unfold.NonDestroyableScopedUnfoldTransitionProgressProvider;
+import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.SettingsCache;
import com.android.launcher3.util.SimpleBroadcastReceiver;
@@ -237,8 +237,8 @@
*/
private UnfoldTransitionProgressProvider getUnfoldTransitionProgressProviderForActivity(
StatefulActivity activity) {
- if (activity instanceof BaseQuickstepLauncher) {
- return ((BaseQuickstepLauncher) activity).getUnfoldTransitionProgressProvider();
+ if (activity instanceof QuickstepLauncher) {
+ return ((QuickstepLauncher) activity).getUnfoldTransitionProgressProvider();
}
return null;
}
@@ -247,11 +247,11 @@
* Creates a {@link TaskbarUIController} to use while the given StatefulActivity is active.
*/
private TaskbarUIController createTaskbarUIControllerForActivity(StatefulActivity activity) {
- if (activity instanceof BaseQuickstepLauncher) {
+ if (activity instanceof QuickstepLauncher) {
if (mTaskbarActivityContext.getPackageManager().hasSystemFeature(FEATURE_PC)) {
- return new DesktopTaskbarUIController((BaseQuickstepLauncher) activity);
+ return new DesktopTaskbarUIController((QuickstepLauncher) activity);
}
- return new LauncherTaskbarUIController((BaseQuickstepLauncher) activity);
+ return new LauncherTaskbarUIController((QuickstepLauncher) activity);
}
if (activity instanceof RecentsActivity) {
return new FallbackTaskbarUIController((RecentsActivity) activity);
diff --git a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
index ea0972f..8427885 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
@@ -42,7 +42,6 @@
import androidx.annotation.NonNull;
-import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.PendingAnimation;
@@ -61,9 +60,9 @@
public abstract class BaseRecentsViewStateController<T extends RecentsView>
implements StateHandler<LauncherState> {
protected final T mRecentsView;
- protected final BaseQuickstepLauncher mLauncher;
+ protected final QuickstepLauncher mLauncher;
- public BaseRecentsViewStateController(@NonNull BaseQuickstepLauncher launcher) {
+ public BaseRecentsViewStateController(@NonNull QuickstepLauncher launcher) {
mLauncher = launcher;
mRecentsView = launcher.getOverviewPanel();
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index 951226c..0f3ea15 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -17,46 +17,90 @@
import static android.view.accessibility.AccessibilityEvent.TYPE_VIEW_FOCUSED;
+import static com.android.launcher3.AbstractFloatingView.TYPE_ALL;
+import static com.android.launcher3.AbstractFloatingView.TYPE_HIDE_BACK_BUTTON;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT;
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT;
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
import static com.android.launcher3.LauncherState.ALL_APPS;
+import static com.android.launcher3.LauncherState.FLAG_HIDE_BACK_BUTTON;
import static com.android.launcher3.LauncherState.NORMAL;
+import static com.android.launcher3.LauncherState.NO_OFFSET;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.LauncherState.OVERVIEW_MODAL_TASK;
+import static com.android.launcher3.LauncherState.OVERVIEW_SPLIT_SELECT;
import static com.android.launcher3.compat.AccessibilityManagerCompat.sendCustomAccessibilityEvent;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_SPLIT_FROM_WORKSPACE;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_APP_LAUNCH_TAP;
+import static com.android.launcher3.model.data.ItemInfo.NO_MATCHING_ID;
+import static com.android.launcher3.popup.QuickstepSystemShortcut.getSplitSelectShortcutByPosition;
+import static com.android.launcher3.taskbar.LauncherTaskbarUIController.ALL_APPS_PAGE_PROGRESS_INDEX;
+import static com.android.launcher3.taskbar.LauncherTaskbarUIController.MINUS_ONE_PAGE_PROGRESS_INDEX;
+import static com.android.launcher3.taskbar.LauncherTaskbarUIController.WIDGETS_PAGE_PROGRESS_INDEX;
import static com.android.launcher3.testing.shared.TestProtocol.HINT_STATE_ORDINAL;
import static com.android.launcher3.testing.shared.TestProtocol.HINT_STATE_TWO_BUTTON_ORDINAL;
import static com.android.launcher3.testing.shared.TestProtocol.OVERVIEW_STATE_ORDINAL;
import static com.android.launcher3.testing.shared.TestProtocol.QUICK_SWITCH_STATE_ORDINAL;
+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.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.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY;
+import android.animation.AnimatorSet;
+import android.animation.ValueAnimator;
+import android.app.ActivityManager;
+import android.app.ActivityOptions;
+import android.content.Context;
import android.content.Intent;
+import android.content.IntentSender;
import android.content.SharedPreferences;
import android.content.res.Configuration;
+import android.hardware.SensorManager;
+import android.hardware.devicestate.DeviceStateManager;
+import android.os.Bundle;
+import android.os.CancellationSignal;
+import android.os.IBinder;
+import android.view.Display;
import android.view.HapticFeedbackConstants;
import android.view.View;
+import android.window.SplashScreen;
-import com.android.launcher3.BaseQuickstepLauncher;
+import androidx.annotation.Nullable;
+
+import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.LauncherState;
import com.android.launcher3.QuickstepAccessibilityDelegate;
+import com.android.launcher3.QuickstepTransitionManager;
+import com.android.launcher3.R;
import com.android.launcher3.Workspace;
import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.appprediction.PredictionRowView;
+import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.hybridhotseat.HotseatPredictionController;
import com.android.launcher3.logging.InstanceId;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.logging.StatsLogManager.StatsLogger;
import com.android.launcher3.model.BgDataModel.FixedContainerItems;
+import com.android.launcher3.model.WellbeingModel;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.popup.SystemShortcut;
+import com.android.launcher3.proxy.ProxyActivityStarter;
+import com.android.launcher3.proxy.StartActivityParams;
+import com.android.launcher3.statehandlers.BackButtonAlphaHandler;
+import com.android.launcher3.statehandlers.DepthController;
import com.android.launcher3.statemanager.StateManager.AtomicAnimationFactory;
+import com.android.launcher3.statemanager.StateManager.StateHandler;
+import com.android.launcher3.taskbar.LauncherTaskbarUIController;
+import com.android.launcher3.taskbar.TaskbarManager;
import com.android.launcher3.uioverrides.states.QuickstepAtomicAnimationFactory;
import com.android.launcher3.uioverrides.touchcontrollers.NavBarToHomeTouchController;
import com.android.launcher3.uioverrides.touchcontrollers.NoButtonNavbarToOverviewTouchController;
@@ -67,27 +111,53 @@
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.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.PendingRequestArgs;
+import com.android.launcher3.util.PendingSplitSelectInfo;
+import com.android.launcher3.util.RunnableList;
+import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
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.OverviewCommandHelper;
+import com.android.quickstep.RecentsModel;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.TaskUtils;
+import com.android.quickstep.TouchInteractionService.TISBinder;
+import com.android.quickstep.util.LauncherUnfoldAnimationController;
+import com.android.quickstep.util.ProxyScreenStatusProvider;
import com.android.quickstep.util.QuickstepOnboardingPrefs;
+import com.android.quickstep.util.RemoteAnimationProvider;
+import com.android.quickstep.util.RemoteFadeOutAnimationListener;
+import com.android.quickstep.util.SplitSelectStateController;
+import com.android.quickstep.util.TISBindHelper;
+import com.android.quickstep.views.OverviewActionsView;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.ActivityOptionsCompat;
+import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
+import com.android.systemui.unfold.UnfoldTransitionFactory;
+import com.android.systemui.unfold.UnfoldTransitionProgressProvider;
+import com.android.systemui.unfold.config.ResourceUnfoldTransitionConfig;
+import com.android.systemui.unfold.config.UnfoldTransitionConfig;
+import com.android.systemui.unfold.system.ActivityManagerActivityTypeProvider;
+import com.android.systemui.unfold.system.DeviceStateManagerFoldProvider;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;
import java.util.stream.Stream;
-public class QuickstepLauncher extends BaseQuickstepLauncher {
+public class QuickstepLauncher extends Launcher {
public static final boolean GO_LOW_RAM_RECENTS_ENABLED = false;
/**
@@ -95,13 +165,51 @@
*/
public static final AsyncCommand SET_SHELF_HEIGHT = (context, arg1, arg2) ->
SystemUiProxy.INSTANCE.get(context).setShelfHeight(arg1 != 0, arg2);
+ /**
+ * Reusable command for applying the back button alpha on the background thread.
+ */
+ public static final AsyncCommand SET_BACK_BUTTON_ALPHA =
+ (context, arg1, arg2) -> SystemUiProxy.INSTANCE.get(context).setNavBarButtonAlpha(
+ Float.intBitsToFloat(arg1), arg2 != 0);
private FixedContainerItems mAllAppsPredictions;
private HotseatPredictionController mHotseatPredictionController;
+ private DepthController mDepthController;
+ private QuickstepTransitionManager mAppTransitionManager;
+ private OverviewActionsView mActionsView;
+ private TISBindHelper mTISBindHelper;
+ private @Nullable TaskbarManager mTaskbarManager;
+ private @Nullable OverviewCommandHelper mOverviewCommandHelper;
+ private @Nullable LauncherTaskbarUIController mTaskbarUIController;
+ // Will be updated when dragging from taskbar.
+ private @Nullable DragOptions mNextWorkspaceDragOptions = null;
+ private @Nullable UnfoldTransitionProgressProvider mUnfoldTransitionProgressProvider;
+ private @Nullable LauncherUnfoldAnimationController mLauncherUnfoldAnimationController;
+ /**
+ * If Launcher restarted while in the middle of an Overview split select, it needs this data to
+ * recover. In all other cases this will remain null.
+ */
+ private PendingSplitSelectInfo mPendingSplitSelectInfo = null;
@Override
protected void setupViews() {
super.setupViews();
+
+ mActionsView = findViewById(R.id.overview_actions_view);
+ RecentsView overviewPanel = (RecentsView) getOverviewPanel();
+ SplitSelectStateController controller =
+ new SplitSelectStateController(this, mHandler, getStateManager(),
+ getDepthController());
+ overviewPanel.init(mActionsView, controller);
+ mActionsView.updateDimension(getDeviceProfile(), overviewPanel.getLastComputedTaskSize());
+ mActionsView.updateVerticalMargin(DisplayController.getNavigationMode(this));
+
+ mAppTransitionManager = new QuickstepTransitionManager(this);
+ mAppTransitionManager.registerRemoteAnimations();
+ mAppTransitionManager.registerRemoteTransitions();
+
+ mTISBindHelper = new TISBindHelper(this, this::onTISConnected);
+ mDepthController = new DepthController(this);
mHotseatPredictionController = new HotseatPredictionController(this);
}
@@ -183,6 +291,21 @@
@Override
protected void onActivityFlagsChanged(int changeBits) {
+ if ((changeBits
+ & (ACTIVITY_STATE_WINDOW_FOCUSED | ACTIVITY_STATE_TRANSITION_ACTIVE)) != 0) {
+ onLauncherStateOrFocusChanged();
+ }
+
+ if ((changeBits & ACTIVITY_STATE_STARTED) != 0) {
+ mDepthController.setActivityStarted(isStarted());
+ }
+
+ if ((changeBits & ACTIVITY_STATE_RESUMED) != 0) {
+ if (mTaskbarUIController != null) {
+ mTaskbarUIController.onLauncherResumedOrPaused(hasBeenResumed());
+ }
+ }
+
super.onActivityFlagsChanged(changeBits);
if ((changeBits & (ACTIVITY_STATE_DEFERRED_RESUMED | ACTIVITY_STATE_STARTED
| ACTIVITY_STATE_USER_ACTIVE | ACTIVITY_STATE_TRANSITION_ACTIVE)) != 0) {
@@ -203,8 +326,22 @@
@Override
public Stream<SystemShortcut.Factory> getSupportedShortcuts() {
+ Stream<SystemShortcut.Factory> base = Stream.of(WellbeingModel.SHORTCUT_FACTORY);
+ if (ENABLE_SPLIT_FROM_WORKSPACE.get() && mDeviceProfile.isTablet) {
+ RecentsView recentsView = getOverviewPanel();
+ // TODO: Pull it out of PagedOrentationHandler for split from workspace.
+ List<SplitPositionOption> positions =
+ recentsView.getPagedOrientationHandler().getSplitPositionOptions(
+ mDeviceProfile);
+ List<SystemShortcut.Factory<QuickstepLauncher>> splitShortcuts = new ArrayList<>();
+ for (SplitPositionOption position : positions) {
+ splitShortcuts.add(getSplitSelectShortcutByPosition(position));
+ }
+ base = Stream.concat(base, splitShortcuts.stream());
+ }
return Stream.concat(
- Stream.of(mHotseatPredictionController), super.getSupportedShortcuts());
+ Stream.of(mHotseatPredictionController),
+ Stream.concat(base, super.getSupportedShortcuts()));
}
/**
@@ -251,6 +388,20 @@
@Override
public void onDestroy() {
+ mAppTransitionManager.onActivityDestroyed();
+ if (mUnfoldTransitionProgressProvider != null) {
+ mUnfoldTransitionProgressProvider.destroy();
+ }
+
+ mTISBindHelper.onDestroy();
+ if (mTaskbarManager != null) {
+ mTaskbarManager.clearActivity(this);
+ }
+
+ if (mLauncherUnfoldAnimationController != null) {
+ mLauncherUnfoldAnimationController.onDestroy();
+ }
+
super.onDestroy();
mHotseatPredictionController.destroy();
}
@@ -258,6 +409,7 @@
@Override
public void onStateSetEnd(LauncherState state) {
super.onStateSetEnd(state);
+ handlePendingActivityRequest();
switch (state.ordinal) {
case HINT_STATE_ORDINAL: {
@@ -342,6 +494,481 @@
return appWidgetHost;
}
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ if (savedInstanceState != null) {
+ mPendingSplitSelectInfo = ObjectWrapper.unwrap(
+ savedInstanceState.getIBinder(PENDING_SPLIT_SELECT_INFO));
+ }
+ addMultiWindowModeChangedListener(mDepthController);
+ initUnfoldTransitionProgressProvider();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+
+ if (mLauncherUnfoldAnimationController != null) {
+ mLauncherUnfoldAnimationController.onResume();
+ }
+ }
+
+ @Override
+ protected void onPause() {
+ if (mLauncherUnfoldAnimationController != null) {
+ mLauncherUnfoldAnimationController.onPause();
+ }
+
+ super.onPause();
+ }
+
+ @Override
+ protected void onNewIntent(Intent intent) {
+ super.onNewIntent(intent);
+
+ if (mOverviewCommandHelper != null) {
+ mOverviewCommandHelper.clearPendingCommands();
+ }
+ }
+
+ public QuickstepTransitionManager getAppTransitionManager() {
+ return mAppTransitionManager;
+ }
+
+ @Override
+ public void onEnterAnimationComplete() {
+ super.onEnterAnimationComplete();
+ // After the transition to home, enable the high-res thumbnail loader if it wasn't enabled
+ // as a part of quickstep, so that high-res thumbnails can load the next time we enter
+ // overview
+ RecentsModel.INSTANCE.get(this).getThumbnailCache()
+ .getHighResLoadingState().setVisible(true);
+ }
+
+ @Override
+ protected void handleGestureContract(Intent intent) {
+ if (FeatureFlags.SEPARATE_RECENTS_ACTIVITY.get()) {
+ super.handleGestureContract(intent);
+ }
+ }
+
+ @Override
+ public void onTrimMemory(int level) {
+ super.onTrimMemory(level);
+ RecentsModel.INSTANCE.get(this).onTrimMemory(level);
+ }
+
+ @Override
+ public void onUiChangedWhileSleeping() {
+ // Remove the snapshot because the content view may have obvious changes.
+ UI_HELPER_EXECUTOR.execute(
+ () -> ActivityManagerWrapper.getInstance().invalidateHomeTaskSnapshot(this));
+ }
+
+ @Override
+ protected void onScreenOff() {
+ super.onScreenOff();
+ if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
+ RecentsView recentsView = getOverviewPanel();
+ recentsView.finishRecentsAnimation(true /* toRecents */, null);
+ }
+ }
+
+ /**
+ * {@code LauncherOverlayCallbacks} scroll amount.
+ * Indicates transition progress to -1 screen.
+ * @param progress From 0 to 1.
+ */
+ @Override
+ public void onScrollChanged(float progress) {
+ super.onScrollChanged(progress);
+ onTaskbarInAppDisplayProgressUpdate(progress, MINUS_ONE_PAGE_PROGRESS_INDEX);
+ }
+
+ @Override
+ public void onAllAppsTransition(float progress) {
+ super.onAllAppsTransition(progress);
+ onTaskbarInAppDisplayProgressUpdate(progress, ALL_APPS_PAGE_PROGRESS_INDEX);
+ }
+
+ @Override
+ public void onWidgetsTransition(float progress) {
+ super.onWidgetsTransition(progress);
+ onTaskbarInAppDisplayProgressUpdate(progress, WIDGETS_PAGE_PROGRESS_INDEX);
+ }
+
+ private void onTaskbarInAppDisplayProgressUpdate(float progress, int flag) {
+ if (mTaskbarManager == null
+ || mTaskbarManager.getCurrentActivityContext() == null
+ || mTaskbarUIController == null) {
+ return;
+ }
+ mTaskbarUIController.onTaskbarInAppDisplayProgressUpdate(progress, flag);
+ }
+
+ @Override
+ public void startIntentSenderForResult(IntentSender intent, int requestCode,
+ Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, Bundle options) {
+ if (requestCode != -1) {
+ mPendingActivityRequestCode = requestCode;
+ StartActivityParams params = new StartActivityParams(this, requestCode);
+ params.intentSender = intent;
+ params.fillInIntent = fillInIntent;
+ params.flagsMask = flagsMask;
+ params.flagsValues = flagsValues;
+ params.extraFlags = extraFlags;
+ params.options = options;
+ startActivity(ProxyActivityStarter.getLaunchIntent(this, params));
+ } else {
+ super.startIntentSenderForResult(intent, requestCode, fillInIntent, flagsMask,
+ flagsValues, extraFlags, options);
+ }
+ }
+
+ @Override
+ public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
+ if (requestCode != -1) {
+ mPendingActivityRequestCode = requestCode;
+ StartActivityParams params = new StartActivityParams(this, requestCode);
+ params.intent = intent;
+ params.options = options;
+ startActivity(ProxyActivityStarter.getLaunchIntent(this, params));
+ } else {
+ super.startActivityForResult(intent, requestCode, options);
+ }
+ }
+
+ @Override
+ protected void onDeferredResumed() {
+ super.onDeferredResumed();
+ handlePendingActivityRequest();
+ }
+
+ private void handlePendingActivityRequest() {
+ if (mPendingActivityRequestCode != -1 && isInState(NORMAL)
+ && ((getActivityFlags() & ACTIVITY_STATE_DEFERRED_RESUMED) != 0)) {
+ // Remove any active ProxyActivityStarter task and send RESULT_CANCELED to Launcher.
+ onActivityResult(mPendingActivityRequestCode, RESULT_CANCELED, null);
+ // ProxyActivityStarter is started with clear task to reset the task after which it
+ // removes the task itself.
+ startActivity(ProxyActivityStarter.getLaunchIntent(this, null));
+ }
+ }
+
+ private void onTISConnected(TISBinder binder) {
+ mTaskbarManager = binder.getTaskbarManager();
+ mTaskbarManager.setActivity(this);
+ mOverviewCommandHelper = binder.getOverviewCommandHelper();
+ }
+
+ @Override
+ public void runOnBindToTouchInteractionService(Runnable r) {
+ mTISBindHelper.runOnBindToTouchInteractionService(r);
+ }
+
+ private void initUnfoldTransitionProgressProvider() {
+ final UnfoldTransitionConfig config = new ResourceUnfoldTransitionConfig();
+ if (config.isEnabled()) {
+ mUnfoldTransitionProgressProvider =
+ UnfoldTransitionFactory.createUnfoldTransitionProgressProvider(
+ /* context= */ this,
+ config,
+ ProxyScreenStatusProvider.INSTANCE,
+ new DeviceStateManagerFoldProvider(
+ getSystemService(DeviceStateManager.class), /* context */this),
+ new ActivityManagerActivityTypeProvider(
+ getSystemService(ActivityManager.class)),
+ getSystemService(SensorManager.class),
+ getMainThreadHandler(),
+ getMainExecutor(),
+ /* backgroundExecutor= */ THREAD_POOL_EXECUTOR,
+ /* tracingTagPrefix= */ "launcher"
+ );
+
+ mLauncherUnfoldAnimationController = new LauncherUnfoldAnimationController(
+ this,
+ getWindowManager(),
+ mUnfoldTransitionProgressProvider
+ );
+ }
+ }
+
+ public void setTaskbarUIController(LauncherTaskbarUIController taskbarUIController) {
+ mTaskbarUIController = taskbarUIController;
+ }
+
+ public @Nullable LauncherTaskbarUIController getTaskbarUIController() {
+ return mTaskbarUIController;
+ }
+
+ public <T extends OverviewActionsView> T getActionsView() {
+ return (T) mActionsView;
+ }
+
+ @Override
+ protected void closeOpenViews(boolean animate) {
+ super.closeOpenViews(animate);
+ TaskUtils.closeSystemWindowsAsync(CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY);
+ }
+
+ @Override
+ protected void collectStateHandlers(List<StateHandler> out) {
+ super.collectStateHandlers(out);
+ out.add(getDepthController());
+ out.add(new RecentsViewStateController(this));
+ out.add(new BackButtonAlphaHandler(this));
+ }
+
+ public DepthController getDepthController() {
+ return mDepthController;
+ }
+
+ @Nullable
+ public UnfoldTransitionProgressProvider getUnfoldTransitionProgressProvider() {
+ return mUnfoldTransitionProgressProvider;
+ }
+
+ @Override
+ public boolean supportsAdaptiveIconAnimation(View clickedView) {
+ return mAppTransitionManager.hasControlRemoteAppTransitionPermission();
+ }
+
+ @Override
+ public DragOptions getDefaultWorkspaceDragOptions() {
+ if (mNextWorkspaceDragOptions != null) {
+ DragOptions options = mNextWorkspaceDragOptions;
+ mNextWorkspaceDragOptions = null;
+ return options;
+ }
+ return super.getDefaultWorkspaceDragOptions();
+ }
+
+ public void setNextWorkspaceDragOptions(DragOptions dragOptions) {
+ mNextWorkspaceDragOptions = dragOptions;
+ }
+
+ @Override
+ public void useFadeOutAnimationForLauncherStart(CancellationSignal signal) {
+ QuickstepTransitionManager appTransitionManager = getAppTransitionManager();
+ appTransitionManager.setRemoteAnimationProvider(new RemoteAnimationProvider() {
+ @Override
+ public AnimatorSet createWindowAnimation(RemoteAnimationTargetCompat[] appTargets,
+ RemoteAnimationTargetCompat[] wallpaperTargets) {
+
+ // On the first call clear the reference.
+ signal.cancel();
+
+ ValueAnimator fadeAnimation = ValueAnimator.ofFloat(1, 0);
+ fadeAnimation.addUpdateListener(new RemoteFadeOutAnimationListener(appTargets,
+ wallpaperTargets));
+ AnimatorSet anim = new AnimatorSet();
+ anim.play(fadeAnimation);
+ return anim;
+ }
+ }, signal);
+ }
+
+ @Override
+ public float[] getNormalOverviewScaleAndOffset() {
+ return DisplayController.getNavigationMode(this).hasGestures
+ ? new float[] {1, 1} : new float[] {1.1f, NO_OFFSET};
+ }
+
+ @Override
+ public void onDragLayerHierarchyChanged() {
+ onLauncherStateOrFocusChanged();
+ }
+
+ public boolean shouldBackButtonBeHidden(LauncherState toState) {
+ NavigationMode mode = DisplayController.getNavigationMode(this);
+ boolean shouldBackButtonBeHidden = mode.hasGestures
+ && toState.hasFlag(FLAG_HIDE_BACK_BUTTON)
+ && hasWindowFocus()
+ && (getActivityFlags() & ACTIVITY_STATE_TRANSITION_ACTIVE) == 0;
+ if (shouldBackButtonBeHidden) {
+ // Show the back button if there is a floating view visible.
+ shouldBackButtonBeHidden = AbstractFloatingView.getTopOpenViewWithType(this,
+ TYPE_ALL & ~TYPE_HIDE_BACK_BUTTON) == null;
+ }
+ return shouldBackButtonBeHidden;
+ }
+
+ /**
+ * Sets the back button visibility based on the current state/window focus.
+ */
+ private void onLauncherStateOrFocusChanged() {
+ boolean shouldBackButtonBeHidden = shouldBackButtonBeHidden(getStateManager().getState());
+ if (DisplayController.getNavigationMode(this) == TWO_BUTTONS) {
+ UiThreadHelper.setBackButtonAlphaAsync(this, SET_BACK_BUTTON_ALPHA,
+ shouldBackButtonBeHidden ? 0f : 1f, true /* animate */);
+ }
+ if (getDragLayer() != null) {
+ getRootView().setDisallowBackGesture(shouldBackButtonBeHidden);
+ }
+ }
+
+ @Override
+ public void finishBindingItems(IntSet pagesBoundFirst) {
+ super.finishBindingItems(pagesBoundFirst);
+ // Instantiate and initialize WellbeingModel now that its loading won't interfere with
+ // populating workspace.
+ // TODO: Find a better place for this
+ WellbeingModel.INSTANCE.get(this);
+ }
+
+ @Override
+ public void onInitialBindComplete(IntSet boundPages, RunnableList pendingTasks) {
+ pendingTasks.add(() -> {
+ // This is added in pending task as we need to wait for views to be positioned
+ // correctly before registering them for the animation.
+ if (mLauncherUnfoldAnimationController != null) {
+ // This is needed in case items are rebound while the unfold animation is in
+ // progress.
+ mLauncherUnfoldAnimationController.updateRegisteredViewsIfNeeded();
+ }
+ });
+ super.onInitialBindComplete(boundPages, pendingTasks);
+ }
+
+ @Override
+ public ActivityOptionsWrapper getActivityLaunchOptions(View v, @Nullable ItemInfo item) {
+ ActivityOptionsWrapper activityOptions =
+ mAppTransitionManager.hasControlRemoteAppTransitionPermission()
+ ? mAppTransitionManager.getActivityLaunchOptions(v)
+ : super.getActivityLaunchOptions(v, item);
+ if (mLastTouchUpTime > 0) {
+ ActivityOptionsCompat.setLauncherSourceInfo(
+ activityOptions.options, mLastTouchUpTime);
+ }
+ activityOptions.options.setSplashScreenStyle(SplashScreen.SPLASH_SCREEN_STYLE_ICON);
+ activityOptions.options.setLaunchDisplayId(
+ (v != null && v.getDisplay() != null) ? v.getDisplay().getDisplayId()
+ : Display.DEFAULT_DISPLAY);
+ addLaunchCookie(item, activityOptions.options);
+ return activityOptions;
+ }
+
+ /**
+ * Adds a new launch cookie for the activity launch if supported.
+ *
+ * @param info the item info for the launch
+ * @param opts the options to set the launchCookie on.
+ */
+ public void addLaunchCookie(ItemInfo info, ActivityOptions opts) {
+ IBinder launchCookie = getLaunchCookie(info);
+ if (launchCookie != null) {
+ opts.setLaunchCookie(launchCookie);
+ }
+ }
+
+ /**
+ * Return a new launch cookie for the activity launch if supported.
+ *
+ * @param info the item info for the launch
+ */
+ public IBinder getLaunchCookie(ItemInfo info) {
+ if (info == null) {
+ return null;
+ }
+ switch (info.container) {
+ case Favorites.CONTAINER_DESKTOP:
+ case Favorites.CONTAINER_HOTSEAT:
+ // Fall through and continue it's on the workspace (we don't support swiping back
+ // to other containers like all apps or the hotseat predictions (which can change)
+ break;
+ default:
+ if (info.container >= 0) {
+ // Also allow swiping to folders
+ break;
+ }
+ // Reset any existing launch cookies associated with the cookie
+ return ObjectWrapper.wrap(NO_MATCHING_ID);
+ }
+ switch (info.itemType) {
+ case Favorites.ITEM_TYPE_APPLICATION:
+ case Favorites.ITEM_TYPE_SHORTCUT:
+ case Favorites.ITEM_TYPE_DEEP_SHORTCUT:
+ case Favorites.ITEM_TYPE_APPWIDGET:
+ // Fall through and continue if it's an app, shortcut, or widget
+ break;
+ default:
+ // Reset any existing launch cookies associated with the cookie
+ return ObjectWrapper.wrap(NO_MATCHING_ID);
+ }
+ return ObjectWrapper.wrap(new Integer(info.id));
+ }
+
+ public void setHintUserWillBeActive() {
+ addActivityFlags(ACTIVITY_STATE_USER_WILL_BE_ACTIVE);
+ }
+
+ @Override
+ public void onDisplayInfoChanged(Context context, DisplayController.Info info, int flags) {
+ super.onDisplayInfoChanged(context, info, flags);
+ // When changing screens, force moving to rest state similar to StatefulActivity.onStop, as
+ // StatefulActivity isn't called consistently.
+ if ((flags & CHANGE_ACTIVE_SCREEN) != 0) {
+ getStateManager().moveToRestState();
+ }
+
+ if ((flags & CHANGE_NAVIGATION_MODE) != 0) {
+ getDragLayer().recreateControllers();
+ if (mActionsView != null) {
+ mActionsView.updateVerticalMargin(info.navigationMode);
+ }
+ }
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+
+ // If Launcher shuts downs during split select, we save some extra data in the recovery
+ // bundle to allow graceful recovery. The normal LauncherState restore mechanism doesn't
+ // work in this case because restoring straight to OverviewSplitSelect without staging data,
+ // or before the tasks themselves have loaded into Overview, causes a crash. So we tell
+ // Launcher to first restore into Overview state, wait for the relevant tasks and icons to
+ // load in, and then proceed to OverviewSplitSelect.
+ if (isInState(OVERVIEW_SPLIT_SELECT)) {
+ SplitSelectStateController splitSelectStateController =
+ ((RecentsView) getOverviewPanel()).getSplitPlaceholder();
+ // Launcher will restart in Overview and then transition to OverviewSplitSelect.
+ outState.putIBinder(PENDING_SPLIT_SELECT_INFO, ObjectWrapper.wrap(
+ new PendingSplitSelectInfo(
+ splitSelectStateController.getInitialTaskId(),
+ splitSelectStateController.getActiveSplitStagePosition()
+ )
+ ));
+ outState.putInt(RUNTIME_STATE, OVERVIEW.ordinal);
+ }
+ }
+
+ /**
+ * When Launcher restarts, it sometimes needs to recover to a split selection state.
+ * This function checks if such a recovery is needed.
+ * @return a boolean representing whether the launcher is waiting to recover to
+ * OverviewSplitSelect state.
+ */
+ public boolean hasPendingSplitSelectInfo() {
+ return mPendingSplitSelectInfo != null;
+ }
+
+ /**
+ * See {@link #hasPendingSplitSelectInfo()}
+ */
+ public @Nullable PendingSplitSelectInfo getPendingSplitSelectInfo() {
+ return mPendingSplitSelectInfo;
+ }
+
+ /**
+ * When the launcher has successfully recovered to OverviewSplitSelect state, this function
+ * deletes the recovery data, returning it to a null state.
+ */
+ public void finishSplitSelectRecovery() {
+ mPendingSplitSelectInfo = null;
+ }
+
private static final class LauncherTaskViewController extends
TaskViewTouchController<Launcher> {
@@ -368,6 +995,9 @@
@Override
public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
super.dump(prefix, fd, writer, args);
+ if (mDepthController != null) {
+ mDepthController.dump(prefix, writer);
+ }
RecentsView recentsView = getOverviewPanel();
writer.println("\nQuickstepLauncher:");
writer.println(prefix + "\tmOrientationState: " + (recentsView == null ? "recentsNull" :
diff --git a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
index 00a98c0..5cddd07 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
@@ -35,7 +35,6 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.anim.AnimatorListeners;
import com.android.launcher3.anim.PendingAnimation;
@@ -55,7 +54,7 @@
public final class RecentsViewStateController extends
BaseRecentsViewStateController<LauncherRecentsView> {
- public RecentsViewStateController(BaseQuickstepLauncher launcher) {
+ public RecentsViewStateController(QuickstepLauncher launcher) {
super(launcher);
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
index 8faabc9..918b3c1 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
@@ -34,13 +34,13 @@
import android.view.MotionEvent;
import android.view.ViewConfiguration;
-import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.taskbar.LauncherTaskbarUIController;
+import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.util.AnimatorControllerWithResistance;
import com.android.quickstep.util.MotionPauseDetector;
@@ -114,7 +114,7 @@
public void onDragStart(boolean start, float startDisplacement) {
if (mLauncher.isInState(ALL_APPS)) {
LauncherTaskbarUIController controller =
- ((BaseQuickstepLauncher) mLauncher).getTaskbarUIController();
+ ((QuickstepLauncher) mLauncher).getTaskbarUIController();
if (controller != null) {
controller.setShouldDelayLauncherStateAnim(true);
}
@@ -151,7 +151,7 @@
@Override
public void onDragEnd(float velocity) {
LauncherTaskbarUIController controller =
- ((BaseQuickstepLauncher) mLauncher).getTaskbarUIController();
+ ((QuickstepLauncher) mLauncher).getTaskbarUIController();
if (controller != null) {
controller.setShouldDelayLauncherStateAnim(false);
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
index bc76487..6f925db 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
@@ -58,7 +58,6 @@
import android.view.MotionEvent;
import android.view.animation.Interpolator;
-import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
@@ -67,6 +66,7 @@
import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.touch.BaseSwipeDetector;
import com.android.launcher3.touch.BothAxesSwipeDetector;
+import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.TouchController;
import com.android.quickstep.AnimatedFloat;
import com.android.quickstep.SystemUiProxy;
@@ -91,7 +91,7 @@
private static final Interpolator SCALE_DOWN_INTERPOLATOR = LINEAR;
private static final long ATOMIC_DURATION_FROM_PAUSED_TO_OVERVIEW = 300;
- private final BaseQuickstepLauncher mLauncher;
+ private final QuickstepLauncher mLauncher;
private final BothAxesSwipeDetector mSwipeDetector;
private final float mXRange;
private final float mYRange;
@@ -113,7 +113,7 @@
private AnimatorPlaybackController mXOverviewAnim;
private AnimatedFloat mYOverviewAnim;
- public NoButtonQuickSwitchTouchController(BaseQuickstepLauncher launcher) {
+ public NoButtonQuickSwitchTouchController(QuickstepLauncher launcher) {
mLauncher = launcher;
mSwipeDetector = new BothAxesSwipeDetector(mLauncher, this);
mRecentsView = mLauncher.getOverviewPanel();
diff --git a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
index c13b95f..4ceafeb 100644
--- a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
@@ -33,7 +33,6 @@
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
-import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherInitListener;
@@ -44,6 +43,7 @@
import com.android.launcher3.statemanager.StateManager;
import com.android.launcher3.taskbar.LauncherTaskbarUIController;
import com.android.launcher3.touch.PagedOrientationHandler;
+import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.DisplayController.NavigationMode;
import com.android.quickstep.GestureState.GestureEndTarget;
@@ -61,7 +61,7 @@
* {@link BaseActivityInterface} for the in-launcher recents.
*/
public final class LauncherActivityInterface extends
- BaseActivityInterface<LauncherState, BaseQuickstepLauncher> {
+ BaseActivityInterface<LauncherState, QuickstepLauncher> {
public static final LauncherActivityInterface INSTANCE = new LauncherActivityInterface();
@@ -122,7 +122,7 @@
notifyRecentsOfOrientation(deviceState.getRotationTouchHelper());
DefaultAnimationFactory factory = new DefaultAnimationFactory(callback) {
@Override
- protected void createBackgroundToOverviewAnim(BaseQuickstepLauncher activity,
+ protected void createBackgroundToOverviewAnim(QuickstepLauncher activity,
PendingAnimation pa) {
super.createBackgroundToOverviewAnim(activity, pa);
@@ -135,7 +135,7 @@
}
};
- BaseQuickstepLauncher launcher = factory.initBackgroundStateUI();
+ QuickstepLauncher launcher = factory.initBackgroundStateUI();
// Since all apps is not visible, we can safely reset the scroll position.
// This ensures then the next swipe up to all-apps starts from scroll 0.
launcher.getAppsView().reset(false /* animate */);
@@ -159,14 +159,14 @@
@Nullable
@Override
- public BaseQuickstepLauncher getCreatedActivity() {
- return BaseQuickstepLauncher.ACTIVITY_TRACKER.getCreatedActivity();
+ public QuickstepLauncher getCreatedActivity() {
+ return QuickstepLauncher.ACTIVITY_TRACKER.getCreatedActivity();
}
@Nullable
@Override
public DepthController getDepthController() {
- BaseQuickstepLauncher launcher = getCreatedActivity();
+ QuickstepLauncher launcher = getCreatedActivity();
if (launcher == null) {
return null;
}
@@ -176,7 +176,7 @@
@Nullable
@Override
public LauncherTaskbarUIController getTaskbarController() {
- BaseQuickstepLauncher launcher = getCreatedActivity();
+ QuickstepLauncher launcher = getCreatedActivity();
if (launcher == null) {
return null;
}
@@ -318,7 +318,7 @@
}
@Override
- protected int getOverviewScrimColorForState(BaseQuickstepLauncher launcher,
+ protected int getOverviewScrimColorForState(QuickstepLauncher launcher,
LauncherState state) {
return state.getWorkspaceScrimColor(launcher);
}
diff --git a/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java b/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java
index fd9f922..7a281dd 100644
--- a/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java
+++ b/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java
@@ -39,10 +39,10 @@
import android.window.IOnBackInvokedCallback;
import com.android.launcher3.AbstractFloatingView;
-import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.QuickstepTransitionManager;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
+import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.quickstep.util.RectFSpringAnim;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
@@ -75,7 +75,7 @@
private final RectF mCancelRect = new RectF();
/** The current window position. */
private final RectF mCurrentRect = new RectF();
- private final BaseQuickstepLauncher mLauncher;
+ private final QuickstepLauncher mLauncher;
private final int mWindowScaleMarginX;
/** Max window translation in the Y axis. */
private final int mWindowMaxDeltaY;
@@ -93,7 +93,7 @@
private IOnBackInvokedCallback mBackCallback;
public LauncherBackAnimationController(
- BaseQuickstepLauncher launcher,
+ QuickstepLauncher launcher,
QuickstepTransitionManager quickstepTransitionManager) {
mLauncher = launcher;
mQuickstepTransitionManager = quickstepTransitionManager;
diff --git a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
index 196a664..36ca993 100644
--- a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
+++ b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
@@ -35,10 +35,10 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.states.StateAnimationConfig;
+import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.ObjectWrapper;
import com.android.launcher3.views.FloatingIconView;
import com.android.launcher3.views.FloatingView;
@@ -57,7 +57,7 @@
* Temporary class to allow easier refactoring
*/
public class LauncherSwipeHandlerV2 extends
- AbsSwipeUpHandler<BaseQuickstepLauncher, RecentsView, LauncherState> {
+ AbsSwipeUpHandler<QuickstepLauncher, RecentsView, LauncherState> {
public LauncherSwipeHandlerV2(Context context, RecentsAnimationDeviceState deviceState,
TaskAnimationManager taskAnimationManager, GestureState gestureState, long touchTimeMs,
diff --git a/quickstep/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java b/quickstep/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java
index de527a7..eec8582 100644
--- a/quickstep/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java
+++ b/quickstep/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java
@@ -35,7 +35,6 @@
import androidx.annotation.Nullable;
-import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.CellLayout;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Hotseat;
@@ -49,6 +48,7 @@
import com.android.launcher3.anim.SpringAnimationBuilder;
import com.android.launcher3.statehandlers.DepthController;
import com.android.launcher3.states.StateAnimationConfig;
+import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.DynamicResource;
import com.android.quickstep.views.RecentsView;
import com.android.systemui.plugins.ResourceProvider;
@@ -295,11 +295,11 @@
}
private void addDepthAnimationForState(Launcher launcher, LauncherState state, long duration) {
- if (!(launcher instanceof BaseQuickstepLauncher)) {
+ if (!(launcher instanceof QuickstepLauncher)) {
return;
}
PendingAnimation builder = new PendingAnimation(duration);
- DepthController depthController = ((BaseQuickstepLauncher) launcher).getDepthController();
+ DepthController depthController = ((QuickstepLauncher) launcher).getDepthController();
depthController.setStateWithAnimation(state, new StateAnimationConfig(), builder);
mAnimators.play(builder.buildAnim());
}
diff --git a/quickstep/src/com/android/quickstep/util/WorkspaceRevealAnim.java b/quickstep/src/com/android/quickstep/util/WorkspaceRevealAnim.java
index 5eb543e..34fa7f1 100644
--- a/quickstep/src/com/android/quickstep/util/WorkspaceRevealAnim.java
+++ b/quickstep/src/com/android/quickstep/util/WorkspaceRevealAnim.java
@@ -32,7 +32,6 @@
import android.util.FloatProperty;
import android.view.View;
-import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.Hotseat;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
@@ -41,6 +40,7 @@
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.statehandlers.DepthController;
import com.android.launcher3.states.StateAnimationConfig;
+import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.DynamicResource;
import com.android.quickstep.views.RecentsView;
import com.android.systemui.plugins.ResourceProvider;
@@ -84,9 +84,9 @@
}
// Add depth controller animation.
- if (launcher instanceof BaseQuickstepLauncher) {
+ if (launcher instanceof QuickstepLauncher) {
PendingAnimation depthBuilder = new PendingAnimation(DURATION_MS);
- DepthController depth = ((BaseQuickstepLauncher) launcher).getDepthController();
+ DepthController depth = ((QuickstepLauncher) launcher).getDepthController();
depth.setStateWithAnimation(NORMAL, new StateAnimationConfig(), depthBuilder);
mAnimators.play(depthBuilder.buildAnim());
}
diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
index 3c5a626..6a33d36 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -32,11 +32,11 @@
import androidx.annotation.Nullable;
import com.android.launcher3.AbstractFloatingView;
-import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.popup.QuickstepSystemShortcut;
import com.android.launcher3.statehandlers.DepthController;
import com.android.launcher3.statemanager.StateManager.StateListener;
+import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.PendingSplitSelectInfo;
import com.android.launcher3.util.SplitConfigurationOptions;
import com.android.quickstep.LauncherActivityInterface;
@@ -46,7 +46,7 @@
* {@link RecentsView} used in Launcher activity
*/
@TargetApi(Build.VERSION_CODES.O)
-public class LauncherRecentsView extends RecentsView<BaseQuickstepLauncher, LauncherState>
+public class LauncherRecentsView extends RecentsView<QuickstepLauncher, LauncherState>
implements StateListener<LauncherState> {
public LauncherRecentsView(Context context) {