Merge "Add more logging to Activity Lifecycler."
This commit is contained in:
@@ -166,6 +166,7 @@ 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.List;
|
||||
@@ -220,6 +221,9 @@ public final class ActivityThread extends ClientTransactionHandler {
|
||||
// Whether to invoke an activity callback after delivering new configuration.
|
||||
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;
|
||||
|
||||
/**
|
||||
* Denotes an invalid sequence number corresponding to a process state change.
|
||||
*/
|
||||
@@ -252,6 +256,8 @@ 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<>();
|
||||
|
||||
// List of new activities (via ActivityRecord.nextIdle) that should
|
||||
// be reported when next we idle.
|
||||
ActivityClientRecord mNewActivities = null;
|
||||
@@ -2168,6 +2174,18 @@ public final class ActivityThread extends ClientTransactionHandler {
|
||||
pw.println(String.format(format, objs));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(PrintWriter pw, String prefix) {
|
||||
pw.println(prefix + "mActivities:");
|
||||
|
||||
for (ArrayMap.Entry<IBinder, ActivityClientRecord> entry : mActivities.entrySet()) {
|
||||
pw.println(prefix + " [token:" + entry.getKey().hashCode() + " record:"
|
||||
+ entry.getValue().toString() + "]");
|
||||
}
|
||||
|
||||
pw.println(prefix + "mRecentTokens:" + mRecentTokens);
|
||||
}
|
||||
|
||||
public static void dumpMemInfoTable(PrintWriter pw, Debug.MemoryInfo memInfo, boolean checkin,
|
||||
boolean dumpFullInfo, boolean dumpDalvik, boolean dumpSummaryOnly,
|
||||
int pid, String processName,
|
||||
@@ -2852,6 +2870,11 @@ 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;
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.os.IBinder;
|
||||
|
||||
import com.android.internal.content.ReferrerIntent;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -121,4 +122,11 @@ public abstract class ClientTransactionHandler {
|
||||
* provided token.
|
||||
*/
|
||||
public abstract ActivityThread.ActivityClientRecord getActivityClient(IBinder token);
|
||||
|
||||
/**
|
||||
* Debugging output.
|
||||
* @param pw {@link PrintWriter} to write logs to.
|
||||
* @param prefix Prefix to prepend to output.
|
||||
*/
|
||||
public abstract void dump(PrintWriter pw, String prefix);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,9 @@
|
||||
package android.app.servertransaction;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.os.Parcel;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@@ -26,6 +28,7 @@ import java.lang.annotation.RetentionPolicy;
|
||||
* @hide
|
||||
*/
|
||||
public abstract class ActivityLifecycleItem extends ClientTransactionItem {
|
||||
private String mDescription;
|
||||
|
||||
@IntDef(prefix = { "UNDEFINED", "PRE_", "ON_" }, value = {
|
||||
UNDEFINED,
|
||||
@@ -53,4 +56,39 @@ public abstract class ActivityLifecycleItem extends ClientTransactionItem {
|
||||
/** A final lifecycle state that an activity should reach. */
|
||||
@LifecycleState
|
||||
public abstract int getTargetState();
|
||||
|
||||
|
||||
protected ActivityLifecycleItem() {
|
||||
}
|
||||
|
||||
protected ActivityLifecycleItem(Parcel in) {
|
||||
mDescription = in.readString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(mDescription);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a description that can be retrieved later for debugging purposes.
|
||||
* @param description Description to set.
|
||||
* @return The {@link ActivityLifecycleItem}.
|
||||
*/
|
||||
public ActivityLifecycleItem setDescription(String description) {
|
||||
mDescription = description;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves description if set through {@link #setDescription(String)}.
|
||||
*/
|
||||
public String getDescription() {
|
||||
return mDescription;
|
||||
}
|
||||
|
||||
void dump(PrintWriter pw, String prefix) {
|
||||
pw.println(prefix + "target state:" + getTargetState());
|
||||
pw.println(prefix + "description: " + mDescription);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import android.os.RemoteException;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
@@ -237,4 +238,12 @@ public class ClientTransaction implements Parcelable, ObjectPoolItem {
|
||||
result = 31 * result + Objects.hashCode(mLifecycleStateRequest);
|
||||
return result;
|
||||
}
|
||||
|
||||
void dump(PrintWriter pw, String prefix) {
|
||||
pw.println(prefix + "mActivityToken:" + mActivityToken.hashCode());
|
||||
pw.println(prefix + "mLifecycleStateRequest:");
|
||||
if (mLifecycleStateRequest != null) {
|
||||
mLifecycleStateRequest.dump(pw, prefix + " ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,12 +76,14 @@ public class DestroyActivityItem extends ActivityLifecycleItem {
|
||||
/** Write to Parcel. */
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
super.writeToParcel(dest, flags);
|
||||
dest.writeBoolean(mFinished);
|
||||
dest.writeInt(mConfigChanges);
|
||||
}
|
||||
|
||||
/** Read from Parcel. */
|
||||
private DestroyActivityItem(Parcel in) {
|
||||
super(in);
|
||||
mFinished = in.readBoolean();
|
||||
mConfigChanges = in.readInt();
|
||||
}
|
||||
|
||||
@@ -114,6 +114,7 @@ public class PauseActivityItem extends ActivityLifecycleItem {
|
||||
/** Write to Parcel. */
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
super.writeToParcel(dest, flags);
|
||||
dest.writeBoolean(mFinished);
|
||||
dest.writeBoolean(mUserLeaving);
|
||||
dest.writeInt(mConfigChanges);
|
||||
@@ -122,6 +123,7 @@ public class PauseActivityItem extends ActivityLifecycleItem {
|
||||
|
||||
/** Read from Parcel. */
|
||||
private PauseActivityItem(Parcel in) {
|
||||
super(in);
|
||||
mFinished = in.readBoolean();
|
||||
mUserLeaving = in.readBoolean();
|
||||
mConfigChanges = in.readInt();
|
||||
|
||||
@@ -113,6 +113,7 @@ public class ResumeActivityItem extends ActivityLifecycleItem {
|
||||
/** Write to Parcel. */
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
super.writeToParcel(dest, flags);
|
||||
dest.writeInt(mProcState);
|
||||
dest.writeBoolean(mUpdateProcState);
|
||||
dest.writeBoolean(mIsForward);
|
||||
@@ -120,6 +121,7 @@ public class ResumeActivityItem extends ActivityLifecycleItem {
|
||||
|
||||
/** Read from Parcel. */
|
||||
private ResumeActivityItem(Parcel in) {
|
||||
super(in);
|
||||
mProcState = in.readInt();
|
||||
mUpdateProcState = in.readBoolean();
|
||||
mIsForward = in.readBoolean();
|
||||
|
||||
@@ -83,12 +83,14 @@ public class StopActivityItem extends ActivityLifecycleItem {
|
||||
/** Write to Parcel. */
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
super.writeToParcel(dest, flags);
|
||||
dest.writeBoolean(mShowWindow);
|
||||
dest.writeInt(mConfigChanges);
|
||||
}
|
||||
|
||||
/** Read from Parcel. */
|
||||
private StopActivityItem(Parcel in) {
|
||||
super(in);
|
||||
mShowWindow = in.readBoolean();
|
||||
mConfigChanges = in.readInt();
|
||||
}
|
||||
|
||||
@@ -33,6 +33,8 @@ import android.util.Slog;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -122,6 +124,21 @@ public class TransactionExecutor {
|
||||
final IBinder token = transaction.getActivityToken();
|
||||
final ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
|
||||
|
||||
// TODO(b/71506345): Remove once root cause is found.
|
||||
if (r == null) {
|
||||
final StringWriter stringWriter = new StringWriter();
|
||||
final PrintWriter pw = new PrintWriter(stringWriter);
|
||||
final String prefix = " ";
|
||||
|
||||
pw.println("Lifecycle transaction does not have valid ActivityClientRecord.");
|
||||
pw.println("Transaction:");
|
||||
transaction.dump(pw, prefix);
|
||||
pw.println("Executor:");
|
||||
dump(pw, prefix);
|
||||
|
||||
Slog.wtf(TAG, stringWriter.toString());
|
||||
}
|
||||
|
||||
// Cycle to the state right before the final requested state.
|
||||
cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */);
|
||||
|
||||
@@ -245,4 +262,9 @@ public class TransactionExecutor {
|
||||
private static void log(String message) {
|
||||
if (DEBUG_RESOLVER) Slog.d(TAG, message);
|
||||
}
|
||||
|
||||
private void dump(PrintWriter pw, String prefix) {
|
||||
pw.println(prefix + "mTransactionHandler:");
|
||||
mTransactionHandler.dump(pw, prefix + " ");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user