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

Commit 1940f94f authored by Riddle Hsu's avatar Riddle Hsu Committed by Automerger Merge Worker
Browse files

Merge "Avoid killing task process after its activity was died" into main am: 637ec738

parents a92f9ad8 637ec738
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -4214,6 +4214,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
                Slog.v(TAG_APP, "Keeping entry during removeHistory for activity " + this);
                Slog.v(TAG_APP, "Keeping entry during removeHistory for activity " + this);
            }
            }
        }
        }
        if (task != null && task.mKillProcessesOnDestroyed) {
            mTaskSupervisor.removeTimeoutOfKillProcessesOnProcessDied(this, task);
        }
        // upgrade transition trigger to task if this is the last activity since it means we are
        // upgrade transition trigger to task if this is the last activity since it means we are
        // closing the task.
        // closing the task.
        final WindowContainer trigger = remove && task != null && task.getChildCount() == 1
        final WindowContainer trigger = remove && task != null && task.getChildCount() == 1
+20 −2
Original line number Original line Diff line number Diff line
@@ -1891,7 +1891,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
        // DestroyActivityItem may be called first.
        // DestroyActivityItem may be called first.
        final ActivityRecord top = task.getTopMostActivity();
        final ActivityRecord top = task.getTopMostActivity();
        if (top != null && top.finishing && !top.mAppStopped && top.lastVisibleTime > 0
        if (top != null && top.finishing && !top.mAppStopped && top.lastVisibleTime > 0
                && !task.mKillProcessesOnDestroyed) {
                && !task.mKillProcessesOnDestroyed && top.hasProcess()) {
            task.mKillProcessesOnDestroyed = true;
            task.mKillProcessesOnDestroyed = true;
            mHandler.sendMessageDelayed(
            mHandler.sendMessageDelayed(
                    mHandler.obtainMessage(KILL_TASK_PROCESSES_TIMEOUT_MSG, task),
                    mHandler.obtainMessage(KILL_TASK_PROCESSES_TIMEOUT_MSG, task),
@@ -1901,8 +1901,26 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
        killTaskProcessesIfPossible(task);
        killTaskProcessesIfPossible(task);
    }
    }


    void removeTimeoutOfKillProcessesOnProcessDied(@NonNull ActivityRecord r, @NonNull Task task) {
        if (r.packageName.equals(task.getBasePackageName())) {
            task.mKillProcessesOnDestroyed = false;
            mHandler.removeMessages(KILL_TASK_PROCESSES_TIMEOUT_MSG, task);
        }
    }

    void killTaskProcessesOnDestroyedIfNeeded(Task task) {
    void killTaskProcessesOnDestroyedIfNeeded(Task task) {
        if (task == null || !task.mKillProcessesOnDestroyed) return;
        if (task == null || !task.mKillProcessesOnDestroyed) return;
        final int[] numDestroyingActivities = new int[1];
        task.forAllActivities(r ->  {
            if (r.finishing && r.lastVisibleTime > 0 && r.attachedToProcess()) {
                numDestroyingActivities[0]++;
            }
        });
        if (numDestroyingActivities[0] > 1) {
            // Skip if there are still destroying activities. When the last activity reports
            // destroyed, the number will be 1 to proceed the kill.
            return;
        }
        mHandler.removeMessages(KILL_TASK_PROCESSES_TIMEOUT_MSG, task);
        mHandler.removeMessages(KILL_TASK_PROCESSES_TIMEOUT_MSG, task);
        killTaskProcessesIfPossible(task);
        killTaskProcessesIfPossible(task);
    }
    }
@@ -2763,7 +2781,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
                } break;
                } break;
                case KILL_TASK_PROCESSES_TIMEOUT_MSG: {
                case KILL_TASK_PROCESSES_TIMEOUT_MSG: {
                    final Task task = (Task) msg.obj;
                    final Task task = (Task) msg.obj;
                    if (task.mKillProcessesOnDestroyed) {
                    if (task.mKillProcessesOnDestroyed && task.hasActivity()) {
                        Slog.i(TAG, "Destroy timeout of remove-task, attempt to kill " + task);
                        Slog.i(TAG, "Destroy timeout of remove-task, attempt to kill " + task);
                        killTaskProcessesIfPossible(task);
                        killTaskProcessesIfPossible(task);
                    }
                    }
+13 −2
Original line number Original line Diff line number Diff line
@@ -1040,14 +1040,25 @@ public class RecentTasksTest extends WindowTestsBase {


        // If the task has a non-stopped activity, the removal will wait for its onDestroy.
        // If the task has a non-stopped activity, the removal will wait for its onDestroy.
        final Task task = tasks.get(0);
        final Task task = tasks.get(0);
        final ActivityRecord bottom = new ActivityBuilder(mAtm).setTask(task).build();
        final ActivityRecord top = new ActivityBuilder(mAtm).setTask(task).build();
        final ActivityRecord top = new ActivityBuilder(mAtm).setTask(task).build();
        top.lastVisibleTime = 123;
        bottom.lastVisibleTime = top.lastVisibleTime = 123;
        top.setState(ActivityRecord.State.RESUMED, "test");
        top.setState(ActivityRecord.State.RESUMED, "test");
        mRecentTasks.removeTasksByPackageName(task.getBasePackageName(), TEST_USER_0_ID);
        mRecentTasks.removeTasksByPackageName(task.getBasePackageName(), TEST_USER_0_ID);
        assertTrue(task.mKillProcessesOnDestroyed);
        assertTrue(task.mKillProcessesOnDestroyed);
        top.setState(ActivityRecord.State.DESTROYING, "test");
        top.setState(ActivityRecord.State.DESTROYING, "test");
        bottom.destroyed("test");
        assertTrue("Wait for all destroyed", task.mKillProcessesOnDestroyed);
        top.destroyed("test");
        top.destroyed("test");
        assertFalse(task.mKillProcessesOnDestroyed);
        assertFalse("Consume kill", task.mKillProcessesOnDestroyed);

        // If the process is died, the state should be cleared.
        final Task lastTask = tasks.get(0);
        lastTask.intent.setComponent(top.mActivityComponent);
        lastTask.addChild(top);
        lastTask.mKillProcessesOnDestroyed = true;
        top.handleAppDied();
        assertFalse(lastTask.mKillProcessesOnDestroyed);
    }
    }


    @Test
    @Test