summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Egnor <egnor@google.com>2009-12-09 16:22:32 -0800
committerDan Egnor <egnor@google.com>2009-12-11 13:27:04 -0800
commitb7f0367cec1c744aa66ef397b0244e25d507491c (patch)
tree7b70d87b9886ea1567647aac00fccb3198accc8c
parentaf1255dab8fa3eab1caf9bae799f80de14a74470 (diff)
downloadframeworks_base-b7f0367cec1c744aa66ef397b0244e25d507491c.zip
frameworks_base-b7f0367cec1c744aa66ef397b0244e25d507491c.tar.gz
frameworks_base-b7f0367cec1c744aa66ef397b0244e25d507491c.tar.bz2
Eliminate CrashData and friends.
(CrashData was a custom-marshalled crash-info class used for a server crash reporting system I am deprecating). Use ApplicationErrorReport.CrashInfo instead to report crash details (mostly the stack trace) from RuntimeInfo to ActivityManagerService, since we're likely to need the crash information in that form anyway. Remove the (long-disabled) flags and support for the "Debug" button in the crash dialog. Further gut the ICheckinService interface by removing the crash-reporting APIs (and everything that calls them), plus the synchronous checkin() method (which has been stubbed out for a while now). A new dropbox-based crash reporting system is in the works, but not part of this change.
-rw-r--r--core/java/android/app/ActivityManager.java21
-rw-r--r--core/java/android/app/ActivityManagerNative.java25
-rw-r--r--core/java/android/app/ApplicationErrorReport.java27
-rw-r--r--core/java/android/app/IActivityController.aidl5
-rw-r--r--core/java/android/app/IActivityManager.java8
-rw-r--r--core/java/android/os/ICheckinService.aidl15
-rw-r--r--core/java/android/provider/Checkin.java56
-rw-r--r--core/java/android/server/data/BuildData.java89
-rw-r--r--core/java/android/server/data/CrashData.java145
-rw-r--r--core/java/android/server/data/StackTraceElementData.java80
-rw-r--r--core/java/android/server/data/ThrowableData.java138
-rwxr-xr-xcore/java/android/server/data/package.html5
-rw-r--r--core/java/android/util/Log.java4
-rw-r--r--core/java/com/android/internal/os/RuntimeInit.java123
-rw-r--r--core/res/res/values/strings.xml2
-rw-r--r--preloaded-classes1
-rw-r--r--services/java/com/android/server/FallbackCheckinService.java12
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java170
-rw-r--r--services/java/com/android/server/am/AppErrorDialog.java15
-rw-r--r--services/java/com/android/server/am/AppNotRespondingDialog.java2
-rw-r--r--services/java/com/android/server/am/BaseErrorDialog.java4
-rw-r--r--tests/AndroidTests/src/com/android/unit_tests/BuildTest.java59
-rw-r--r--tests/SmokeTest/tests/src/com/android/smoketest/ProcessErrorsTest.java22
23 files changed, 134 insertions, 894 deletions
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index d709deb..676d6d5 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -621,9 +621,15 @@ public class ActivityManager {
public String longMsg;
/**
- * Raw data about the crash (typically a stack trace).
+ * The stack trace where the error originated. May be null.
+ * @pending
*/
- public byte[] crashData;
+ public String stackTrace;
+
+ /**
+ * to be deprecated: This value will always be null.
+ */
+ public byte[] crashData = null;
public ProcessErrorStateInfo() {
}
@@ -640,8 +646,7 @@ public class ActivityManager {
dest.writeString(tag);
dest.writeString(shortMsg);
dest.writeString(longMsg);
- dest.writeInt(crashData == null ? -1 : crashData.length);
- dest.writeByteArray(crashData);
+ dest.writeString(stackTrace);
}
public void readFromParcel(Parcel source) {
@@ -652,13 +657,7 @@ public class ActivityManager {
tag = source.readString();
shortMsg = source.readString();
longMsg = source.readString();
- int cdLen = source.readInt();
- if (cdLen == -1) {
- crashData = null;
- } else {
- crashData = new byte[cdLen];
- source.readByteArray(crashData);
- }
+ stackTrace = source.readString();
}
public static final Creator<ProcessErrorStateInfo> CREATOR =
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 3b8aee9..a0498aa 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -982,18 +982,13 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
case HANDLE_APPLICATION_ERROR_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
IBinder app = data.readStrongBinder();
- int fl = data.readInt();
String tag = data.readString();
- String shortMsg = data.readString();
- String longMsg = data.readString();
- byte[] crashData = data.createByteArray();
- int res = handleApplicationError(app, fl, tag, shortMsg, longMsg,
- crashData);
+ ApplicationErrorReport.CrashInfo ci = new ApplicationErrorReport.CrashInfo(data);
+ handleApplicationError(app, tag, ci);
reply.writeNoException();
- reply.writeInt(res);
return true;
}
-
+
case SIGNAL_PERSISTENT_PROCESSES_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
int sig = data.readInt();
@@ -2342,27 +2337,21 @@ class ActivityManagerProxy implements IActivityManager
/* this base class version is never called */
return true;
}
- public int handleApplicationError(IBinder app, int flags,
- String tag, String shortMsg, String longMsg,
- byte[] crashData) throws RemoteException
+ public void handleApplicationError(IBinder app, String tag,
+ ApplicationErrorReport.CrashInfo crashInfo) throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(app);
- data.writeInt(flags);
data.writeString(tag);
- data.writeString(shortMsg);
- data.writeString(longMsg);
- data.writeByteArray(crashData);
+ crashInfo.writeToParcel(data, 0);
mRemote.transact(HANDLE_APPLICATION_ERROR_TRANSACTION, data, reply, 0);
reply.readException();
- int res = reply.readInt();
reply.recycle();
data.recycle();
- return res;
}
-
+
public void signalPersistentProcesses(int sig) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
diff --git a/core/java/android/app/ApplicationErrorReport.java b/core/java/android/app/ApplicationErrorReport.java
index aeae5f9..e89b3ad0 100644
--- a/core/java/android/app/ApplicationErrorReport.java
+++ b/core/java/android/app/ApplicationErrorReport.java
@@ -19,6 +19,8 @@ package android.app;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Printer;
+import java.io.PrintWriter;
+import java.io.StringWriter;
/**
* Describes an application error.
@@ -187,6 +189,31 @@ public class ApplicationErrorReport implements Parcelable {
}
/**
+ * Create an instance of CrashInfo initialized from an exception.
+ */
+ public CrashInfo(Throwable tr) {
+ StringWriter sw = new StringWriter();
+ tr.printStackTrace(new PrintWriter(sw));
+ stackTrace = sw.toString();
+
+ // Populate fields with the "root cause" exception
+ while (tr.getCause() != null) {
+ tr = tr.getCause();
+ String msg = tr.getMessage();
+ if (msg != null && msg.length() > 0) {
+ exceptionMessage = msg;
+ }
+ }
+
+ exceptionClassName = tr.getClass().getName();
+ StackTraceElement trace = tr.getStackTrace()[0];
+ throwFileName = trace.getFileName();
+ throwClassName = trace.getClassName();
+ throwMethodName = trace.getMethodName();
+ throwLineNumber = trace.getLineNumber();
+ }
+
+ /**
* Create an instance of CrashInfo initialized from a Parcel.
*/
public CrashInfo(Parcel in) {
diff --git a/core/java/android/app/IActivityController.aidl b/core/java/android/app/IActivityController.aidl
index 8f6b252..804dd61 100644
--- a/core/java/android/app/IActivityController.aidl
+++ b/core/java/android/app/IActivityController.aidl
@@ -43,8 +43,9 @@ interface IActivityController
* normal error recovery (app crash dialog) to occur, false to kill
* it immediately.
*/
- boolean appCrashed(String processName, int pid, String shortMsg,
- String longMsg, in byte[] crashData);
+ boolean appCrashed(String processName, int pid,
+ String tag, String shortMsg, String longMsg,
+ long timeMillis, String stackTrace);
/**
* An application process is not responding. Return 0 to show the "app
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 9f505ac..c890c4c 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -242,11 +242,9 @@ public interface IActivityManager extends IInterface {
// Special low-level communication with activity manager.
public void startRunning(String pkg, String cls, String action,
String data) throws RemoteException;
- // Returns 1 if the user wants to debug.
- public int handleApplicationError(IBinder app,
- int flags, /* 1 == can debug */
- String tag, String shortMsg, String longMsg,
- byte[] crashData) throws RemoteException;
+
+ public void handleApplicationError(IBinder app, String tag,
+ ApplicationErrorReport.CrashInfo crashInfo) throws RemoteException;
/*
* This will deliver the specified signal to all the persistent processes. Currently only
diff --git a/core/java/android/os/ICheckinService.aidl b/core/java/android/os/ICheckinService.aidl
index e56b55d..619079a 100644
--- a/core/java/android/os/ICheckinService.aidl
+++ b/core/java/android/os/ICheckinService.aidl
@@ -26,21 +26,6 @@ import android.os.IParentalControlCallback;
* {@hide}
*/
interface ICheckinService {
- /** Synchronously attempt a checkin with the server, return true
- * on success.
- * @throws IllegalStateException whenever an error occurs. The
- * cause of the exception will be the real exception:
- * IOException for network errors, JSONException for invalid
- * server responses, etc.
- */
- boolean checkin();
-
- /** Direct submission of crash data; returns after writing the crash. */
- void reportCrashSync(in byte[] crashData);
-
- /** Asynchronous "fire and forget" version of crash reporting. */
- oneway void reportCrashAsync(in byte[] crashData);
-
/** Reboot into the recovery system and wipe all user data. */
void masterClear();
diff --git a/core/java/android/provider/Checkin.java b/core/java/android/provider/Checkin.java
index 84753ee..75936a1 100644
--- a/core/java/android/provider/Checkin.java
+++ b/core/java/android/provider/Checkin.java
@@ -23,7 +23,6 @@ import android.content.ContentValues;
import android.database.SQLException;
import android.net.Uri;
import android.os.SystemClock;
-import android.server.data.CrashData;
import android.util.Log;
import java.io.ByteArrayOutputStream;
@@ -267,59 +266,4 @@ public final class Checkin {
/** {@link SystemClock#elapsedRealtime} of the last time a crash report failed. */
static private volatile long sLastCrashFailureRealtime = -MIN_CRASH_FAILURE_RETRY;
-
- /**
- * Helper function to report a crash.
- *
- * @param resolver from {@link android.content.Context#getContentResolver}
- * @param crash data from {@link android.server.data.CrashData}
- * @return URI of the crash report that was added
- */
- static public Uri reportCrash(ContentResolver resolver, byte[] crash) {
- try {
- // If we are in a situation where crash reports fail (such as a full disk),
- // it's important that we don't get into a loop trying to report failures.
- // So discard all crash reports for a few seconds after reporting fails.
- long realtime = SystemClock.elapsedRealtime();
- if (realtime - sLastCrashFailureRealtime < MIN_CRASH_FAILURE_RETRY) {
- Log.e(TAG, "Crash logging skipped, too soon after logging failure");
- return null;
- }
-
- // HACK: we don't support BLOB values, so base64 encode it.
- byte[] encoded = Base64.encodeBase64(crash);
- ContentValues values = new ContentValues();
- values.put(Crashes.DATA, new String(encoded));
- Uri uri = resolver.insert(Crashes.CONTENT_URI, values);
- if (uri == null) {
- Log.e(TAG, "Error reporting crash");
- sLastCrashFailureRealtime = SystemClock.elapsedRealtime();
- }
- return uri;
- } catch (Throwable t) {
- // To avoid an infinite crash-reporting loop, swallow all errors and exceptions.
- Log.e(TAG, "Error reporting crash: " + t);
- sLastCrashFailureRealtime = SystemClock.elapsedRealtime();
- return null;
- }
- }
-
- /**
- * Report a crash in CrashData format.
- *
- * @param resolver from {@link android.content.Context#getContentResolver}
- * @param crash data to report
- * @return URI of the crash report that was added
- */
- static public Uri reportCrash(ContentResolver resolver, CrashData crash) {
- try {
- ByteArrayOutputStream data = new ByteArrayOutputStream();
- crash.write(new DataOutputStream(data));
- return reportCrash(resolver, data.toByteArray());
- } catch (Throwable t) {
- // Swallow all errors and exceptions when writing crash report
- Log.e(TAG, "Error writing crash: " + t);
- return null;
- }
- }
}
diff --git a/core/java/android/server/data/BuildData.java b/core/java/android/server/data/BuildData.java
deleted file mode 100644
index 53ffa3f..0000000
--- a/core/java/android/server/data/BuildData.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2007 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.server.data;
-
-import android.os.Build;
-
-import java.io.DataInput;
-import java.io.DataOutput;
-import java.io.IOException;
-
-import static com.android.internal.util.Objects.nonNull;
-
-/**
- * Build data transfer object. Keep in sync. with the server side version.
- */
-public class BuildData {
-
- /** The version of the data returned by write() and understood by the constructor. */
- private static final int VERSION = 0;
-
- private final String fingerprint;
- private final String incrementalVersion;
- private final long time; // in *seconds* since the epoch (not msec!)
-
- public BuildData() {
- this.fingerprint = "android:" + Build.FINGERPRINT;
- this.incrementalVersion = Build.VERSION.INCREMENTAL;
- this.time = Build.TIME / 1000; // msec -> sec
- }
-
- public BuildData(String fingerprint, String incrementalVersion, long time) {
- this.fingerprint = nonNull(fingerprint);
- this.incrementalVersion = incrementalVersion;
- this.time = time;
- }
-
- /*package*/ BuildData(DataInput in) throws IOException {
- int dataVersion = in.readInt();
- if (dataVersion != VERSION) {
- throw new IOException("Expected " + VERSION + ". Got: " + dataVersion);
- }
-
- this.fingerprint = in.readUTF();
- this.incrementalVersion = Long.toString(in.readLong());
- this.time = in.readLong();
- }
-
- /*package*/ void write(DataOutput out) throws IOException {
- out.writeInt(VERSION);
- out.writeUTF(fingerprint);
-
- // TODO: change the format/version to expect a string for this field.
- // Version 0, still used by the server side, expects a long.
- long changelist;
- try {
- changelist = Long.parseLong(incrementalVersion);
- } catch (NumberFormatException ex) {
- changelist = -1;
- }
- out.writeLong(changelist);
- out.writeLong(time);
- }
-
- public String getFingerprint() {
- return fingerprint;
- }
-
- public String getIncrementalVersion() {
- return incrementalVersion;
- }
-
- public long getTime() {
- return time;
- }
-}
diff --git a/core/java/android/server/data/CrashData.java b/core/java/android/server/data/CrashData.java
deleted file mode 100644
index d652bb3..0000000
--- a/core/java/android/server/data/CrashData.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (C) 2006 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.server.data;
-
-import java.io.DataInput;
-import java.io.DataOutput;
-import java.io.IOException;
-
-import static com.android.internal.util.Objects.nonNull;
-
-/**
- * Crash data transfer object. Keep in sync. with the server side version.
- */
-public class CrashData {
-
- final String id;
- final String activity;
- final long time;
- final BuildData buildData;
- final ThrowableData throwableData;
- final byte[] state;
-
- public CrashData(String id, String activity, BuildData buildData,
- ThrowableData throwableData) {
- this.id = nonNull(id);
- this.activity = nonNull(activity);
- this.buildData = nonNull(buildData);
- this.throwableData = nonNull(throwableData);
- this.time = System.currentTimeMillis();
- this.state = null;
- }
-
- public CrashData(String id, String activity, BuildData buildData,
- ThrowableData throwableData, byte[] state) {
- this.id = nonNull(id);
- this.activity = nonNull(activity);
- this.buildData = nonNull(buildData);
- this.throwableData = nonNull(throwableData);
- this.time = System.currentTimeMillis();
- this.state = state;
- }
-
- public CrashData(DataInput in) throws IOException {
- int dataVersion = in.readInt();
- if (dataVersion != 0 && dataVersion != 1) {
- throw new IOException("Expected 0 or 1. Got: " + dataVersion);
- }
-
- this.id = in.readUTF();
- this.activity = in.readUTF();
- this.time = in.readLong();
- this.buildData = new BuildData(in);
- this.throwableData = new ThrowableData(in);
- if (dataVersion == 1) {
- int len = in.readInt();
- if (len == 0) {
- this.state = null;
- } else {
- this.state = new byte[len];
- in.readFully(this.state, 0, len);
- }
- } else {
- this.state = null;
- }
- }
-
- public CrashData(String tag, Throwable throwable) {
- id = "";
- activity = tag;
- buildData = new BuildData();
- throwableData = new ThrowableData(throwable);
- time = System.currentTimeMillis();
- state = null;
- }
-
- public void write(DataOutput out) throws IOException {
- // version
- if (this.state == null) {
- out.writeInt(0);
- } else {
- out.writeInt(1);
- }
-
- out.writeUTF(this.id);
- out.writeUTF(this.activity);
- out.writeLong(this.time);
- buildData.write(out);
- throwableData.write(out);
- if (this.state != null) {
- out.writeInt(this.state.length);
- out.write(this.state, 0, this.state.length);
- }
- }
-
- public BuildData getBuildData() {
- return buildData;
- }
-
- public ThrowableData getThrowableData() {
- return throwableData;
- }
-
- public String getId() {
- return id;
- }
-
- public String getActivity() {
- return activity;
- }
-
- public long getTime() {
- return time;
- }
-
- public byte[] getState() {
- return state;
- }
-
- /**
- * Return a brief description of this CrashData record. The details of the
- * representation are subject to change.
- *
- * @return Returns a String representing the contents of the object.
- */
- @Override
- public String toString() {
- return "[CrashData: id=" + id + " activity=" + activity + " time=" + time +
- " buildData=" + buildData.toString() +
- " throwableData=" + throwableData.toString() + "]";
- }
-}
diff --git a/core/java/android/server/data/StackTraceElementData.java b/core/java/android/server/data/StackTraceElementData.java
deleted file mode 100644
index 07185a0..0000000
--- a/core/java/android/server/data/StackTraceElementData.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2006 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.server.data;
-
-import java.io.DataInput;
-import java.io.DataOutput;
-import java.io.IOException;
-
-/**
- * Stack trace element data transfer object. Keep in sync. with the server side
- * version.
- */
-public class StackTraceElementData {
-
- final String className;
- final String fileName;
- final String methodName;
- final int lineNumber;
-
- public StackTraceElementData(StackTraceElement element) {
- this.className = element.getClassName();
-
- String fileName = element.getFileName();
- this.fileName = fileName == null ? "[unknown source]" : fileName;
-
- this.methodName = element.getMethodName();
- this.lineNumber = element.getLineNumber();
- }
-
- public StackTraceElementData(DataInput in) throws IOException {
- int dataVersion = in.readInt();
- if (dataVersion != 0) {
- throw new IOException("Expected 0. Got: " + dataVersion);
- }
-
- this.className = in.readUTF();
- this.fileName = in.readUTF();
- this.methodName = in.readUTF();
- this.lineNumber = in.readInt();
- }
-
- void write(DataOutput out) throws IOException {
- out.writeInt(0); // version
-
- out.writeUTF(className);
- out.writeUTF(fileName);
- out.writeUTF(methodName);
- out.writeInt(lineNumber);
- }
-
- public String getClassName() {
- return className;
- }
-
- public String getFileName() {
- return fileName;
- }
-
- public String getMethodName() {
- return methodName;
- }
-
- public int getLineNumber() {
- return lineNumber;
- }
-}
diff --git a/core/java/android/server/data/ThrowableData.java b/core/java/android/server/data/ThrowableData.java
deleted file mode 100644
index e500aca..0000000
--- a/core/java/android/server/data/ThrowableData.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2006 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.server.data;
-
-import java.io.DataInput;
-import java.io.DataOutput;
-import java.io.IOException;
-
-/**
- * Throwable data transfer object. Keep in sync. with the server side version.
- */
-public class ThrowableData {
-
- final String message;
- final String type;
- final StackTraceElementData[] stackTrace;
- final ThrowableData cause;
-
- public ThrowableData(Throwable throwable) {
- this.type = throwable.getClass().getName();
- String message = throwable.getMessage();
- this.message = message == null ? "" : message;
-
- StackTraceElement[] elements = throwable.getStackTrace();
- this.stackTrace = new StackTraceElementData[elements.length];
- for (int i = 0; i < elements.length; i++) {
- this.stackTrace[i] = new StackTraceElementData(elements[i]);
- }
-
- Throwable cause = throwable.getCause();
- this.cause = cause == null ? null : new ThrowableData(cause);
- }
-
- public ThrowableData(DataInput in) throws IOException {
- int dataVersion = in.readInt();
- if (dataVersion != 0) {
- throw new IOException("Expected 0. Got: " + dataVersion);
- }
-
- this.message = in.readUTF();
- this.type = in.readUTF();
-
- int count = in.readInt();
- this.stackTrace = new StackTraceElementData[count];
- for (int i = 0; i < count; i++) {
- this.stackTrace[i] = new StackTraceElementData(in);
- }
-
- this.cause = in.readBoolean() ? new ThrowableData(in) : null;
- }
-
- public void write(DataOutput out) throws IOException {
- out.writeInt(0); // version
-
- out.writeUTF(message);
- out.writeUTF(type);
-
- out.writeInt(stackTrace.length);
- for (StackTraceElementData elementData : stackTrace) {
- elementData.write(out);
- }
-
- out.writeBoolean(cause != null);
- if (cause != null) {
- cause.write(out);
- }
- }
-
- public String getMessage() {
- return message;
- }
-
- public String getType() {
- return type;
- }
-
- public StackTraceElementData[] getStackTrace() {
- return stackTrace;
- }
-
- public ThrowableData getCause() {
- return cause;
- }
-
-
- public String toString() {
- return toString(null);
- }
-
- public String toString(String prefix) {
- StringBuilder builder = new StringBuilder();
- append(prefix, builder, this);
- return builder.toString();
- }
-
- private static void append(String prefix, StringBuilder builder,
- ThrowableData throwableData) {
- if (prefix != null) builder.append(prefix);
- builder.append(throwableData.getType())
- .append(": ")
- .append(throwableData.getMessage())
- .append('\n');
- for (StackTraceElementData element : throwableData.getStackTrace()) {
- if (prefix != null ) builder.append(prefix);
- builder.append(" at ")
- .append(element.getClassName())
- .append('.')
- .append(element.getMethodName())
- .append("(")
- .append(element.getFileName())
- .append(':')
- .append(element.getLineNumber())
- .append(")\n");
-
- }
-
- ThrowableData cause = throwableData.getCause();
- if (cause != null) {
- if (prefix != null ) builder.append(prefix);
- builder.append("Caused by: ");
- append(prefix, builder, cause);
- }
- }
-}
diff --git a/core/java/android/server/data/package.html b/core/java/android/server/data/package.html
deleted file mode 100755
index 1c9bf9d..0000000
--- a/core/java/android/server/data/package.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<html>
-<body>
- {@hide}
-</body>
-</html>
diff --git a/core/java/android/util/Log.java b/core/java/android/util/Log.java
index 2572679..e95d0be 100644
--- a/core/java/android/util/Log.java
+++ b/core/java/android/util/Log.java
@@ -216,9 +216,7 @@ public final class Log {
* @param tr An exception to log
*/
public static int e(String tag, String msg, Throwable tr) {
- int r = println(ERROR, tag, msg + '\n' + getStackTraceString(tr));
- RuntimeInit.reportException(tag, tr, false); // asynchronous
- return r;
+ return println(ERROR, tag, msg + '\n' + getStackTraceString(tr));
}
/**
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java
index c782c8c..b7bb72d 100644
--- a/core/java/com/android/internal/os/RuntimeInit.java
+++ b/core/java/com/android/internal/os/RuntimeInit.java
@@ -17,7 +17,9 @@
package com.android.internal.os;
import android.app.ActivityManagerNative;
+import android.app.ApplicationErrorReport;
import android.app.IActivityManager;
+import android.os.Build;
import android.os.Debug;
import android.os.IBinder;
import android.os.ICheckinService;
@@ -25,8 +27,6 @@ import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
-import android.os.Build;
-import android.server.data.CrashData;
import android.util.Config;
import android.util.Log;
@@ -309,51 +309,18 @@ public class RuntimeInit {
*/
public static void crash(String tag, Throwable t) {
if (mApplicationObject != null) {
- byte[] crashData = null;
try {
// Log exception.
Log.e(TAG, Log.getStackTraceString(t));
- crashData = marshallException(tag, t);
- if (crashData == null) {
- throw new NullPointerException("Can't marshall crash data");
- }
- } catch (Throwable t2) {
- try {
- // Log exception as a string so we don't get in an infinite loop.
- Log.e(TAG, "Error reporting crash: "
- + Log.getStackTraceString(t2));
- } catch (Throwable t3) {
- // Do nothing, must be OOM so we can't format the message
- }
- }
-
- try {
- // Display user-visible error message.
- String msg = t.getMessage();
- if (msg == null) {
- msg = t.toString();
- }
+ // Show a message to the user.
IActivityManager am = ActivityManagerNative.getDefault();
- try {
- int res = am.handleApplicationError(mApplicationObject,
- 0, tag, msg, t.toString(), crashData);
- // Is waiting for the debugger the right thing?
- // For now I have turned off the Debug button, because
- // I'm not sure what we should do if it is actually
- // selected.
- //Log.i(TAG, "Got app error result: " + res);
- if (res == 1) {
- Debug.waitForDebugger();
- return;
- }
- } catch (RemoteException e) {
- }
+ am.handleApplicationError(mApplicationObject, tag,
+ new ApplicationErrorReport.CrashInfo(t));
} catch (Throwable t2) {
try {
// Log exception as a string so we don't get in an infinite loop.
- Log.e(TAG, "Error reporting crash: "
- + Log.getStackTraceString(t2));
+ Log.e(TAG, "Error reporting crash: " + Log.getStackTraceString(t2));
} catch (Throwable t3) {
// Do nothing, must be OOM so we can't format the message
}
@@ -366,7 +333,6 @@ public class RuntimeInit {
try {
Log.e(TAG, "*** EXCEPTION IN SYSTEM PROCESS. System will crash.");
Log.e(tag, Log.getStackTraceString(t));
- reportException(tag, t, true); // synchronous
} catch (Throwable t2) {
// Do nothing, must be OOM so we can't format the message
} finally {
@@ -381,82 +347,6 @@ public class RuntimeInit {
private static final AtomicInteger sInReportException = new AtomicInteger();
/**
- * Report an error in the current process. The exception information will
- * be handed off to the checkin service and eventually uploaded for analysis.
- * This is expensive! Only use this when the exception indicates a programming
- * error ("should not happen").
- *
- * @param tag to use when logging the error
- * @param t exception that was generated by the error
- * @param sync true to wait for the report, false to "fire and forget"
- */
- public static void reportException(String tag, Throwable t, boolean sync) {
- if (!initialized) {
- // Exceptions during, eg, zygote cannot use this mechanism
- return;
- }
-
- // It's important to prevent an infinite crash-reporting loop:
- // while this function is running, don't let it be called again.
- int reenter = sInReportException.getAndIncrement();
- if (reenter != 0) {
- sInReportException.decrementAndGet();
- Log.e(TAG, "Crash logging skipped, already logging another crash");
- return;
- }
-
- // TODO: Enable callers to specify a level (i.e. warn or error).
- try {
- // Submit crash data to statistics service.
- byte[] crashData = marshallException(tag, t);
- ICheckinService checkin = ICheckinService.Stub.asInterface(
- ServiceManager.getService("checkin"));
- if (checkin == null) {
- Log.e(TAG, "Crash logging skipped, no checkin service");
- } else if (sync) {
- checkin.reportCrashSync(crashData);
- } else {
- checkin.reportCrashAsync(crashData);
- }
- } catch (Throwable t2) {
- // Log exception as a string so we don't get in an infinite loop.
- Log.e(TAG, "Crash logging failed: " + t2);
- } finally {
- sInReportException.decrementAndGet();
- }
- }
-
- private static byte[] marshallException(String tag, Throwable t) {
- // Convert crash data to bytes.
- ByteArrayOutputStream bout = new ByteArrayOutputStream();
- DataOutputStream dout = new DataOutputStream(bout);
- try {
- new CrashData(tag, t).write(dout);
- dout.close();
- } catch (IOException e) {
- return null;
- }
- return bout.toByteArray();
- }
-
- /**
- * Replay an encoded CrashData record back into a useable CrashData record. This can be
- * helpful for providing debugging output after a process error.
- *
- * @param crashDataBytes The byte array containing the encoded crash record
- * @return new CrashData record, or null if could not create one.
- */
- public static CrashData unmarshallException(byte[] crashDataBytes) {
- try {
- ByteArrayInputStream bin = new ByteArrayInputStream(crashDataBytes);
- DataInputStream din = new DataInputStream(bin);
- return new CrashData(din);
- } catch (IOException e) {
- return null;
- }
- }
-
- /**
* Set the object identifying this application/process, for reporting VM
* errors.
*/
@@ -473,5 +363,4 @@ public class RuntimeInit {
}
private static IBinder mApplicationObject;
-
}
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 3683aab..9e72f64 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1844,8 +1844,6 @@
<string name="report">Report</string>
<!-- Button allowing the user to choose to wait for an application that is not responding to become responsive again. -->
<string name="wait">Wait</string>
- <!-- Button allowing a developer to connect a debugger to an application that is not responding. -->
- <string name="debug">Debug</string>
<!-- Displayed in the title of the chooser for things to do with text that
is to be sent to another application. For example, I can send text through SMS or IM. A dialog with those choices would be shown, and this would be the title. -->
diff --git a/preloaded-classes b/preloaded-classes
index c6d0bf9..0410557 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -637,7 +637,6 @@ android.security.Sha1MessageDigest
android.server.BluetoothA2dpService
android.server.BluetoothEventLoop
android.server.BluetoothService
-android.server.data.CrashData
android.speech.IRecognitionListener$Stub
android.speech.IRecognitionService$Stub
android.speech.RecognitionResult
diff --git a/services/java/com/android/server/FallbackCheckinService.java b/services/java/com/android/server/FallbackCheckinService.java
index cf22446..88c549b 100644
--- a/services/java/com/android/server/FallbackCheckinService.java
+++ b/services/java/com/android/server/FallbackCheckinService.java
@@ -34,21 +34,11 @@ import com.google.android.net.ParentalControlState;
public final class FallbackCheckinService extends ICheckinService.Stub {
static final String TAG = "FallbackCheckinService";
final Context mContext;
-
+
public FallbackCheckinService(Context context) {
mContext = context;
}
- public boolean checkin() {
- return false; // failure, because not implemented
- }
-
- public void reportCrashSync(byte[] crashData) {
- }
-
- public void reportCrashAsync(byte[] crashData) {
- }
-
public void masterClear() {
if (mContext.checkCallingOrSelfPermission("android.permission.MASTER_CLEAR") !=
PackageManager.PERMISSION_GRANTED) {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 6c5c52f..d9c7d6f 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -88,9 +88,6 @@ import android.os.SystemClock;
import android.os.SystemProperties;
import android.provider.Checkin;
import android.provider.Settings;
-import android.server.data.CrashData;
-import android.server.data.StackTraceElementData;
-import android.server.data.ThrowableData;
import android.text.TextUtils;
import android.util.Config;
import android.util.EventLog;
@@ -944,12 +941,6 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
switch (msg.what) {
case SHOW_ERROR_MSG: {
HashMap data = (HashMap) msg.obj;
- byte[] crashData = (byte[])data.get("crashData");
- if (crashData != null) {
- // This needs to be *un*synchronized to avoid deadlock.
- ContentResolver resolver = mContext.getContentResolver();
- Checkin.reportCrash(resolver, crashData);
- }
synchronized (ActivityManagerService.this) {
ProcessRecord proc = (ProcessRecord)data.get("app");
if (proc != null && proc.crashDialog != null) {
@@ -958,11 +949,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
}
AppErrorResult res = (AppErrorResult) data.get("result");
if (!mSleeping && !mShuttingDown) {
- Dialog d = new AppErrorDialog(
- mContext, res, proc,
- (Integer)data.get("flags"),
- (String)data.get("shortMsg"),
- (String)data.get("longMsg"));
+ Dialog d = new AppErrorDialog(mContext, res, proc);
d.show();
proc.crashDialog = d;
} else {
@@ -4706,7 +4693,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
makeAppNotRespondingLocked(app,
activity != null ? activity.shortComponentName : null,
annotation != null ? "ANR " + annotation : "ANR",
- info.toString(), null);
+ info.toString());
Message msg = Message.obtain();
HashMap map = new HashMap();
msg.what = SHOW_NOT_RESPONDING_MSG;
@@ -8544,11 +8531,12 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
}
}
- boolean makeAppCrashingLocked(ProcessRecord app,
- String tag, String shortMsg, String longMsg, byte[] crashData) {
+ private boolean makeAppCrashingLocked(ProcessRecord app,
+ String tag, String shortMsg, String longMsg, String stackTrace) {
app.crashing = true;
- app.crashingReport = generateProcessError(app,
- ActivityManager.ProcessErrorStateInfo.CRASHED, tag, shortMsg, longMsg, crashData);
+ app.crashingReport = generateProcessError(app,
+ ActivityManager.ProcessErrorStateInfo.CRASHED, tag, shortMsg, longMsg,
+ stackTrace);
startAppProblemLocked(app);
app.stopFreezingAllLocked();
return handleAppCrashLocked(app);
@@ -8621,12 +8609,11 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
return new ComponentName(receiverPackage, info.activityInfo.name);
}
- void makeAppNotRespondingLocked(ProcessRecord app,
- String tag, String shortMsg, String longMsg, byte[] crashData) {
+ private void makeAppNotRespondingLocked(ProcessRecord app,
+ String tag, String shortMsg, String longMsg) {
app.notResponding = true;
- app.notRespondingReport = generateProcessError(app,
- ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, tag, shortMsg, longMsg,
- crashData);
+ app.notRespondingReport = generateProcessError(app,
+ ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, tag, shortMsg, longMsg, null);
startAppProblemLocked(app);
app.stopFreezingAllLocked();
}
@@ -8640,14 +8627,14 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
* @param tag The tag that was passed into handleApplicationError(). Typically the classname.
* @param shortMsg Short message describing the crash.
* @param longMsg Long message describing the crash.
- * @param crashData Raw data passed into handleApplicationError(). Typically a stack trace.
- *
+ * @param stackTrace Full crash stack trace, may be null.
+ *
* @return Returns a fully-formed AppErrorStateInfo record.
*/
private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
- int condition, String tag, String shortMsg, String longMsg, byte[] crashData) {
+ int condition, String tag, String shortMsg, String longMsg, String stackTrace) {
ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
-
+
report.condition = condition;
report.processName = app.processName;
report.pid = app.pid;
@@ -8655,7 +8642,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
report.tag = tag;
report.shortMsg = shortMsg;
report.longMsg = longMsg;
- report.crashData = crashData;
+ report.stackTrace = stackTrace;
return report;
}
@@ -8686,7 +8673,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
}
}
- boolean handleAppCrashLocked(ProcessRecord app) {
+ private boolean handleAppCrashLocked(ProcessRecord app) {
long now = SystemClock.uptimeMillis();
Long crashTime = mProcessCrashTimes.get(app.info.processName,
@@ -8769,10 +8756,20 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
}
}
- public int handleApplicationError(IBinder app, int flags,
- String tag, String shortMsg, String longMsg, byte[] crashData) {
+ public void handleApplicationError(IBinder app, String tag,
+ ApplicationErrorReport.CrashInfo crashInfo) {
AppErrorResult result = new AppErrorResult();
ProcessRecord r = null;
+ long timeMillis = System.currentTimeMillis();
+ String shortMsg = crashInfo.exceptionClassName;
+ String longMsg = crashInfo.exceptionMessage;
+ String stackTrace = crashInfo.stackTrace;
+ if (shortMsg != null && longMsg != null) {
+ longMsg = shortMsg + ": " + longMsg;
+ } else if (shortMsg != null) {
+ longMsg = shortMsg;
+ }
+
synchronized (this) {
if (app != null) {
for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
@@ -8799,12 +8796,12 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
try {
String name = r != null ? r.processName : null;
int pid = r != null ? r.pid : Binder.getCallingPid();
- if (!mController.appCrashed(name, pid,
- shortMsg, longMsg, crashData)) {
+ if (!mController.appCrashed(name, pid, tag,
+ shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Log.w(TAG, "Force-killing crashed app " + name
+ " at watcher's request");
Process.killProcess(pid);
- return 0;
+ return;
}
} catch (RemoteException e) {
mController = null;
@@ -8824,12 +8821,12 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
info.putString("longMsg", longMsg);
finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
Binder.restoreCallingIdentity(origId);
- return 0;
+ return;
}
if (r != null) {
- if (!makeAppCrashingLocked(r, tag, shortMsg, longMsg, crashData)) {
- return 0;
+ if (!makeAppCrashingLocked(r, tag, shortMsg, longMsg, stackTrace)) {
+ return;
}
} else {
Log.w(TAG, "Some application object " + app + " tag " + tag
@@ -8837,7 +8834,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
Log.w(TAG, "ShortMsg:" + shortMsg);
Log.w(TAG, "LongMsg:" + longMsg);
Binder.restoreCallingIdentity(origId);
- return 0;
+ return;
}
Message msg = Message.obtain();
@@ -8845,13 +8842,6 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
HashMap data = new HashMap();
data.put("result", result);
data.put("app", r);
- data.put("flags", flags);
- data.put("shortMsg", shortMsg);
- data.put("longMsg", longMsg);
- if (r != null && (r.info.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
- // For system processes, submit crash data to the server.
- data.put("crashData", crashData);
- }
msg.obj = data;
mHandler.sendMessage(msg);
@@ -8867,8 +8857,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
SystemClock.uptimeMillis());
}
if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
- appErrorIntent = createAppErrorIntentLocked(r);
- res = AppErrorDialog.FORCE_QUIT;
+ appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
}
}
@@ -8879,12 +8868,11 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
Log.w(TAG, "bug report receiver dissappeared", e);
}
}
-
- return res;
}
-
- Intent createAppErrorIntentLocked(ProcessRecord r) {
- ApplicationErrorReport report = createAppErrorReportLocked(r);
+
+ Intent createAppErrorIntentLocked(ProcessRecord r,
+ long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
+ ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
if (report == null) {
return null;
}
@@ -8895,7 +8883,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
return result;
}
- ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r) {
+ private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
+ long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
if (r.errorReportReceiver == null) {
return null;
}
@@ -8904,58 +8893,25 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
return null;
}
- try {
- ApplicationErrorReport report = new ApplicationErrorReport();
- report.packageName = r.info.packageName;
- report.installerPackageName = r.errorReportReceiver.getPackageName();
- report.processName = r.processName;
-
- if (r.crashing) {
- report.type = ApplicationErrorReport.TYPE_CRASH;
- report.crashInfo = new ApplicationErrorReport.CrashInfo();
-
- ByteArrayInputStream byteStream = new ByteArrayInputStream(
- r.crashingReport.crashData);
- DataInputStream dataStream = new DataInputStream(byteStream);
- CrashData crashData = new CrashData(dataStream);
- ThrowableData throwData = crashData.getThrowableData();
-
- report.time = crashData.getTime();
- report.crashInfo.stackTrace = throwData.toString();
-
- // Extract the source of the exception, useful for report
- // clustering. Also extract the "deepest" non-null exception
- // message.
- String exceptionMessage = throwData.getMessage();
- while (throwData.getCause() != null) {
- throwData = throwData.getCause();
- String msg = throwData.getMessage();
- if (msg != null && msg.length() > 0) {
- exceptionMessage = msg;
- }
- }
- StackTraceElementData trace = throwData.getStackTrace()[0];
- report.crashInfo.exceptionMessage = exceptionMessage;
- report.crashInfo.exceptionClassName = throwData.getType();
- report.crashInfo.throwFileName = trace.getFileName();
- report.crashInfo.throwClassName = trace.getClassName();
- report.crashInfo.throwMethodName = trace.getMethodName();
- report.crashInfo.throwLineNumber = trace.getLineNumber();
- } else if (r.notResponding) {
- report.type = ApplicationErrorReport.TYPE_ANR;
- report.anrInfo = new ApplicationErrorReport.AnrInfo();
-
- report.anrInfo.activity = r.notRespondingReport.tag;
- report.anrInfo.cause = r.notRespondingReport.shortMsg;
- report.anrInfo.info = r.notRespondingReport.longMsg;
- }
-
- return report;
- } catch (IOException e) {
- // we don't send it
+ ApplicationErrorReport report = new ApplicationErrorReport();
+ report.packageName = r.info.packageName;
+ report.installerPackageName = r.errorReportReceiver.getPackageName();
+ report.processName = r.processName;
+ report.time = timeMillis;
+
+ if (r.crashing) {
+ report.type = ApplicationErrorReport.TYPE_CRASH;
+ report.crashInfo = crashInfo;
+ } else if (r.notResponding) {
+ report.type = ApplicationErrorReport.TYPE_ANR;
+ report.anrInfo = new ApplicationErrorReport.AnrInfo();
+
+ report.anrInfo.activity = r.notRespondingReport.tag;
+ report.anrInfo.cause = r.notRespondingReport.shortMsg;
+ report.anrInfo.info = r.notRespondingReport.longMsg;
}
- return null;
+ return report;
}
public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
@@ -11432,8 +11388,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
}
if (timeout != null && mLRUProcesses.contains(proc)) {
Log.w(TAG, "Timeout executing service: " + timeout);
- appNotRespondingLocked(proc, null, null, "Executing service "
- + timeout.name);
+ appNotRespondingLocked(proc, null, null, "Executing service " + timeout.name);
} else {
Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
msg.obj = proc;
@@ -12233,8 +12188,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
}
if (app != null) {
- appNotRespondingLocked(app, null, null,
- "Broadcast of " + r.intent.toString());
+ appNotRespondingLocked(app, null, null, "Broadcast of " + r.intent.toString());
}
if (mPendingBroadcast == r) {
diff --git a/services/java/com/android/server/am/AppErrorDialog.java b/services/java/com/android/server/am/AppErrorDialog.java
index 33894d6..328f5e7 100644
--- a/services/java/com/android/server/am/AppErrorDialog.java
+++ b/services/java/com/android/server/am/AppErrorDialog.java
@@ -33,15 +33,12 @@ class AppErrorDialog extends BaseErrorDialog {
// Event 'what' codes
static final int FORCE_QUIT = 0;
- static final int DEBUG = 1;
- static final int FORCE_QUIT_AND_REPORT = 2;
+ static final int FORCE_QUIT_AND_REPORT = 1;
// 5-minute timeout, then we automatically dismiss the crash dialog
static final long DISMISS_TIMEOUT = 1000 * 60 * 5;
- public AppErrorDialog(Context context, AppErrorResult result,
- ProcessRecord app, int flags,
- String shortMsg, String longMsg) {
+ public AppErrorDialog(Context context, AppErrorResult result, ProcessRecord app) {
super(context);
Resources res = context.getResources();
@@ -67,12 +64,6 @@ class AppErrorDialog extends BaseErrorDialog {
res.getText(com.android.internal.R.string.force_close),
mHandler.obtainMessage(FORCE_QUIT));
- if ((flags&1) != 0) {
- setButton(DialogInterface.BUTTON_NEUTRAL,
- res.getText(com.android.internal.R.string.debug),
- mHandler.obtainMessage(DEBUG));
- }
-
if (app.errorReportReceiver != null) {
setButton(DialogInterface.BUTTON_NEGATIVE,
res.getText(com.android.internal.R.string.report),
@@ -88,7 +79,7 @@ class AppErrorDialog extends BaseErrorDialog {
mHandler.obtainMessage(FORCE_QUIT),
DISMISS_TIMEOUT);
}
-
+
public void onStop() {
}
diff --git a/services/java/com/android/server/am/AppNotRespondingDialog.java b/services/java/com/android/server/am/AppNotRespondingDialog.java
index 03c2a04..1851853 100644
--- a/services/java/com/android/server/am/AppNotRespondingDialog.java
+++ b/services/java/com/android/server/am/AppNotRespondingDialog.java
@@ -114,7 +114,7 @@ class AppNotRespondingDialog extends BaseErrorDialog {
ProcessRecord app = mProc;
if (msg.what == WAIT_AND_REPORT) {
- appErrorIntent = mService.createAppErrorIntentLocked(app);
+ appErrorIntent = mService.createAppErrorIntentLocked(app, 0, null);
}
app.notResponding = false;
diff --git a/services/java/com/android/server/am/BaseErrorDialog.java b/services/java/com/android/server/am/BaseErrorDialog.java
index bed2768..aa80ae6 100644
--- a/services/java/com/android/server/am/BaseErrorDialog.java
+++ b/services/java/com/android/server/am/BaseErrorDialog.java
@@ -61,6 +61,10 @@ class BaseErrorDialog extends AlertDialog {
if (b != null) {
b.setEnabled(enabled);
}
+ b = (Button)findViewById(R.id.button3);
+ if (b != null) {
+ b.setEnabled(enabled);
+ }
}
private Handler mHandler = new Handler() {
diff --git a/tests/AndroidTests/src/com/android/unit_tests/BuildTest.java b/tests/AndroidTests/src/com/android/unit_tests/BuildTest.java
index dbfd0e7..88fa3cc 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/BuildTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/BuildTest.java
@@ -17,15 +17,14 @@
package com.android.unit_tests;
import android.os.Build;
-import android.server.data.BuildData;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Log;
import junit.framework.Assert;
import junit.framework.TestCase;
/**
- * Provides test cases for android.os.Build and android.server.data.BuildData,
- * and, in turn, many of the system properties set by the build system.
+ * Provides test cases for android.os.Build and, in turn, many of the
+ * system properties set by the build system.
*/
public class BuildTest extends TestCase {
@@ -74,58 +73,4 @@ public class BuildTest extends TestCase {
// (e.g., must be a C identifier, must be a valid filename, must not contain any spaces)
// add tests for them.
}
-
- /**
- * Asserts that android.server.data.BuildData behaves as expected.
- */
- @SmallTest
- public void testBuildData() throws Exception {
- BuildData bd;
-
- /*
- * Default constructor
- */
- bd = new BuildData();
- assertNotEmpty(bd.getFingerprint());
- assertNotEmpty(bd.getIncrementalVersion());
- Assert.assertTrue(bd.getTime() > 0);
-
- /*
- * Explicit constructor
- */
- final String FINGERPRINT = "fingerprint";
- final String INCREMENTAL_VERSION = "74321"; // a valid long, for the serialization test
- final long TIME = 12345;
- bd = new BuildData(FINGERPRINT, INCREMENTAL_VERSION, TIME);
- Assert.assertEquals(FINGERPRINT, bd.getFingerprint());
- Assert.assertEquals(INCREMENTAL_VERSION, bd.getIncrementalVersion());
- Assert.assertTrue(bd.getTime() == TIME);
-
-// The serialization methods are package-private.
-//
-// import java.io.ByteArrayInputStream;
-// import java.io.ByteArrayOutputStream;
-// import java.io.DataInputStream;
-// import java.io.DataOutputStream;
-//
-// /*
-// * Serialization
-// */
-// ByteArrayOutputStream out = new ByteArrayOutputStream();
-// bd.write(new DataOutputStream(out));
-// Assert.assertTrue(out.size() > 0);
-//
-// /*
-// * Deserialization
-// *
-// * The current version of BuildData converts the incremental version to
-// * and from a long when serializing/deserializing. Future versions should
-// * treat it as a string.
-// */
-// BuildData bd2 =
-// new BuildData(new DataInputStream(new ByteArrayInputStream(out.toByteArray())));
-// Assert.assertEquals(bd.getFingerprint(), bd2.getFingerprint());
-// Assert.assertEquals(bd.getIncrementalVersion(), bd2.getIncrementalVersion());
-// Assert.assertTrue(bd.getTime() == bd2.getTime());
- }
}
diff --git a/tests/SmokeTest/tests/src/com/android/smoketest/ProcessErrorsTest.java b/tests/SmokeTest/tests/src/com/android/smoketest/ProcessErrorsTest.java
index 85b91f1..5f53a9b 100644
--- a/tests/SmokeTest/tests/src/com/android/smoketest/ProcessErrorsTest.java
+++ b/tests/SmokeTest/tests/src/com/android/smoketest/ProcessErrorsTest.java
@@ -20,7 +20,6 @@ import com.android.internal.os.RuntimeInit;
import android.app.ActivityManager;
import android.content.Context;
-import android.server.data.CrashData;
import android.test.AndroidTestCase;
import android.util.Log;
@@ -91,25 +90,12 @@ public class ProcessErrorsTest extends AndroidTestCase {
break;
default:
condition = "<unknown>";
- break;
- }
-
- String stackTrace = null;
- try {
- if (entry.crashData != null) {
- CrashData cd = RuntimeInit.unmarshallException(entry.crashData);
- stackTrace = cd.toString();
- }
- } catch (RuntimeException e) { }
- if (stackTrace == null) {
- stackTrace = "<no stack trace>";
+ break;
}
- final String entryReport = "Process error " + condition + " " + entry.shortMsg +
- " detected in " + entry.processName + " " + entry.tag +
- ". \n" + stackTrace;
-
- builder.append(entryReport).append(" ");
+ builder.append("Process error ").append(condition).append(" ");
+ builder.append(" ").append(entry.shortMsg);
+ builder.append(" detected in ").append(entry.processName).append(" ").append(entry.tag);
}
return builder.toString();
}