diff options
author | Dan Egnor <egnor@google.com> | 2009-12-09 16:22:32 -0800 |
---|---|---|
committer | Dan Egnor <egnor@google.com> | 2009-12-11 13:27:04 -0800 |
commit | b7f0367cec1c744aa66ef397b0244e25d507491c (patch) | |
tree | 7b70d87b9886ea1567647aac00fccb3198accc8c | |
parent | af1255dab8fa3eab1caf9bae799f80de14a74470 (diff) | |
download | frameworks_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.
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(); } |