Revert "Revert "Revert "Changing GridMigrationTask to use ModelDbController directly"""

This reverts commit 8d9e468dbb.

Reason for revert: b/281179368

Change-Id: Ibfc5329f72cdbcb37d01a8bf3dac2ba0724b9faf
This commit is contained in:
Sunny Goyal
2023-05-06 18:18:07 +00:00
committed by Android (Google) Code Review
parent 8d9e468dbb
commit 3772b246c2
18 changed files with 505 additions and 448 deletions

View File

@@ -19,10 +19,11 @@ import static android.util.Base64.NO_PADDING;
import static android.util.Base64.NO_WRAP;
import static com.android.launcher3.DefaultLayoutParser.RES_PARTNER_DEFAULT_LAYOUT;
import static com.android.launcher3.LauncherSettings.Favorites.addTableToDb;
import static com.android.launcher3.LauncherSettings.Settings.LAYOUT_DIGEST_KEY;
import static com.android.launcher3.LauncherSettings.Settings.LAYOUT_DIGEST_LABEL;
import static com.android.launcher3.LauncherSettings.Settings.LAYOUT_DIGEST_TAG;
import static com.android.launcher3.model.DatabaseHelper.EMPTY_DATABASE_CREATED;
import static com.android.launcher3.provider.LauncherDbUtils.copyTable;
import static com.android.launcher3.provider.LauncherDbUtils.tableExists;
import android.app.blob.BlobHandle;
@@ -30,6 +31,7 @@ import android.app.blob.BlobStoreManager;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
import android.content.res.Resources;
@@ -41,7 +43,6 @@ import android.os.Binder;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.text.TextUtils;
@@ -53,22 +54,18 @@ import androidx.annotation.WorkerThread;
import com.android.launcher3.AutoInstallsLayout;
import com.android.launcher3.AutoInstallsLayout.SourceResources;
import com.android.launcher3.ConstantItem;
import com.android.launcher3.DefaultLayoutParser;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherFiles;
import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.Utilities;
import com.android.launcher3.pm.UserCache;
import com.android.launcher3.provider.LauncherDbUtils;
import com.android.launcher3.provider.LauncherDbUtils.SQLiteTransaction;
import com.android.launcher3.provider.RestoreDbTask;
import com.android.launcher3.util.IOUtils;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.MainThreadInitializedObject.SandboxContext;
import com.android.launcher3.util.Partner;
import com.android.launcher3.widget.LauncherWidgetHolder;
@@ -76,6 +73,7 @@ import org.xmlpull.v1.XmlPullParser;
import java.io.InputStream;
import java.io.StringReader;
import java.util.function.Supplier;
/**
* Utility class which maintains an instance of Launcher database and provides utility methods
@@ -84,8 +82,6 @@ import java.io.StringReader;
public class ModelDbController {
private static final String TAG = "LauncherProvider";
private static final String EMPTY_DATABASE_CREATED = "EMPTY_DATABASE_CREATED";
protected DatabaseHelper mOpenHelper;
private final Context mContext;
@@ -96,36 +92,26 @@ public class ModelDbController {
private synchronized void createDbIfNotExists() {
if (mOpenHelper == null) {
mOpenHelper = createDatabaseHelper(false /* forMigration */);
RestoreDbTask.restoreIfNeeded(mContext, this);
mOpenHelper = DatabaseHelper.createDatabaseHelper(
mContext, false /* forMigration */);
RestoreDbTask.restoreIfNeeded(mContext, mOpenHelper);
}
}
protected DatabaseHelper createDatabaseHelper(boolean forMigration) {
boolean isSandbox = mContext instanceof SandboxContext;
String dbName = isSandbox ? null : InvariantDeviceProfile.INSTANCE.get(mContext).dbFile;
// Set the flag for empty DB
Runnable onEmptyDbCreateCallback = forMigration ? () -> { }
: () -> LauncherPrefs.get(mContext).putSync(getEmptyDbCreatedKey(dbName).to(true));
DatabaseHelper databaseHelper = new DatabaseHelper(mContext, dbName,
this::getSerialNumberForUser, onEmptyDbCreateCallback);
// 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(databaseHelper.getReadableDatabase(), Favorites.TABLE_NAME)) {
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.
addTableToDb(databaseHelper.getWritableDatabase(),
getSerialNumberForUser(Process.myUserHandle()),
true /* optional */);
private synchronized boolean prepForMigration(String dbFile, String targetTableName,
Supplier<DatabaseHelper> src, Supplier<DatabaseHelper> dst) {
if (TextUtils.equals(dbFile, mOpenHelper.getDatabaseName())) {
Log.e(TAG, "prepForMigration - target db is same as current: " + dbFile);
return false;
}
databaseHelper.mHotseatRestoreTableExists = tableExists(
databaseHelper.getReadableDatabase(), Favorites.HYBRID_HOTSEAT_BACKUP_TABLE);
databaseHelper.initIds();
return databaseHelper;
final DatabaseHelper helper = src.get();
mOpenHelper = dst.get();
copyTable(helper.getReadableDatabase(), Favorites.TABLE_NAME,
mOpenHelper.getWritableDatabase(), targetTableName, mContext);
helper.close();
return true;
}
/**
@@ -281,40 +267,42 @@ public class ModelDbController {
}
/**
* Migrates the DB if needed, and returns false if the migration failed
* and DB needs to be cleared.
* @return true if migration was success or ignored, false if migration failed
* and the DB should be reset.
* Updates the current DB and copies all the existing data to the temp table
* @param dbFile name of the target db file name
*/
public boolean migrateGridIfNeeded() {
InvariantDeviceProfile idp = LauncherAppState.getIDP(mContext);
if (!GridSizeMigrationUtil.needsToMigrate(mContext, idp)) {
return true;
}
String targetDbName = new DeviceGridState(idp).getDbFile();
if (TextUtils.equals(targetDbName, mOpenHelper.getDatabaseName())) {
Log.e(TAG, "migrateGridIfNeeded - target db is same as current: " + targetDbName);
return false;
}
DatabaseHelper oldHelper = mOpenHelper;
mOpenHelper = (mContext instanceof SandboxContext) ? oldHelper
: createDatabaseHelper(true /* forMigration */);
try {
return GridSizeMigrationUtil.migrateGridIfNeeded(mContext, idp, mOpenHelper,
oldHelper.getWritableDatabase());
} finally {
if (mOpenHelper != oldHelper) {
oldHelper.close();
}
}
@WorkerThread
public boolean updateCurrentOpenHelper(String dbFile) {
createDbIfNotExists();
return prepForMigration(
dbFile,
Favorites.TMP_TABLE,
() -> mOpenHelper,
() -> DatabaseHelper.createDatabaseHelper(
mContext, true /* forMigration */));
}
/**
* Returns the underlying model database
* Returns the current DatabaseHelper.
* Only for tests
*/
public SQLiteDatabase getDb() {
@WorkerThread
public DatabaseHelper getDatabaseHelper() {
createDbIfNotExists();
return mOpenHelper.getWritableDatabase();
return mOpenHelper;
}
/**
* Prepares the DB for preview by copying all existing data to preview table
*/
@WorkerThread
public boolean prepareForPreview(String dbFile) {
createDbIfNotExists();
return prepForMigration(
dbFile,
Favorites.PREVIEW_TABLE_NAME,
() -> DatabaseHelper.createDatabaseHelper(
mContext, dbFile, true /* forMigration */),
() -> mOpenHelper);
}
private void onAddOrDeleteOp(SQLiteDatabase db) {
@@ -357,7 +345,8 @@ public class ModelDbController {
}
private void clearFlagEmptyDbCreated() {
LauncherPrefs.get(mContext).removeSync(getEmptyDbCreatedKey(mOpenHelper.getDatabaseName()));
LauncherPrefs.getPrefs(mContext).edit()
.remove(mOpenHelper.getKey(EMPTY_DATABASE_CREATED)).commit();
}
/**
@@ -370,8 +359,9 @@ public class ModelDbController {
@WorkerThread
public synchronized void loadDefaultFavoritesIfNecessary() {
createDbIfNotExists();
SharedPreferences sp = LauncherPrefs.getPrefs(mContext);
if (LauncherPrefs.get(mContext).get(getEmptyDbCreatedKey(mOpenHelper.getDatabaseName()))) {
if (sp.getBoolean(mOpenHelper.getKey(EMPTY_DATABASE_CREATED), false)) {
Log.d(TAG, "loading default workspace");
LauncherWidgetHolder widgetHolder = mOpenHelper.newLauncherWidgetHolder();
@@ -489,27 +479,4 @@ public class ModelDbController {
return new DefaultLayoutParser(mContext, widgetHolder,
mOpenHelper, mContext.getResources(), defaultLayout);
}
/**
* Re-composite given key in respect to database. If the current db is
* {@link LauncherFiles#LAUNCHER_DB}, return the key as-is. Otherwise append the db name to
* given key. e.g. consider key="EMPTY_DATABASE_CREATED", dbName="minimal.db", the returning
* string will be "EMPTY_DATABASE_CREATED@minimal.db".
*/
private ConstantItem<Boolean> getEmptyDbCreatedKey(String dbName) {
if (mContext instanceof SandboxContext) {
return LauncherPrefs.nonRestorableItem(EMPTY_DATABASE_CREATED,
false /* default value */, false /* boot aware */);
}
String key = TextUtils.equals(dbName, LauncherFiles.LAUNCHER_DB)
? EMPTY_DATABASE_CREATED : EMPTY_DATABASE_CREATED + "@" + dbName;
return LauncherPrefs.backedUpItem(key, false /* default value */, false /* boot aware */);
}
/**
* Returns the serial number for the provided user
*/
public long getSerialNumberForUser(UserHandle user) {
return UserCache.INSTANCE.get(mContext).getSerialNumberForUser(user);
}
}