Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8b7b5e67 authored by wilsonshih's avatar wilsonshih
Browse files

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
parent 1623f60d
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -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<Integer, Integer> listener);
}
+23 −0
Original line number Diff line number Diff line
@@ -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<Integer, Integer> 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<Integer, Integer> 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<Integer, Integer> listener) {
            StartingWindowController.this.setStartingWindowListener(listener);
        }
    }
}
+30 −0
Original line number Diff line number Diff line
/*
 * 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);
}
+6 −1
Original line number Diff line number Diff line
@@ -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;
}
+37 −1
Original line number Diff line number Diff line
@@ -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<OneHanded> mOneHandedOptional;
    private final CommandQueue mCommandQueue;
    private final RemoteTransitions mShellTransitions;
    private final Optional<StartingSurface> 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<IRemoteTransition> 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<Boolean> mPinnedStackAnimationCallback =
            this::notifyPinnedStackAnimationStarted;

    private final BiConsumer<Integer, Integer> 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<Lazy<StatusBar>> statusBarOptionalLazy,
            Optional<OneHanded> oneHandedOptional,
            BroadcastDispatcher broadcastDispatcher,
            RemoteTransitions shellTransitions) {
            RemoteTransitions shellTransitions,
            Optional<StartingSurface> 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,
Loading