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

Commit db46d6b0 authored by riddle_hsu's avatar riddle_hsu
Browse files

[ActivityManager] Reduce report wrong anr activity

Symptom:
Report ANR on wrong activity.

Reproduce steps:
 (All launchMode, taskAffinity are default and
  without additional intent flag)
 Case 1:
  1.Launch activity A from launcher.
  2.Activity A starts B activity.
  3.Press home key.
  4.Launch activity A from launcher (B is top).
  5.Press back key twice to finish B and A,
    A sleep 10s in onResume.
  6.ANR will report on launcher.

 Case 2:
  1.Launch activity A from launcher.
  2.Press home key.
  3.Kill process of A.
  4.Launch activity A from launcher.
  5.A sleep 10s in onResume, press back key immediately.
  6.ANR will report on launcher.

Possible root cause:
Focused activity will not be updated every time when activity
resumed. (the condition to call setFocusedActivityLocked)

Case 1:
Launcher was stopped and not waitingVisible due to launcher
is not the previous one, then getWaitingHistoryRecordLocked
has no chance to correct the real ANR activity.

Case 2:
Due to process of next activity is died, bring existed
task will not set mResumedActivity (it will be set when its
process is started), so when assigning waitingVisible from
processStoppingActivitiesLocked, the return value of
allResumedActivitiesVisible will be true even there is no
mResumedActivity. That results set waitingVisible to false
to previous activity (e.g. launcher), then also cannot
correct ANR target as case 1.

Change-Id: I0b24f46a8fab266382ebc6e2ed84ebeca9358768
parent 562c6a71
Loading
Loading
Loading
Loading
+9 −12
Original line number Diff line number Diff line
@@ -982,24 +982,21 @@ final class ActivityRecord {
    }

    private ActivityRecord getWaitingHistoryRecordLocked() {
        // First find the real culprit...  if we are waiting
        // for another app to start, then we have paused dispatching
        // for this activity.
        ActivityRecord r = this;
        if (r.waitingVisible) {
        // First find the real culprit...  if this activity is waiting for
        // another activity to start or has stopped, then the key dispatching
        // timeout should not be caused by this.
        if (waitingVisible || stopped) {
            final ActivityStack stack = mStackSupervisor.getFocusedStack();
            // Hmmm, who might we be waiting for?
            r = stack.mResumedActivity;
            // Try to use the one which is closest to top.
            ActivityRecord r = stack.mResumedActivity;
            if (r == null) {
                r = stack.mPausingActivity;
            }
            // Both of those null?  Fall back to 'this' again
            if (r == null) {
                r = this;
            if (r != null) {
                return r;
            }
        }

        return r;
        return this;
    }

    public boolean keyDispatchingTimedOut(String reason) {
+7 −3
Original line number Diff line number Diff line
@@ -607,17 +607,21 @@ public final class ActivityStackSupervisor implements DisplayListener {
    }

    boolean allResumedActivitiesVisible() {
        boolean foundResumed = false;
        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                final ActivityStack stack = stacks.get(stackNdx);
                final ActivityRecord r = stack.mResumedActivity;
                if (r != null && (!r.nowVisible || r.waitingVisible)) {
                if (r != null) {
                    if (!r.nowVisible || r.waitingVisible) {
                        return false;
                    }
                    foundResumed = true;
                }
            }
        return true;
        }
        return foundResumed;
    }

    /**