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

Commit 6c75e58f authored by Winson Chung's avatar Winson Chung
Browse files

9/ Update transitions/starting window for shell thread

Bug: 161979899
Test: atest WMShellUnitTests
Test: atest SystemUITests
Change-Id: I0afbacd0db32ef02f1e178f7a53b16df5b64449b
parent f3e26616
Loading
Loading
Loading
Loading
+33 −37
Original line number Original line Diff line number Diff line
@@ -377,12 +377,10 @@ public class StartingSurfaceDrawer {
        final int taskId = startingWindowInfo.taskInfo.taskId;
        final int taskId = startingWindowInfo.taskInfo.taskId;
        final TaskSnapshotWindow surface = TaskSnapshotWindow.create(startingWindowInfo, appToken,
        final TaskSnapshotWindow surface = TaskSnapshotWindow.create(startingWindowInfo, appToken,
                snapshot, mMainExecutor, () -> removeWindowSynced(taskId) /* clearWindow */);
                snapshot, mMainExecutor, () -> removeWindowSynced(taskId) /* clearWindow */);
        mMainExecutor.execute(() -> {
        mMainExecutor.executeDelayed(() -> removeWindowSynced(taskId), REMOVE_WHEN_TIMEOUT);
        mMainExecutor.executeDelayed(() -> removeWindowSynced(taskId), REMOVE_WHEN_TIMEOUT);
        final StartingWindowRecord tView =
        final StartingWindowRecord tView =
                new StartingWindowRecord(null/* decorView */, surface);
                new StartingWindowRecord(null/* decorView */, surface);
        mStartingWindowRecords.put(taskId, tView);
        mStartingWindowRecords.put(taskId, tView);
        });
    }
    }


    /**
    /**
@@ -392,12 +390,11 @@ public class StartingSurfaceDrawer {
        if (DEBUG_SPLASH_SCREEN || DEBUG_TASK_SNAPSHOT) {
        if (DEBUG_SPLASH_SCREEN || DEBUG_TASK_SNAPSHOT) {
            Slog.d(TAG, "Task start finish, remove starting surface for task " + taskId);
            Slog.d(TAG, "Task start finish, remove starting surface for task " + taskId);
        }
        }
        mMainExecutor.execute(() -> removeWindowSynced(taskId));
        removeWindowSynced(taskId);
    }
    }


    protected void postAddWindow(int taskId, IBinder appToken,
    protected void postAddWindow(int taskId, IBinder appToken,
        View view, WindowManager wm, WindowManager.LayoutParams params) {
        View view, WindowManager wm, WindowManager.LayoutParams params) {
        mMainExecutor.execute(() -> {
        boolean shouldSaveView = true;
        boolean shouldSaveView = true;
        try {
        try {
            wm.addView(view, params);
            wm.addView(view, params);
@@ -427,7 +424,6 @@ public class StartingSurfaceDrawer {
                    new StartingWindowRecord(view, null /* TaskSnapshotWindow */);
                    new StartingWindowRecord(view, null /* TaskSnapshotWindow */);
            mStartingWindowRecords.put(taskId, tView);
            mStartingWindowRecords.put(taskId, tView);
        }
        }
        });
    }
    }


    protected void removeWindowSynced(int taskId) {
    protected void removeWindowSynced(int taskId) {
@@ -445,7 +441,7 @@ public class StartingSurfaceDrawer {
                if (DEBUG_TASK_SNAPSHOT) {
                if (DEBUG_TASK_SNAPSHOT) {
                    Slog.v(TAG, "Removing task snapshot window for " + taskId);
                    Slog.v(TAG, "Removing task snapshot window for " + taskId);
                }
                }
                record.mTaskSnapshotWindow.remove(mMainExecutor);
                record.mTaskSnapshotWindow.remove();
            }
            }
            mStartingWindowRecords.remove(taskId);
            mStartingWindowRecords.remove(taskId);
        }
        }
+27 −29
Original line number Original line Diff line number Diff line
@@ -82,6 +82,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.policy.DecorView;
import com.android.internal.policy.DecorView;
import com.android.internal.view.BaseIWindow;
import com.android.internal.view.BaseIWindow;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.annotations.ExternalThread;


