From f29dc7c5ec4a24ea59959545beddc447fff83ccd Mon Sep 17 00:00:00 2001 From: randypfohl Date: Tue, 30 Jul 2024 11:24:27 -0700 Subject: [PATCH] abstracting fallback views to support container instead of activity Test: Built and tested locally Flag: NONE just abstracting in this cl Bug:292269949 Change-Id: I0ce5efb4f193211216430f373605107c87de2c1a --- .../launcher3/taskbar/TaskbarDragLayer.java | 6 +- .../overlay/TaskbarOverlayDragLayer.java | 14 +- .../quickstep/BaseActivityInterface.java | 8 - .../quickstep/BaseContainerInterface.java | 11 + .../quickstep/FallbackSwipeHandler.java | 2 +- .../quickstep/FallbackWindowInterface.java | 257 ++++++++++++++++++ .../com/android/quickstep/GestureState.java | 2 +- .../quickstep/OverviewCommandHelper.kt | 26 +- .../quickstep/OverviewComponentObserver.java | 27 +- .../QuickstepTestInformationHandler.java | 6 +- .../android/quickstep/RecentsActivity.java | 2 +- .../quickstep/TouchInteractionService.java | 54 ++-- .../FallbackRecentsStateController.java | 25 +- .../fallback/FallbackRecentsView.java | 7 +- .../quickstep/fallback/RecentsDragLayer.java | 9 +- .../fallback/RecentsTaskController.java | 16 +- .../quickstep/views/RecentsViewContainer.java | 34 ++- .../FallbackSwipeHandlerTestCase.java | 2 +- .../android/launcher3/LauncherRootView.java | 14 +- .../launcher3/dragndrop/DragLayer.java | 18 +- .../launcher3/graphics/SysUiScrim.java | 18 +- .../secondarydisplay/SecondaryDragLayer.java | 36 +-- .../statemanager/StatefulActivity.java | 11 +- .../statemanager/StatefulContainer.java | 33 ++- .../testing/TestInformationHandler.java | 30 +- .../launcher3/views/ActivityContext.java | 19 +- .../launcher3/views/BaseDragLayer.java | 18 +- .../android/launcher3/views/ScrimView.java | 4 +- 28 files changed, 515 insertions(+), 194 deletions(-) create mode 100644 quickstep/src/com/android/quickstep/FallbackWindowInterface.java diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java index a090956ca4..53bd3d778f 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java @@ -100,7 +100,7 @@ public class TaskbarDragLayer extends BaseDragLayer { public TaskbarDragLayer(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, 1 /* alphaChannelCount */); - mBackgroundRenderer = new TaskbarBackgroundRenderer(mActivity); + mBackgroundRenderer = new TaskbarBackgroundRenderer(mContainer); mTaskbarBackgroundAlpha = new MultiPropertyFactory<>(this, BG_ALPHA, INDEX_COUNT, (a, b) -> a * b, 1f); @@ -109,7 +109,7 @@ public class TaskbarDragLayer extends BaseDragLayer { public void init(TaskbarDragLayerController.TaskbarDragLayerCallbacks callbacks) { mControllerCallbacks = callbacks; - mBackgroundRenderer.updateStashedHandleWidth(mActivity, getResources()); + mBackgroundRenderer.updateStashedHandleWidth(mContainer, getResources()); recreateControllers(); } @@ -275,7 +275,7 @@ public class TaskbarDragLayer extends BaseDragLayer { @Override public boolean dispatchKeyEvent(KeyEvent event) { if (event.getAction() == ACTION_UP && event.getKeyCode() == KEYCODE_BACK) { - AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mActivity); + AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mContainer); if (topView != null && topView.canHandleBack()) { topView.onBackInvoked(); // Handled by the floating view. diff --git a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java index 773b0b956f..669850cb41 100644 --- a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java +++ b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java @@ -73,7 +73,7 @@ public class TaskbarOverlayDragLayer extends @Override public void recreateControllers() { List controllers = new ArrayList<>(); - controllers.add(mActivity.getDragController()); + controllers.add(mContainer.getDragController()); controllers.addAll(mTouchControllers); mControllers = controllers.toArray(new TouchController[0]); } @@ -87,7 +87,7 @@ public class TaskbarOverlayDragLayer extends @Override public boolean dispatchKeyEvent(KeyEvent event) { if (event.getAction() == ACTION_UP && event.getKeyCode() == KEYCODE_BACK) { - AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mActivity); + AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mContainer); if (topView != null && topView.canHandleBack()) { topView.onBackInvoked(); return true; @@ -96,7 +96,7 @@ public class TaskbarOverlayDragLayer extends && event.getKeyCode() == KeyEvent.KEYCODE_ESCAPE && event.hasNoModifiers()) { // Ignore escape if pressed in conjunction with any modifier keys. Close each // floating view one at a time for each key press. - AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mActivity); + AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mContainer); if (topView != null) { topView.close(/* animate= */ true); return true; @@ -107,7 +107,7 @@ public class TaskbarOverlayDragLayer extends @Override public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo inoutInfo) { - if (mActivity.isAnySystemDragInProgress()) { + if (mContainer.isAnySystemDragInProgress()) { inoutInfo.touchableRegion.setEmpty(); inoutInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION); } @@ -123,7 +123,7 @@ public class TaskbarOverlayDragLayer extends @Override public void onViewRemoved(View child) { super.onViewRemoved(child); - mActivity.getOverlayController().maybeCloseWindow(); + mContainer.getOverlayController().maybeCloseWindow(); } /** Adds a {@link TouchController} to this drag layer. */ @@ -147,14 +147,14 @@ public class TaskbarOverlayDragLayer extends * 2) Sets tappableInsets bottom inset to 0. */ private WindowInsets updateInsetsDueToStashing(WindowInsets oldInsets) { - if (!DisplayController.isTransientTaskbar(mActivity)) { + if (!DisplayController.isTransientTaskbar(mContainer)) { 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.getStashedTaskbarHeight()); + mContainer.getStashedTaskbarHeight()); updatedInsetsBuilder.setInsets(WindowInsets.Type.navigationBars(), newNavInsets); Insets oldTappableInsets = oldInsets.getInsets(WindowInsets.Type.tappableElement()); diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java index 87038439bf..91379b1c23 100644 --- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java +++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java @@ -36,7 +36,6 @@ import android.animation.AnimatorSet; import android.view.MotionEvent; import androidx.annotation.Nullable; -import androidx.annotation.UiThread; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.PendingAnimation; @@ -124,13 +123,6 @@ public abstract class BaseActivityInterface T getVisibleRecentsView(); - - @UiThread - public abstract boolean switchToRecentsIfVisible(Animator.AnimatorListener animatorListener); - public boolean deferStartingActivity(RecentsAnimationDeviceState deviceState, MotionEvent ev) { TaskbarUIController controller = getTaskbarController(); boolean isEventOverBubbleBarStashHandle = diff --git a/quickstep/src/com/android/quickstep/BaseContainerInterface.java b/quickstep/src/com/android/quickstep/BaseContainerInterface.java index bf3a662c4a..6447775f7d 100644 --- a/quickstep/src/com/android/quickstep/BaseContainerInterface.java +++ b/quickstep/src/com/android/quickstep/BaseContainerInterface.java @@ -34,6 +34,7 @@ import android.view.RemoteAnimationTarget; import android.view.View; import androidx.annotation.Nullable; +import androidx.annotation.UiThread; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Flags; @@ -59,8 +60,16 @@ import java.util.function.Predicate; public abstract class BaseContainerInterface, CONTAINER_TYPE extends RecentsViewContainer> { + public boolean rotationSupportedByActivity = false; + @UiThread + @Nullable + public abstract > T getVisibleRecentsView(); + + @UiThread + public abstract boolean switchToRecentsIfVisible(Animator.AnimatorListener animatorListener); + @Nullable public abstract CONTAINER_TYPE getCreatedContainer(); @@ -126,6 +135,8 @@ public abstract class BaseContainerInterface { + AbsSwipeUpHandler, RecentsState> { private static final String TAG = "FallbackSwipeHandler"; diff --git a/quickstep/src/com/android/quickstep/FallbackWindowInterface.java b/quickstep/src/com/android/quickstep/FallbackWindowInterface.java new file mode 100644 index 0000000000..ca0c88ae7a --- /dev/null +++ b/quickstep/src/com/android/quickstep/FallbackWindowInterface.java @@ -0,0 +1,257 @@ +/* + * Copyright (C) 2024 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.util.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; + +import android.animation.Animator; +import android.animation.AnimatorSet; +import android.content.Context; +import android.graphics.Rect; +import android.view.MotionEvent; +import android.view.RemoteAnimationTarget; + +import androidx.annotation.Nullable; + +import com.android.launcher3.DeviceProfile; +import com.android.launcher3.statemanager.StateManager; +import com.android.launcher3.taskbar.FallbackTaskbarUIController; +import com.android.launcher3.util.DisplayController; +import com.android.quickstep.GestureState.GestureEndTarget; +import com.android.quickstep.fallback.RecentsState; +import com.android.quickstep.fallback.window.RecentsWindowManager; +import com.android.quickstep.orientation.RecentsPagedOrientationHandler; +import com.android.quickstep.util.ActivityInitListener; +import com.android.quickstep.util.AnimatorControllerWithResistance; +import com.android.quickstep.views.RecentsView; + +import java.util.function.Consumer; +import java.util.function.Predicate; + +/** + * {@link BaseActivityInterface} for recents when the default launcher is different than the + * currently running one and apps should interact with the {@link RecentsActivity} as opposed + * to the in-launcher one. + */ +public final class FallbackWindowInterface extends BaseWindowInterface{ + + private static FallbackWindowInterface INSTANCE; + + private final RecentsWindowManager mRecentsWindowManager; + + @Nullable + public static FallbackWindowInterface getInstance(){ + return INSTANCE; + } + + public static FallbackWindowInterface init(RecentsWindowManager recentsWindowManager) { + if (INSTANCE == null) { + INSTANCE = new FallbackWindowInterface(recentsWindowManager); + } + return INSTANCE; + } + + private FallbackWindowInterface(RecentsWindowManager recentsWindowManager) { + super(DEFAULT, BACKGROUND_APP); + mRecentsWindowManager = recentsWindowManager; + } + + public void destroy() { + INSTANCE = null; + } + + /** 2 */ + @Override + public int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context, Rect outRect, + RecentsPagedOrientationHandler orientationHandler) { + calculateTaskSize(context, dp, outRect, orientationHandler); + if (dp.isVerticalBarLayout() && DisplayController.getNavigationMode(context) != NO_BUTTON) { + return dp.isSeascape() ? outRect.left : (dp.widthPx - outRect.right); + } else { + return dp.heightPx - outRect.bottom; + } + } + + /** 5 */ + @Override + public void onAssistantVisibilityChanged(float visibility) { + // This class becomes active when the screen is locked. + // Rather than having it handle assistant visibility changes, the assistant visibility is + // set to zero prior to this class becoming active. + } + + /** 6 */ + @Override + public BaseWindowInterface.AnimationFactory prepareRecentsUI(RecentsAnimationDeviceState + deviceState, boolean activityVisible, + Consumer callback) { + notifyRecentsOfOrientation(deviceState.getRotationTouchHelper()); + BaseWindowInterface.DefaultAnimationFactory factory = + new BaseWindowInterface.DefaultAnimationFactory(callback); + factory.initBackgroundStateUI(); + return factory; + } + + @Override + public ActivityInitListener createActivityInitListener( + Predicate onInitListener) { + //todo figure out how to properly replace this + return new ActivityInitListener<>((activity, alreadyOnHome) -> + onInitListener.test(alreadyOnHome), RecentsActivity.ACTIVITY_TRACKER); + } + + @Nullable + @Override + public RecentsWindowManager getCreatedContainer() { + return mRecentsWindowManager; + } + + @Override + public FallbackTaskbarUIController getTaskbarController() { + RecentsWindowManager manager = getCreatedContainer(); + if (manager == null) { + return null; + } + return null; + // todo b/365775636: pass a taskbar implementation + // return manager.getTaskbarUIController(); + } + + @Override + public Rect getOverviewWindowBounds(Rect homeBounds, RemoteAnimationTarget target) { + // TODO: Remove this once b/77875376 is fixed + return target.screenSpaceBounds; + } + + @Nullable + @Override + public > T getVisibleRecentsView() { + RecentsWindowManager manager = getCreatedContainer(); + if(manager.isStarted() || isInLiveTileMode()){ + return getCreatedContainer().getOverviewPanel(); + } + return null; + } + + @Override + public boolean switchToRecentsIfVisible(Animator.AnimatorListener animatorListener) { + return false; + } + + @Override + protected int getOverviewScrimColorForState(RecentsWindowManager container, + RecentsState state) { + return state.getScrimColor(container.asContext()); + } + + @Override + public boolean deferStartingActivity(RecentsAnimationDeviceState deviceState, MotionEvent ev) { + // In non-gesture mode, user might be clicking on the home button which would directly + // start the home activity instead of going through recents. In that case, defer starting + // recents until we are sure it is a gesture. + return false; +// return !deviceState.isFullyGesturalNavMode(); +// || super.deferStartingActivity(deviceState, ev); + } + + @Override + public void onExitOverview(RotationTouchHelper deviceState, Runnable exitRunnable) { + final StateManager stateManager = + getCreatedContainer().getStateManager(); + if (stateManager.getState() == HOME) { + exitRunnable.run(); + notifyRecentsOfOrientation(deviceState); + return; + } + + stateManager.addStateListener( + new StateManager.StateListener() { + @Override + public void onStateTransitionComplete(RecentsState toState) { + // Are we going from Recents to Workspace? + if (toState == HOME) { + exitRunnable.run(); + notifyRecentsOfOrientation(deviceState); + stateManager.removeStateListener(this); + } + } + }); + } + + @Override + public boolean isInLiveTileMode() { + RecentsWindowManager windowManager = getCreatedContainer(); + return windowManager != null && windowManager.getStateManager().getState() == DEFAULT && + windowManager.isStarted(); + } + + @Override + public void onLaunchTaskFailed() { + // TODO: probably go back to overview instead. + RecentsWindowManager manager = getCreatedContainer(); + if (manager == null) { + return; + } + manager.getOverviewPanel().startHome(); + } + + @Override + public RecentsState stateFromGestureEndTarget(GestureEndTarget endTarget) { + switch (endTarget) { + case RECENTS: + return DEFAULT; + case NEW_TASK: + case LAST_TASK: + return BACKGROUND_APP; + case HOME: + case ALL_APPS: + default: + return HOME; + } + } + + private void notifyRecentsOfOrientation(RotationTouchHelper rotationTouchHelper) { + // reset layout on swipe to home + RecentsView recentsView = getCreatedContainer().getOverviewPanel(); + recentsView.setLayoutRotation(rotationTouchHelper.getCurrentActiveRotation(), + rotationTouchHelper.getDisplayRotation()); + } + + @Override + public @Nullable Animator getParallelAnimationToLauncher(GestureEndTarget endTarget, + long duration, RecentsAnimationCallbacks callbacks) { + FallbackTaskbarUIController uiController = getTaskbarController(); + Animator superAnimator = super.getParallelAnimationToLauncher( + endTarget, duration, callbacks); + if (uiController == null) { + return superAnimator; + } + RecentsState toState = stateFromGestureEndTarget(endTarget); + Animator taskbarAnimator = uiController.createAnimToRecentsState(toState, duration); + if (taskbarAnimator == null) { + return superAnimator; + } + if (superAnimator == null) { + return taskbarAnimator; + } + AnimatorSet animatorSet = new AnimatorSet(); + animatorSet.playTogether(superAnimator, taskbarAnimator); + return animatorSet; + } +} diff --git a/quickstep/src/com/android/quickstep/GestureState.java b/quickstep/src/com/android/quickstep/GestureState.java index 9cc463a31d..3bd87ce178 100644 --- a/quickstep/src/com/android/quickstep/GestureState.java +++ b/quickstep/src/com/android/quickstep/GestureState.java @@ -190,7 +190,7 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL public GestureState(OverviewComponentObserver componentObserver, int gestureId) { mHomeIntent = componentObserver.getHomeIntent(); mOverviewIntent = componentObserver.getOverviewIntent(); - mContainerInterface = componentObserver.getActivityInterface(); + mContainerInterface = componentObserver.getContainerInterface(); mStateCallback = new MultiStateCallback( STATE_NAMES.toArray(new String[0]), GestureState::getTrackedEventForState); mGestureId = gestureId; diff --git a/quickstep/src/com/android/quickstep/OverviewCommandHelper.kt b/quickstep/src/com/android/quickstep/OverviewCommandHelper.kt index 520bec35c7..76b5b22fee 100644 --- a/quickstep/src/com/android/quickstep/OverviewCommandHelper.kt +++ b/quickstep/src/com/android/quickstep/OverviewCommandHelper.kt @@ -50,15 +50,15 @@ import com.android.quickstep.views.RecentsViewContainer import com.android.quickstep.views.TaskView import com.android.systemui.shared.recents.model.ThumbnailData import com.android.systemui.shared.system.InteractionJankMonitorWrapper -import java.io.PrintWriter -import java.util.concurrent.ConcurrentLinkedDeque -import kotlin.coroutines.resume import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.ensureActive import kotlinx.coroutines.launch import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.withTimeout +import java.io.PrintWriter +import java.util.concurrent.ConcurrentLinkedDeque +import kotlin.coroutines.resume /** Helper class to handle various atomic commands for switching between Overview. */ class OverviewCommandHelper @@ -80,11 +80,11 @@ constructor( */ private var keyboardTaskFocusIndex = -1 - private val activityInterface: BaseActivityInterface<*, *> - get() = overviewComponentObserver.activityInterface + private val containerInterface: BaseContainerInterface<*, *> + get() = overviewComponentObserver.containerInterface private val visibleRecentsView: RecentsView<*, *>? - get() = activityInterface.getVisibleRecentsView>() + get() = containerInterface.getVisibleRecentsView>() /** * Adds a command to be executed next, after all pending tasks are completed. Max commands that @@ -258,10 +258,10 @@ constructor( command: CommandInfo, onCallbackResult: () -> Unit, ): Boolean { - val recentsViewContainer = activityInterface.getCreatedContainer() as? RecentsViewContainer + val recentsViewContainer = containerInterface.getCreatedContainer() val recentsView: RecentsView<*, *>? = recentsViewContainer?.getOverviewPanel() val deviceProfile = recentsViewContainer?.getDeviceProfile() - val uiController = activityInterface.getTaskbarController() + val uiController = containerInterface.getTaskbarController() val allowQuickSwitch = uiController != null && deviceProfile != null && @@ -316,13 +316,13 @@ constructor( onCallbackResult() } } - if (activityInterface.switchToRecentsIfVisible(animatorListener)) { + if (containerInterface.switchToRecentsIfVisible(animatorListener)) { Log.d(TAG, "switching to Overview state - waiting: $command") // If successfully switched, wait until animation finishes return false } - val activity = activityInterface.getCreatedContainer() + val activity = containerInterface.getCreatedContainer() if (activity != null) { InteractionJankMonitorWrapper.begin(activity.rootView, Cuj.CUJ_LAUNCHER_QUICK_SWITCH) } @@ -352,7 +352,7 @@ constructor( Log.d(TAG, "recents animation started: $command") updateRecentsViewFocus(command) logShowOverviewFrom(command.type) - activityInterface.runOnInitBackgroundStateUI { + containerInterface.runOnInitBackgroundStateUI { Log.d(TAG, "recents animation started - onInitBackgroundStateUI: $command") interactionHandler.onGestureEnded(0f, PointF()) } @@ -366,7 +366,7 @@ constructor( interactionHandler.onGestureCancelled() command.removeListener(this) - activityInterface.getCreatedContainer() ?: return + containerInterface.getCreatedContainer() ?: return recentsView?.onRecentsAnimationComplete() } } @@ -473,7 +473,7 @@ constructor( } private fun logShowOverviewFrom(commandType: CommandType) { - val container = activityInterface.getCreatedContainer() as? RecentsViewContainer ?: return + val container = containerInterface.getCreatedContainer() ?: return val event = when (commandType) { SHOW -> LAUNCHER_OVERVIEW_SHOW_OVERVIEW_FROM_KEYBOARD_SHORTCUT diff --git a/quickstep/src/com/android/quickstep/OverviewComponentObserver.java b/quickstep/src/com/android/quickstep/OverviewComponentObserver.java index ca19480b07..e474a81ec1 100644 --- a/quickstep/src/com/android/quickstep/OverviewComponentObserver.java +++ b/quickstep/src/com/android/quickstep/OverviewComponentObserver.java @@ -73,7 +73,7 @@ public final class OverviewComponentObserver { private Consumer mOverviewChangeListener = b -> { }; private String mUpdateRegisteredPackage; - private BaseActivityInterface mActivityInterface; + private BaseContainerInterface mContainerInterface; private Intent mOverviewIntent; private boolean mIsHomeAndOverviewSame; private boolean mIsDefaultHome; @@ -150,8 +150,8 @@ public final class OverviewComponentObserver { // Set assistant visibility to 0 from launcher's perspective, ensures any elements that // launcher made invisible become visible again before the new activity control helper // becomes active. - if (mActivityInterface != null) { - mActivityInterface.onAssistantVisibilityChanged(0.f); + if (mContainerInterface != null) { + mContainerInterface.onAssistantVisibilityChanged(0.f); } if (SEPARATE_RECENTS_ACTIVITY.get()) { @@ -168,7 +168,7 @@ public final class OverviewComponentObserver { if (!mIsHomeDisabled && (defaultHome == null || mIsDefaultHome)) { // User default home is same as out home app. Use Overview integrated in Launcher. - mActivityInterface = LauncherActivityInterface.INSTANCE; + mContainerInterface = LauncherActivityInterface.INSTANCE; mIsHomeAndOverviewSame = true; mOverviewIntent = mMyHomeIntent; mCurrentHomeIntent.setComponent(mMyHomeIntent.getComponent()); @@ -178,7 +178,7 @@ public final class OverviewComponentObserver { } else { // The default home app is a different launcher. Use the fallback Overview instead. - mActivityInterface = FallbackActivityInterface.INSTANCE; + mContainerInterface = FallbackActivityInterface.INSTANCE; mIsHomeAndOverviewSame = false; mOverviewIntent = mFallbackIntent; mCurrentHomeIntent.setComponent(defaultHome); @@ -266,21 +266,12 @@ public final class OverviewComponentObserver { } /** - * Get the current activity control helper for managing interactions to the overview activity. + * Get the current control helper for managing interactions to the overview container. * - * @return the current activity control helper + * @return the current control helper */ - public BaseActivityInterface getActivityInterface() { - return mActivityInterface; - } - - /** - * Get the current container control helper for managing interactions to the overview activity. - * - * @return the current container control helper - */ - public BaseContainerInterface getContainerInterface() { - return mActivityInterface; + public BaseContainerInterface getContainerInterface() { + return mContainerInterface; } public void dump(PrintWriter pw) { diff --git a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java index 49b6f57313..c3b9736293 100644 --- a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java +++ b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java @@ -7,6 +7,7 @@ import android.app.Activity; import android.content.Context; import android.content.res.Resources; import android.os.Bundle; +import android.view.WindowInsets; import androidx.annotation.Nullable; @@ -203,11 +204,12 @@ public class QuickstepTestInformationHandler extends TestInformationHandler { } @Override - protected Activity getCurrentActivity() { + protected WindowInsets getWindowInsets() { RecentsAnimationDeviceState rads = new RecentsAnimationDeviceState(mContext); OverviewComponentObserver observer = new OverviewComponentObserver(mContext, rads); try { - return observer.getActivityInterface().getCreatedContainer(); + return observer.getContainerInterface() + .getCreatedContainer().getRootView().getRootWindowInsets(); } finally { observer.onDestroy(); rads.destroy(); diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java index 9c60693e65..464ebc1f00 100644 --- a/quickstep/src/com/android/quickstep/RecentsActivity.java +++ b/quickstep/src/com/android/quickstep/RecentsActivity.java @@ -198,7 +198,7 @@ public final class RecentsActivity extends StatefulActivity implem } @Override - protected void onHandleConfigurationChanged() { + public void onHandleConfigurationChanged() { initDeviceProfile(); AbstractFloatingView.closeOpenViews(this, true, diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java index 178636e474..399cb0f237 100644 --- a/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -83,7 +83,6 @@ import androidx.annotation.Nullable; import androidx.annotation.UiThread; import androidx.annotation.VisibleForTesting; -import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.ConstantItem; import com.android.launcher3.EncryptionType; import com.android.launcher3.Flags; @@ -324,10 +323,10 @@ public class TouchInteractionService extends Service { @Override public void enterStageSplitFromRunningApp(boolean leftOrTop) { executeForTouchInteractionService(tis -> { - StatefulActivity activity = - tis.mOverviewComponentObserver.getActivityInterface().getCreatedContainer(); - if (activity != null) { - activity.enterStageSplitFromRunningApp(leftOrTop); + RecentsViewContainer container = tis.mOverviewComponentObserver + .getContainerInterface().getCreatedContainer(); + if (container != null) { + container.enterStageSplitFromRunningApp(leftOrTop); } }); } @@ -761,11 +760,12 @@ public class TouchInteractionService extends Service { private void onOverviewTargetChange(boolean isHomeAndOverviewSame) { mAllAppsActionManager.setHomeAndOverviewSame(isHomeAndOverviewSame); - - StatefulActivity newOverviewActivity = - mOverviewComponentObserver.getActivityInterface().getCreatedContainer(); - if (newOverviewActivity != null) { - mTaskbarManager.setActivity(newOverviewActivity); + RecentsViewContainer newOverviewContainer = + mOverviewComponentObserver.getContainerInterface().getCreatedContainer(); + if (newOverviewContainer != null + && newOverviewContainer instanceof StatefulActivity activity) { + //TODO(b/368030750) refactor taskbarManager to accept RecentsViewContainer + mTaskbarManager.setActivity(activity); } mTISBinder.onOverviewTargetChange(); } @@ -795,7 +795,7 @@ public class TouchInteractionService extends Service { @UiThread private void onAssistantVisibilityChanged() { if (LockedUserState.get(this).isUserUnlocked()) { - mOverviewComponentObserver.getActivityInterface().onAssistantVisibilityChanged( + mOverviewComponentObserver.getContainerInterface().onAssistantVisibilityChanged( mDeviceState.getAssistantVisibility()); } } @@ -1575,11 +1575,11 @@ public class TouchInteractionService extends Service { return; } - final BaseActivityInterface activityInterface = - mOverviewComponentObserver.getActivityInterface(); + final BaseContainerInterface containerInterface = + mOverviewComponentObserver.getContainerInterface(); final Intent overviewIntent = new Intent( mOverviewComponentObserver.getOverviewIntentIgnoreSysUiState()); - if (activityInterface.getCreatedContainer() != null && fromInit) { + if (containerInterface.getCreatedContainer() != null && fromInit) { // The activity has been created before the initialization of overview service. It is // usually happens when booting or launcher is the top activity, so we should already // have the latest state. @@ -1599,18 +1599,18 @@ public class TouchInteractionService extends Service { if (!LockedUserState.get(this).isUserUnlocked()) { return; } - final BaseActivityInterface activityInterface = - mOverviewComponentObserver.getActivityInterface(); - final BaseDraggingActivity activity = activityInterface.getCreatedContainer(); - if (activity == null || activity.isStarted()) { + final BaseContainerInterface containerInterface = + mOverviewComponentObserver.getContainerInterface(); + final RecentsViewContainer container = containerInterface.getCreatedContainer(); + if (container == null || container.isStarted()) { // We only care about the existing background activity. return; } - Configuration oldConfig = activity.getResources().getConfiguration(); + Configuration oldConfig = container.asContext().getResources().getConfiguration(); boolean isFoldUnfold = isTablet(oldConfig) != isTablet(newConfig); if (!isFoldUnfold && mOverviewComponentObserver.canHandleConfigChanges( - activity.getComponentName(), - activity.getResources().getConfiguration().diff(newConfig))) { + container.getComponentName(), + container.asContext().getResources().getConfiguration().diff(newConfig))) { // Since navBar gestural height are different between portrait and landscape, // can handle orientation changes and refresh navigation gestural region through // onOneHandedModeChanged() @@ -1649,11 +1649,11 @@ public class TouchInteractionService extends Service { pw.println("\tmInputEventReceiver=" + mInputEventReceiver); DisplayController.INSTANCE.get(this).dump(pw); pw.println("TouchState:"); - BaseDraggingActivity createdOverviewActivity = mOverviewComponentObserver == null ? null - : mOverviewComponentObserver.getActivityInterface().getCreatedContainer(); + RecentsViewContainer createdOverviewContainer = mOverviewComponentObserver == null ? null + : mOverviewComponentObserver.getContainerInterface().getCreatedContainer(); boolean resumed = mOverviewComponentObserver != null - && mOverviewComponentObserver.getActivityInterface().isResumed(); - pw.println("\tcreatedOverviewActivity=" + createdOverviewActivity); + && mOverviewComponentObserver.getContainerInterface().isResumed(); + pw.println("\tcreatedOverviewActivity=" + createdOverviewContainer); pw.println("\tresumed=" + resumed); pw.println("\tmConsumer=" + mConsumer.getName()); ActiveGestureLog.INSTANCE.dump("", pw); @@ -1661,8 +1661,8 @@ public class TouchInteractionService extends Service { if (mTaskAnimationManager != null) { mTaskAnimationManager.dump("", pw); } - if (createdOverviewActivity != null) { - createdOverviewActivity.getDeviceProfile().dump(this, "", pw); + if (createdOverviewContainer != null) { + createdOverviewContainer.getDeviceProfile().dump(this, "", pw); } mTaskbarManager.dumpLogs("", pw); mDesktopVisibilityController.dumpLogs("", pw); diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java index 94764a58cc..11f11518a9 100644 --- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java +++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java @@ -47,9 +47,9 @@ import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.anim.PropertySetter; import com.android.launcher3.statemanager.StateManager.StateHandler; import com.android.launcher3.states.StateAnimationConfig; -import com.android.quickstep.RecentsActivity; import com.android.quickstep.views.ClearAllButton; import com.android.quickstep.views.RecentsView; +import com.android.quickstep.views.RecentsViewContainer; /** * State controller for fallback recents activity @@ -57,12 +57,12 @@ import com.android.quickstep.views.RecentsView; public class FallbackRecentsStateController implements StateHandler { private final StateAnimationConfig mNoConfig = new StateAnimationConfig(); - private final RecentsActivity mActivity; + private final RecentsViewContainer mRecentsViewContainer; private final FallbackRecentsView mRecentsView; - public FallbackRecentsStateController(RecentsActivity activity) { - mActivity = activity; - mRecentsView = activity.getOverviewPanel(); + public FallbackRecentsStateController(RecentsViewContainer container) { + mRecentsViewContainer = container; + mRecentsView = container.getOverviewPanel(); } @Override @@ -96,10 +96,10 @@ public class FallbackRecentsStateController implements StateHandler, FloatProperty> taskViewsFloat = mRecentsView.getPagedOrientationHandler().getSplitSelectTaskOffset( TASK_PRIMARY_SPLIT_TRANSLATION, TASK_SECONDARY_SPLIT_TRANSLATION, - mActivity.getDeviceProfile()); + mRecentsViewContainer.getDeviceProfile()); setter.setFloat(mRecentsView, taskViewsFloat.first, isSplitSelectionState(state) ? mRecentsView.getSplitSelectTranslation() : 0, LINEAR); setter.setFloat(mRecentsView, taskViewsFloat.second, 0, LINEAR); diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java index e67a9bc1b6..6dfcf154db 100644 --- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java +++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java @@ -38,6 +38,7 @@ import com.android.launcher3.desktop.DesktopRecentsTransitionController; import com.android.launcher3.logging.StatsLogManager; import com.android.launcher3.statemanager.StateManager; import com.android.launcher3.statemanager.StateManager.StateListener; +import com.android.launcher3.statemanager.StatefulContainer; import com.android.launcher3.util.SplitConfigurationOptions; import com.android.launcher3.util.SplitConfigurationOptions.SplitSelectSource; import com.android.quickstep.FallbackActivityInterface; @@ -49,6 +50,7 @@ import com.android.quickstep.util.SplitSelectStateController; import com.android.quickstep.util.TaskViewSimulator; import com.android.quickstep.views.OverviewActionsView; import com.android.quickstep.views.RecentsView; +import com.android.quickstep.views.RecentsViewContainer; import com.android.quickstep.views.TaskView; import com.android.systemui.shared.recents.model.Task; @@ -56,7 +58,8 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -public class FallbackRecentsView extends RecentsView +public class FallbackRecentsView> extends RecentsView implements StateListener { private static final int TASK_DISMISS_DURATION = 150; @@ -93,7 +96,7 @@ public class FallbackRecentsView extends RecentsView getStateManager() { + public StateManager getStateManager() { return mContainer.getStateManager(); } diff --git a/quickstep/src/com/android/quickstep/fallback/RecentsDragLayer.java b/quickstep/src/com/android/quickstep/fallback/RecentsDragLayer.java index 29c3dc81da..a2884b6c9d 100644 --- a/quickstep/src/com/android/quickstep/fallback/RecentsDragLayer.java +++ b/quickstep/src/com/android/quickstep/fallback/RecentsDragLayer.java @@ -20,13 +20,12 @@ import android.util.AttributeSet; import com.android.launcher3.util.TouchController; import com.android.launcher3.views.BaseDragLayer; -import com.android.quickstep.RecentsActivity; +import com.android.quickstep.views.RecentsViewContainer; /** * Drag layer for fallback recents activity */ -public class RecentsDragLayer extends BaseDragLayer { - +public class RecentsDragLayer extends BaseDragLayer { public RecentsDragLayer(Context context, AttributeSet attrs) { super(context, attrs, 1 /* alphaChannelCount */); } @@ -34,8 +33,8 @@ public class RecentsDragLayer extends BaseDragLayer { @Override public void recreateControllers() { mControllers = new TouchController[] { - new RecentsTaskController(mActivity), - new FallbackNavBarTouchController(mActivity), + new RecentsTaskController(mContainer), + new FallbackNavBarTouchController(mContainer), }; } } diff --git a/quickstep/src/com/android/quickstep/fallback/RecentsTaskController.java b/quickstep/src/com/android/quickstep/fallback/RecentsTaskController.java index 2cb398cfff..07da379236 100644 --- a/quickstep/src/com/android/quickstep/fallback/RecentsTaskController.java +++ b/quickstep/src/com/android/quickstep/fallback/RecentsTaskController.java @@ -15,18 +15,22 @@ */ package com.android.quickstep.fallback; +import android.content.Context; + +import com.android.launcher3.statemanager.StatefulContainer; import com.android.launcher3.uioverrides.touchcontrollers.TaskViewTouchController; -import com.android.quickstep.RecentsActivity; +import com.android.quickstep.views.RecentsViewContainer; -public class RecentsTaskController extends TaskViewTouchController { - - public RecentsTaskController(RecentsActivity activity) { - super(activity); +public class RecentsTaskController> extends TaskViewTouchController { + public RecentsTaskController(T container) { + super(container); } @Override protected boolean isRecentsInteractive() { - return mContainer.hasWindowFocus() || mContainer.getStateManager().getState().hasLiveTile(); + return mContainer.getRootView().hasWindowFocus() + || mContainer.getStateManager().getState().hasLiveTile(); } @Override diff --git a/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java b/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java index 8f194442d0..462c53aec2 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java +++ b/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java @@ -17,6 +17,7 @@ package com.android.quickstep.views; import android.app.Activity; +import android.content.ComponentName; import android.content.Context; import android.content.ContextWrapper; import android.content.LocusId; @@ -31,7 +32,6 @@ import androidx.annotation.Nullable; import com.android.launcher3.BaseActivity; import com.android.launcher3.logger.LauncherAtom; import com.android.launcher3.statehandlers.DesktopVisibilityController; -import com.android.launcher3.util.SystemUiController; import com.android.launcher3.views.ActivityContext; import com.android.launcher3.views.ScrimView; @@ -54,11 +54,6 @@ public interface RecentsViewContainer extends ActivityContext { } } - /** - * Returns {@link SystemUiController} to manage various window flags to control system UI. - */ - SystemUiController getSystemUiController(); - /** * Returns {@link ScrimView} */ @@ -95,7 +90,7 @@ public interface RecentsViewContainer extends ActivityContext { /** * Returns overview actions view as a view */ - View getActionsView(); + OverviewActionsView getActionsView(); /** * @see BaseActivity#addForceInvisibleFlag(int) @@ -143,10 +138,10 @@ public interface RecentsViewContainer extends ActivityContext { void runOnBindToTouchInteractionService(Runnable r); /** - * @see Activity#getWindow() - * @return Window + * @see Activity#getComponentName() + * @return ComponentName */ - Window getWindow(); + ComponentName getComponentName(); /** * @see @@ -176,6 +171,25 @@ public interface RecentsViewContainer extends ActivityContext { */ boolean isRecentsViewVisible(); + /** + * Begins transition to start home through container + */ + default void startHome(){ + // no op + } + + /** + * Checks container to see if we can start home transition safely + */ + boolean canStartHomeSafely(); + + + /** + * Enter staged split directly from the current running app. + * @param leftOrTop if the staged split will be positioned left or top. + */ + default void enterStageSplitFromRunningApp(boolean leftOrTop){} + /** * Overwrites any logged item in Launcher that doesn't have a container with the * {@link com.android.launcher3.touch.PagedOrientationHandler} in use for Overview. diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/FallbackSwipeHandlerTestCase.java b/quickstep/tests/multivalentTests/src/com/android/quickstep/FallbackSwipeHandlerTestCase.java index dd0b4b30d0..8d6906fca4 100644 --- a/quickstep/tests/multivalentTests/src/com/android/quickstep/FallbackSwipeHandlerTestCase.java +++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/FallbackSwipeHandlerTestCase.java @@ -30,7 +30,7 @@ import org.mockito.Mock; public class FallbackSwipeHandlerTestCase extends AbsSwipeUpHandlerTestCase< RecentsActivity, RecentsState, - FallbackRecentsView, + FallbackRecentsView, RecentsActivity, FallbackActivityInterface, FallbackSwipeHandler> { diff --git a/src/com/android/launcher3/LauncherRootView.java b/src/com/android/launcher3/LauncherRootView.java index 7176733786..d64573477d 100644 --- a/src/com/android/launcher3/LauncherRootView.java +++ b/src/com/android/launcher3/LauncherRootView.java @@ -11,6 +11,7 @@ import android.view.WindowInsets; import com.android.launcher3.graphics.SysUiScrim; import com.android.launcher3.statemanager.StatefulActivity; +import com.android.launcher3.statemanager.StatefulContainer; import com.android.launcher3.util.window.WindowManagerProxy; import java.util.Collections; @@ -20,7 +21,7 @@ public class LauncherRootView extends InsettableFrameLayout { private final Rect mTempRect = new Rect(); - private final StatefulActivity mActivity; + private final StatefulContainer mStatefulContainer; @ViewDebug.ExportedProperty(category = "launcher") private static final List SYSTEM_GESTURE_EXCLUSION_RECT = @@ -36,24 +37,25 @@ public class LauncherRootView extends InsettableFrameLayout { public LauncherRootView(Context context, AttributeSet attrs) { super(context, attrs); - mActivity = StatefulActivity.fromContext(context); + mStatefulContainer = StatefulContainer.fromContext(context); mSysUiScrim = new SysUiScrim(this); } private void handleSystemWindowInsets(Rect insets) { // Update device profile before notifying the children. - mActivity.getDeviceProfile().updateInsets(insets); + mStatefulContainer.getDeviceProfile().updateInsets(insets); boolean resetState = !insets.equals(mInsets); setInsets(insets); if (resetState) { - mActivity.getStateManager().reapplyState(true /* cancelCurrentAnimation */); + mStatefulContainer.getStateManager().reapplyState(true /* cancelCurrentAnimation */); } } @Override public WindowInsets onApplyWindowInsets(WindowInsets insets) { - mActivity.handleConfigurationChanged(mActivity.getResources().getConfiguration()); + mStatefulContainer.handleConfigurationChanged( + mStatefulContainer.getContext().getResources().getConfiguration()); insets = WindowManagerProxy.INSTANCE.get(getContext()) .normalizeWindowInsets(getContext(), insets, mTempRect); @@ -72,7 +74,7 @@ public class LauncherRootView extends InsettableFrameLayout { } public void dispatchInsets() { - mActivity.getDeviceProfile().updateInsets(mInsets); + mStatefulContainer.getDeviceProfile().updateInsets(mInsets); super.setInsets(mInsets); } diff --git a/src/com/android/launcher3/dragndrop/DragLayer.java b/src/com/android/launcher3/dragndrop/DragLayer.java index 8b1f42b91f..a24f3ff1e7 100644 --- a/src/com/android/launcher3/dragndrop/DragLayer.java +++ b/src/com/android/launcher3/dragndrop/DragLayer.java @@ -121,7 +121,7 @@ public class DragLayer extends BaseDragLayer implements LauncherOverla @Override public void recreateControllers() { - mControllers = mActivity.createTouchControllers(); + mControllers = mContainer.createTouchControllers(); } public ViewGroupFocusHelper getFocusIndicatorHelper() { @@ -134,15 +134,15 @@ public class DragLayer extends BaseDragLayer implements LauncherOverla } private boolean isEventOverAccessibleDropTargetBar(MotionEvent ev) { - return isInAccessibleDrag() && isEventOverView(mActivity.getDropTargetBar(), ev); + return isInAccessibleDrag() && isEventOverView(mContainer.getDropTargetBar(), ev); } @Override public boolean onInterceptHoverEvent(MotionEvent ev) { - if (mActivity == null || mActivity.getWorkspace() == null) { + if (mContainer == null || mContainer.getWorkspace() == null) { return false; } - AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mActivity); + AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mContainer); if (!(topView instanceof Folder)) { return false; } else { @@ -197,7 +197,7 @@ public class DragLayer extends BaseDragLayer implements LauncherOverla private boolean isInAccessibleDrag() { - return mActivity.getAccessibilityDelegate().isInAccessibleDrag(); + return mContainer.getAccessibilityDelegate().isInAccessibleDrag(); } @Override @@ -210,12 +210,12 @@ public class DragLayer extends BaseDragLayer implements LauncherOverla @Override public void addChildrenForAccessibility(ArrayList childrenForAccessibility) { - View topView = AbstractFloatingView.getTopOpenViewWithType(mActivity, + View topView = AbstractFloatingView.getTopOpenViewWithType(mContainer, AbstractFloatingView.TYPE_ACCESSIBLE); if (topView != null) { addAccessibleChildToList(topView, childrenForAccessibility); if (isInAccessibleDrag()) { - addAccessibleChildToList(mActivity.getDropTargetBar(), childrenForAccessibility); + addAccessibleChildToList(mContainer.getDropTargetBar(), childrenForAccessibility); } } else { super.addChildrenForAccessibility(childrenForAccessibility); @@ -420,14 +420,14 @@ public class DragLayer extends BaseDragLayer implements LauncherOverla public void onViewAdded(View child) { super.onViewAdded(child); updateChildIndices(); - mActivity.onDragLayerHierarchyChanged(); + mContainer.onDragLayerHierarchyChanged(); } @Override public void onViewRemoved(View child) { super.onViewRemoved(child); updateChildIndices(); - mActivity.onDragLayerHierarchyChanged(); + mContainer.onDragLayerHierarchyChanged(); } @Override diff --git a/src/com/android/launcher3/graphics/SysUiScrim.java b/src/com/android/launcher3/graphics/SysUiScrim.java index 077ddfc665..d59fc1934c 100644 --- a/src/com/android/launcher3/graphics/SysUiScrim.java +++ b/src/com/android/launcher3/graphics/SysUiScrim.java @@ -32,10 +32,10 @@ import android.view.View; import androidx.annotation.ColorInt; import androidx.annotation.VisibleForTesting; -import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.DeviceProfile; import com.android.launcher3.R; import com.android.launcher3.anim.AnimatedFloat; +import com.android.launcher3.statemanager.StatefulContainer; import com.android.launcher3.testing.shared.ResourceUtils; import com.android.launcher3.util.ScreenOnTracker; import com.android.launcher3.util.ScreenOnTracker.ScreenOnListener; @@ -84,7 +84,7 @@ public class SysUiScrim implements View.OnAttachStateChangeListener { private final int mBottomMaskHeight; private final View mRoot; - private final BaseDraggingActivity mActivity; + private final StatefulContainer mContainer; private final boolean mHideSysUiScrim; private boolean mSkipScrimAnimationForTest = false; @@ -94,8 +94,8 @@ public class SysUiScrim implements View.OnAttachStateChangeListener { public SysUiScrim(View view) { mRoot = view; - mActivity = BaseDraggingActivity.fromContext(view.getContext()); - DisplayMetrics dm = mActivity.getResources().getDisplayMetrics(); + mContainer = StatefulContainer.fromContext(view.getContext()); + DisplayMetrics dm = mContainer.getContext().getResources().getDisplayMetrics(); mTopMaskHeight = ResourceUtils.pxFromDp(TOP_MASK_HEIGHT_DP, dm); mBottomMaskHeight = ResourceUtils.pxFromDp(BOTTOM_MASK_HEIGHT_DP, dm); @@ -130,7 +130,7 @@ public class SysUiScrim implements View.OnAttachStateChangeListener { ObjectAnimator oa = mSysUiAnimMultiplier.animateToValue(1); oa.setDuration(600); - oa.setStartDelay(mActivity.getWindow().getTransitionBackgroundFadeDuration()); + oa.setStartDelay(mContainer.getWindow().getTransitionBackgroundFadeDuration()); oa.start(); mAnimateScrimOnNextDraw = false; } @@ -166,19 +166,19 @@ public class SysUiScrim implements View.OnAttachStateChangeListener { * horizontal */ public void onInsetsChanged(Rect insets) { - DeviceProfile dp = mActivity.getDeviceProfile(); + DeviceProfile dp = mContainer.getDeviceProfile(); mDrawTopScrim = insets.top > 0; mDrawBottomScrim = !dp.isVerticalBarLayout() && !dp.isGestureMode && !dp.isTaskbarPresent; } @Override public void onViewAttachedToWindow(View view) { - ScreenOnTracker.INSTANCE.get(mActivity).addListener(mScreenOnListener); + ScreenOnTracker.INSTANCE.get(mContainer.getContext()).addListener(mScreenOnListener); } @Override public void onViewDetachedFromWindow(View view) { - ScreenOnTracker.INSTANCE.get(mActivity).removeListener(mScreenOnListener); + ScreenOnTracker.INSTANCE.get(mContainer.getContext()).removeListener(mScreenOnListener); } /** @@ -213,7 +213,7 @@ public class SysUiScrim implements View.OnAttachStateChangeListener { } private Bitmap createDitheredAlphaMask(int height, @ColorInt int[] colors, float[] positions) { - DisplayMetrics dm = mActivity.getResources().getDisplayMetrics(); + DisplayMetrics dm = mContainer.getContext().getResources().getDisplayMetrics(); int width = ResourceUtils.pxFromDp(ALPHA_MASK_BITMAP_WIDTH_DP, dm); Bitmap dst = Bitmap.createBitmap(width, height, Bitmap.Config.ALPHA_8); Canvas c = new Canvas(dst); diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java b/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java index 6e697d9def..d5c87f4874 100644 --- a/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java +++ b/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java @@ -65,7 +65,7 @@ public class SecondaryDragLayer extends BaseDragLayer @Override public void recreateControllers() { mControllers = new TouchController[]{new CloseAllAppsTouchController(), - mActivity.getDragController()}; + mContainer.getDragController()}; } /** @@ -79,10 +79,10 @@ public class SecondaryDragLayer extends BaseDragLayer mAppsView = findViewById(R.id.apps_view); // Setup workspace mWorkspace = findViewById(R.id.workspace_grid); - mPinnedAppsAdapter = new PinnedAppsAdapter(mActivity, mAppsView.getAppsStore(), + mPinnedAppsAdapter = new PinnedAppsAdapter(mContainer, mAppsView.getAppsStore(), this::onIconLongClicked); mWorkspace.setAdapter(mPinnedAppsAdapter); - mWorkspace.setNumColumns(mActivity.getDeviceProfile().inv.numColumns); + mWorkspace.setNumColumns(mContainer.getDeviceProfile().inv.numColumns); } /** @@ -112,7 +112,7 @@ public class SecondaryDragLayer extends BaseDragLayer int height = MeasureSpec.getSize(heightMeasureSpec); setMeasuredDimension(width, height); - DeviceProfile grid = mActivity.getDeviceProfile(); + DeviceProfile grid = mContainer.getDeviceProfile(); int count = getChildCount(); for (int i = 0; i < count; i++) { final View child = getChildAt(i); @@ -153,17 +153,17 @@ public class SecondaryDragLayer extends BaseDragLayer @Override public boolean onControllerInterceptTouchEvent(MotionEvent ev) { - if (!mActivity.isAppDrawerShown()) { + if (!mContainer.isAppDrawerShown()) { return false; } - if (AbstractFloatingView.getTopOpenView(mActivity) != null) { + if (AbstractFloatingView.getTopOpenView(mContainer) != null) { return false; } if (ev.getAction() == MotionEvent.ACTION_DOWN - && !isEventOverView(mActivity.getAppsView(), ev)) { - mActivity.showAppDrawer(false); + && !isEventOverView(mContainer.getAppsView(), ev)) { + mContainer.showAppDrawer(false); return true; } return false; @@ -178,7 +178,7 @@ public class SecondaryDragLayer extends BaseDragLayer if (!(v instanceof BubbleTextView)) { return false; } - if (PopupContainerWithArrow.getOpen(mActivity) != null) { + if (PopupContainerWithArrow.getOpen(mContainer) != null) { // There is already an items container open, so don't open this one. v.clearFocus(); return false; @@ -187,32 +187,32 @@ public class SecondaryDragLayer extends BaseDragLayer if (!ShortcutUtil.supportsShortcuts(item)) { return false; } - PopupDataProvider popupDataProvider = mActivity.getPopupDataProvider(); + PopupDataProvider popupDataProvider = mContainer.getPopupDataProvider(); if (popupDataProvider == null) { return false; } // order of this list will reflect in the popup List systemShortcuts = new ArrayList<>(); - systemShortcuts.add(APP_INFO.getShortcut(mActivity, item, v)); + systemShortcuts.add(APP_INFO.getShortcut(mContainer, item, v)); // Hide redundant pin shortcut for app drawer icons if drag-n-drop is enabled. - if (!FeatureFlags.SECONDARY_DRAG_N_DROP_TO_PIN.get() || !mActivity.isAppDrawerShown()) { + if (!FeatureFlags.SECONDARY_DRAG_N_DROP_TO_PIN.get() || !mContainer.isAppDrawerShown()) { systemShortcuts.add(mPinnedAppsAdapter.getSystemShortcut(item, v)); } int deepShortcutCount = popupDataProvider.getShortcutCountForItem(item); final PopupContainerWithArrow container; - container = (PopupContainerWithArrow) mActivity.getLayoutInflater().inflate( - R.layout.popup_container, mActivity.getDragLayer(), false); + container = (PopupContainerWithArrow) mContainer.getLayoutInflater().inflate( + R.layout.popup_container, mContainer.getDragLayer(), false); container.populateAndShowRows((BubbleTextView) v, deepShortcutCount, systemShortcuts); container.requestFocus(); - if (!FeatureFlags.SECONDARY_DRAG_N_DROP_TO_PIN.get() || !mActivity.isAppDrawerShown()) { + if (!FeatureFlags.SECONDARY_DRAG_N_DROP_TO_PIN.get() || !mContainer.isAppDrawerShown()) { return true; } DragOptions options = new DragOptions(); - DeviceProfile grid = mActivity.getDeviceProfile(); + DeviceProfile grid = mContainer.getDeviceProfile(); options.intrinsicIconScaleFactor = (float) grid.allAppsIconSizePx / grid.iconSizePx; options.preDragCondition = container.createPreDragCondition(false); if (options.preDragCondition == null) { @@ -229,7 +229,7 @@ public class SecondaryDragLayer extends BaseDragLayer mDragView = dragObject.dragView; if (!shouldStartDrag(0)) { mDragView.setOnScaleAnimEndCallback(() -> - mActivity.beginDragShared(v, mActivity.getAppsView(), options)); + mContainer.beginDragShared(v, mContainer.getAppsView(), options)); } } @@ -239,7 +239,7 @@ public class SecondaryDragLayer extends BaseDragLayer } }; } - mActivity.beginDragShared(v, mActivity.getAppsView(), options); + mContainer.beginDragShared(v, mContainer.getAppsView(), options); return true; } } diff --git a/src/com/android/launcher3/statemanager/StatefulActivity.java b/src/com/android/launcher3/statemanager/StatefulActivity.java index 28f2def8ab..54b2eaeab4 100644 --- a/src/com/android/launcher3/statemanager/StatefulActivity.java +++ b/src/com/android/launcher3/statemanager/StatefulActivity.java @@ -20,6 +20,7 @@ import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE; import static com.android.launcher3.LauncherState.FLAG_NON_INTERACTIVE; +import android.content.Context; import android.content.res.Configuration; import android.os.Bundle; import android.os.Handler; @@ -195,15 +196,15 @@ public abstract class StatefulActivity> mOldRotation = rotation; } + @Override + public Context getContext() { + return this; + } + /** * Logic for when device configuration changes (rotation, screen size change, multi-window, * etc.) */ protected abstract void onHandleConfigurationChanged(); - /** - * Enter staged split directly from the current running app. - * @param leftOrTop if the staged split will be positioned left or top. - */ - public void enterStageSplitFromRunningApp(boolean leftOrTop) { } } diff --git a/src/com/android/launcher3/statemanager/StatefulContainer.java b/src/com/android/launcher3/statemanager/StatefulContainer.java index 0cf0a27685..702dc6ac33 100644 --- a/src/com/android/launcher3/statemanager/StatefulContainer.java +++ b/src/com/android/launcher3/statemanager/StatefulContainer.java @@ -20,6 +20,12 @@ package com.android.launcher3.statemanager; import static com.android.launcher3.LauncherState.FLAG_CLOSE_POPUPS; import static com.android.launcher3.statemanager.BaseState.FLAG_NON_INTERACTIVE; +import android.app.Activity; +import android.content.Context; +import android.content.ContextWrapper; +import android.content.res.Configuration; +import android.view.Window; + import androidx.annotation.CallSuper; import com.android.launcher3.AbstractFloatingView; @@ -35,6 +41,23 @@ import java.util.List; public interface StatefulContainer> extends ActivityContext { + /** + * Returns an instance of an implementation of StatefulContainer + * + * @param context will find instance of StatefulContainer from given context. + */ + static T fromContext(Context context) { + if (context instanceof StatefulContainer) { + return (T) context; + } else if (context instanceof ContextWrapper) { + return fromContext(((ContextWrapper) context).getBaseContext()); + } else { + throw new IllegalArgumentException("Cannot find StatefulContainer in parent tree"); + } + } + + Context getContext(); + /** * Creates a factory for atomic state animations */ @@ -54,12 +77,15 @@ public interface StatefulContainer> ext /** * Called when transition to state ends + * * @param state current state of State_Type */ - default void onStateSetEnd(STATE_TYPE state) { } + default void onStateSetEnd(STATE_TYPE state) { + } /** * Called when transition to state starts + * * @param state current state of State_Type */ @CallSuper @@ -71,6 +97,7 @@ public interface StatefulContainer> ext /** * Returns true if the activity is in the provided state + * * @param state current state of State_Type */ default boolean isInState(STATE_TYPE state) { @@ -81,4 +108,8 @@ public interface StatefulContainer> ext * Returns true if state change should transition with animation */ boolean shouldAnimateStateChange(); + + default void handleConfigurationChanged(Configuration configuration){ + //no op + } } diff --git a/src/com/android/launcher3/testing/TestInformationHandler.java b/src/com/android/launcher3/testing/TestInformationHandler.java index 6d9b891e53..3a93981f0a 100644 --- a/src/com/android/launcher3/testing/TestInformationHandler.java +++ b/src/com/android/launcher3/testing/TestInformationHandler.java @@ -168,21 +168,14 @@ public class TestInformationHandler implements ResourceBasedOverride { } case TestProtocol.REQUEST_TARGET_INSETS: { - return getUIProperty(Bundle::putParcelable, activity -> { - WindowInsets insets = activity.getWindow() - .getDecorView().getRootWindowInsets(); - return Insets.max( - insets.getSystemGestureInsets(), - insets.getSystemWindowInsets()); - }, this::getCurrentActivity); + return getUIProperty(Bundle::putParcelable, insets -> Insets.max( + insets.getSystemGestureInsets(), + insets.getSystemWindowInsets()), this::getWindowInsets); } case TestProtocol.REQUEST_WINDOW_INSETS: { - return getUIProperty(Bundle::putParcelable, activity -> { - WindowInsets insets = activity.getWindow() - .getDecorView().getRootWindowInsets(); - return insets.getSystemWindowInsets(); - }, this::getCurrentActivity); + return getUIProperty(Bundle::putParcelable, + WindowInsets::getSystemWindowInsets, this::getWindowInsets); } case TestProtocol.REQUEST_CELL_LAYOUT_BOARDER_HEIGHT: { @@ -192,13 +185,13 @@ public class TestInformationHandler implements ResourceBasedOverride { } case TestProtocol.REQUEST_SYSTEM_GESTURE_REGION: { - return getUIProperty(Bundle::putParcelable, activity -> { - WindowInsetsCompat insets = WindowInsetsCompat.toWindowInsetsCompat( - activity.getWindow().getDecorView().getRootWindowInsets()); + return getUIProperty(Bundle::putParcelable, windowInsets -> { + WindowInsetsCompat insets = + WindowInsetsCompat.toWindowInsetsCompat(windowInsets); return insets.getInsets(WindowInsetsCompat.Type.ime() | WindowInsetsCompat.Type.systemGestures()) .toPlatformInsets(); - }, this::getCurrentActivity); + }, this::getWindowInsets); } case TestProtocol.REQUEST_ICON_HEIGHT: { @@ -486,8 +479,9 @@ public class TestInformationHandler implements ResourceBasedOverride { || LauncherAppState.getInstance(mContext).getModel().isModelLoaded(); } - protected Activity getCurrentActivity() { - return Launcher.ACTIVITY_TRACKER.getCreatedActivity(); + protected WindowInsets getWindowInsets(){ + return Launcher.ACTIVITY_TRACKER.getCreatedActivity().getWindow().getDecorView() + .getRootWindowInsets(); } /** diff --git a/src/com/android/launcher3/views/ActivityContext.java b/src/com/android/launcher3/views/ActivityContext.java index d3160e0db3..a86caf38e4 100644 --- a/src/com/android/launcher3/views/ActivityContext.java +++ b/src/com/android/launcher3/views/ActivityContext.java @@ -26,6 +26,7 @@ import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCH import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; +import android.app.Activity; import android.app.ActivityOptions; import android.app.PendingIntent; import android.content.ActivityNotFoundException; @@ -46,6 +47,7 @@ import android.view.Display; import android.view.LayoutInflater; import android.view.View; import android.view.View.AccessibilityDelegate; +import android.view.Window; import android.view.WindowInsets; import android.view.WindowInsetsController; import android.view.inputmethod.InputMethodManager; @@ -80,6 +82,7 @@ import com.android.launcher3.util.PackageManagerHelper; import com.android.launcher3.util.Preconditions; import com.android.launcher3.util.RunnableList; import com.android.launcher3.util.SplitConfigurationOptions; +import com.android.launcher3.util.SystemUiController; import com.android.launcher3.util.ViewCache; import com.android.launcher3.widget.picker.model.WidgetPickerDataProvider; @@ -172,7 +175,16 @@ public interface ActivityContext { /** * The root view to support drag-and-drop and popup support. */ - BaseDragLayer getDragLayer(); + BaseDragLayer getDragLayer(); + + /** + * @see Activity#getWindow() + * @return Window + */ + @Nullable + default Window getWindow() { + return null; + } /** * The all apps container, if it exists in this context. @@ -216,6 +228,11 @@ public interface ActivityContext { return null; } + @Nullable + default SystemUiController getSystemUiController() { + return null; + } + /** * Handler for actions taken on drop targets that require launcher */ diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java index 5d2d3f4e9f..ea3fb3fb42 100644 --- a/src/com/android/launcher3/views/BaseDragLayer.java +++ b/src/com/android/launcher3/views/BaseDragLayer.java @@ -107,7 +107,7 @@ public abstract class BaseDragLayer protected final RectF mSystemGestureRegion = new RectF(); private int mTouchDispatchState = 0; - protected final T mActivity; + protected final T mContainer; private final MultiValueAlpha mMultiValueAlpha; // All the touch controllers for the view @@ -121,7 +121,7 @@ public abstract class BaseDragLayer public BaseDragLayer(Context context, AttributeSet attrs, int alphaChannelCount) { super(context, attrs); - mActivity = ActivityContext.lookupContext(context); + mContainer = ActivityContext.lookupContext(context); mMultiValueAlpha = new MultiValueAlpha(this, alphaChannelCount); } @@ -159,7 +159,7 @@ public abstract class BaseDragLayer } mTouchCompleteListener = null; } else if (action == MotionEvent.ACTION_DOWN) { - mActivity.finishAutoCancelActionMode(); + mContainer.finishAutoCancelActionMode(); } return findActiveController(ev); } @@ -173,7 +173,7 @@ public abstract class BaseDragLayer } private TouchController findControllerToHandleTouch(MotionEvent ev) { - AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mActivity); + AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mContainer); if (topView != null && (isEventWithinSystemGestureRegion(ev) || topView.canInterceptEventsInSystemGestureRegion()) @@ -207,7 +207,7 @@ public abstract class BaseDragLayer @Override public boolean onRequestSendAccessibilityEvent(View child, AccessibilityEvent event) { // Shortcuts can appear above folder - View topView = AbstractFloatingView.getTopOpenViewWithType(mActivity, + View topView = AbstractFloatingView.getTopOpenViewWithType(mContainer, AbstractFloatingView.TYPE_ACCESSIBLE); if (topView != null) { if (child == topView) { @@ -222,7 +222,7 @@ public abstract class BaseDragLayer @Override public void addChildrenForAccessibility(ArrayList childrenForAccessibility) { - View topView = AbstractFloatingView.getTopOpenViewWithType(mActivity, + View topView = AbstractFloatingView.getTopOpenViewWithType(mContainer, AbstractFloatingView.TYPE_ACCESSIBLE); if (topView != null) { // Only add the top view as a child for accessibility when it is open @@ -458,7 +458,7 @@ public abstract class BaseDragLayer @Override protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) { - View topView = AbstractFloatingView.getTopOpenView(mActivity); + View topView = AbstractFloatingView.getTopOpenView(mContainer); if (topView != null) { return topView.requestFocus(direction, previouslyFocusedRect); } else { @@ -468,7 +468,7 @@ public abstract class BaseDragLayer @Override public void addFocusables(ArrayList views, int direction, int focusableMode) { - View topView = AbstractFloatingView.getTopOpenView(mActivity); + View topView = AbstractFloatingView.getTopOpenView(mContainer); if (topView != null) { topView.addFocusables(views, direction); } else { @@ -555,7 +555,7 @@ public abstract class BaseDragLayer Insets gestureInsets = insets.getMandatorySystemGestureInsets(); int gestureInsetBottom = gestureInsets.bottom; Insets imeInset = insets.getInsets(WindowInsets.Type.ime()); - DeviceProfile dp = mActivity.getDeviceProfile(); + DeviceProfile dp = mContainer.getDeviceProfile(); if (dp.isTaskbarPresent) { // Ignore taskbar gesture insets to avoid interfering with TouchControllers. gestureInsetBottom = ResourceUtils.getNavbarSize( diff --git a/src/com/android/launcher3/views/ScrimView.java b/src/com/android/launcher3/views/ScrimView.java index f6c49847de..ce58de1ee5 100644 --- a/src/com/android/launcher3/views/ScrimView.java +++ b/src/com/android/launcher3/views/ScrimView.java @@ -29,7 +29,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Px; import androidx.core.graphics.ColorUtils; -import com.android.launcher3.BaseActivity; import com.android.launcher3.Insettable; import com.android.launcher3.util.SystemUiController; @@ -143,7 +142,8 @@ public class ScrimView extends View implements Insettable { private SystemUiController getSystemUiController() { if (mSystemUiController == null) { - mSystemUiController = BaseActivity.fromContext(getContext()).getSystemUiController(); + mSystemUiController = + ActivityContext.lookupContext(getContext()).getSystemUiController(); } return mSystemUiController; }