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

Commit b576a7b4 authored by Louis Chang's avatar Louis Chang
Browse files

Remove the ActivityClientRecord reference once destroyed

The ActivityClientRecord was referenced in ActivityThread
#mNewActivities even after it was destroyed. That was possible
when the app main thread is busy without idle reported.

Use ArrayList to easier maintain the activities to report idle.

Bug: 161230418
Test: verified on sample app
Change-Id: I8a8c49da9d942bb6efdfd29dba5495eed896209c
parent dc8992c4
Loading
Loading
Loading
Loading
+15 −26
Original line number Diff line number Diff line
@@ -359,9 +359,8 @@ public final class ActivityThread extends ClientTransactionHandler
    /** The activities to be truly destroyed (not include relaunch). */
    final Map<IBinder, ClientTransactionItem> mActivitiesToBeDestroyed =
            Collections.synchronizedMap(new ArrayMap<IBinder, ClientTransactionItem>());
    // List of new activities (via ActivityRecord.nextIdle) that should
    // be reported when next we idle.
    ActivityClientRecord mNewActivities = null;
    // List of new activities that should be reported when next we idle.
    final ArrayList<ActivityClientRecord> mNewActivities = new ArrayList<>();
    // Number of activities that are currently visible on-screen.
    @UnsupportedAppUsage
    int mNumVisibleActivities = 0;
@@ -562,7 +561,6 @@ public final class ActivityThread extends ClientTransactionHandler
        private Configuration tmpConfig = new Configuration();
        // Callback used for updating activity override config and camera compat control state.
        ViewRootImpl.ActivityConfigCallback activityConfigCallback;
        ActivityClientRecord nextIdle;

        // Indicates whether this activity is currently the topmost resumed one in the system.
        // This holds the last reported value from server.
@@ -656,7 +654,6 @@ public final class ActivityThread extends ClientTransactionHandler
            paused = false;
            stopped = false;
            hideForNow = false;
            nextIdle = null;
            activityConfigCallback = new ViewRootImpl.ActivityConfigCallback() {
                @Override
                public void onConfigurationChanged(Configuration overrideConfig,
@@ -2482,29 +2479,22 @@ public final class ActivityThread extends ClientTransactionHandler
    private class Idler implements MessageQueue.IdleHandler {
        @Override
        public final boolean queueIdle() {
            ActivityClientRecord a = mNewActivities;
            boolean stopProfiling = false;
            if (mBoundApplication != null && mProfiler.profileFd != null
                    && mProfiler.autoStopProfiler) {
                stopProfiling = true;
            }
            if (a != null) {
                mNewActivities = null;
            final ActivityClient ac = ActivityClient.getInstance();
                ActivityClientRecord prev;
                do {
                    if (localLOGV) Slog.v(
                        TAG, "Reporting idle of " + a +
                        " finished=" +
                        (a.activity != null && a.activity.mFinished));
            while (mNewActivities.size() > 0) {
                final ActivityClientRecord a = mNewActivities.remove(0);
                if (localLOGV) {
                    Slog.v(TAG, "Reporting idle of " + a + " finished="
                            + (a.activity != null && a.activity.mFinished));
                }
                if (a.activity != null && !a.activity.mFinished) {
                    ac.activityIdle(a.token, a.createdConfig, stopProfiling);
                    a.createdConfig = null;
                }
                    prev = a;
                    a = a.nextIdle;
                    prev.nextIdle = null;
                } while (a != null);
            }
            if (stopProfiling) {
                mProfiler.stopProfiling();
@@ -5104,8 +5094,7 @@ public final class ActivityThread extends ClientTransactionHandler
            }
        }

        r.nextIdle = mNewActivities;
        mNewActivities = r;
        mNewActivities.add(r);
        if (localLOGV) Slog.v(TAG, "Scheduling idle handler for " + r);
        Looper.myQueue().addIdleHandler(new Idler());
    }
@@ -5706,6 +5695,7 @@ public final class ActivityThread extends ClientTransactionHandler
        }
        if (finishing) {
            ActivityClient.getInstance().activityDestroyed(r.token);
            mNewActivities.remove(r);
        }
        mSomeActivitiesChanged = true;
    }
@@ -5926,7 +5916,6 @@ public final class ActivityThread extends ClientTransactionHandler
        r.activity = null;
        r.window = null;
        r.hideForNow = false;
        r.nextIdle = null;
        // Merge any pending results and pending intents; don't just replace them
        if (pendingResults != null) {
            if (r.pendingResults == null) {