From 44dc76a8a702d6a919fcea1c2d19ba3792687c85 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Wed, 2 Jun 2010 15:12:05 -0700 Subject: [PATCH] Log.wtf when databases go to be downgraded. BUG=2734435 Change-Id: I686d6d9415f3081544c3fbe379287c31e0ecec20 --- .../database/sqlite/SQLiteOpenHelper.java | 10 ++++++ core/java/android/util/Log.java | 35 +++++++++++++++++-- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/core/java/android/database/sqlite/SQLiteOpenHelper.java b/core/java/android/database/sqlite/SQLiteOpenHelper.java index 52aac3a822b3f..aefbabc4da914 100644 --- a/core/java/android/database/sqlite/SQLiteOpenHelper.java +++ b/core/java/android/database/sqlite/SQLiteOpenHelper.java @@ -28,6 +28,12 @@ import android.util.Log; * Transactions are used to make sure the database is always in a sensible state. *

For an example, see the NotePadProvider class in the NotePad sample application, * in the samples/ directory of the SDK.

+ * + *

Note: this class assumes + * monotonically increasing version numbers for upgrades. Also, there + * is no concept of a database downgrade; installing a new version of + * your app which uses a lower version number than a + * previously-installed version will result in undefined behavior.

*/ public abstract class SQLiteOpenHelper { private static final String TAG = SQLiteOpenHelper.class.getSimpleName(); @@ -105,6 +111,10 @@ public abstract class SQLiteOpenHelper { if (version == 0) { onCreate(db); } else { + if (version > mNewVersion) { + Log.wtf(TAG, "Can't downgrade read-only database from version " + + version + " to " + mNewVersion + ": " + db.getPath()); + } onUpgrade(db, version, mNewVersion); } db.setVersion(mNewVersion); diff --git a/core/java/android/util/Log.java b/core/java/android/util/Log.java index e1116694e4a64..d577b74d5d2bd 100644 --- a/core/java/android/util/Log.java +++ b/core/java/android/util/Log.java @@ -88,6 +88,21 @@ public final class Log { TerribleFailure(String msg, Throwable cause) { super(msg, cause); } } + /** + * Interface to handle terrible failures from {@link #wtf()}. + * + * @hide + */ + public interface TerribleFailureHandler { + void onTerribleFailure(String tag, TerribleFailure what); + } + + private static TerribleFailureHandler sWtfHandler = new TerribleFailureHandler() { + public void onTerribleFailure(String tag, TerribleFailure what) { + RuntimeInit.wtf(tag, what); + } + }; + private Log() { } @@ -257,12 +272,28 @@ public final class Log { * @param tr An exception to log. May be null. */ public static int wtf(String tag, String msg, Throwable tr) { - tr = new TerribleFailure(msg, tr); + TerribleFailure what = new TerribleFailure(msg, tr); int bytes = println_native(LOG_ID_MAIN, ASSERT, tag, getStackTraceString(tr)); - RuntimeInit.wtf(tag, tr); + sWtfHandler.onTerribleFailure(tag, what); return bytes; } + /** + * Sets the terrible failure handler, for testing. + * + * @return the old handler + * + * @hide + */ + public static TerribleFailureHandler setWtfHandler(TerribleFailureHandler handler) { + if (handler == null) { + throw new NullPointerException("handler == null"); + } + TerribleFailureHandler oldHandler = sWtfHandler; + sWtfHandler = handler; + return oldHandler; + } + /** * Handy function to get a loggable stack trace from a Throwable * @param tr An exception to log