diff options
author | Sunny Goyal <sunnygoyal@google.com> | 2015-09-23 11:40:53 -0700 |
---|---|---|
committer | Sunny Goyal <sunnygoyal@google.com> | 2015-10-06 16:47:14 -0700 |
commit | 6fb929e0038a9d03b60540fdbf6b6914146f7b21 (patch) | |
tree | 76a0b95ae9eefe1666cdb5a2b0ddb5637cbbb126 /src/com/android/launcher3/LauncherProvider.java | |
parent | a67ba8612f4408c42bb6988304aeb86bd3382796 (diff) | |
download | android_packages_apps_Trebuchet-6fb929e0038a9d03b60540fdbf6b6914146f7b21.tar.gz android_packages_apps_Trebuchet-6fb929e0038a9d03b60540fdbf6b6914146f7b21.tar.bz2 android_packages_apps_Trebuchet-6fb929e0038a9d03b60540fdbf6b6914146f7b21.zip |
Verifying that the table was successfully created during initialzation
Table creation sometimes fails scilently, which leads to a crash loop.
This way, we will try to create a table every time after crash, so
the device would eventually be able to recover.
Bug: 24263894
Change-Id: Ic0169d33f4092042423afa24320182786c544d47
Diffstat (limited to 'src/com/android/launcher3/LauncherProvider.java')
-rw-r--r-- | src/com/android/launcher3/LauncherProvider.java | 104 |
1 files changed, 62 insertions, 42 deletions
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java index 8791e9e57..a6fd28242 100644 --- a/src/com/android/launcher3/LauncherProvider.java +++ b/src/com/android/launcher3/LauncherProvider.java @@ -331,10 +331,6 @@ public class LauncherProvider extends ContentProvider { return mOpenHelper.generateNewItemId(); } - public void updateMaxItemId(long id) { - mOpenHelper.updateMaxItemId(id); - } - public long generateNewScreenId() { return mOpenHelper.generateNewScreenId(); } @@ -488,6 +484,16 @@ public class LauncherProvider extends ContentProvider { mContext = context; mAppWidgetHost = new AppWidgetHost(context, Launcher.APPWIDGET_HOST_ID); + // Table creation sometimes fails silently, which leads to a crash loop. + // This way, we will try to create a table every time after crash, so the device + // would eventually be able to recover. + if (!tableExists(TABLE_FAVORITES) || !tableExists(TABLE_WORKSPACE_SCREENS)) { + Log.e(TAG, "Tables are missing after onCreate has been called. Trying to recreate"); + // This operation is a no-op if the table already exists. + addFavoritesTable(getWritableDatabase(), true); + addWorkspacesTable(getWritableDatabase(), true); + } + // In the case where neither onCreate nor onUpgrade gets called, we read the maxId from // the DB here if (mMaxItemId == -1) { @@ -498,6 +504,18 @@ public class LauncherProvider extends ContentProvider { } } + private boolean tableExists(String tableName) { + Cursor c = getReadableDatabase().query( + true, "sqlite_master", new String[] {"tbl_name"}, + "tbl_name = ?", new String[] {tableName}, + null, null, null, null, null); + try { + return c.getCount() > 0; + } finally { + c.close(); + } + } + public boolean wasNewDbCreated() { return mNewDbCreated; } @@ -510,11 +528,45 @@ public class LauncherProvider extends ContentProvider { mMaxScreenId = 0; mNewDbCreated = true; + addFavoritesTable(db, false); + addWorkspacesTable(db, false); + + // Database was just created, so wipe any previous widgets + if (mAppWidgetHost != null) { + mAppWidgetHost.deleteHost(); + + /** + * Send notification that we've deleted the {@link AppWidgetHost}, + * probably as part of the initial database creation. The receiver may + * want to re-call {@link AppWidgetHost#startListening()} to ensure + * callbacks are correctly set. + */ + new MainThreadExecutor().execute(new Runnable() { + + @Override + public void run() { + if (mListener != null) { + mListener.onAppWidgetHostReset(); + } + } + }); + } + + // Fresh and clean launcher DB. + mMaxItemId = initializeMaxItemId(db); + setFlagEmptyDbCreated(); + + // When a new DB is created, remove all previously stored managed profile information. + ManagedProfileHeuristic.processAllUsers(Collections.<UserHandleCompat>emptyList(), mContext); + } + + private void addFavoritesTable(SQLiteDatabase db, boolean optional) { UserManagerCompat userManager = UserManagerCompat.getInstance(mContext); long userSerialNumber = userManager.getSerialNumberForUser( UserHandleCompat.myUserHandle()); + String ifNotExists = optional ? " IF NOT EXISTS " : ""; - db.execSQL("CREATE TABLE favorites (" + + db.execSQL("CREATE TABLE " + ifNotExists + TABLE_FAVORITES + " (" + "_id INTEGER PRIMARY KEY," + "title TEXT," + "intent TEXT," + @@ -540,39 +592,11 @@ public class LauncherProvider extends ContentProvider { "rank INTEGER NOT NULL DEFAULT 0," + "options INTEGER NOT NULL DEFAULT 0" + ");"); - addWorkspacesTable(db); - - // Database was just created, so wipe any previous widgets - if (mAppWidgetHost != null) { - mAppWidgetHost.deleteHost(); - - /** - * Send notification that we've deleted the {@link AppWidgetHost}, - * probably as part of the initial database creation. The receiver may - * want to re-call {@link AppWidgetHost#startListening()} to ensure - * callbacks are correctly set. - */ - new MainThreadExecutor().execute(new Runnable() { - - @Override - public void run() { - if (mListener != null) { - mListener.onAppWidgetHostReset(); - } - } - }); - } - - // Fresh and clean launcher DB. - mMaxItemId = initializeMaxItemId(db); - setFlagEmptyDbCreated(); - - // When a new DB is created, remove all previously stored managed profile information. - ManagedProfileHeuristic.processAllUsers(Collections.<UserHandleCompat>emptyList(), mContext); } - private void addWorkspacesTable(SQLiteDatabase db) { - db.execSQL("CREATE TABLE " + TABLE_WORKSPACE_SCREENS + " (" + + private void addWorkspacesTable(SQLiteDatabase db, boolean optional) { + String ifNotExists = optional ? " IF NOT EXISTS " : ""; + db.execSQL("CREATE TABLE " + ifNotExists + TABLE_WORKSPACE_SCREENS + " (" + LauncherSettings.WorkspaceScreens._ID + " INTEGER PRIMARY KEY," + LauncherSettings.WorkspaceScreens.SCREEN_RANK + " INTEGER," + LauncherSettings.ChangeLogColumns.MODIFIED + " INTEGER NOT NULL DEFAULT 0" + @@ -632,7 +656,7 @@ public class LauncherProvider extends ContentProvider { // With the new shrink-wrapped and re-orderable workspaces, it makes sense // to persist workspace screens and their relative order. mMaxScreenId = 0; - addWorkspacesTable(db); + addWorkspacesTable(db, false); } case 13: { db.beginTransaction(); @@ -828,7 +852,7 @@ public class LauncherProvider extends ContentProvider { } db.execSQL("DROP TABLE IF EXISTS " + TABLE_WORKSPACE_SCREENS); - addWorkspacesTable(db); + addWorkspacesTable(db, false); // Add all screen ids back int total = sortedIDs.size(); @@ -926,10 +950,6 @@ public class LauncherProvider extends ContentProvider { return dbInsertAndCheck(this, db, TABLE_FAVORITES, null, values); } - public void updateMaxItemId(long id) { - mMaxItemId = id + 1; - } - public void checkId(String table, ContentValues values) { long id = values.getAsLong(LauncherSettings.BaseLauncherColumns._ID); if (table == LauncherProvider.TABLE_WORKSPACE_SCREENS) { |