diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java index f209920e95..acb686b6d9 100644 --- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java +++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java @@ -100,6 +100,11 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn TaskAnimationManager(Context ctx) { mCtx = ctx; } + + SystemUiProxy getSystemUiProxy() { + return SystemUiProxy.INSTANCE.get(mCtx); + } + /** * Preloads the recents animation. */ @@ -153,7 +158,7 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn final BaseContainerInterface containerInterface = gestureState.getContainerInterface(); mLastGestureState = gestureState; RecentsAnimationCallbacks newCallbacks = new RecentsAnimationCallbacks( - SystemUiProxy.INSTANCE.get(mCtx), containerInterface.allowMinimizeSplitScreen()); + getSystemUiProxy(), containerInterface.allowMinimizeSplitScreen()); mCallbacks = newCallbacks; mCallbacks.addListener(new RecentsAnimationCallbacks.RecentsAnimationListener() { @Override @@ -260,7 +265,7 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn } RemoteAnimationTarget[] nonAppTargets = ENABLE_SHELL_TRANSITIONS - ? null : SystemUiProxy.INSTANCE.get(mCtx).onStartingSplitLegacy( + ? null : getSystemUiProxy().onStartingSplitLegacy( appearedTaskTargets); if (nonAppTargets == null) { nonAppTargets = new RemoteAnimationTarget[0]; @@ -327,12 +332,13 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn if (ENABLE_SHELL_TRANSITIONS) { final ActivityOptions options = ActivityOptions.makeBasic(); + options.setPendingIntentBackgroundActivityLaunchAllowedByPermission(true); // Use regular (non-transient) launch for all apps page to control IME. if (!containerInterface.allowAllAppsFromOverview()) { options.setTransientLaunch(); } options.setSourceInfo(ActivityOptions.SourceInfo.TYPE_RECENTS_ANIMATION, eventTime); - mRecentsAnimationStartPending = SystemUiProxy.INSTANCE.get(mCtx) + mRecentsAnimationStartPending = getSystemUiProxy() .startRecentsActivity(intent, options, mCallbacks); if (enableHandleDelayedGestureCallbacks()) { ActiveGestureLog.INSTANCE.addLog(new ActiveGestureLog.CompoundString( diff --git a/quickstep/tests/src/com/android/quickstep/TaskAnimationManagerTest.java b/quickstep/tests/src/com/android/quickstep/TaskAnimationManagerTest.java new file mode 100644 index 0000000000..2d796234b8 --- /dev/null +++ b/quickstep/tests/src/com/android/quickstep/TaskAnimationManagerTest.java @@ -0,0 +1,77 @@ +/* + * 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 org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import android.app.ActivityOptions; +import android.content.Context; +import android.content.Intent; + +import androidx.test.filters.SmallTest; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +@SmallTest +public class TaskAnimationManagerTest { + + @Mock + private Context mContext; + + @Mock + private SystemUiProxy mSystemUiProxy; + + private TaskAnimationManager mTaskAnimationManager; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mTaskAnimationManager = new TaskAnimationManager(mContext) { + @Override + SystemUiProxy getSystemUiProxy() { + return mSystemUiProxy; + } + }; + } + + @Test + public void startRecentsActivity_allowBackgroundLaunch() { + assumeTrue(TaskAnimationManager.ENABLE_SHELL_TRANSITIONS); + + final LauncherActivityInterface activityInterface = mock(LauncherActivityInterface.class); + final GestureState gestureState = mock(GestureState.class); + final RecentsAnimationCallbacks.RecentsAnimationListener listener = + mock(RecentsAnimationCallbacks.RecentsAnimationListener.class); + doReturn(activityInterface).when(gestureState).getContainerInterface(); + mTaskAnimationManager.startRecentsAnimation(gestureState, new Intent(), listener); + + final ArgumentCaptor optionsCaptor = + ArgumentCaptor.forClass(ActivityOptions.class); + verify(mSystemUiProxy).startRecentsActivity(any(), optionsCaptor.capture(), any()); + assertTrue(optionsCaptor.getValue() + .isPendingIntentBackgroundActivityLaunchAllowedByPermission()); + } +}