ForegroundServiceDidNotStartInTimeException now has...
an inner exception that captures the stacktrace where
Context.startForegroundService() was called last time,
from the same process.
Bug: 124137635
Test: Manual test with a tesapp. 1: when startForegroundService() is called by
the same process:
```
11-17 17:00:12.483 10241 9545 9545 E AndroidRuntime: FATAL EXCEPTION: main
11-17 17:00:12.483 10241 9545 9545 E AndroidRuntime: Process: com.google.omakoto.testapp, PID: 9545
11-17 17:00:12.483 10241 9545 9545 E AndroidRuntime: android.app.RemoteServiceException$ForegroundServiceDidNotStartInTimeException: Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{e7674af u0 com.google.omakoto.testapp/.MyFgs3}
11-17 17:00:12.483 10241 9545 9545 E AndroidRuntime: at android.app.ActivityThread.generateForegroundServiceDidNotStartInTimeException(ActivityThread.java:1965)
11-17 17:00:12.483 10241 9545 9545 E AndroidRuntime: at android.app.ActivityThread.throwRemoteServiceException(ActivityThread.java:1934)
11-17 17:00:12.483 10241 9545 9545 E AndroidRuntime: at android.app.ActivityThread.access$2700(ActivityThread.java:255)
11-17 17:00:12.483 10241 9545 9545 E AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2190)
11-17 17:00:12.483 10241 9545 9545 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:106)
11-17 17:00:12.483 10241 9545 9545 E AndroidRuntime: at android.os.Looper.loopOnce(Looper.java:201)
11-17 17:00:12.483 10241 9545 9545 E AndroidRuntime: at android.os.Looper.loop(Looper.java:288)
11-17 17:00:12.483 10241 9545 9545 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:7839)
11-17 17:00:12.483 10241 9545 9545 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
11-17 17:00:12.483 10241 9545 9545 E AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
11-17 17:00:12.483 10241 9545 9545 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
11-17 17:00:12.483 10241 9545 9545 E AndroidRuntime: Caused by: android.app.StackTrace: Last startServiceCommon() call for this service was made here
11-17 17:00:12.483 10241 9545 9545 E AndroidRuntime: at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1868)
11-17 17:00:12.483 10241 9545 9545 E AndroidRuntime: at android.app.ContextImpl.startForegroundService(ContextImpl.java:1823)
11-17 17:00:12.483 10241 9545 9545 E AndroidRuntime: at android.content.ContextWrapper.startForegroundService(ContextWrapper.java:779)
11-17 17:00:12.483 10241 9545 9545 E AndroidRuntime: at android.content.ContextWrapper.startForegroundService(ContextWrapper.java:779)
11-17 17:00:12.483 10241 9545 9545 E AndroidRuntime: at com.google.omakoto.testapp.MyReceiver.onReceive(MyReceiver.java:53)
11-17 17:00:12.483 10241 9545 9545 E AndroidRuntime: at android.app.ActivityThread.handleReceiver(ActivityThread.java:4345)
11-17 17:00:12.483 10241 9545 9545 E AndroidRuntime: at android.app.ActivityThread.access$1600(ActivityThread.java:255)
11-17 17:00:12.483 10241 9545 9545 E AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2102)
11-17 17:00:12.483 10241 9545 9545 E AndroidRuntime: ... 7 more
```
Test: Manual test with a tesapp. 1: when startForegroundService() is called by
another process:
```
11-17 16:59:34.456 10241 9432 9432 E AndroidRuntime: FATAL EXCEPTION: main
11-17 16:59:34.456 10241 9432 9432 E AndroidRuntime: Process: com.google.omakoto.testapp:second, PID: 9432
11-17 16:59:34.456 10241 9432 9432 E AndroidRuntime: android.app.RemoteServiceException$ForegroundServiceDidNotStartInTimeException: Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{dcaa127 u0 com.google.omakoto.testapp/.MyFgs3}
11-17 16:59:34.456 10241 9432 9432 E AndroidRuntime: at android.app.ActivityThread.generateForegroundServiceDidNotStartInTimeException(ActivityThread.java:1965)
11-17 16:59:34.456 10241 9432 9432 E AndroidRuntime: at android.app.ActivityThread.throwRemoteServiceException(ActivityThread.java:1934)
11-17 16:59:34.456 10241 9432 9432 E AndroidRuntime: at android.app.ActivityThread.access$2700(ActivityThread.java:255)
11-17 16:59:34.456 10241 9432 9432 E AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2190)
11-17 16:59:34.456 10241 9432 9432 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:106)
11-17 16:59:34.456 10241 9432 9432 E AndroidRuntime: at android.os.Looper.loopOnce(Looper.java:201)
11-17 16:59:34.456 10241 9432 9432 E AndroidRuntime: at android.os.Looper.loop(Looper.java:288)
11-17 16:59:34.456 10241 9432 9432 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:7839)
11-17 16:59:34.456 10241 9432 9432 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
11-17 16:59:34.456 10241 9432 9432 E AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
11-17 16:59:34.456 10241 9432 9432 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
```
Change-Id: I2dd8ec76213d53728eaa8fcc3760813d82a328a5
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 17bb797..5edced1 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -1293,8 +1293,11 @@
}
@Override
- public void scheduleCrash(String msg, int typeId) {
- sendMessage(H.SCHEDULE_CRASH, msg, typeId);
+ public void scheduleCrash(String msg, int typeId, @Nullable Bundle extras) {
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = msg;
+ args.arg2 = extras;
+ sendMessage(H.SCHEDULE_CRASH, args, typeId);
}
public void dumpActivity(ParcelFileDescriptor pfd, IBinder activitytoken,
@@ -1924,11 +1927,11 @@
}
}
- private void throwRemoteServiceException(String message, int typeId) {
+ private void throwRemoteServiceException(String message, int typeId, @Nullable Bundle extras) {
// Use a switch to ensure all the type IDs are unique.
switch (typeId) {
case ForegroundServiceDidNotStartInTimeException.TYPE_ID:
- throw new ForegroundServiceDidNotStartInTimeException(message);
+ throw generateForegroundServiceDidNotStartInTimeException(message, extras);
case CannotDeliverBroadcastException.TYPE_ID:
throw new CannotDeliverBroadcastException(message);
@@ -1951,6 +1954,15 @@
}
}
+ private ForegroundServiceDidNotStartInTimeException
+ generateForegroundServiceDidNotStartInTimeException(String message, Bundle extras) {
+ final String serviceClassName =
+ ForegroundServiceDidNotStartInTimeException.getServiceClassNameFromExtras(extras);
+ final Exception inner = (serviceClassName == null) ? null
+ : Service.getStartForegroundServiceStackTrace(serviceClassName);
+ throw new ForegroundServiceDidNotStartInTimeException(message, inner);
+ }
+
class H extends Handler {
public static final int BIND_APPLICATION = 110;
@UnsupportedAppUsage
@@ -2168,9 +2180,14 @@
handleDispatchPackageBroadcast(msg.arg1, (String[])msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
- case SCHEDULE_CRASH:
- throwRemoteServiceException((String) msg.obj, msg.arg1);
+ case SCHEDULE_CRASH: {
+ SomeArgs args = (SomeArgs) msg.obj;
+ String message = (String) args.arg1;
+ Bundle extras = (Bundle) args.arg2;
+ args.recycle();
+ throwRemoteServiceException(message, msg.arg1, extras);
break;
+ }
case DUMP_HEAP:
handleDumpHeap((DumpHeapData) msg.obj);
break;
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index b5ed171..22df35d 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1862,6 +1862,14 @@
"Not allowed to start service " + service + ": " + cn.getClassName());
}
}
+ // If we started a foreground service in the same package, remember the stack trace.
+ if (cn != null && requireForeground) {
+ if (cn.getPackageName().equals(getOpPackageName())) {
+ Service.setStartForegroundServiceStackTrace(cn.getClassName(),
+ new StackTrace("Last startServiceCommon() call for this service was "
+ + "made here"));
+ }
+ }
return cn;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 9e9e28b..dcc9085 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -321,6 +321,8 @@
boolean isTopActivityImmersive();
void crashApplicationWithType(int uid, int initialPid, in String packageName, int userId,
in String message, boolean force, int exceptionTypeId);
+ void crashApplicationWithTypeWithExtras(int uid, int initialPid, in String packageName,
+ int userId, in String message, boolean force, int exceptionTypeId, in Bundle extras);
/** @deprecated -- use getProviderMimeTypeAsync */
@UnsupportedAppUsage(maxTargetSdk = 29, publicAlternatives =
"Use {@link android.content.ContentResolver#getType} public API instead.")
diff --git a/core/java/android/app/IApplicationThread.aidl b/core/java/android/app/IApplicationThread.aidl
index d6ff6d3..448c3cf 100644
--- a/core/java/android/app/IApplicationThread.aidl
+++ b/core/java/android/app/IApplicationThread.aidl
@@ -107,7 +107,7 @@
void scheduleOnNewActivityOptions(IBinder token, in Bundle options);
void scheduleSuicide();
void dispatchPackageBroadcast(int cmd, in String[] packages);
- void scheduleCrash(in String msg, int typeId);
+ void scheduleCrash(in String msg, int typeId, in Bundle extras);
void dumpHeap(boolean managed, boolean mallocInfo, boolean runGc, in String path,
in ParcelFileDescriptor fd, in RemoteCallback finishCallback);
void dumpActivity(in ParcelFileDescriptor fd, IBinder servicetoken, in String prefix,
diff --git a/core/java/android/app/RemoteServiceException.java b/core/java/android/app/RemoteServiceException.java
index 1038530..e220627 100644
--- a/core/java/android/app/RemoteServiceException.java
+++ b/core/java/android/app/RemoteServiceException.java
@@ -16,6 +16,10 @@
package android.app;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.os.Bundle;
import android.util.AndroidRuntimeException;
/**
@@ -33,6 +37,10 @@
super(msg);
}
+ public RemoteServiceException(String msg, Throwable cause) {
+ super(msg, cause);
+ }
+
/**
* Exception used to crash an app process when it didn't call {@link Service#startForeground}
* in time after the service was started with
@@ -44,8 +52,21 @@
/** The type ID passed to {@link IApplicationThread#scheduleCrash}. */
public static final int TYPE_ID = 1;
- public ForegroundServiceDidNotStartInTimeException(String msg) {
- super(msg);
+ private static final String KEY_SERVICE_CLASS_NAME = "serviceclassname";
+
+ public ForegroundServiceDidNotStartInTimeException(String msg, Throwable cause) {
+ super(msg, cause);
+ }
+
+ public static Bundle createExtrasForService(@NonNull ComponentName service) {
+ Bundle b = new Bundle();
+ b.putString(KEY_SERVICE_CLASS_NAME, service.getClassName());
+ return b;
+ }
+
+ @Nullable
+ public static String getServiceClassNameFromExtras(@Nullable Bundle extras) {
+ return (extras == null) ? null : extras.getString(KEY_SERVICE_CLASS_NAME);
}
}
diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java
index 3363872..5a5ccb5 100644
--- a/core/java/android/app/Service.java
+++ b/core/java/android/app/Service.java
@@ -33,9 +33,12 @@
import android.os.Build;
import android.os.IBinder;
import android.os.RemoteException;
+import android.util.ArrayMap;
import android.util.Log;
import android.view.contentcapture.ContentCaptureManager;
+import com.android.internal.annotations.GuardedBy;
+
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
@@ -733,6 +736,7 @@
mActivityManager.setServiceForeground(
new ComponentName(this, mClassName), mToken, id,
notification, 0, FOREGROUND_SERVICE_TYPE_MANIFEST);
+ clearStartForegroundServiceStackTrace();
} catch (RemoteException ex) {
}
}
@@ -786,6 +790,7 @@
mActivityManager.setServiceForeground(
new ComponentName(this, mClassName), mToken, id,
notification, 0, foregroundServiceType);
+ clearStartForegroundServiceStackTrace();
} catch (RemoteException ex) {
}
}
@@ -941,4 +946,34 @@
private IActivityManager mActivityManager = null;
@UnsupportedAppUsage
private boolean mStartCompatibility = false;
+
+ /**
+ * This keeps track of the stacktrace where Context.startForegroundService() was called
+ * for each service class. We use that when we crash the app for not calling
+ * {@link #startForeground} in time, in {@link ActivityThread#throwRemoteServiceException}.
+ */
+ @GuardedBy("sStartForegroundServiceStackTraces")
+ private static final ArrayMap<String, StackTrace> sStartForegroundServiceStackTraces =
+ new ArrayMap<>();
+
+ /** @hide */
+ public static void setStartForegroundServiceStackTrace(
+ @NonNull String className, @NonNull StackTrace stacktrace) {
+ synchronized (sStartForegroundServiceStackTraces) {
+ sStartForegroundServiceStackTraces.put(className, stacktrace);
+ }
+ }
+
+ private void clearStartForegroundServiceStackTrace() {
+ synchronized (sStartForegroundServiceStackTraces) {
+ sStartForegroundServiceStackTraces.remove(this.getClassName());
+ }
+ }
+
+ /** @hide */
+ public static StackTrace getStartForegroundServiceStackTrace(@NonNull String className) {
+ synchronized (sStartForegroundServiceStackTraces) {
+ return sStartForegroundServiceStackTraces.get(className);
+ }
+ }
}
diff --git a/core/java/android/app/StackTrace.java b/core/java/android/app/StackTrace.java
new file mode 100644
index 0000000..ec058f8
--- /dev/null
+++ b/core/java/android/app/StackTrace.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+/**
+ * An Exception subclass that's used only for logging stacktraces.
+ * @hide
+ */
+public class StackTrace extends Exception {
+ public StackTrace(String message) {
+ super(message);
+ }
+}
diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
index df0c64c..9f48c06 100644
--- a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
@@ -532,7 +532,7 @@
}
@Override
- public void scheduleCrash(String s, int i) throws RemoteException {
+ public void scheduleCrash(String s, int i, Bundle extras) throws RemoteException {
}
@Override
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index df2ae98..9a371f3 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -157,6 +157,7 @@
import com.android.internal.app.procstats.ServiceState;
import com.android.internal.messages.nano.SystemMessageProto;
import com.android.internal.notification.SystemNotificationChannels;
+import com.android.internal.os.SomeArgs;
import com.android.internal.os.TransferPipe;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastPrintWriter;
@@ -4209,9 +4210,12 @@
if (r.app != null) {
Message msg = mAm.mHandler.obtainMessage(
ActivityManagerService.SERVICE_FOREGROUND_CRASH_MSG);
- msg.obj = r.app;
- msg.getData().putCharSequence(
- ActivityManagerService.SERVICE_RECORD_KEY, r.toString());
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = r.app;
+ args.arg2 = r.toString();
+ args.arg3 = r.getComponentName();
+
+ msg.obj = args;
mAm.mHandler.sendMessage(msg);
}
}
@@ -5272,11 +5276,14 @@
}
}
- void serviceForegroundCrash(ProcessRecord app, CharSequence serviceRecord) {
- mAm.crashApplicationWithType(app.uid, app.getPid(), app.info.packageName, app.userId,
+ void serviceForegroundCrash(ProcessRecord app, String serviceRecord,
+ ComponentName service) {
+ mAm.crashApplicationWithTypeWithExtras(
+ app.uid, app.getPid(), app.info.packageName, app.userId,
"Context.startForegroundService() did not then call Service.startForeground(): "
+ serviceRecord, false /*force*/,
- ForegroundServiceDidNotStartInTimeException.TYPE_ID);
+ ForegroundServiceDidNotStartInTimeException.TYPE_ID,
+ ForegroundServiceDidNotStartInTimeException.createExtrasForService(service));
}
void scheduleServiceTimeoutLocked(ProcessRecord proc) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 5cd66aa..3998af5 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -338,6 +338,7 @@
import com.android.internal.os.ByteTransferPipe;
import com.android.internal.os.IResultReceiver;
import com.android.internal.os.ProcessCpuTracker;
+import com.android.internal.os.SomeArgs;
import com.android.internal.os.TransferPipe;
import com.android.internal.os.Zygote;
import com.android.internal.policy.AttributeCache;
@@ -1472,8 +1473,6 @@
static final int FIRST_BROADCAST_QUEUE_MSG = 200;
- static final String SERVICE_RECORD_KEY = "servicerecord";
-
/**
* Flag whether the current user is a "monkey", i.e. whether
* the UI is driven by a UI automation tool.
@@ -1652,8 +1651,12 @@
mServices.serviceForegroundTimeout((ServiceRecord) msg.obj);
} break;
case SERVICE_FOREGROUND_CRASH_MSG: {
- mServices.serviceForegroundCrash((ProcessRecord) msg.obj,
- msg.getData().getCharSequence(SERVICE_RECORD_KEY));
+ SomeArgs args = (SomeArgs) msg.obj;
+ mServices.serviceForegroundCrash(
+ (ProcessRecord) args.arg1,
+ (String) args.arg2,
+ (ComponentName) args.arg3);
+ args.recycle();
} break;
case UPDATE_TIME_ZONE: {
synchronized (mProcLock) {
@@ -3001,6 +3004,14 @@
@Override
public void crashApplicationWithType(int uid, int initialPid, String packageName, int userId,
String message, boolean force, int exceptionTypeId) {
+ crashApplicationWithTypeWithExtras(uid, initialPid, packageName, userId, message,
+ force, exceptionTypeId, null);
+ }
+
+ @Override
+ public void crashApplicationWithTypeWithExtras(int uid, int initialPid, String packageName,
+ int userId, String message, boolean force, int exceptionTypeId,
+ @Nullable Bundle extras) {
if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
!= PackageManager.PERMISSION_GRANTED) {
String msg = "Permission Denial: crashApplication() from pid="
@@ -3013,7 +3024,7 @@
synchronized(this) {
mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId,
- message, force, exceptionTypeId);
+ message, force, exceptionTypeId, extras);
}
}
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index bcb42bb..0bf0fe2 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -27,6 +27,7 @@
import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_FREE_RESIZE;
import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE;
+import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.AnrController;
@@ -40,6 +41,7 @@
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
+import android.os.Bundle;
import android.os.Message;
import android.os.Process;
import android.os.SystemClock;
@@ -489,7 +491,7 @@
* @param message
*/
void scheduleAppCrashLocked(int uid, int initialPid, String packageName, int userId,
- String message, boolean force, int exceptionTypeId) {
+ String message, boolean force, int exceptionTypeId, @Nullable Bundle extras) {
ProcessRecord proc = null;
// Figure out which process to kill. We don't trust that initialPid
@@ -521,7 +523,7 @@
return;
}
- proc.scheduleCrashLocked(message, exceptionTypeId);
+ proc.scheduleCrashLocked(message, exceptionTypeId, extras);
if (force) {
// If the app is responsive, the scheduled crash will happen as expected
// and then the delayed summary kill will be a no-op.
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 487101b..2da4107 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -611,7 +611,7 @@
Slog.w(TAG, "Can't deliver broadcast to " + app.processName
+ " (pid " + app.getPid() + "). Crashing it.");
app.scheduleCrashLocked("can't deliver broadcast",
- CannotDeliverBroadcastException.TYPE_ID);
+ CannotDeliverBroadcastException.TYPE_ID, /* extras=*/ null);
}
throw ex;
}
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 14ba716..b9d7917 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -31,6 +31,7 @@
import android.content.pm.VersionedPackage;
import android.content.res.CompatibilityInfo;
import android.os.Binder;
+import android.os.Bundle;
import android.os.IBinder;
import android.os.Process;
import android.os.RemoteException;
@@ -958,7 +959,7 @@
* of its subclasses.
*/
@GuardedBy("mService")
- void scheduleCrashLocked(String message, int exceptionTypeId) {
+ void scheduleCrashLocked(String message, int exceptionTypeId, @Nullable Bundle extras) {
// Checking killedbyAm should keep it from showing the crash dialog if the process
// was already dead for a good / normal reason.
if (!mKilledByAm) {
@@ -969,7 +970,7 @@
}
final long ident = Binder.clearCallingIdentity();
try {
- mThread.scheduleCrash(message, exceptionTypeId);
+ mThread.scheduleCrash(message, exceptionTypeId, extras);
} catch (RemoteException e) {
// If it's already dead our work is done. If it's wedged just kill it.
// We won't get the crash dialog or the error reporting.