diff --git a/core/java/android/database/sqlite/SQLiteOpenHelper.java b/core/java/android/database/sqlite/SQLiteOpenHelper.java index 851f5ea9d5c35..0f2e872e54e1d 100644 --- a/core/java/android/database/sqlite/SQLiteOpenHelper.java +++ b/core/java/android/database/sqlite/SQLiteOpenHelper.java @@ -30,6 +30,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(); @@ -137,6 +143,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