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

Commit 5c233013 authored by Ming-Shin Lu's avatar Ming-Shin Lu
Browse files

RESTRICT AUTOMERGE: More improve IME transition during task switch

This CL aims to optimize the previous CL[1] to schedule removing
tasksnapshot after a fixed timeout according the tasksnapshot:
    - With IME snapshot: 350ms
    - Without IME snapshot: 100ms

As the previous approach has some cons espically when the tasksnapshot
has IME shown:
1) It lacks a signal or callback to notify WmShell to dismiss
tasksnapshot when IME is actually drawn on the task and always
dismissed after the timeout.

2) The timing to schedule tasksnapsit removal is when
ActivityRecord#onWindowFirstDrawn, which is much eariler than the
window focused (about 100-150ms), and it may easier to see flickering
when the task is showing IME.

The reason is that IME is drawn after window focused and started input
connection. Also, starts from R, IME insets visiblity
is handled by the app's UI thread, so if the schedule removal timing
been triggered too early and if IME / App takes more time to handle IME
surface layout, then user might aware the app task flickering when
tasksnapshot dismissed, since IME is not yet be drawn and then it
show up again when the next layout finished.

In this CL, we made the following changes to improve the above cons
- Postpone the schedule removing tasksnapshot (with IME) timing to
  after the app task has focused.
- Modify the tasksnapshot removal timeout (with IME)  from 350ms to
  450ms (with renaming to MAX_DELAY_REMOVAL_TIME_IME_VISIBLE),
  in case some edge cases may take longer time to process IME layout.
- add ITaskOrganizer#onImeDrawnOnTask(taskId) to notify the shell
  task organizer to properly remove the tasksnapshot without waiting
  until the max timeout.

[1]: I7865e17b57961e12a0cdcf068e412195123a6ec7

Fix: 192065018
Test: ateset StartingSurfaceDrawerTests#\
        testRemoveTaskSnapshotWithImeSurfaceWhenOnImeDrawn
Test: manual tests by
   1) launching Android Message with focusing an editor
   2) swiping out to home and launch another apps (e.g. chrome)
   3) swiping up to overview, tapping Android Message task
   4) verify if IME is flickering after switched back.
Change-Id: I81031f64966b1aeb55cc09f381d4d83ec3460dc9
(cherry picked from commit 278e944f)
parent 2be6cfe7
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -88,4 +88,9 @@ oneway interface ITaskOrganizer {
     * user has pressed back on the root activity of a task controlled by the task organizer.
     */
    void onBackPressedOnTaskRoot(in ActivityManager.RunningTaskInfo taskInfo);

    /**
     * Called when the IME has drawn on the organized task.
     */
    void onImeDrawnOnTask(int taskId);
}
+9 −0
Original line number Diff line number Diff line
@@ -144,6 +144,10 @@ public class TaskOrganizer extends WindowOrganizer {
    @BinderThread
    public void onBackPressedOnTaskRoot(@NonNull ActivityManager.RunningTaskInfo taskInfo) {}

    /** @hide */
    @BinderThread
    public void onImeDrawnOnTask(int taskId) {}

    /**
     * Creates a persistent root task in WM for a particular windowing-mode.
     * @param displayId The display to create the root task on.
@@ -287,6 +291,11 @@ public class TaskOrganizer extends WindowOrganizer {
        public void onBackPressedOnTaskRoot(ActivityManager.RunningTaskInfo info) {
            mExecutor.execute(() -> TaskOrganizer.this.onBackPressedOnTaskRoot(info));
        }

        @Override
        public void onImeDrawnOnTask(int taskId) {
            mExecutor.execute(() -> TaskOrganizer.this.onImeDrawnOnTask(taskId));
        }
    };

    private ITaskOrganizerController getController() {
+7 −0
Original line number Diff line number Diff line
@@ -335,6 +335,13 @@ public class ShellTaskOrganizer extends TaskOrganizer implements
        }
    }

    @Override
    public void onImeDrawnOnTask(int taskId) {
        if (mStartingWindow != null) {
            mStartingWindow.onImeDrawnOnTask(taskId);
        }
    }

    @Override
    public void onTaskAppeared(RunningTaskInfo taskInfo, SurfaceControl leash) {
        synchronized (mLock) {
+12 −2
Original line number Diff line number Diff line
@@ -545,6 +545,15 @@ public class StartingSurfaceDrawer {
        removeWindowSynced(taskId, null, null, false);
    }

    void onImeDrawnOnTask(int taskId) {
        final StartingWindowRecord record = mStartingWindowRecords.get(taskId);
        if (record != null && record.mTaskSnapshotWindow != null
                && record.mTaskSnapshotWindow.hasImeSurface()) {
            record.mTaskSnapshotWindow.removeImmediately();
        }
        mStartingWindowRecords.remove(taskId);
    }

    protected void removeWindowSynced(int taskId, SurfaceControl leash, Rect frame,
            boolean playRevealAnimation) {
        final StartingWindowRecord record = mStartingWindowRecords.get(taskId);
@@ -572,14 +581,15 @@ public class StartingSurfaceDrawer {
                    Slog.e(TAG, "Found empty splash screen, remove!");
                    removeWindowInner(record.mDecorView, false);
                }
                mStartingWindowRecords.remove(taskId);
            }
            if (record.mTaskSnapshotWindow != null) {
                if (DEBUG_TASK_SNAPSHOT) {
                    Slog.v(TAG, "Removing task snapshot window for " + taskId);
                }
                record.mTaskSnapshotWindow.remove();
                record.mTaskSnapshotWindow.scheduleRemove(
                        () -> mStartingWindowRecords.remove(taskId));
            }
            mStartingWindowRecords.remove(taskId);
        }
    }

+7 −0
Original line number Diff line number Diff line
@@ -176,6 +176,13 @@ public class StartingWindowController implements RemoteCallable<StartingWindowCo
                () -> mStartingSurfaceDrawer.onAppSplashScreenViewRemoved(taskId));
    }

    /**
     * Called when the IME has drawn on the organized task.
     */
    public void onImeDrawnOnTask(int taskId) {
        mSplashScreenExecutor.execute(() -> mStartingSurfaceDrawer.onImeDrawnOnTask(taskId));
    }

    /**
     * Called when the content of a task is ready to show, starting window can be removed.
     */
Loading