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

Commit 9916e7bb authored by wilsonshih's avatar wilsonshih Committed by Android Build Coastguard Worker
Browse files

Defer remove splash screen while device is locked

...and activity does not request showWhenLocked.
The splash screen won't contains secure information, so it's safe to
declared as showWhenLocked. But before remove starting window, if the
activity does not request showWhenLocked and device is locked, try to
trigger unoccluding animation, and keep app window hide until transition
animation finish.

Bug: 378088391
Bug: 383131643
Test: run simulate app repeatly, verify the app content won't be visible
during transition animation.
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:ec6d53979d48b8e948777014ab047162e8bddd6e)
Merged-In: Ia2ddece125521eefb15d67e22ea863dfae6af112
Change-Id: Ia2ddece125521eefb15d67e22ea863dfae6af112
parent f1b1bce4
Loading
Loading
Loading
Loading
+25 −0
Original line number Original line Diff line number Diff line
@@ -244,7 +244,9 @@ import static com.android.server.wm.IdentifierProto.USER_ID;
import static com.android.server.wm.LetterboxConfiguration.DEFAULT_LETTERBOX_ASPECT_RATIO_FOR_MULTI_WINDOW;
import static com.android.server.wm.LetterboxConfiguration.DEFAULT_LETTERBOX_ASPECT_RATIO_FOR_MULTI_WINDOW;
import static com.android.server.wm.LetterboxConfiguration.MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO;
import static com.android.server.wm.LetterboxConfiguration.MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO;
import static com.android.server.wm.StartingData.AFTER_TRANSACTION_COPY_TO_CLIENT;
import static com.android.server.wm.StartingData.AFTER_TRANSACTION_COPY_TO_CLIENT;
import static com.android.server.wm.StartingData.AFTER_TRANSACTION_IDLE;
import static com.android.server.wm.StartingData.AFTER_TRANSACTION_REMOVE_DIRECTLY;
import static com.android.server.wm.StartingData.AFTER_TRANSACTION_REMOVE_DIRECTLY;
import static com.android.server.wm.StartingData.AFTER_TRANSITION_FINISH;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_PREDICT_BACK;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_PREDICT_BACK;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS;
@@ -2940,9 +2942,28 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        attachStartingSurfaceToAssociatedTask();
        attachStartingSurfaceToAssociatedTask();
    }
    }
    /**
     * If the device is locked and the app does not request showWhenLocked,
     * defer removing the starting window until the transition is complete.
     * This prevents briefly appearing the app context and causing secure concern.
     */
    void deferStartingWindowRemovalForKeyguardUnoccluding() {
        if (mStartingData != null
                && mStartingData.mRemoveAfterTransaction != AFTER_TRANSITION_FINISH
                && isKeyguardLocked() && !canShowWhenLockedInner(this) && !isVisibleRequested()
                && mTransitionController.inTransition(this)) {
            mStartingData.mRemoveAfterTransaction = AFTER_TRANSITION_FINISH;
        }
    }
    void removeStartingWindow() {
    void removeStartingWindow() {
        boolean prevEligibleForLetterboxEducation = isEligibleForLetterboxEducation();
        boolean prevEligibleForLetterboxEducation = isEligibleForLetterboxEducation();
        if (mStartingData != null
                && mStartingData.mRemoveAfterTransaction == AFTER_TRANSITION_FINISH) {
            return;
        }
        if (transferSplashScreenIfNeeded()) {
        if (transferSplashScreenIfNeeded()) {
            return;
            return;
        }
        }
@@ -4700,6 +4721,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
                tStartingWindow.mToken = this;
                tStartingWindow.mToken = this;
                tStartingWindow.mActivityRecord = this;
                tStartingWindow.mActivityRecord = this;
                if (mStartingData.mRemoveAfterTransaction == AFTER_TRANSITION_FINISH) {
                    mStartingData.mRemoveAfterTransaction = AFTER_TRANSACTION_IDLE;
                }
                ProtoLog.v(WM_DEBUG_ADD_REMOVE,
                ProtoLog.v(WM_DEBUG_ADD_REMOVE,
                        "Removing starting %s from %s", tStartingWindow, fromActivity);
                        "Removing starting %s from %s", tStartingWindow, fromActivity);
                mTransitionController.collect(tStartingWindow);
                mTransitionController.collect(tStartingWindow);
+7 −0
Original line number Original line Diff line number Diff line
@@ -31,11 +31,18 @@ public abstract class StartingData {
    static final int AFTER_TRANSACTION_REMOVE_DIRECTLY = 1;
    static final int AFTER_TRANSACTION_REMOVE_DIRECTLY = 1;
    /** Do copy splash screen to client after transaction done. */
    /** Do copy splash screen to client after transaction done. */
    static final int AFTER_TRANSACTION_COPY_TO_CLIENT = 2;
    static final int AFTER_TRANSACTION_COPY_TO_CLIENT = 2;
    /**
     * Remove the starting window after transition finish.
     * Used when activity doesn't request show when locked, so the app window should never show to
     * the user if device is locked.
     **/
    static final int AFTER_TRANSITION_FINISH = 3;


    @IntDef(prefix = { "AFTER_TRANSACTION" }, value = {
    @IntDef(prefix = { "AFTER_TRANSACTION" }, value = {
            AFTER_TRANSACTION_IDLE,
            AFTER_TRANSACTION_IDLE,
            AFTER_TRANSACTION_REMOVE_DIRECTLY,
            AFTER_TRANSACTION_REMOVE_DIRECTLY,
            AFTER_TRANSACTION_COPY_TO_CLIENT,
            AFTER_TRANSACTION_COPY_TO_CLIENT,
            AFTER_TRANSITION_FINISH,
    })
    })
    @interface AfterTransaction {}
    @interface AfterTransaction {}


+9 −0
Original line number Original line Diff line number Diff line
@@ -71,6 +71,8 @@ import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_W
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_PREDICT_BACK;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_PREDICT_BACK;
import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
import static com.android.server.wm.WindowState.BLAST_TIMEOUT_DURATION;
import static com.android.server.wm.WindowState.BLAST_TIMEOUT_DURATION;
import static com.android.server.wm.StartingData.AFTER_TRANSACTION_IDLE;
import static com.android.server.wm.StartingData.AFTER_TRANSITION_FINISH;


import android.annotation.IntDef;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.NonNull;
@@ -1290,6 +1292,13 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
                        enterAutoPip = true;
                        enterAutoPip = true;
                    }
                    }
                }
                }

                if (ar.mStartingData != null && ar.mStartingData.mRemoveAfterTransaction
                        == AFTER_TRANSITION_FINISH
                        && (!ar.isVisible() || !ar.mTransitionController.inTransition(ar))) {
                    ar.mStartingData.mRemoveAfterTransaction = AFTER_TRANSACTION_IDLE;
                    ar.removeStartingWindow();
                }
                final ChangeInfo changeInfo = mChanges.get(ar);
                final ChangeInfo changeInfo = mChanges.get(ar);
                // Due to transient-hide, there may be some activities here which weren't in the
                // Due to transient-hide, there may be some activities here which weren't in the
                // transition.
                // transition.
