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
This commit is contained in:
randypfohl
2024-09-20 10:23:31 -07:00
parent f0123c9129
commit f29dc7c5ec
28 changed files with 515 additions and 194 deletions
@@ -100,7 +100,7 @@ public class TaskbarDragLayer extends BaseDragLayer<TaskbarActivityContext> {
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<TaskbarActivityContext> {
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<TaskbarActivityContext> {
@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.
@@ -73,7 +73,7 @@ public class TaskbarOverlayDragLayer extends
@Override
public void recreateControllers() {
List<TouchController> 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());
@@ -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<STATE_TYPE extends BaseState<STATE_T
return activity != null && activity.isStarted();
}
@UiThread
@Nullable
public abstract <T extends RecentsView> T getVisibleRecentsView();
@UiThread
public abstract boolean switchToRecentsIfVisible(Animator.AnimatorListener animatorListener);
public boolean deferStartingActivity(RecentsAnimationDeviceState deviceState, MotionEvent ev) {
TaskbarUIController controller = getTaskbarController();
boolean isEventOverBubbleBarStashHandle =
@@ -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<STATE_TYPE extends BaseState<STATE_TYPE>,
CONTAINER_TYPE extends RecentsViewContainer> {
public boolean rotationSupportedByActivity = false;
@UiThread
@Nullable
public abstract <T extends RecentsView<?,?>> T getVisibleRecentsView();
@UiThread
public abstract boolean switchToRecentsIfVisible(Animator.AnimatorListener animatorListener);
@Nullable
public abstract CONTAINER_TYPE getCreatedContainer();
@@ -126,6 +135,8 @@ public abstract class BaseContainerInterface<STATE_TYPE extends BaseState<STATE_
return false;
}
abstract void runOnInitBackgroundStateUI(Runnable callback);
@Nullable
public DesktopVisibilityController getDesktopVisibilityController() {
CONTAINER_TYPE container = getCreatedContainer();
@@ -82,7 +82,7 @@ import java.util.function.Consumer;
* Handles the navigation gestures when a 3rd party launcher is the default home activity.
*/
public class FallbackSwipeHandler extends
AbsSwipeUpHandler<RecentsActivity, FallbackRecentsView, RecentsState> {
AbsSwipeUpHandler<RecentsActivity, FallbackRecentsView<RecentsActivity>, RecentsState> {
private static final String TAG = "FallbackSwipeHandler";
@@ -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<AnimatorControllerWithResistance> callback) {
notifyRecentsOfOrientation(deviceState.getRotationTouchHelper());
BaseWindowInterface.DefaultAnimationFactory factory =
new BaseWindowInterface.DefaultAnimationFactory(callback);
factory.initBackgroundStateUI();
return factory;
}
@Override
public ActivityInitListener createActivityInitListener(
Predicate<Boolean> 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 extends RecentsView<?, ?>> 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<RecentsState, RecentsWindowManager> stateManager =
getCreatedContainer().getStateManager();
if (stateManager.getState() == HOME) {
exitRunnable.run();
notifyRecentsOfOrientation(deviceState);
return;
}
stateManager.addStateListener(
new StateManager.StateListener<RecentsState>() {
@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.<RecentsView>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;
}
}
@@ -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;
@@ -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<RecentsView<*, *>>()
get() = containerInterface.getVisibleRecentsView<RecentsView<*, *>>()
/**
* 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
@@ -73,7 +73,7 @@ public final class OverviewComponentObserver {
private Consumer<Boolean> 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) {
@@ -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();
@@ -198,7 +198,7 @@ public final class RecentsActivity extends StatefulActivity<RecentsState> implem
}
@Override
protected void onHandleConfigurationChanged() {
public void onHandleConfigurationChanged() {
initDeviceProfile();
AbstractFloatingView.closeOpenViews(this, true,
@@ -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);
@@ -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<RecentsState> {
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<RecentsState
setter.setFloat(mRecentsView.getClearAllButton(), ClearAllButton.VISIBILITY_ALPHA,
clearAllButtonAlpha, LINEAR);
float overviewButtonAlpha = state.hasOverviewActions() ? 1 : 0;
setter.setFloat(mActivity.getActionsView().getVisibilityAlpha(),
setter.setFloat(mRecentsViewContainer.getActionsView().getVisibilityAlpha(),
AnimatedFloat.VALUE, overviewButtonAlpha, LINEAR);
float[] scaleAndOffset = state.getOverviewScaleAndOffset(mActivity);
float[] scaleAndOffset = state.getOverviewScaleAndOffset(mRecentsViewContainer);
setter.setFloat(mRecentsView, RECENTS_SCALE_PROPERTY, scaleAndOffset[0],
config.getInterpolator(ANIM_OVERVIEW_SCALE, LINEAR));
setter.setFloat(mRecentsView, ADJACENT_PAGE_HORIZONTAL_OFFSET, scaleAndOffset[1],
@@ -110,16 +110,19 @@ public class FallbackRecentsStateController implements StateHandler<RecentsState
setter.setFloat(mRecentsView, TASK_MODALNESS, state.getOverviewModalness(),
config.getInterpolator(ANIM_OVERVIEW_MODAL, LINEAR));
setter.setFloat(mRecentsView, FULLSCREEN_PROGRESS, state.isFullScreen() ? 1 : 0, LINEAR);
boolean showAsGrid = state.displayOverviewTasksAsGrid(mActivity.getDeviceProfile());
boolean showAsGrid =
state.displayOverviewTasksAsGrid(mRecentsViewContainer.getDeviceProfile());
setter.setFloat(mRecentsView, RECENTS_GRID_PROGRESS, showAsGrid ? 1f : 0f,
getOverviewInterpolator(state));
setter.setFloat(mRecentsView, TASK_THUMBNAIL_SPLASH_ALPHA,
state.showTaskThumbnailSplash() ? 1f : 0f, getOverviewInterpolator(state));
setter.setViewBackgroundColor(mActivity.getScrimView(), state.getScrimColor(mActivity),
setter.setViewBackgroundColor(mRecentsViewContainer.getScrimView(),
state.getScrimColor(mRecentsViewContainer.asContext()),
config.getInterpolator(ANIM_SCRIM_FADE, LINEAR));
if (isSplitSelectionState(state)) {
int duration = state.getTransitionDuration(mActivity, true /* isToState */);
int duration =
state.getTransitionDuration(mRecentsViewContainer.asContext(), true);
// TODO (b/246851887): Pass in setter as a NO_ANIM PendingAnimation instead
PendingAnimation pa = new PendingAnimation(duration);
mRecentsView.createSplitSelectInitAnimation(pa, duration);
@@ -129,7 +132,7 @@ public class FallbackRecentsStateController implements StateHandler<RecentsState
Pair<FloatProperty<RecentsView>, FloatProperty<RecentsView>> 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);
@@ -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<RecentsActivity, RecentsState>
public class FallbackRecentsView<CONTAINER_TYPE extends Context & RecentsViewContainer
& StatefulContainer<RecentsState>> extends RecentsView<CONTAINER_TYPE, RecentsState>
implements StateListener<RecentsState> {
private static final int TASK_DISMISS_DURATION = 150;
@@ -93,7 +96,7 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity, RecentsSta
}
@Override
public StateManager<RecentsState, RecentsActivity> getStateManager() {
public StateManager<RecentsState, ?> getStateManager() {
return mContainer.getStateManager();
}
@@ -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<RecentsActivity> {
public class RecentsDragLayer<T extends Context & RecentsViewContainer> extends BaseDragLayer<T> {
public RecentsDragLayer(Context context, AttributeSet attrs) {
super(context, attrs, 1 /* alphaChannelCount */);
}
@@ -34,8 +33,8 @@ public class RecentsDragLayer extends BaseDragLayer<RecentsActivity> {
@Override
public void recreateControllers() {
mControllers = new TouchController[] {
new RecentsTaskController(mActivity),
new FallbackNavBarTouchController(mActivity),
new RecentsTaskController(mContainer),
new FallbackNavBarTouchController(mContainer),
};
}
}
@@ -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<RecentsActivity> {
public RecentsTaskController(RecentsActivity activity) {
super(activity);
public class RecentsTaskController<T extends Context & RecentsViewContainer &
StatefulContainer<RecentsState>> extends TaskViewTouchController<T> {
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
@@ -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.