summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Bryce Lee <brycelee@google.com> 2018-02-08 14:37:06 -0800
committer Bryce Lee <brycelee@google.com> 2018-02-09 07:56:49 -0800
commita33c13df134ee3618c72e70a69433a27b934702f (patch)
tree44e50340e6a3c986b901005c0feb4be042953f99
parentbc48bd8f6137955b99f51562ab4959783f827e22 (diff)
Improve temporary logging around activity destruction.
This changelist improves logging for capture details around b/71506345. These modifications are intended to be reverted once the root cause has been found. Bug: 71506345 Test: manual Change-Id: I1dd5eba710e81bf78632359d4ee4c047fefa5da6
-rw-r--r--core/java/android/app/ActivityThread.java69
-rw-r--r--core/java/android/app/ClientTransactionHandler.java2
-rw-r--r--core/java/android/app/LocalActivityManager.java4
-rw-r--r--core/java/android/app/servertransaction/DestroyActivityItem.java2
-rw-r--r--core/java/android/app/servertransaction/TransactionExecutor.java4
-rw-r--r--services/core/java/com/android/server/am/ActivityRecord.java3
-rw-r--r--services/core/java/com/android/server/am/ActivityStack.java3
7 files changed, 63 insertions, 24 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 3d088ff9e5c3..394edf107737 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -166,9 +166,9 @@ import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.text.DateFormat;
-import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -222,7 +222,7 @@ public final class ActivityThread extends ClientTransactionHandler {
private static final boolean REPORT_TO_ACTIVITY = true;
// Maximum number of recent tokens to maintain for debugging purposes
- private static final int MAX_RECENT_TOKENS = 10;
+ private static final int MAX_DESTROYED_ACTIVITIES = 10;
/**
* Denotes an invalid sequence number corresponding to a process state change.
@@ -256,7 +256,7 @@ public final class ActivityThread extends ClientTransactionHandler {
final H mH = new H();
final Executor mExecutor = new HandlerExecutor(mH);
final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>();
- final ArrayDeque<Integer> mRecentTokens = new ArrayDeque<>();
+ final ArrayList<DestroyedActivityInfo> mRecentDestroyedActivities = new ArrayList<>();
// List of new activities (via ActivityRecord.nextIdle) that should
// be reported when next we idle.
@@ -339,6 +339,26 @@ public final class ActivityThread extends ClientTransactionHandler {
}
}
+ /**
+ * TODO(b/71506345): Remove this once bug is resolved.
+ */
+ private static final class DestroyedActivityInfo {
+ private final Integer mToken;
+ private final String mReason;
+ private final long mTime;
+
+ DestroyedActivityInfo(Integer token, String reason) {
+ mToken = token;
+ mReason = reason;
+ mTime = System.currentTimeMillis();
+ }
+
+ void dump(PrintWriter pw, String prefix) {
+ pw.println(prefix + "[token:" + mToken + " | time:" + mTime + " | reason:" + mReason
+ + "]");
+ }
+ }
+
// The lock of mProviderMap protects the following variables.
final ArrayMap<ProviderKey, ProviderClientRecord> mProviderMap
= new ArrayMap<ProviderKey, ProviderClientRecord>();
@@ -2182,14 +2202,28 @@ public final class ActivityThread extends ClientTransactionHandler {
@Override
public void dump(PrintWriter pw, String prefix) {
- pw.println(prefix + "mActivities:");
+ pw.println(prefix + "Activities:");
- for (ArrayMap.Entry<IBinder, ActivityClientRecord> entry : mActivities.entrySet()) {
- pw.println(prefix + " [token:" + entry.getKey().hashCode() + " record:"
- + entry.getValue().toString() + "]");
+ if (!mActivities.isEmpty()) {
+ final Iterator<Map.Entry<IBinder, ActivityClientRecord>> activitiesIterator =
+ mActivities.entrySet().iterator();
+
+ while (activitiesIterator.hasNext()) {
+ final ArrayMap.Entry<IBinder, ActivityClientRecord> entry =
+ activitiesIterator.next();
+ pw.println(prefix + " [token:" + entry.getKey().hashCode() + " record:"
+ + entry.getValue().toString() + "]");
+ }
}
- pw.println(prefix + "mRecentTokens:" + mRecentTokens);
+ if (!mRecentDestroyedActivities.isEmpty()) {
+ pw.println(prefix + "Recent destroyed activities:");
+ for (int i = 0, size = mRecentDestroyedActivities.size(); i < size; i++) {
+ final DestroyedActivityInfo info = mRecentDestroyedActivities.get(i);
+ pw.print(prefix);
+ info.dump(pw, " ");
+ }
+ }
}
public static void dumpMemInfoTable(PrintWriter pw, Debug.MemoryInfo memInfo, boolean checkin,
@@ -2876,11 +2910,6 @@ public final class ActivityThread extends ClientTransactionHandler {
r.setState(ON_CREATE);
mActivities.put(r.token, r);
- mRecentTokens.push(r.token.hashCode());
-
- if (mRecentTokens.size() > MAX_RECENT_TOKENS) {
- mRecentTokens.removeLast();
- }
} catch (SuperNotCalledException e) {
throw e;
@@ -4453,7 +4482,7 @@ public final class ActivityThread extends ClientTransactionHandler {
/** Core implementation of activity destroy call. */
ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
- int configChanges, boolean getNonConfigInstance) {
+ int configChanges, boolean getNonConfigInstance, String reason) {
ActivityClientRecord r = mActivities.get(token);
Class<? extends Activity> activityClass = null;
if (localLOGV) Slog.v(TAG, "Performing finish of " + r);
@@ -4505,6 +4534,12 @@ public final class ActivityThread extends ClientTransactionHandler {
r.setState(ON_DESTROY);
}
mActivities.remove(token);
+ mRecentDestroyedActivities.add(0, new DestroyedActivityInfo(token.hashCode(), reason));
+
+ final int recentDestroyedActivitiesSize = mRecentDestroyedActivities.size();
+ if (recentDestroyedActivitiesSize > MAX_DESTROYED_ACTIVITIES) {
+ mRecentDestroyedActivities.remove(recentDestroyedActivitiesSize - 1);
+ }
StrictMode.decrementExpectedActivityCount(activityClass);
return r;
}
@@ -4516,9 +4551,9 @@ public final class ActivityThread extends ClientTransactionHandler {
@Override
public void handleDestroyActivity(IBinder token, boolean finishing, int configChanges,
- boolean getNonConfigInstance) {
+ boolean getNonConfigInstance, String reason) {
ActivityClientRecord r = performDestroyActivity(token, finishing,
- configChanges, getNonConfigInstance);
+ configChanges, getNonConfigInstance, reason);
if (r != null) {
cleanUpPendingRemoveWindows(r, finishing);
WindowManager wm = r.activity.getWindowManager();
@@ -4780,7 +4815,7 @@ public final class ActivityThread extends ClientTransactionHandler {
callActivityOnStop(r, true /* saveState */, "handleRelaunchActivity");
}
- handleDestroyActivity(r.token, false, configChanges, true);
+ handleDestroyActivity(r.token, false, configChanges, true, "handleRelaunchActivity");
r.activity = null;
r.window = null;
diff --git a/core/java/android/app/ClientTransactionHandler.java b/core/java/android/app/ClientTransactionHandler.java
index 5b61fdf8677f..d061a9824f65 100644
--- a/core/java/android/app/ClientTransactionHandler.java
+++ b/core/java/android/app/ClientTransactionHandler.java
@@ -60,7 +60,7 @@ public abstract class ClientTransactionHandler {
/** Destroy the activity. */
public abstract void handleDestroyActivity(IBinder token, boolean finishing, int configChanges,
- boolean getNonConfigInstance);
+ boolean getNonConfigInstance, String reason);
/** Pause the activity. */
public abstract void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving,
diff --git a/core/java/android/app/LocalActivityManager.java b/core/java/android/app/LocalActivityManager.java
index 1d3459534f0c..e297719f9e4c 100644
--- a/core/java/android/app/LocalActivityManager.java
+++ b/core/java/android/app/LocalActivityManager.java
@@ -380,7 +380,7 @@ public class LocalActivityManager {
}
if (localLOGV) Log.v(TAG, r.id + ": destroying");
mActivityThread.performDestroyActivity(r, finish, 0 /* configChanges */,
- false /* getNonConfigInstance */);
+ false /* getNonConfigInstance */, "LocalActivityManager::performDestroy");
r.activity = null;
r.window = null;
if (finish) {
@@ -645,7 +645,7 @@ public class LocalActivityManager {
LocalActivityRecord r = mActivityArray.get(i);
if (localLOGV) Log.v(TAG, r.id + ": destroying");
mActivityThread.performDestroyActivity(r, finishing, 0 /* configChanges */,
- false /* getNonConfigInstance */);
+ false /* getNonConfigInstance */, "LocalActivityManager::dispatchDestroy");
}
mActivities.clear();
mActivityArray.clear();
diff --git a/core/java/android/app/servertransaction/DestroyActivityItem.java b/core/java/android/app/servertransaction/DestroyActivityItem.java
index cbcf6c750fed..48a79f79dae1 100644
--- a/core/java/android/app/servertransaction/DestroyActivityItem.java
+++ b/core/java/android/app/servertransaction/DestroyActivityItem.java
@@ -37,7 +37,7 @@ public class DestroyActivityItem extends ActivityLifecycleItem {
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityDestroy");
client.handleDestroyActivity(token, mFinished, mConfigChanges,
- false /* getNonConfigInstance */);
+ false /* getNonConfigInstance */, getDescription());
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
diff --git a/core/java/android/app/servertransaction/TransactionExecutor.java b/core/java/android/app/servertransaction/TransactionExecutor.java
index 78b393a831f9..840fef80a5ff 100644
--- a/core/java/android/app/servertransaction/TransactionExecutor.java
+++ b/core/java/android/app/servertransaction/TransactionExecutor.java
@@ -194,7 +194,9 @@ public class TransactionExecutor {
break;
case ON_DESTROY:
mTransactionHandler.handleDestroyActivity(r.token, false /* finishing */,
- 0 /* configChanges */, false /* getNonConfigInstance */);
+ 0 /* configChanges */, false /* getNonConfigInstance */,
+ "performLifecycleSequence. cycling to:"
+ + mLifecycleSequence.get(size - 1));
break;
case ON_RESTART:
mTransactionHandler.performRestartActivity(r.token, false /* start */);
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index cae0d2bc5dd9..2ad23ec856f8 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -375,7 +375,8 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
}
String getLifecycleDescription(String reason) {
- return "packageName=" + packageName + ", state=" + state + ", reason=" + reason;
+ return "component:" + intent.getComponent().flattenToShortString() + ", state=" + state
+ + ", reason=" + reason + ", time=" + System.currentTimeMillis();
}
void dump(PrintWriter pw, String prefix) {
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index ab2dc36d66d0..ae74958fdc21 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -4214,7 +4214,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
if (DEBUG_SWITCH) Slog.i(TAG_SWITCH, "Destroying: " + r);
mService.mLifecycleManager.scheduleTransaction(r.app.thread, r.appToken,
DestroyActivityItem.obtain(r.finishing, r.configChangeFlags)
- .setDescription(r.getLifecycleDescription("destroyActivityLocked")));
+ .setDescription(
+ r.getLifecycleDescription("destroyActivityLocked:" + reason)));
} catch (Exception e) {
// We can just ignore exceptions here... if the process
// has crashed, our death notification will clean things