diff --git a/quickstep/src/com/android/launcher3/model/WellbeingModel.java b/quickstep/src/com/android/launcher3/model/WellbeingModel.java index cc7b712842..810f4e3c59 100644 --- a/quickstep/src/com/android/launcher3/model/WellbeingModel.java +++ b/quickstep/src/com/android/launcher3/model/WellbeingModel.java @@ -43,9 +43,13 @@ import android.util.ArrayMap; import android.util.Log; import androidx.annotation.MainThread; +import androidx.annotation.NonNull; import androidx.annotation.WorkerThread; import com.android.launcher3.BaseDraggingActivity; +import com.android.launcher3.InvariantDeviceProfile; +import com.android.launcher3.LauncherProvider; +import com.android.launcher3.LauncherSettings; import com.android.launcher3.R; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.model.data.ItemInfo; @@ -74,6 +78,9 @@ public final class WellbeingModel { private static final int MSG_PACKAGE_REMOVED = 2; private static final int MSG_FULL_REFRESH = 3; + private static final int UNKNOWN_MINIMAL_DEVICE_STATE = 0; + private static final int IN_MINIMAL_DEVICE = 2; + // Welbeing contract private static final String PATH_ACTIONS = "actions"; private static final String PATH_MINIMAL_DEVICE = "minimal_device"; @@ -84,6 +91,8 @@ public final class WellbeingModel { private static final String EXTRA_MAX_NUM_ACTIONS_SHOWN = "max_num_actions_shown"; private static final String EXTRA_PACKAGES = "packages"; private static final String EXTRA_SUCCESS = "success"; + private static final String EXTRA_MINIMAL_DEVICE_STATE = "minimal_device_state"; + private static final String DB_NAME_MINIMAL_DEVICE = "minimal.db"; public static final MainThreadInitializedObject INSTANCE = new MainThreadInitializedObject<>(WellbeingModel::new); @@ -121,11 +130,12 @@ public final class WellbeingModel { updateWellbeingData(); } else if (uri.getPath().contains(PATH_MINIMAL_DEVICE)) { // Wellbeing reports that minimal device state or config is changed. - updateLauncherModel(); + updateLauncherModel(context); } } }; - FeatureFlags.ENABLE_MINIMAL_DEVICE.addChangeListener(mContext, this::updateLauncherModel); + FeatureFlags.ENABLE_MINIMAL_DEVICE.addChangeListener(mContext, () -> + updateLauncherModel(context)); if (!TextUtils.isEmpty(mWellbeingProviderPkg)) { context.registerReceiver( @@ -170,7 +180,6 @@ public final class WellbeingModel { Log.e(TAG, "Failed to register content observer for " + actionsUri + ": " + e); if (mIsInTest) throw new RuntimeException(e); } - updateWellbeingData(); } @@ -208,10 +217,34 @@ public final class WellbeingModel { mWorkerHandler.sendEmptyMessage(MSG_FULL_REFRESH); } - private void updateLauncherModel() { - if (!FeatureFlags.ENABLE_MINIMAL_DEVICE.get()) return; + private void updateLauncherModel(@NonNull final Context context) { + if (!FeatureFlags.ENABLE_MINIMAL_DEVICE.get()) { + reloadLauncherInNormalMode(context); + return; + } + runWithMinimalDeviceConfigs((bundle) -> { + if (bundle.getInt(EXTRA_MINIMAL_DEVICE_STATE, UNKNOWN_MINIMAL_DEVICE_STATE) + == IN_MINIMAL_DEVICE) { + reloadLauncherInMinimalMode(context); + } else { + reloadLauncherInNormalMode(context); + } + }); + } - // TODO: init Launcher in minimal device / normal mode + private void reloadLauncherInNormalMode(@NonNull final Context context) { + LauncherSettings.Settings.call(context.getContentResolver(), + LauncherSettings.Settings.METHOD_SWITCH_DATABASE, + InvariantDeviceProfile.INSTANCE.get(context).dbFile); + } + + private void reloadLauncherInMinimalMode(@NonNull final Context context) { + final Bundle extras = new Bundle(); + extras.putString(LauncherProvider.KEY_LAYOUT_PROVIDER_AUTHORITY, + mWellbeingProviderPkg + ".api"); + LauncherSettings.Settings.call(context.getContentResolver(), + LauncherSettings.Settings.METHOD_SWITCH_DATABASE, + DB_NAME_MINIMAL_DEVICE, extras); } private Uri.Builder apiBuilder() { @@ -225,6 +258,9 @@ public final class WellbeingModel { */ @WorkerThread private void runWithMinimalDeviceConfigs(Consumer consumer) { + if (!FeatureFlags.ENABLE_MINIMAL_DEVICE.get()) { + return; + } if (DEBUG || mIsInTest) { Log.d(TAG, "runWithMinimalDeviceConfigs() called"); } diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java index e8b5568783..19a314ffe2 100644 --- a/src/com/android/launcher3/LauncherProvider.java +++ b/src/com/android/launcher3/LauncherProvider.java @@ -100,10 +100,12 @@ public class LauncherProvider extends ContentProvider { public static final int SCHEMA_VERSION = 28; public static final String AUTHORITY = BuildConfig.APPLICATION_ID + ".settings"; + public static final String KEY_LAYOUT_PROVIDER_AUTHORITY = "KEY_LAYOUT_PROVIDER_AUTHORITY"; static final String EMPTY_DATABASE_CREATED = "EMPTY_DATABASE_CREATED"; protected DatabaseHelper mOpenHelper; + protected String mProviderAuthority; private long mLastRestoreTimestamp = 0L; @@ -367,7 +369,8 @@ public class LauncherProvider extends ContentProvider { case LauncherSettings.Settings.METHOD_WAS_EMPTY_DB_CREATED : { Bundle result = new Bundle(); result.putBoolean(LauncherSettings.Settings.EXTRA_VALUE, - Utilities.getPrefs(getContext()).getBoolean(EMPTY_DATABASE_CREATED, false)); + Utilities.getPrefs(getContext()).getBoolean( + mOpenHelper.getKey(EMPTY_DATABASE_CREATED), false)); return result; } case LauncherSettings.Settings.METHOD_DELETE_EMPTY_FOLDERS: { @@ -437,6 +440,7 @@ public class LauncherProvider extends ContentProvider { getContext(), true /* forMigration */))); return result; } + return null; } case LauncherSettings.Settings.METHOD_PREP_FOR_PREVIEW: { if (MULTI_DB_GRID_MIRATION_ALGO.get()) { @@ -450,6 +454,23 @@ public class LauncherProvider extends ContentProvider { () -> mOpenHelper)); return result; } + return null; + } + case LauncherSettings.Settings.METHOD_SWITCH_DATABASE: { + if (TextUtils.equals(arg, mOpenHelper.getDatabaseName())) return null; + final DatabaseHelper helper = mOpenHelper; + if (extras == null || !extras.containsKey(KEY_LAYOUT_PROVIDER_AUTHORITY)) { + mProviderAuthority = null; + } else { + mProviderAuthority = extras.getString(KEY_LAYOUT_PROVIDER_AUTHORITY); + } + mOpenHelper = DatabaseHelper.createDatabaseHelper( + getContext(), arg, false /* forMigration */); + helper.close(); + LauncherAppState app = LauncherAppState.getInstanceNoCreate(); + if (app == null) return null; + app.getModel().forceReload(); + return null; } } return null; @@ -492,7 +513,8 @@ public class LauncherProvider extends ContentProvider { } private void clearFlagEmptyDbCreated() { - Utilities.getPrefs(getContext()).edit().remove(EMPTY_DATABASE_CREATED).commit(); + Utilities.getPrefs(getContext()).edit() + .remove(mOpenHelper.getKey(EMPTY_DATABASE_CREATED)).commit(); } /** @@ -505,7 +527,7 @@ public class LauncherProvider extends ContentProvider { synchronized private void loadDefaultFavoritesIfNecessary() { SharedPreferences sp = Utilities.getPrefs(getContext()); - if (sp.getBoolean(EMPTY_DATABASE_CREATED, false)) { + if (sp.getBoolean(mOpenHelper.getKey(EMPTY_DATABASE_CREATED), false)) { Log.d(TAG, "loading default workspace"); AppWidgetHost widgetHost = mOpenHelper.newLauncherWidgetHost(); @@ -553,8 +575,13 @@ public class LauncherProvider extends ContentProvider { */ private AutoInstallsLayout createWorkspaceLoaderFromAppRestriction(AppWidgetHost widgetHost) { Context ctx = getContext(); - String authority = Settings.Secure.getString(ctx.getContentResolver(), - "launcher3.layout.provider"); + final String authority; + if (!TextUtils.isEmpty(mProviderAuthority)) { + authority = mProviderAuthority; + } else { + authority = Settings.Secure.getString(ctx.getContentResolver(), + "launcher3.layout.provider"); + } if (TextUtils.isEmpty(authority)) { return null; } @@ -693,12 +720,26 @@ public class LauncherProvider extends ContentProvider { } } + /** + * 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". + */ + String getKey(final String key) { + if (TextUtils.equals(getDatabaseName(), LauncherFiles.LAUNCHER_DB)) { + return key; + } + return key + "@" + getDatabaseName(); + } + /** * Overriden in tests. */ protected void onEmptyDbCreated() { // Set the flag for empty DB - Utilities.getPrefs(mContext).edit().putBoolean(EMPTY_DATABASE_CREATED, true).commit(); + Utilities.getPrefs(mContext).edit().putBoolean(getKey(EMPTY_DATABASE_CREATED), true) + .commit(); } public long getSerialNumberForUser(UserHandle user) { diff --git a/src/com/android/launcher3/LauncherSettings.java b/src/com/android/launcher3/LauncherSettings.java index 5512654390..58a418edec 100644 --- a/src/com/android/launcher3/LauncherSettings.java +++ b/src/com/android/launcher3/LauncherSettings.java @@ -354,14 +354,20 @@ public class LauncherSettings { public static final String METHOD_PREP_FOR_PREVIEW = "prep_for_preview"; + public static final String METHOD_SWITCH_DATABASE = "switch_database"; + public static final String EXTRA_VALUE = "value"; public static Bundle call(ContentResolver cr, String method) { - return call(cr, method, null); + return call(cr, method, null /* arg */); } public static Bundle call(ContentResolver cr, String method, String arg) { - return cr.call(CONTENT_URI, method, arg, null); + return call(cr, method, arg, null /* extras */); + } + + public static Bundle call(ContentResolver cr, String method, String arg, Bundle extras) { + return cr.call(CONTENT_URI, method, arg, extras); } } }