1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.launcher3.provider;
18 
19 import android.content.ContentValues;
20 import android.content.Context;
21 import android.database.Cursor;
22 import android.database.sqlite.SQLiteDatabase;
23 import android.graphics.Point;
24 
25 import com.android.launcher3.InvariantDeviceProfile;
26 import com.android.launcher3.LauncherSettings.Favorites;
27 import com.android.launcher3.Utilities;
28 import com.android.launcher3.Workspace;
29 import com.android.launcher3.model.GridSizeMigrationTask;
30 import com.android.launcher3.util.IntSparseArrayMap;
31 
32 import java.util.ArrayList;
33 
34 /**
35  * An extension of {@link GridSizeMigrationTask} which migrates only one screen and
36  * deletes all carry-forward items.
37  */
38 public class LossyScreenMigrationTask extends GridSizeMigrationTask {
39 
40     private final IntSparseArrayMap<DbEntry> mOriginalItems;
41     private final IntSparseArrayMap<DbEntry> mUpdates;
42 
LossyScreenMigrationTask( Context context, InvariantDeviceProfile idp, SQLiteDatabase db)43     protected LossyScreenMigrationTask(
44             Context context, InvariantDeviceProfile idp, SQLiteDatabase db) {
45         // Decrease the rows count by 1
46         super(context, db, getValidPackages(context),
47                 new Point(idp.numColumns, idp.numRows + 1),
48                 new Point(idp.numColumns, idp.numRows));
49 
50         mOriginalItems = new IntSparseArrayMap<>();
51         mUpdates = new IntSparseArrayMap<>();
52     }
53 
54     @Override
update(DbEntry item)55     protected void update(DbEntry item) {
56         mUpdates.put(item.id, item.copy());
57     }
58 
59     @Override
loadWorkspaceEntries(int screen)60     protected ArrayList<DbEntry> loadWorkspaceEntries(int screen) {
61         ArrayList<DbEntry> result = super.loadWorkspaceEntries(screen);
62         for (DbEntry entry : result) {
63             mOriginalItems.put(entry.id, entry.copy());
64 
65             // Shift all items by 1 in y direction and mark them for update.
66             entry.cellY++;
67             mUpdates.put(entry.id, entry.copy());
68         }
69 
70         return result;
71     }
72 
migrateScreen0()73     public void migrateScreen0() {
74         migrateScreen(Workspace.FIRST_SCREEN_ID);
75 
76         ContentValues tempValues = new ContentValues();
77         for (DbEntry update : mUpdates) {
78             DbEntry org = mOriginalItems.get(update.id);
79 
80             if (org.cellX != update.cellX || org.cellY != update.cellY
81                     || org.spanX != update.spanX || org.spanY != update.spanY) {
82                 tempValues.clear();
83                 update.addToContentValues(tempValues);
84                 mDb.update(Favorites.TABLE_NAME, tempValues, "_id = ?",
85                         new String[] {Integer.toString(update.id)});
86             }
87         }
88 
89         // Delete any carry over items as we are only migration a single screen.
90         for (DbEntry entry : mCarryOver) {
91             mEntryToRemove.add(entry.id);
92         }
93 
94         if (!mEntryToRemove.isEmpty()) {
95             mDb.delete(Favorites.TABLE_NAME,
96                     Utilities.createDbSelectionQuery(Favorites._ID, mEntryToRemove), null);
97         }
98     }
99 }
100