summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Louis Chang <louischang@google.com> 2023-03-27 07:11:43 +0000
committer Louis Chang <louischang@google.com> 2023-03-30 09:28:35 +0000
commitb576a7b4bdddf21822386a7cb49d7adffedae718 (patch)
tree0e84cd83a559a2f95d1f6868d52f09fb44a98b96
parentdc8992c4b0f67cde919a79fdaef32f70b4bb1c0f (diff)
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
-rw-r--r--core/java/android/app/ActivityThread.java41
1 files changed, 15 insertions, 26 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 682fec8105d5..dfaf73a4d41a 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -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));
- 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);
+ final ActivityClient ac = ActivityClient.getInstance();
+ 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;
+ }
}
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) {