summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/com/android/launcher3/LauncherProvider.java173
-rw-r--r--src/com/android/launcher3/provider/LauncherDbUtils.java61
-rw-r--r--src/com/android/launcher3/provider/RestoreDbTask.java8
3 files changed, 101 insertions, 141 deletions
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index 03ca24226..ca789d408 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -57,6 +57,7 @@ import com.android.launcher3.dynamicui.ExtractionUtils;
import com.android.launcher3.graphics.IconShapeOverride;
import com.android.launcher3.logging.FileLog;
import com.android.launcher3.provider.LauncherDbUtils;
+import com.android.launcher3.provider.LauncherDbUtils.SQLiteTransaction;
import com.android.launcher3.provider.RestoreDbTask;
import com.android.launcher3.util.ManagedProfileHeuristic;
import com.android.launcher3.util.NoLocaleSqliteContext;
@@ -70,6 +71,7 @@ import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
+import java.util.LinkedHashSet;
public class LauncherProvider extends ContentProvider {
private static final String TAG = "LauncherProvider";
@@ -303,8 +305,7 @@ public class LauncherProvider extends ContentProvider {
SqlArguments args = new SqlArguments(uri);
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- db.beginTransaction();
- try {
+ try (SQLiteTransaction t = new SQLiteTransaction(db)) {
int numValues = values.length;
for (int i = 0; i < numValues; i++) {
addModifiedTime(values[i]);
@@ -312,9 +313,7 @@ public class LauncherProvider extends ContentProvider {
return 0;
}
}
- db.setTransactionSuccessful();
- } finally {
- db.endTransaction();
+ t.commit();
}
notifyListeners();
@@ -326,15 +325,11 @@ public class LauncherProvider extends ContentProvider {
public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
throws OperationApplicationException {
createDbIfNotExists();
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- db.beginTransaction();
- try {
+ try (SQLiteTransaction t = new SQLiteTransaction(mOpenHelper.getWritableDatabase())) {
ContentProviderResult[] result = super.applyBatch(operations);
- db.setTransactionSuccessful();
+ t.commit();
reloadLauncherIfExternal();
return result;
- } finally {
- db.endTransaction();
}
}
@@ -440,31 +435,26 @@ public class LauncherProvider extends ContentProvider {
private ArrayList<Long> deleteEmptyFolders() {
ArrayList<Long> folderIds = new ArrayList<>();
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- db.beginTransaction();
- try {
+ try (SQLiteTransaction t = new SQLiteTransaction(db)) {
// Select folders whose id do not match any container value.
String selection = LauncherSettings.Favorites.ITEM_TYPE + " = "
+ LauncherSettings.Favorites.ITEM_TYPE_FOLDER + " AND "
+ LauncherSettings.Favorites._ID + " NOT IN (SELECT " +
LauncherSettings.Favorites.CONTAINER + " FROM "
+ Favorites.TABLE_NAME + ")";
- Cursor c = db.query(Favorites.TABLE_NAME,
+ try (Cursor c = db.query(Favorites.TABLE_NAME,
new String[] {LauncherSettings.Favorites._ID},
- selection, null, null, null, null);
- while (c.moveToNext()) {
- folderIds.add(c.getLong(0));
+ selection, null, null, null, null)) {
+ LauncherDbUtils.iterateCursor(c, 0, folderIds);
}
- c.close();
if (!folderIds.isEmpty()) {
db.delete(Favorites.TABLE_NAME, Utilities.createDbSelectionQuery(
LauncherSettings.Favorites._ID, folderIds), null);
}
- db.setTransactionSuccessful();
+ t.commit();
} catch (SQLException ex) {
Log.e(TAG, ex.getMessage(), ex);
folderIds.clear();
- } finally {
- db.endTransaction();
}
return folderIds;
}
@@ -718,15 +708,12 @@ public class LauncherProvider extends ContentProvider {
if (oldVersion != DATA_VERSION) {
// Only run the data upgrade path for an existing db.
if (!Utilities.getPrefs(mContext).getBoolean(EMPTY_DATABASE_CREATED, false)) {
- db.beginTransaction();
- try {
+ try (SQLiteTransaction t = new SQLiteTransaction(db)) {
onDataUpgrade(db, oldVersion);
- db.setTransactionSuccessful();
+ t.commit();
} catch (Exception e) {
Log.d(TAG, "Error updating data version, ignoring", e);
return;
- } finally {
- db.endTransaction();
}
}
prefs.edit().putInt(PREF_KEY_DATA_VERISON, DATA_VERSION).apply();
@@ -773,35 +760,29 @@ public class LauncherProvider extends ContentProvider {
addWorkspacesTable(db, false);
}
case 13: {
- db.beginTransaction();
- try {
+ try (SQLiteTransaction t = new SQLiteTransaction(db)) {
// Insert new column for holding widget provider name
db.execSQL("ALTER TABLE favorites " +
"ADD COLUMN appWidgetProvider TEXT;");
- db.setTransactionSuccessful();
+ t.commit();
} catch (SQLException ex) {
Log.e(TAG, ex.getMessage(), ex);
// Old version remains, which means we wipe old data
break;
- } finally {
- db.endTransaction();
}
}
case 14: {
- db.beginTransaction();
- try {
+ try (SQLiteTransaction t = new SQLiteTransaction(db)) {
// Insert new column for holding update timestamp
db.execSQL("ALTER TABLE favorites " +
"ADD COLUMN modified INTEGER NOT NULL DEFAULT 0;");
db.execSQL("ALTER TABLE workspaceScreens " +
"ADD COLUMN modified INTEGER NOT NULL DEFAULT 0;");
- db.setTransactionSuccessful();
+ t.commit();
} catch (SQLException ex) {
Log.e(TAG, ex.getMessage(), ex);
// Old version remains, which means we wipe old data
break;
- } finally {
- db.endTransaction();
}
}
case 15: {
@@ -884,14 +865,11 @@ public class LauncherProvider extends ContentProvider {
* Clears all the data for a fresh start.
*/
public void createEmptyDB(SQLiteDatabase db) {
- db.beginTransaction();
- try {
+ try (SQLiteTransaction t = new SQLiteTransaction(db)) {
db.execSQL("DROP TABLE IF EXISTS " + Favorites.TABLE_NAME);
db.execSQL("DROP TABLE IF EXISTS " + WorkspaceScreens.TABLE_NAME);
onCreate(db);
- db.setTransactionSuccessful();
- } finally {
- db.endTransaction();
+ t.commit();
}
}
@@ -911,28 +889,26 @@ public class LauncherProvider extends ContentProvider {
Log.e(TAG, "getAppWidgetIds not supported", e);
return;
}
- try {
- Cursor c = db.query(Favorites.TABLE_NAME,
- new String[] {Favorites.APPWIDGET_ID },
- "itemType=" + Favorites.ITEM_TYPE_APPWIDGET, null, null, null, null);
- HashSet<Integer> validWidgets = new HashSet<>();
+ final HashSet<Integer> validWidgets = new HashSet<>();
+ try (Cursor c = db.query(Favorites.TABLE_NAME,
+ new String[] {Favorites.APPWIDGET_ID },
+ "itemType=" + Favorites.ITEM_TYPE_APPWIDGET, null, null, null, null)) {
while (c.moveToNext()) {
validWidgets.add(c.getInt(0));
}
- c.close();
-
- for (int widgetId : allWidgets) {
- if (!validWidgets.contains(widgetId)) {
- try {
- FileLog.d(TAG, "Deleting invalid widget " + widgetId);
- host.deleteAppWidgetId(widgetId);
- } catch (RuntimeException e) {
- // Ignore
- }
- }
- }
} catch (SQLException ex) {
Log.w(TAG, "Error getting widgets list", ex);
+ return;
+ }
+ for (int widgetId : allWidgets) {
+ if (!validWidgets.contains(widgetId)) {
+ try {
+ FileLog.d(TAG, "Deleting invalid widget " + widgetId);
+ host.deleteAppWidgetId(widgetId);
+ } catch (RuntimeException e) {
+ // Ignore
+ }
+ }
}
}
@@ -941,22 +917,16 @@ public class LauncherProvider extends ContentProvider {
* launcher activity target with {@link Favorites#ITEM_TYPE_APPLICATION}.
*/
@Thunk void convertShortcutsToLauncherActivities(SQLiteDatabase db) {
- db.beginTransaction();
- Cursor c = null;
- SQLiteStatement updateStmt = null;
-
- try {
- // Only consider the primary user as other users can't have a shortcut.
- long userSerial = getDefaultUserSerial();
- c = db.query(Favorites.TABLE_NAME, new String[] {
- Favorites._ID,
- Favorites.INTENT,
- }, "itemType=" + Favorites.ITEM_TYPE_SHORTCUT + " AND profileId=" + userSerial,
- null, null, null, null);
-
- updateStmt = db.compileStatement("UPDATE favorites SET itemType="
- + Favorites.ITEM_TYPE_APPLICATION + " WHERE _id=?");
-
+ try (SQLiteTransaction t = new SQLiteTransaction(db);
+ // Only consider the primary user as other users can't have a shortcut.
+ Cursor c = db.query(Favorites.TABLE_NAME,
+ new String[] { Favorites._ID, Favorites.INTENT},
+ "itemType=" + Favorites.ITEM_TYPE_SHORTCUT +
+ " AND profileId=" + getDefaultUserSerial(),
+ null, null, null, null);
+ SQLiteStatement updateStmt = db.compileStatement("UPDATE favorites SET itemType="
+ + Favorites.ITEM_TYPE_APPLICATION + " WHERE _id=?")
+ ) {
final int idIndex = c.getColumnIndexOrThrow(Favorites._ID);
final int intentIndex = c.getColumnIndexOrThrow(Favorites.INTENT);
@@ -978,17 +948,9 @@ public class LauncherProvider extends ContentProvider {
updateStmt.bindLong(1, id);
updateStmt.executeUpdateDelete();
}
- db.setTransactionSuccessful();
+ t.commit();
} catch (SQLException ex) {
Log.w(TAG, "Error deduping shortcuts", ex);
- } finally {
- db.endTransaction();
- if (c != null) {
- c.close();
- }
- if (updateStmt != null) {
- updateStmt.close();
- }
}
}
@@ -996,26 +958,17 @@ public class LauncherProvider extends ContentProvider {
* Recreates workspace table and migrates data to the new table.
*/
public boolean recreateWorkspaceTable(SQLiteDatabase db) {
- db.beginTransaction();
- try {
- Cursor c = db.query(WorkspaceScreens.TABLE_NAME,
+ try (SQLiteTransaction t = new SQLiteTransaction(db)) {
+ final ArrayList<Long> sortedIDs;
+
+ try (Cursor c = db.query(WorkspaceScreens.TABLE_NAME,
new String[] {LauncherSettings.WorkspaceScreens._ID},
null, null, null, null,
- LauncherSettings.WorkspaceScreens.SCREEN_RANK);
- ArrayList<Long> sortedIDs = new ArrayList<Long>();
- long maxId = 0;
- try {
- while (c.moveToNext()) {
- Long id = c.getLong(0);
- if (!sortedIDs.contains(id)) {
- sortedIDs.add(id);
- maxId = Math.max(maxId, id);
- }
- }
- } finally {
- c.close();
+ LauncherSettings.WorkspaceScreens.SCREEN_RANK)) {
+ // Use LinkedHashSet so that ordering is preserved
+ sortedIDs = new ArrayList<>(
+ LauncherDbUtils.iterateCursor(c, 0, new LinkedHashSet<Long>()));
}
-
db.execSQL("DROP TABLE IF EXISTS " + WorkspaceScreens.TABLE_NAME);
addWorkspacesTable(db, false);
@@ -1028,21 +981,18 @@ public class LauncherProvider extends ContentProvider {
addModifiedTime(values);
db.insertOrThrow(WorkspaceScreens.TABLE_NAME, null, values);
}
- db.setTransactionSuccessful();
- mMaxScreenId = maxId;
+ t.commit();
+ mMaxScreenId = sortedIDs.isEmpty() ? 0 : Collections.max(sortedIDs);
} catch (SQLException ex) {
// Old version remains, which means we wipe old data
Log.e(TAG, ex.getMessage(), ex);
return false;
- } finally {
- db.endTransaction();
}
return true;
}
@Thunk boolean updateFolderItemsRank(SQLiteDatabase db, boolean addRankColumn) {
- db.beginTransaction();
- try {
+ try (SQLiteTransaction t = new SQLiteTransaction(db)) {
if (addRankColumn) {
// Insert new column for holding rank
db.execSQL("ALTER TABLE favorites ADD COLUMN rank INTEGER NOT NULL DEFAULT 0;");
@@ -1061,13 +1011,11 @@ public class LauncherProvider extends ContentProvider {
}
c.close();
- db.setTransactionSuccessful();
+ t.commit();
} catch (SQLException ex) {
// Old version remains, which means we wipe old data
Log.e(TAG, ex.getMessage(), ex);
return false;
- } finally {
- db.endTransaction();
}
return true;
}
@@ -1077,16 +1025,13 @@ public class LauncherProvider extends ContentProvider {
}
private boolean addIntegerColumn(SQLiteDatabase db, String columnName, long defaultValue) {
- db.beginTransaction();
- try {
+ try (SQLiteTransaction t = new SQLiteTransaction(db)) {
db.execSQL("ALTER TABLE favorites ADD COLUMN "
+ columnName + " INTEGER NOT NULL DEFAULT " + defaultValue + ";");
- db.setTransactionSuccessful();
+ t.commit();
} catch (SQLException ex) {
Log.e(TAG, ex.getMessage(), ex);
return false;
- } finally {
- db.endTransaction();
}
return true;
}
diff --git a/src/com/android/launcher3/provider/LauncherDbUtils.java b/src/com/android/launcher3/provider/LauncherDbUtils.java
index 175835011..632504060 100644
--- a/src/com/android/launcher3/provider/LauncherDbUtils.java
+++ b/src/com/android/launcher3/provider/LauncherDbUtils.java
@@ -19,15 +19,16 @@ package com.android.launcher3.provider;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
+import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.LauncherSettings.WorkspaceScreens;
-import com.android.launcher3.logging.FileLog;
import java.util.ArrayList;
+import java.util.Collection;
/**
* A set of utility methods for Launcher DB used for DB updates and migration.
@@ -44,8 +45,7 @@ public class LauncherDbUtils {
* items are simply deleted.
*/
public static boolean prepareScreenZeroToHostQsb(Context context, SQLiteDatabase db) {
- db.beginTransaction();
- try {
+ try (SQLiteTransaction t = new SQLiteTransaction(db)) {
// Get the existing screens
ArrayList<Long> screenIds = getScreenIdsFromCursor(db.query(WorkspaceScreens.TABLE_NAME,
null, null, null, null, null, WorkspaceScreens.SCREEN_RANK));
@@ -68,23 +68,19 @@ public class LauncherDbUtils {
}
// Check if the first row is empty
- try (Cursor c = db.query(Favorites.TABLE_NAME, null,
- "container = -100 and screen = 0 and cellY = 0", null, null, null, null)) {
- if (c.getCount() == 0) {
- // First row is empty, no need to migrate.
- return true;
- }
+ if (DatabaseUtils.queryNumEntries(db, Favorites.TABLE_NAME,
+ "container = -100 and screen = 0 and cellY = 0") == 0) {
+ // First row is empty, no need to migrate.
+ return true;
}
new LossyScreenMigrationTask(context, LauncherAppState.getIDP(context), db)
.migrateScreen0();
- db.setTransactionSuccessful();
+ t.commit();
return true;
} catch (Exception e) {
Log.e(TAG, "Failed to update workspace size", e);
return false;
- } finally {
- db.endTransaction();
}
}
@@ -104,19 +100,40 @@ public class LauncherDbUtils {
* Parses the cursor containing workspace screens table and returns the list of screen IDs
*/
public static ArrayList<Long> getScreenIdsFromCursor(Cursor sc) {
- ArrayList<Long> screenIds = new ArrayList<Long>();
try {
- final int idIndex = sc.getColumnIndexOrThrow(WorkspaceScreens._ID);
- while (sc.moveToNext()) {
- try {
- screenIds.add(sc.getLong(idIndex));
- } catch (Exception e) {
- FileLog.d(TAG, "Invalid screen id", e);
- }
- }
+ return iterateCursor(sc,
+ sc.getColumnIndexOrThrow(WorkspaceScreens._ID),
+ new ArrayList<Long>());
} finally {
sc.close();
}
- return screenIds;
+ }
+
+ public static <T extends Collection<Long>> T iterateCursor(Cursor c, int columnIndex, T out) {
+ while (c.moveToNext()) {
+ out.add(c.getLong(columnIndex));
+ }
+ return out;
+ }
+
+ /**
+ * Utility class to simplify managing sqlite transactions
+ */
+ public static class SQLiteTransaction implements AutoCloseable {
+ private final SQLiteDatabase mDb;
+
+ public SQLiteTransaction(SQLiteDatabase db) {
+ mDb = db;
+ db.beginTransaction();
+ }
+
+ public void commit() {
+ mDb.setTransactionSuccessful();
+ }
+
+ @Override
+ public void close() {
+ mDb.endTransaction();
+ }
}
}
diff --git a/src/com/android/launcher3/provider/RestoreDbTask.java b/src/com/android/launcher3/provider/RestoreDbTask.java
index dc85abad7..00e2644a5 100644
--- a/src/com/android/launcher3/provider/RestoreDbTask.java
+++ b/src/com/android/launcher3/provider/RestoreDbTask.java
@@ -27,6 +27,7 @@ import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.ShortcutInfo;
import com.android.launcher3.Utilities;
import com.android.launcher3.logging.FileLog;
+import com.android.launcher3.provider.LauncherDbUtils.SQLiteTransaction;
import com.android.launcher3.util.LogConfig;
import java.io.InvalidObjectException;
@@ -47,16 +48,13 @@ public class RestoreDbTask {
public static boolean performRestore(DatabaseHelper helper) {
SQLiteDatabase db = helper.getWritableDatabase();
- db.beginTransaction();
- try {
+ try (SQLiteTransaction t = new SQLiteTransaction(db)) {
new RestoreDbTask().sanitizeDB(helper, db);
- db.setTransactionSuccessful();
+ t.commit();
return true;
} catch (Exception e) {
FileLog.e(TAG, "Failed to verify db", e);
return false;
- } finally {
- db.endTransaction();
}
}