/**
/**
 * This class represents a starting window that shows a snapshot.
 * This class represents a starting window that shows a snapshot.
@@ -121,6 +122,7 @@ public class TaskSnapshotWindow {
    private final Window mWindow;
    private final Window mWindow;
    private final Surface mSurface;
    private final Surface mSurface;
    private final Runnable mClearWindowHandler;
    private final Runnable mClearWindowHandler;
    private final ShellExecutor mMainExecutor;
    private SurfaceControl mSurfaceControl;
    private SurfaceControl mSurfaceControl;
    private SurfaceControl mChildSurfaceControl;
    private SurfaceControl mChildSurfaceControl;
    private final IWindowSession mSession;
    private final IWindowSession mSession;
@@ -213,7 +215,7 @@ public class TaskSnapshotWindow {
        final TaskSnapshotWindow snapshotSurface = new TaskSnapshotWindow(
        final TaskSnapshotWindow snapshotSurface = new TaskSnapshotWindow(
                surfaceControl, snapshot, layoutParams.getTitle(), taskDescription, appearance,
                surfaceControl, snapshot, layoutParams.getTitle(), taskDescription, appearance,
                windowFlags, windowPrivateFlags, taskBounds, orientation, activityType,
                windowFlags, windowPrivateFlags, taskBounds, orientation, activityType,
                topWindowInsetsState, clearWindowHandler);
                topWindowInsetsState, clearWindowHandler, mainExecutor);
        final Window window = snapshotSurface.mWindow;
        final Window window = snapshotSurface.mWindow;


        final InsetsState mTmpInsetsState = new InsetsState();
        final InsetsState mTmpInsetsState = new InsetsState();
@@ -229,7 +231,7 @@ public class TaskSnapshotWindow {
            } catch (RemoteException e) {
            } catch (RemoteException e) {
                snapshotSurface.clearWindowSynced();
                snapshotSurface.clearWindowSynced();
            }
            }
            window.setOuter(snapshotSurface, mainExecutor);
            window.setOuter(snapshotSurface);
            try {
            try {
                session.relayout(window, layoutParams, -1, -1, View.VISIBLE, 0, -1,
                session.relayout(window, layoutParams, -1, -1, View.VISIBLE, 0, -1,
                        tmpFrames, tmpMergedConfiguration, surfaceControl, mTmpInsetsState,
                        tmpFrames, tmpMergedConfiguration, surfaceControl, mTmpInsetsState,
@@ -249,7 +251,8 @@ public class TaskSnapshotWindow {
            TaskSnapshot snapshot, CharSequence title, TaskDescription taskDescription,
            TaskSnapshot snapshot, CharSequence title, TaskDescription taskDescription,
            int appearance, int windowFlags, int windowPrivateFlags, Rect taskBounds,
            int appearance, int windowFlags, int windowPrivateFlags, Rect taskBounds,
            int currentOrientation, int activityType, InsetsState topWindowInsetsState,
            int currentOrientation, int activityType, InsetsState topWindowInsetsState,
            Runnable clearWindowHandler) {
            Runnable clearWindowHandler, ShellExecutor mainExecutor) {
        mMainExecutor = mainExecutor;
        mSurface = new Surface();
        mSurface = new Surface();
        mSession = WindowManagerGlobal.getWindowSession();
        mSession = WindowManagerGlobal.getWindowSession();
        mWindow = new Window();
        mWindow = new Window();
@@ -286,19 +289,18 @@ public class TaskSnapshotWindow {
        mSystemBarBackgroundPainter.drawNavigationBarBackground(c);
        mSystemBarBackgroundPainter.drawNavigationBarBackground(c);
    }
    }


    void remove(ShellExecutor mainExecutor) {
    void remove() {
        final long now = SystemClock.uptimeMillis();
        final long now = SystemClock.uptimeMillis();
        if (mSizeMismatch && now - mShownTime < SIZE_MISMATCH_MINIMUM_TIME_MS
        if (mSizeMismatch && now - mShownTime < SIZE_MISMATCH_MINIMUM_TIME_MS
                // Show the latest content as soon as possible for unlocking to home.
                // Show the latest content as soon as possible for unlocking to home.
                && mActivityType != ACTIVITY_TYPE_HOME) {
                && mActivityType != ACTIVITY_TYPE_HOME) {
            final long delayTime = mShownTime + SIZE_MISMATCH_MINIMUM_TIME_MS - now;
            final long delayTime = mShownTime + SIZE_MISMATCH_MINIMUM_TIME_MS - now;
            mainExecutor.executeDelayed(() -> remove(mainExecutor), delayTime);
            mMainExecutor.executeDelayed(() -> remove(), delayTime);
            if (DEBUG) {
            if (DEBUG) {
                Slog.d(TAG, "Defer removing snapshot surface in " + delayTime);
                Slog.d(TAG, "Defer removing snapshot surface in " + delayTime);
            }
            }
            return;
            return;
        }
        }
        mainExecutor.execute(() -> {
        try {
        try {
            if (DEBUG) {
            if (DEBUG) {
                Slog.d(TAG, "Removing snapshot surface, mHasDrawn: " + mHasDrawn);
                Slog.d(TAG, "Removing snapshot surface, mHasDrawn: " + mHasDrawn);
@@ -307,7 +309,6 @@ public class TaskSnapshotWindow {
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            // nothing
            // nothing
        }
        }
        });
    }
    }


    /**
    /**
@@ -497,13 +498,12 @@ public class TaskSnapshotWindow {
        }
        }
    }
    }


    @ExternalThread
    static class Window extends BaseIWindow {
    static class Window extends BaseIWindow {
        private TaskSnapshotWindow mOuter;
        private TaskSnapshotWindow mOuter;
        private ShellExecutor mMainExecutor;


        public void setOuter(TaskSnapshotWindow outer, ShellExecutor mainExecutor) {
        public void setOuter(TaskSnapshotWindow outer) {
            mOuter = outer;
            mOuter = outer;
            mMainExecutor = mainExecutor;
        }
        }


        @Override
        @Override
@@ -511,22 +511,20 @@ public class TaskSnapshotWindow {
                MergedConfiguration mergedConfiguration, boolean forceLayout,
                MergedConfiguration mergedConfiguration, boolean forceLayout,
                boolean alwaysConsumeSystemBars, int displayId) {
                boolean alwaysConsumeSystemBars, int displayId) {
            if (mOuter != null) {
            if (mOuter != null) {
                mOuter.mMainExecutor.execute(() -> {
                    if (mergedConfiguration != null
                    if (mergedConfiguration != null
                            && mOuter.mOrientationOnCreation
                            && mOuter.mOrientationOnCreation
                            != mergedConfiguration.getMergedConfiguration().orientation) {
                            != mergedConfiguration.getMergedConfiguration().orientation) {
                    // The orientation of the screen is changing. We better remove the snapshot ASAP
                        // The orientation of the screen is changing. We better remove the snapshot
                    // as we are going to wait on the new window in any case to unfreeze the screen,
                        // ASAP as we are going to wait on the new window in any case to unfreeze
                    // and the starting window is not needed anymore.
                        // the screen, and the starting window is not needed anymore.
                    mMainExecutor.execute(() -> {
                        mOuter.clearWindowSynced();
                        mOuter.clearWindowSynced();
                    });
                    } else if (reportDraw) {
                    } else if (reportDraw) {
                    mMainExecutor.execute(() -> {
                        if (mOuter.mHasDrawn) {
                        if (mOuter.mHasDrawn) {
                            mOuter.reportDrawn();
                            mOuter.reportDrawn();
                        }
                        }
                    });
                    }
                    }
                });
            }
            }
        }
        }
    }
    }
+40 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2021 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.wm.shell.transition;

import android.annotation.NonNull;
import android.window.IRemoteTransition;
import android.window.TransitionFilter;

import com.android.wm.shell.common.annotations.ExternalThread;

/**
 * Interface to manage remote transitions.
 */
