Merge "Fix missing broadcast ANR culprit information." into udc-dev

This commit is contained in:
Jeff Sharkey
2023-03-30 02:20:23 +00:00
committed by Android (Google) Code Review
6 changed files with 81 additions and 16 deletions

View File

@@ -11356,12 +11356,15 @@ public class Intent implements Parcelable, Cloneable {
@Override
public String toString() {
StringBuilder b = new StringBuilder(128);
toString(b);
return b.toString();
}
/** @hide */
public void toString(@NonNull StringBuilder b) {
b.append("Intent { ");
toShortString(b, true, true, true, false);
b.append(" }");
return b.toString();
}
/** @hide */

View File

@@ -18,6 +18,8 @@ package com.android.internal.os;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.Intent;
import android.os.SystemClock;
@@ -96,20 +98,43 @@ public class TimeoutRecord {
return new TimeoutRecord(kind, reason, endUptimeMillis, /* endTakenBeforeLocks */ false);
}
/** Record for a broadcast receiver timeout. */
@NonNull
public static TimeoutRecord forBroadcastReceiver(@NonNull Intent intent,
@Nullable String packageName, @Nullable String className) {
final Intent logIntent;
if (packageName != null) {
if (className != null) {
logIntent = new Intent(intent);
logIntent.setComponent(new ComponentName(packageName, className));
} else {
logIntent = new Intent(intent);
logIntent.setPackage(packageName);
}
} else {
logIntent = intent;
}
return forBroadcastReceiver(logIntent);
}
/** Record for a broadcast receiver timeout. */
@NonNull
public static TimeoutRecord forBroadcastReceiver(@NonNull Intent intent) {
String reason = "Broadcast of " + intent.toString();
return TimeoutRecord.endingNow(TimeoutKind.BROADCAST_RECEIVER, reason);
final StringBuilder reason = new StringBuilder("Broadcast of ");
intent.toString(reason);
return TimeoutRecord.endingNow(TimeoutKind.BROADCAST_RECEIVER, reason.toString());
}
/** Record for a broadcast receiver timeout. */
@NonNull
public static TimeoutRecord forBroadcastReceiver(@NonNull Intent intent,
long timeoutDurationMs) {
String reason = "Broadcast of " + intent.toString() + ", waited " + timeoutDurationMs
+ "ms";
return TimeoutRecord.endingNow(TimeoutKind.BROADCAST_RECEIVER, reason);
final StringBuilder reason = new StringBuilder("Broadcast of ");
intent.toString(reason);
reason.append(", waited ");
reason.append(timeoutDurationMs);
reason.append("ms");
return TimeoutRecord.endingNow(TimeoutKind.BROADCAST_RECEIVER, reason.toString());
}
/** Record for an input dispatch no focused window timeout */

View File

@@ -16,6 +16,7 @@
package com.android.server.am;
import android.annotation.Nullable;
import android.content.IntentFilter;
import android.util.PrintWriterPrinter;
import android.util.Printer;
@@ -55,6 +56,16 @@ final class BroadcastFilter extends IntentFilter {
exported = _exported;
}
public @Nullable String getReceiverClassName() {
if (receiverId != null) {
final int index = receiverId.lastIndexOf('@');
if (index > 0) {
return receiverId.substring(0, index);
}
}
return null;
}
@NeverCompile
public void dumpDebug(ProtoOutputStream proto, long fieldId) {
long token = proto.start(fieldId);

View File

@@ -32,6 +32,7 @@ import static com.android.server.am.BroadcastProcessQueue.insertIntoRunnableList
import static com.android.server.am.BroadcastProcessQueue.reasonToString;
import static com.android.server.am.BroadcastProcessQueue.removeFromRunnableList;
import static com.android.server.am.BroadcastRecord.deliveryStateToString;
import static com.android.server.am.BroadcastRecord.getReceiverClassName;
import static com.android.server.am.BroadcastRecord.getReceiverPackageName;
import static com.android.server.am.BroadcastRecord.getReceiverProcessName;
import static com.android.server.am.BroadcastRecord.getReceiverUid;
@@ -1040,7 +1041,10 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
if (deliveryState == BroadcastRecord.DELIVERY_TIMEOUT) {
r.anrCount++;
if (app != null && !app.isDebugging()) {
mService.appNotResponding(queue.app, TimeoutRecord.forBroadcastReceiver(r.intent));
final String packageName = getReceiverPackageName(receiver);
final String className = getReceiverClassName(receiver);
mService.appNotResponding(queue.app,
TimeoutRecord.forBroadcastReceiver(r.intent, packageName, className));
}
} else {
mLocalHandler.removeMessages(MSG_DELIVERY_TIMEOUT_SOFT, queue);

View File

@@ -832,6 +832,14 @@ final class BroadcastRecord extends Binder {
}
}
static @Nullable String getReceiverClassName(@NonNull Object receiver) {
if (receiver instanceof BroadcastFilter) {
return ((BroadcastFilter) receiver).getReceiverClassName();
} else /* if (receiver instanceof ResolveInfo) */ {
return ((ResolveInfo) receiver).activityInfo.name;
}
}
static int getReceiverPriority(@NonNull Object receiver) {
if (receiver instanceof BroadcastFilter) {
return ((BroadcastFilter) receiver).getPriority();

View File

@@ -16,15 +16,15 @@
package com.android.internal.os;
import android.content.ComponentName;
import android.content.Intent;
import android.platform.test.annotations.Presubmit;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import android.content.ComponentName;
import android.content.Intent;
import android.platform.test.annotations.Presubmit;
import androidx.test.filters.SmallTest;
import org.junit.Test;
@@ -40,7 +40,7 @@ public class TimeoutRecordTest {
@Test
public void forBroadcastReceiver_returnsCorrectTimeoutRecord() {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setComponent(ComponentName.createRelative("com.example.app", "ExampleClass"));
intent.setComponent(new ComponentName("com.example.app", "com.example.app.ExampleClass"));
TimeoutRecord record = TimeoutRecord.forBroadcastReceiver(intent);
@@ -48,14 +48,28 @@ public class TimeoutRecordTest {
assertEquals(record.mKind, TimeoutRecord.TimeoutKind.BROADCAST_RECEIVER);
assertEquals(record.mReason,
"Broadcast of Intent { act=android.intent.action.MAIN cmp=com.example"
+ ".app/ExampleClass }");
+ ".app/.ExampleClass }");
assertTrue(record.mEndTakenBeforeLocks);
}
@Test
public void forBroadcastReceiver_withPackageAndClass_returnsCorrectTimeoutRecord() {
Intent intent = new Intent(Intent.ACTION_MAIN);
TimeoutRecord record = TimeoutRecord.forBroadcastReceiver(intent,
"com.example.app", "com.example.app.ExampleClass");
assertNotNull(record);
assertEquals(record.mKind, TimeoutRecord.TimeoutKind.BROADCAST_RECEIVER);
assertEquals(record.mReason,
"Broadcast of Intent { act=android.intent.action.MAIN cmp=com.example"
+ ".app/.ExampleClass }");
assertTrue(record.mEndTakenBeforeLocks);
}
@Test
public void forBroadcastReceiver_withTimeoutDurationMs_returnsCorrectTimeoutRecord() {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setComponent(ComponentName.createRelative("com.example.app", "ExampleClass"));
intent.setComponent(new ComponentName("com.example.app", "com.example.app.ExampleClass"));
TimeoutRecord record = TimeoutRecord.forBroadcastReceiver(intent, 1000L);
@@ -63,7 +77,7 @@ public class TimeoutRecordTest {
assertEquals(record.mKind, TimeoutRecord.TimeoutKind.BROADCAST_RECEIVER);
assertEquals(record.mReason,
"Broadcast of Intent { act=android.intent.action.MAIN cmp=com.example"
+ ".app/ExampleClass }, waited 1000ms");
+ ".app/.ExampleClass }, waited 1000ms");
assertTrue(record.mEndTakenBeforeLocks);
}