From 8b7b5e6781eafd873ed0acc92c584d1359de38d3 Mon Sep 17 00:00:00 2001 From: wilsonshih Date: Thu, 5 Nov 2020 15:00:54 +0800 Subject: [PATCH] Let Launcher able to receive task launching callback(3/N) When StartingWindowController receive addStartingWindow, send a callback out so a listener can know whether current launch cold or warm. Ref doc: go/starting_window_android_s Bug: 131311659 Bug: 131727939 Bug: 152480470 Test: atest WindowOrganizerTests StartingSurfaceDrawerTests SplashscreenTests Change-Id: Ic9f02f51d5de141b56a8f28003bf1cb1a5a63f22 --- .../startingsurface/StartingSurface.java | 8 ++++ .../StartingWindowController.java | 23 +++++++++++ .../recents/IStartingWindowListener.aidl | 30 +++++++++++++++ .../shared/recents/ISystemUiProxy.aidl | 7 +++- .../recents/OverviewProxyService.java | 38 ++++++++++++++++++- .../recents/OverviewProxyServiceTest.java | 4 +- 6 files changed, 107 insertions(+), 3 deletions(-) create mode 100644 packages/SystemUI/shared/src/com/android/systemui/shared/recents/IStartingWindowListener.aidl diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurface.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurface.java index 2c4ceffcb8f55..a594a9f31ddea 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurface.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurface.java @@ -19,6 +19,7 @@ package com.android.wm.shell.startingsurface; import android.os.IBinder; import android.window.StartingWindowInfo; +import java.util.function.BiConsumer; /** * Interface to engage starting window feature. */ @@ -36,4 +37,11 @@ public interface StartingSurface { * @param taskId */ void copySplashScreenView(int taskId); + + /** + * Registers the starting window listener. + * + * @param listener The callback when need a starting window. + */ + void setStartingWindowListener(BiConsumer listener); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java index 73bf8ac90c296..1ac05fbff9c4f 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java @@ -25,6 +25,7 @@ import static android.window.StartingWindowInfo.TYPE_PARAMETER_NEW_TASK; import static android.window.StartingWindowInfo.TYPE_PARAMETER_PROCESS_RUNNING; import static android.window.StartingWindowInfo.TYPE_PARAMETER_TASK_SWITCH; +import android.app.ActivityManager.RunningTaskInfo; import android.app.ActivityTaskManager; import android.content.Context; import android.os.IBinder; @@ -36,6 +37,8 @@ import android.window.TaskSnapshot; import com.android.wm.shell.common.ShellExecutor; +import java.util.function.BiConsumer; + /** * Implementation to draw the starting window to an application, and remove the starting window * until the application displays its own window. @@ -53,6 +56,8 @@ public class StartingWindowController { private final StartingSurfaceDrawer mStartingSurfaceDrawer; private final StartingTypeChecker mStartingTypeChecker = new StartingTypeChecker(); + + private BiConsumer mTaskLaunchingCallback; private final StartingSurfaceImpl mImpl = new StartingSurfaceImpl(); public StartingWindowController(Context context, ShellExecutor mainExecutor) { @@ -151,11 +156,24 @@ public class StartingWindowController { } } + /* + * Registers the starting window listener. + * + * @param listener The callback when need a starting window. + */ + void setStartingWindowListener(BiConsumer listener) { + mTaskLaunchingCallback = listener; + } + /** * Called when a task need a starting window. */ void addStartingWindow(StartingWindowInfo windowInfo, IBinder appToken) { final int suggestionType = mStartingTypeChecker.estimateStartingWindowType(windowInfo); + final RunningTaskInfo runningTaskInfo = windowInfo.taskInfo; + if (mTaskLaunchingCallback != null) { + mTaskLaunchingCallback.accept(runningTaskInfo.taskId, suggestionType); + } if (suggestionType == STARTING_WINDOW_TYPE_SPLASH_SCREEN) { mStartingSurfaceDrawer.addSplashScreenStartingWindow(windowInfo, appToken); } else if (suggestionType == STARTING_WINDOW_TYPE_SNAPSHOT) { @@ -192,5 +210,10 @@ public class StartingWindowController { public void copySplashScreenView(int taskId) { StartingWindowController.this.copySplashScreenView(taskId); } + + @Override + public void setStartingWindowListener(BiConsumer listener) { + StartingWindowController.this.setStartingWindowListener(listener); + } } } diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IStartingWindowListener.aidl b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IStartingWindowListener.aidl new file mode 100644 index 0000000000000..eb3e60cec5c55 --- /dev/null +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IStartingWindowListener.aidl @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2020 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.systemui.shared.recents; + +/** + * Listener interface that Launcher attaches to SystemUI to get + * callbacks when need a new starting window. + */ +interface IStartingWindowListener { + /** + * Notifies when Shell going to create a new starting window. + * @param taskId The task Id + * @param supportedType The starting window type + */ + oneway void onTaskLaunching(int taskId, int supportedType); +} diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl index bac4c43ccddcc..49e86f55bb9ea 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl @@ -30,12 +30,13 @@ import android.view.MotionEvent; import com.android.systemui.shared.recents.IPinnedStackAnimationListener; import com.android.systemui.shared.recents.ISplitScreenListener; +import com.android.systemui.shared.recents.IStartingWindowListener; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.system.RemoteTransitionCompat; /** * Temporary callbacks into SystemUI. - * Next id = 43 + * Next id = 44 */ interface ISystemUiProxy { @@ -255,4 +256,8 @@ interface ISystemUiProxy { in PendingIntent intent, in Intent fillInIntent, in int stage, in int position, in Bundle options) = 41; void removeFromSideStage(in int taskId) = 42; + /** + * Sets listener to get task launching callbacks. + */ + void setStartingWindowListener(IStartingWindowListener listener) = 43; } diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java index e7d42832878b8..a87bfd83916aa 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java +++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java @@ -85,6 +85,7 @@ import com.android.systemui.settings.CurrentUserTracker; import com.android.systemui.shared.recents.IOverviewProxy; import com.android.systemui.shared.recents.IPinnedStackAnimationListener; import com.android.systemui.shared.recents.ISplitScreenListener; +import com.android.systemui.shared.recents.IStartingWindowListener; import com.android.systemui.shared.recents.ISystemUiProxy; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.system.ActivityManagerWrapper; @@ -101,6 +102,7 @@ import com.android.wm.shell.onehanded.OneHanded; import com.android.wm.shell.pip.Pip; import com.android.wm.shell.pip.PipAnimationController; import com.android.wm.shell.splitscreen.SplitScreen; +import com.android.wm.shell.startingsurface.StartingSurface; import com.android.wm.shell.transition.RemoteTransitions; import java.io.FileDescriptor; @@ -150,6 +152,7 @@ public class OverviewProxyService extends CurrentUserTracker implements private final Optional mOneHandedOptional; private final CommandQueue mCommandQueue; private final RemoteTransitions mShellTransitions; + private final Optional mStartingSurface; private Region mActiveNavBarRegion; @@ -167,6 +170,7 @@ public class OverviewProxyService extends CurrentUserTracker implements private boolean mSupportsRoundedCornersOnWindows; private int mNavBarMode = NAV_BAR_MODE_3BUTTON; private final ArraySet mRemoteTransitions = new ArraySet<>(); + private IStartingWindowListener mIStartingWindowListener; @VisibleForTesting public ISystemUiProxy mSysUiProxy = new ISystemUiProxy.Stub() { @@ -439,6 +443,21 @@ public class OverviewProxyService extends CurrentUserTracker implements } } + @Override + public void setStartingWindowListener(IStartingWindowListener listener) { + if (!verifyCaller("setStartingWindowListener")) { + return; + } + mIStartingWindowListener = listener; + final long token = Binder.clearCallingIdentity(); + try { + mStartingSurface.ifPresent(s -> + s.setStartingWindowListener(mStartingWindowListener)); + } finally { + Binder.restoreCallingIdentity(token); + } + } + @Override public void onQuickSwitchToNewTask(@Surface.Rotation int rotation) { if (!verifyCaller("onQuickSwitchToNewTask")) { @@ -785,6 +804,9 @@ public class OverviewProxyService extends CurrentUserTracker implements private final Consumer mPinnedStackAnimationCallback = this::notifyPinnedStackAnimationStarted; + private final BiConsumer mStartingWindowListener = + this::notifyTaskLaunching; + // This is the death handler for the binder from the launcher service private final IBinder.DeathRecipient mOverviewServiceDeathRcpt = this::cleanupAfterDeath; @@ -827,7 +849,8 @@ public class OverviewProxyService extends CurrentUserTracker implements Optional> statusBarOptionalLazy, Optional oneHandedOptional, BroadcastDispatcher broadcastDispatcher, - RemoteTransitions shellTransitions) { + RemoteTransitions shellTransitions, + Optional startingSurface) { super(broadcastDispatcher); mContext = context; mPipOptional = pipOptional; @@ -887,6 +910,7 @@ public class OverviewProxyService extends CurrentUserTracker implements // Connect to the service updateEnabledState(); startConnectionToCurrentUser(); + mStartingSurface = startingSurface; } @Override @@ -953,6 +977,18 @@ public class OverviewProxyService extends CurrentUserTracker implements } } + private void notifyTaskLaunching(int taskId, int supportedType) { + if (mIStartingWindowListener == null) { + return; + } + + try { + mIStartingWindowListener.onTaskLaunching(taskId, supportedType); + } catch (RemoteException e) { + Log.e(TAG_OPS, "Failed to call notifyTaskLaunching()", e); + } + } + private void onStatusBarStateChanged(boolean keyguardShowing, boolean keyguardOccluded, boolean bouncerShowing) { mSysUiState.setFlag(SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING, diff --git a/packages/SystemUI/tests/src/com/android/systemui/recents/OverviewProxyServiceTest.java b/packages/SystemUI/tests/src/com/android/systemui/recents/OverviewProxyServiceTest.java index 6d2b8e415e969..25104b8b1d20d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/recents/OverviewProxyServiceTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/recents/OverviewProxyServiceTest.java @@ -43,6 +43,7 @@ import com.android.systemui.statusbar.phone.StatusBar; import com.android.wm.shell.legacysplitscreen.LegacySplitScreen; import com.android.wm.shell.pip.Pip; import com.android.wm.shell.splitscreen.SplitScreen; +import com.android.wm.shell.startingsurface.StartingSurface; import com.android.wm.shell.transition.RemoteTransitions; import org.junit.Before; @@ -79,6 +80,7 @@ public class OverviewProxyServiceTest extends SysuiTestCase { @Mock private PackageManager mPackageManager; @Mock private SysUiState mMockSysUiState; @Mock private RemoteTransitions mMockTransitions; + @Mock private Optional mStartingSurface; @Before public void setUp() throws RemoteException { @@ -93,7 +95,7 @@ public class OverviewProxyServiceTest extends SysuiTestCase { mMockNavBarControllerLazy, mMockNavModeController, mMockStatusBarWinController, mMockSysUiState, mMockPipOptional, mMockLegacySplitScreenOptional, mMockSplitScreenOptional, mMockStatusBarOptionalLazy, mMockOneHandedOptional, - mMockBroadcastDispatcher, mMockTransitions)); + mMockBroadcastDispatcher, mMockTransitions, mStartingSurface)); } @Test