@ExternalThread
public interface RemoteTransitions {
    /**
     * Registers a remote transition.
     */
    void registerRemote(@NonNull TransitionFilter filter,
            @NonNull IRemoteTransition remoteTransition);

    /**
     * Unregisters a remote transition.
     */
    void unregisterRemote(@NonNull IRemoteTransition remoteTransition);
}
+39 −6
Original line number Original line Diff line number Diff line
@@ -67,6 +67,7 @@ public class Transitions {
    private final ShellExecutor mAnimExecutor;
    private final ShellExecutor mAnimExecutor;
    private final TransitionPlayerImpl mPlayerImpl;
    private final TransitionPlayerImpl mPlayerImpl;
    private final RemoteTransitionHandler mRemoteTransitionHandler;
    private final RemoteTransitionHandler mRemoteTransitionHandler;
    private final RemoteTransitionImpl mImpl = new RemoteTransitionImpl();


    /** List of possible handlers. Ordered by specificity (eg. tapped back to front). */
    /** List of possible handlers. Ordered by specificity (eg. tapped back to front). */
    private final ArrayList<TransitionHandler> mHandlers = new ArrayList<>();
    private final ArrayList<TransitionHandler> mHandlers = new ArrayList<>();
@@ -78,6 +79,10 @@ public class Transitions {
    /** Keeps track of currently tracked transitions and all the animations associated with each */
    /** Keeps track of currently tracked transitions and all the animations associated with each */
    private final ArrayMap<IBinder, ActiveTransition> mActiveTransitions = new ArrayMap<>();
    private final ArrayMap<IBinder, ActiveTransition> mActiveTransitions = new ArrayMap<>();


    public static RemoteTransitions asRemoteTransitions(Transitions transitions) {
        return transitions.mImpl;
    }

    public Transitions(@NonNull WindowOrganizer organizer, @NonNull TransactionPool pool,
    public Transitions(@NonNull WindowOrganizer organizer, @NonNull TransactionPool pool,
            @NonNull ShellExecutor mainExecutor, @NonNull ShellExecutor animExecutor) {
            @NonNull ShellExecutor mainExecutor, @NonNull ShellExecutor animExecutor) {
        mOrganizer = organizer;
        mOrganizer = organizer;
@@ -101,8 +106,20 @@ public class Transitions {


    /** Create an empty/non-registering transitions object for system-ui tests. */
    /** Create an empty/non-registering transitions object for system-ui tests. */
    @VisibleForTesting
    @VisibleForTesting
    public static Transitions createEmptyForTesting() {
    public static RemoteTransitions createEmptyForTesting() {
        return new Transitions();
        return new RemoteTransitions() {
            @Override
            public void registerRemote(@androidx.annotation.NonNull TransitionFilter filter,
                    @androidx.annotation.NonNull IRemoteTransition remoteTransition) {
                // Do nothing
            }

            @Override
            public void unregisterRemote(
                    @androidx.annotation.NonNull IRemoteTransition remoteTransition) {
                // Do nothing
            }
        };
    }
    }


    /** Register this transition handler with Core */
    /** Register this transition handler with Core */
@@ -134,16 +151,14 @@ public class Transitions {
    }
    }


    /** Register a remote transition to be used when `filter` matches an incoming transition */
    /** Register a remote transition to be used when `filter` matches an incoming transition */
    @ExternalThread
    public void registerRemote(@NonNull TransitionFilter filter,
    public void registerRemote(@NonNull TransitionFilter filter,
            @NonNull IRemoteTransition remoteTransition) {
            @NonNull IRemoteTransition remoteTransition) {
        mMainExecutor.execute(() -> mRemoteTransitionHandler.addFiltered(filter, remoteTransition));
        mRemoteTransitionHandler.addFiltered(filter, remoteTransition);
    }
    }


    /** Unregisters a remote transition and all associated filters */
    /** Unregisters a remote transition and all associated filters */
    @ExternalThread
    public void unregisterRemote(@NonNull IRemoteTransition remoteTransition) {
    public void unregisterRemote(@NonNull IRemoteTransition remoteTransition) {
        mMainExecutor.execute(() -> mRemoteTransitionHandler.removeFiltered(remoteTransition));
        mRemoteTransitionHandler.removeFiltered(remoteTransition);
    }
    }


    /** @return true if the transition was triggered by opening something vs closing something */
    /** @return true if the transition was triggered by opening something vs closing something */
@@ -361,4 +376,22 @@ public class Transitions {
            mMainExecutor.execute(() -> Transitions.this.requestStartTransition(iBinder, request));
            mMainExecutor.execute(() -> Transitions.this.requestStartTransition(iBinder, request));
        }
        }
    }
    }

    @ExternalThread
    private class RemoteTransitionImpl implements RemoteTransitions {
        @Override
        public void registerRemote(@NonNull TransitionFilter filter,
                @NonNull IRemoteTransition remoteTransition) {
            mMainExecutor.execute(() -> {
                Transitions.this.registerRemote(filter, remoteTransition);
            });
        }

        @Override
        public void unregisterRemote(@NonNull IRemoteTransition remoteTransition) {
            mMainExecutor.execute(() -> {
                Transitions.this.unregisterRemote(remoteTransition);
            });
        }
    }
}
}
+2 −1
Original line number Original line Diff line number Diff line
@@ -47,6 +47,7 @@ import android.window.TaskSnapshot;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import androidx.test.filters.SmallTest;


import com.android.wm.shell.TestShellExecutor;
import com.android.wm.shell.startingsurface.TaskSnapshotWindow;
import com.android.wm.shell.startingsurface.TaskSnapshotWindow;


import org.junit.Test;
import org.junit.Test;
@@ -83,7 +84,7 @@ public class TaskSnapshotWindowTest {
                createTaskDescription(Color.WHITE, Color.RED, Color.BLUE),
                createTaskDescription(Color.WHITE, Color.RED, Color.BLUE),
                0 /* appearance */, windowFlags /* windowFlags */, 0 /* privateWindowFlags */,
                0 /* appearance */, windowFlags /* windowFlags */, 0 /* privateWindowFlags */,
                taskBounds, ORIENTATION_PORTRAIT, ACTIVITY_TYPE_STANDARD, new InsetsState(),
                taskBounds, ORIENTATION_PORTRAIT, ACTIVITY_TYPE_STANDARD, new InsetsState(),
                null /* clearWindow */);
                null /* clearWindow */, new TestShellExecutor());
    }
    }


    private TaskSnapshot createTaskSnapshot(int width, int height, Point taskSize,
    private TaskSnapshot createTaskSnapshot(int width, int height, Point taskSize,
Loading