summaryrefslogtreecommitdiffstats
path: root/src/com/android/launcher3/provider
diff options
context:
space:
mode:
authorSunny Goyal <sunnygoyal@google.com>2016-06-10 12:22:04 -0700
committerSunny Goyal <sunnygoyal@google.com>2016-06-15 10:03:12 -0700
commita9e2f5abb3c21d9721939c625ffb0caabb34e8d9 (patch)
treed9ac34c73a79fd9d59b782ba42b96f84edd9882a /src/com/android/launcher3/provider
parentb25b2c41c2fa277e16d708ad827e283efcb86452 (diff)
downloadandroid_packages_apps_Trebuchet-a9e2f5abb3c21d9721939c625ffb0caabb34e8d9.tar.gz
android_packages_apps_Trebuchet-a9e2f5abb3c21d9721939c625ffb0caabb34e8d9.tar.bz2
android_packages_apps_Trebuchet-a9e2f5abb3c21d9721939c625ffb0caabb34e8d9.zip
Adding a DB update path to handle the QSB position change
> Renamed the id of 1st screen to 0 and making space for the QSB by running the grid migration task. > Added a feature flag to easily disable the QSB-in-workspace behavior Change-Id: Ie3369f0d4433d916e9d6215d414770d4333f3e26
Diffstat (limited to 'src/com/android/launcher3/provider')
-rw-r--r--src/com/android/launcher3/provider/LauncherDbUtils.java122
-rw-r--r--src/com/android/launcher3/provider/LossyScreenMigrationTask.java108
2 files changed, 230 insertions, 0 deletions
diff --git a/src/com/android/launcher3/provider/LauncherDbUtils.java b/src/com/android/launcher3/provider/LauncherDbUtils.java
new file mode 100644
index 000000000..faa5fad12
--- /dev/null
+++ b/src/com/android/launcher3/provider/LauncherDbUtils.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2016 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 com.android.launcher3.provider;
+
+import android.content.ContentValues;
+import android.database.Cursor;
+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;
+
+/**
+ * A set of utility methods for Launcher DB used for DB updates and migration.
+ */
+public class LauncherDbUtils {
+
+ private static final String TAG = "LauncherDbUtils";
+
+ /**
+ * Makes the first screen as screen 0 (if screen 0 already exists,
+ * renames it to some other number).
+ * If the first row of screen 0 is non empty, runs a 'lossy' GridMigrationTask to clear
+ * the first row. The items in the first screen are moved and resized but the carry-forward
+ * items are simply deleted.
+ */
+ public static boolean prepareScreenZeroToHostQsb(SQLiteDatabase db) {
+ db.beginTransaction();
+ try {
+ // Get the existing screens
+ ArrayList<Long> screenIds = getScreenIdsFromCursor(db.query(WorkspaceScreens.TABLE_NAME,
+ null, null, null, null, null, WorkspaceScreens.SCREEN_RANK));
+
+ if (screenIds.isEmpty()) {
+ // No update needed
+ return true;
+ }
+ if (screenIds.get(0) != 0) {
+ // First screen is not 0, we need to rename screens
+ if (screenIds.indexOf(0L) > -1) {
+ // There is already a screen 0. First rename it to a differen screen.
+ long newScreenId = 1;
+ while (screenIds.indexOf(newScreenId) > -1) newScreenId++;
+ renameScreen(db, 0, newScreenId);
+ }
+
+ // Rename the first screen to 0.
+ renameScreen(db, screenIds.get(0), 0);
+ }
+
+ // 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;
+ }
+ }
+
+ LauncherAppState app = LauncherAppState.getInstance();
+ new LossyScreenMigrationTask(app.getContext(), app.getInvariantDeviceProfile(), db)
+ .migrateScreen0();
+ db.setTransactionSuccessful();
+ return true;
+ } catch (Exception e) {
+ Log.e(TAG, "Failed to update workspace size", e);
+ return false;
+ } finally {
+ db.endTransaction();
+ }
+ }
+
+ private static void renameScreen(SQLiteDatabase db, long oldScreen, long newScreen) {
+ String[] whereParams = new String[] { Long.toString(oldScreen) };
+
+ ContentValues values = new ContentValues();
+ values.put(WorkspaceScreens._ID, newScreen);
+ db.update(WorkspaceScreens.TABLE_NAME, values, "_id = ?", whereParams);
+
+ values.clear();
+ values.put(Favorites.SCREEN, newScreen);
+ db.update(Favorites.TABLE_NAME, values, "container = -100 and screen = ?", whereParams);
+ }
+
+ /**
+ * 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);
+ }
+ }
+ } finally {
+ sc.close();
+ }
+ return screenIds;
+ }
+}
diff --git a/src/com/android/launcher3/provider/LossyScreenMigrationTask.java b/src/com/android/launcher3/provider/LossyScreenMigrationTask.java
new file mode 100644
index 000000000..bb6ed0de9
--- /dev/null
+++ b/src/com/android/launcher3/provider/LossyScreenMigrationTask.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2016 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 com.android.launcher3.provider;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.graphics.Point;
+import android.util.Log;
+
+import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.LauncherSettings.Favorites;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.Workspace;
+import com.android.launcher3.model.GridSizeMigrationTask;
+import com.android.launcher3.util.LongArrayMap;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * An extension of {@link GridSizeMigrationTask} which migrates only one screen and
+ * deletes all carry-forward items.
+ */
+public class LossyScreenMigrationTask extends GridSizeMigrationTask {
+
+ private final SQLiteDatabase mDb;
+
+ private final LongArrayMap<DbEntry> mOriginalItems;
+ private final LongArrayMap<DbEntry> mUpdates;
+
+ protected LossyScreenMigrationTask(
+ Context context, InvariantDeviceProfile idp, SQLiteDatabase db) {
+ // Decrease the rows count by 1
+ super(context, idp, getValidPackages(context), new HashMap<String, Point>(),
+ new Point(idp.numColumns, idp.numRows + 1), new Point(idp.numColumns, idp.numRows));
+
+ mDb = db;
+ mOriginalItems = new LongArrayMap<>();
+ mUpdates = new LongArrayMap<>();
+ }
+
+ @Override
+ protected Cursor queryWorkspace(String[] columns, String where) {
+ return mDb.query(Favorites.TABLE_NAME, columns, where, null, null, null, null);
+ }
+
+ @Override
+ protected void update(DbEntry item) {
+ mUpdates.put(item.id, item.copy());
+ }
+
+ @Override
+ protected ArrayList<DbEntry> loadWorkspaceEntries(long screen) {
+ ArrayList<DbEntry> result = super.loadWorkspaceEntries(screen);
+ for (DbEntry entry : result) {
+ mOriginalItems.put(entry.id, entry.copy());
+
+ // Shift all items by 1 in y direction and mark them for update.
+ entry.cellY++;
+ mUpdates.put(entry.id, entry.copy());
+ }
+
+ return result;
+ }
+
+ public void migrateScreen0() {
+ migrateScreen(Workspace.FIRST_SCREEN_ID);
+
+ ContentValues tempValues = new ContentValues();
+ for (DbEntry update : mUpdates) {
+ DbEntry org = mOriginalItems.get(update.id);
+
+ if (org.cellX != update.cellX || org.cellY != update.cellY
+ || org.spanX != update.spanX || org.spanY != update.spanY) {
+ tempValues.clear();
+ update.addToContentValues(tempValues);
+ mDb.update(Favorites.TABLE_NAME, tempValues, "_id = ?",
+ new String[] {Long.toString(update.id)});
+ }
+ }
+
+ // Delete any carry over items as we are only migration a single screen.
+ for (DbEntry entry : mCarryOver) {
+ mEntryToRemove.add(entry.id);
+ }
+
+ if (!mEntryToRemove.isEmpty()) {
+ mDb.delete(Favorites.TABLE_NAME,
+ Utilities.createDbSelectionQuery(Favorites._ID, mEntryToRemove), null);
+ }
+ }
+}