+15 −0
Original line number Original line Diff line number Diff line
@@ -122,6 +122,7 @@ import static com.android.server.wm.IdentifierProto.USER_ID;
import static com.android.server.wm.MoveAnimationSpecProto.DURATION_MS;
import static com.android.server.wm.MoveAnimationSpecProto.DURATION_MS;
import static com.android.server.wm.MoveAnimationSpecProto.FROM;
import static com.android.server.wm.MoveAnimationSpecProto.FROM;
import static com.android.server.wm.MoveAnimationSpecProto.TO;
import static com.android.server.wm.MoveAnimationSpecProto.TO;
import static com.android.server.wm.StartingData.AFTER_TRANSITION_FINISH;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_ALL;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_ALL;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS;
@@ -1909,6 +1910,13 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
        }
        }
        final ActivityRecord atoken = mActivityRecord;
        final ActivityRecord atoken = mActivityRecord;
        if (atoken != null) {
        if (atoken != null) {
            if (atoken.mStartingData != null && mAttrs.type != TYPE_APPLICATION_STARTING
                    && atoken.mStartingData.mRemoveAfterTransaction
                    == AFTER_TRANSITION_FINISH) {
                // Preventing app window from visible during un-occluding animation playing due to
                // alpha blending.
                return false;
            }
            final boolean isVisible = isStartingWindowAssociatedToTask()
            final boolean isVisible = isStartingWindowAssociatedToTask()
                    ? mStartingData.mAssociatedTask.isVisible() : atoken.isVisible();
                    ? mStartingData.mAssociatedTask.isVisible() : atoken.isVisible();
            return ((!isParentWindowHidden() && isVisible)
            return ((!isParentWindowHidden() && isVisible)
@@ -2892,7 +2900,14 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
            final int mask = FLAG_SHOW_WHEN_LOCKED | FLAG_DISMISS_KEYGUARD
            final int mask = FLAG_SHOW_WHEN_LOCKED | FLAG_DISMISS_KEYGUARD
                    | FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
                    | FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
            WindowManager.LayoutParams sa = mActivityRecord.mStartingWindow.mAttrs;
            WindowManager.LayoutParams sa = mActivityRecord.mStartingWindow.mAttrs;
            final boolean wasShowWhenLocked = (sa.flags & FLAG_SHOW_WHEN_LOCKED) != 0;
            final boolean removeShowWhenLocked = (mAttrs.flags & FLAG_SHOW_WHEN_LOCKED) == 0;
            sa.flags = (sa.flags & ~mask) | (mAttrs.flags & mask);
            sa.flags = (sa.flags & ~mask) | (mAttrs.flags & mask);
            if (wasShowWhenLocked && removeShowWhenLocked) {
                // Trigger unoccluding animation if needed.
                mActivityRecord.checkKeyguardFlagsChanged();
                mActivityRecord.deferStartingWindowRemovalForKeyguardUnoccluding();
            }
        }
        }
    }
    }