diff options
author | Ryan Lothian <rjlothian@google.com> | 2018-10-12 14:14:16 -0400 |
---|---|---|
committer | Ryan Lothian <rjlothian@google.com> | 2018-10-15 17:24:48 -0400 |
commit | fa530cd23f4f8f2d96e74dc169948ad141550550 (patch) | |
tree | 6a64018b92e9a98019eac063858113ee5d152ddd | |
parent | cf7715511e4e54bfe15d8a24e68403d6e2e34e7f (diff) | |
download | android_packages_apps_Trebuchet-fa530cd23f4f8f2d96e74dc169948ad141550550.tar.gz android_packages_apps_Trebuchet-fa530cd23f4f8f2d96e74dc169948ad141550550.tar.bz2 android_packages_apps_Trebuchet-fa530cd23f4f8f2d96e74dc169948ad141550550.zip |
Make flags UI available on release build of launcher
The UI will only be shown on eng/userdebug platform builds.
Bug: 117223984
Change-Id: I27843f2d856a4a19f3fe53c4d306606eaa5714a2
-rw-r--r-- | go/src_flags/com/android/launcher3/config/FeatureFlags.java | 8 | ||||
-rw-r--r-- | res/xml/flag_preferences.xml | 24 | ||||
-rw-r--r-- | res/xml/launcher_preferences.xml | 6 | ||||
-rw-r--r-- | src/com/android/launcher3/Launcher.java | 7 | ||||
-rw-r--r-- | src/com/android/launcher3/LauncherProvider.java | 5 | ||||
-rw-r--r-- | src/com/android/launcher3/MainProcessInitializer.java | 2 | ||||
-rw-r--r-- | src/com/android/launcher3/SettingsActivity.java | 9 | ||||
-rw-r--r-- | src/com/android/launcher3/Workspace.java | 6 | ||||
-rw-r--r-- | src/com/android/launcher3/config/BaseFlags.java | 143 | ||||
-rw-r--r-- | src/com/android/launcher3/config/FlagTogglerPreferenceFragment.java | 120 | ||||
-rw-r--r-- | src/com/android/launcher3/model/GridSizeMigrationTask.java | 37 | ||||
-rw-r--r-- | src/com/android/launcher3/model/LoaderCursor.java | 2 | ||||
-rw-r--r-- | src/com/android/launcher3/provider/ImportDataTask.java | 2 | ||||
-rw-r--r-- | src/com/android/launcher3/qsb/QsbContainerView.java | 2 | ||||
-rw-r--r-- | src_flags/com/android/launcher3/config/FeatureFlags.java | 8 |
15 files changed, 338 insertions, 43 deletions
diff --git a/go/src_flags/com/android/launcher3/config/FeatureFlags.java b/go/src_flags/com/android/launcher3/config/FeatureFlags.java index 6be9de805..a90808c1e 100644 --- a/go/src_flags/com/android/launcher3/config/FeatureFlags.java +++ b/go/src_flags/com/android/launcher3/config/FeatureFlags.java @@ -22,14 +22,10 @@ import android.content.Context; * Defines a set of flags used to control various launcher behaviors */ public final class FeatureFlags extends BaseFlags { - private static FeatureFlags instance = new FeatureFlags(); - - public static FeatureFlags getInstance(Context context) { - return instance; + private FeatureFlags() { + // Prevent instantiation } - private FeatureFlags() {} - // Features to control Launcher3Go behavior public static final boolean GO_DISABLE_WIDGETS = true; public static final boolean LAUNCHER3_SPRING_ICONS = false; diff --git a/res/xml/flag_preferences.xml b/res/xml/flag_preferences.xml new file mode 100644 index 000000000..aea1a6ab7 --- /dev/null +++ b/res/xml/flag_preferences.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* + * Copyright (C) 2018 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. + */ +--> + +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" + android:key="feature_flags" + android:persistent="false"> + +</PreferenceScreen>
\ No newline at end of file diff --git a/res/xml/launcher_preferences.xml b/res/xml/launcher_preferences.xml index 3bba73a6c..1df7c2fba 100644 --- a/res/xml/launcher_preferences.xml +++ b/res/xml/launcher_preferences.xml @@ -52,4 +52,10 @@ android:defaultValue="" android:persistent="false" /> + <PreferenceScreen + android:fragment="com.android.launcher3.config.FlagTogglerPreferenceFragment" + android:key="flag_toggler" + android:persistent="false" + android:title="Feature flags"/> + </PreferenceScreen> diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 4b181d8d8..55d6984f8 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -1753,12 +1753,12 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, @Override public void bindScreens(IntArray orderedScreenIds) { // Make sure the first screen is always at the start. - if (FeatureFlags.getInstance(this).isQsbOnFirstScreenEnabled() && + if (FeatureFlags.QSB_ON_FIRST_SCREEN.get() && orderedScreenIds.indexOf(Workspace.FIRST_SCREEN_ID) != 0) { orderedScreenIds.removeValue(Workspace.FIRST_SCREEN_ID); orderedScreenIds.add(0, Workspace.FIRST_SCREEN_ID); LauncherModel.updateWorkspaceScreenOrder(this, orderedScreenIds); - } else if (!FeatureFlags.getInstance(this).isQsbOnFirstScreenEnabled() + } else if (!FeatureFlags.QSB_ON_FIRST_SCREEN.get() && orderedScreenIds.isEmpty()) { // If there are no screens, we need to have an empty screen mWorkspace.addExtraEmptyScreen(); @@ -1775,8 +1775,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, int count = orderedScreenIds.size(); for (int i = 0; i < count; i++) { int screenId = orderedScreenIds.get(i); - if (!FeatureFlags.getInstance(this).isQsbOnFirstScreenEnabled() - || screenId != Workspace.FIRST_SCREEN_ID) { + if (!FeatureFlags.QSB_ON_FIRST_SCREEN.get() || screenId != Workspace.FIRST_SCREEN_ID) { // No need to bind the first screen, as its always bound. mWorkspace.insertNewWorkspaceScreenBeforeEmptyScreen(screenId); } diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java index a423a90f8..7d62adaf4 100644 --- a/src/com/android/launcher3/LauncherProvider.java +++ b/src/com/android/launcher3/LauncherProvider.java @@ -70,9 +70,6 @@ import java.io.PrintWriter; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedHashSet; public class LauncherProvider extends ContentProvider { private static final String TAG = "LauncherProvider"; @@ -793,7 +790,7 @@ public class LauncherProvider extends ContentProvider { convertShortcutsToLauncherActivities(db); case 26: // QSB was moved to the grid. Clear the first row on screen 0. - if (FeatureFlags.getInstance(mContext).isQsbOnFirstScreenEnabled() && + if (FeatureFlags.QSB_ON_FIRST_SCREEN.get() && !LauncherDbUtils.prepareScreenZeroToHostQsb(mContext, db)) { break; } diff --git a/src/com/android/launcher3/MainProcessInitializer.java b/src/com/android/launcher3/MainProcessInitializer.java index 0028f97cd..a18dfde31 100644 --- a/src/com/android/launcher3/MainProcessInitializer.java +++ b/src/com/android/launcher3/MainProcessInitializer.java @@ -18,6 +18,7 @@ package com.android.launcher3; import android.content.Context; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.graphics.IconShapeOverride; import com.android.launcher3.logging.FileLog; import com.android.launcher3.util.ResourceBasedOverride; @@ -35,6 +36,7 @@ public class MainProcessInitializer implements ResourceBasedOverride { protected void init(Context context) { FileLog.setDir(context.getApplicationContext().getFilesDir()); + FeatureFlags.initialize(context); IconShapeOverride.apply(context); SessionCommitReceiver.applyDefaultUserPrefs(context); } diff --git a/src/com/android/launcher3/SettingsActivity.java b/src/com/android/launcher3/SettingsActivity.java index 1f802267c..60edcda32 100644 --- a/src/com/android/launcher3/SettingsActivity.java +++ b/src/com/android/launcher3/SettingsActivity.java @@ -43,6 +43,7 @@ import android.view.View; import android.widget.Adapter; import android.widget.ListView; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.graphics.IconShapeOverride; import com.android.launcher3.notification.NotificationListener; import com.android.launcher3.util.ListViewHighlighter; @@ -57,6 +58,8 @@ import java.util.Objects; public class SettingsActivity extends Activity implements PreferenceFragment.OnPreferenceStartFragmentCallback { + private static final String FLAGS_PREFERENCE_KEY = "flag_toggler"; + private static final String ICON_BADGING_PREFERENCE_KEY = "pref_icon_badging"; /** Hidden field Settings.Secure.NOTIFICATION_BADGING */ public static final String NOTIFICATION_BADGING = "notification_badging"; @@ -126,6 +129,12 @@ public class SettingsActivity extends Activity getPreferenceManager().setSharedPreferencesName(LauncherFiles.SHARED_PREFERENCES_KEY); addPreferencesFromResource(R.xml.launcher_preferences); + // Only show flag toggler UI if this build variant implements that. + Preference flagToggler = findPreference(FLAGS_PREFERENCE_KEY); + if (flagToggler != null && !FeatureFlags.showFlagTogglerUi()) { + getPreferenceScreen().removePreference(flagToggler); + } + ContentResolver resolver = getActivity().getContentResolver(); ButtonPreference iconBadgingPref = diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 5e1c54cfb..11e601c7f 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -480,7 +480,7 @@ public class Workspace extends PagedView<WorkspacePageIndicator> * @param qsb an existing qsb to recycle or null. */ public void bindAndInitFirstWorkspaceScreen(View qsb) { - if (!FeatureFlags.getInstance(getContext()).isQsbOnFirstScreenEnabled()) { + if (!FeatureFlags.QSB_ON_FIRST_SCREEN.get()) { return; } // Add the first page @@ -779,9 +779,7 @@ public class Workspace extends PagedView<WorkspacePageIndicator> int id = mWorkspaceScreens.keyAt(i); CellLayout cl = mWorkspaceScreens.valueAt(i); // FIRST_SCREEN_ID can never be removed. - boolean qsbFirstScreenEnabled = - FeatureFlags.getInstance(getContext()).isQsbOnFirstScreenEnabled(); - if ((!qsbFirstScreenEnabled || id > FIRST_SCREEN_ID) + if ((!FeatureFlags.QSB_ON_FIRST_SCREEN.get() || id > FIRST_SCREEN_ID) && cl.getShortcutsAndWidgets().getChildCount() == 0) { removeScreens.add(id); } diff --git a/src/com/android/launcher3/config/BaseFlags.java b/src/com/android/launcher3/config/BaseFlags.java index de842f5fe..dc60c8fff 100644 --- a/src/com/android/launcher3/config/BaseFlags.java +++ b/src/com/android/launcher3/config/BaseFlags.java @@ -16,6 +16,21 @@ package com.android.launcher3.config; +import static androidx.core.util.Preconditions.checkNotNull; + +import android.content.Context; +import android.content.SharedPreferences; + +import androidx.annotation.GuardedBy; +import androidx.annotation.Keep; + +import com.android.launcher3.Utilities; + +import java.util.ArrayList; +import java.util.List; +import java.util.SortedMap; +import java.util.TreeMap; + /** * Defines a set of flags used to control various launcher behaviors. * @@ -23,11 +38,21 @@ package com.android.launcher3.config; * * <p>This class is kept package-private to prevent direct access. */ +@Keep abstract class BaseFlags { - private static final String TAG = "FeatureFlags"; + private static final Object sLock = new Object(); + @GuardedBy("sLock") + private static final List<TogglableFlag> sFlags = new ArrayList<>(); + + static final String FLAGS_PREF_NAME = "featureFlags"; BaseFlags() { + throw new UnsupportedOperationException("Don't instantiate BaseFlags"); + } + + public static boolean showFlagTogglerUi() { + return Utilities.IS_DEBUG_DEVICE; } public static final boolean IS_DOGFOOD_BUILD = false; @@ -36,10 +61,12 @@ abstract class BaseFlags { // When enabled the promise icon is visible in all apps while installation an app. public static final boolean LAUNCHER3_PROMISE_APPS_IN_ALL_APPS = false; - /** Feature flag to enable moving the QSB on the 0th screen of the workspace. */ - public boolean isQsbOnFirstScreenEnabled() { - return true; - } + public static final TogglableFlag QSB_ON_FIRST_SCREEN = new TogglableFlag("QSB_ON_FIRST_SCREEN", + true, + "Enable moving the QSB on the 0th screen of the workspace"); + + public static final TogglableFlag EXAMPLE_FLAG = new TogglableFlag("EXAMPLE_FLAG", true, + "An example flag that doesn't do anything. Useful for testing"); //Feature flag to enable pulling down navigation shade from workspace. public static final boolean PULL_DOWN_STATUS_BAR = true; @@ -56,4 +83,110 @@ abstract class BaseFlags { // When true, overview shows screenshots in the orientation they were taken rather than // trying to make them fit the orientation the device is in. public static final boolean OVERVIEW_USE_SCREENSHOT_ORIENTATION = true; + + public static void initialize(Context context) { + // Avoid the disk read for builds without the flags UI. + if (showFlagTogglerUi()) { + SharedPreferences sharedPreferences = + context.getSharedPreferences(FLAGS_PREF_NAME, Context.MODE_PRIVATE); + synchronized (sLock) { + for (TogglableFlag flag : sFlags) { + flag.currentValue = sharedPreferences.getBoolean(flag.key, flag.defaultValue); + } + } + } else { + synchronized (sLock) { + for (TogglableFlag flag : sFlags) { + flag.currentValue = flag.defaultValue; + } + } + } + } + + static List<TogglableFlag> getTogglableFlags() { + // By Java Language Spec 12.4.2 + // https://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4.2, the + // TogglableFlag instances on BaseFlags will be created before those on the FeatureFlags + // subclass. This code handles flags that are redeclared in FeatureFlags, ensuring the + // FeatureFlags one takes priority. + SortedMap<String, TogglableFlag> flagsByKey = new TreeMap<>(); + synchronized (sLock) { + for (TogglableFlag flag : sFlags) { + flagsByKey.put(flag.key, flag); + } + } + return new ArrayList<>(flagsByKey.values()); + } + + public static final class TogglableFlag { + private final String key; + private final boolean defaultValue; + private final String description; + private boolean currentValue; + + TogglableFlag( + String key, + boolean defaultValue, + String description) { + this.key = checkNotNull(key); + this.defaultValue = defaultValue; + this.description = checkNotNull(description); + synchronized (sLock) { + sFlags.add(this); + } + } + + String getKey() { + return key; + } + + boolean getDefaultValue() { + return defaultValue; + } + + /** Returns the value of the flag at process start, including any overrides present. */ + public boolean get() { + return currentValue; + } + + String getDescription() { + return description; + } + + @Override + public String toString() { + return "TogglableFlag{" + + "key=" + key + ", " + + "defaultValue=" + defaultValue + ", " + + "description=" + description + + "}"; + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (o instanceof TogglableFlag) { + TogglableFlag that = (TogglableFlag) o; + return (this.key.equals(that.getKey())) + && (this.defaultValue == that.getDefaultValue()) + && (this.description.equals(that.getDescription())); + } + return false; + } + + @Override + public int hashCode() { + int h$ = 1; + h$ *= 1000003; + h$ ^= key.hashCode(); + h$ *= 1000003; + h$ ^= defaultValue ? 1231 : 1237; + h$ *= 1000003; + h$ ^= description.hashCode(); + return h$; + } + } + } diff --git a/src/com/android/launcher3/config/FlagTogglerPreferenceFragment.java b/src/com/android/launcher3/config/FlagTogglerPreferenceFragment.java new file mode 100644 index 000000000..0a1fd2fe0 --- /dev/null +++ b/src/com/android/launcher3/config/FlagTogglerPreferenceFragment.java @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2018 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.config; + +import android.content.Context; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.os.Process; +import android.preference.PreferenceDataStore; +import android.preference.PreferenceFragment; +import android.preference.SwitchPreference; +import android.util.Log; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.widget.Toast; + +import com.android.launcher3.R; +import com.android.launcher3.config.BaseFlags.TogglableFlag; + +/** + * Dev-build only UI allowing developers to toggle flag settings. See {@link FeatureFlags}. + */ +public final class FlagTogglerPreferenceFragment extends PreferenceFragment { + private static final String TAG = "FlagTogglerPrefFrag"; + + private SharedPreferences mSharedPreferences; + private MenuItem saveButton; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + addPreferencesFromResource(R.xml.flag_preferences); + mSharedPreferences = getContext().getSharedPreferences( + FeatureFlags.FLAGS_PREF_NAME, Context.MODE_PRIVATE); + + // For flag overrides we only want to store when the engineer chose to override the + // flag with a different value than the default. That way, when we flip flags in + // future, engineers will pick up the new value immediately. To accomplish this, we use a + // custom preference data store. + getPreferenceManager().setPreferenceDataStore(new PreferenceDataStore() { + @Override + public void putBoolean(String key, boolean value) { + for (TogglableFlag flag : FeatureFlags.getTogglableFlags()) { + if (flag.getKey().equals(key)) { + if (value == flag.getDefaultValue()) { + mSharedPreferences.edit().remove(key).apply(); + } else { + mSharedPreferences.edit().putBoolean(key, value).apply(); + } + } + } + } + }); + + for (TogglableFlag flag : FeatureFlags.getTogglableFlags()) { + SwitchPreference switchPreference = new SwitchPreference(getContext()); + switchPreference.setKey(flag.getKey()); + switchPreference.setDefaultValue(flag.getDefaultValue()); + switchPreference.setChecked(getFlagStateFromSharedPrefs(flag)); + switchPreference.setTitle(flag.getKey()); + switchPreference.setSummaryOn(flag.getDefaultValue() ? "" : "overridden"); + switchPreference.setSummaryOff(flag.getDefaultValue() ? "overridden" : ""); + getPreferenceScreen().addPreference(switchPreference); + } + setHasOptionsMenu(true); + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + saveButton = menu.add("Apply"); + saveButton.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item == saveButton) { + mSharedPreferences.edit().commit(); + Log.e(TAG, + "Killing launcher process " + Process.myPid() + " to apply new flag values"); + System.exit(0); + } + return super.onOptionsItemSelected(item); + } + + @Override + public void onStop() { + boolean anyChanged = false; + for (TogglableFlag flag : FeatureFlags.getTogglableFlags()) { + anyChanged = anyChanged || + getFlagStateFromSharedPrefs(flag) != flag.get(); + } + + if (anyChanged) { + Toast.makeText( + getContext(), + "Flag won't be applied until you restart launcher", + Toast.LENGTH_LONG).show(); + } + super.onStop(); + } + + private boolean getFlagStateFromSharedPrefs(TogglableFlag flag) { + return mSharedPreferences.getBoolean(flag.getKey(), flag.getDefaultValue()); + } +}
\ No newline at end of file diff --git a/src/com/android/launcher3/model/GridSizeMigrationTask.java b/src/com/android/launcher3/model/GridSizeMigrationTask.java index 0115fd9f9..2c1aa745f 100644 --- a/src/com/android/launcher3/model/GridSizeMigrationTask.java +++ b/src/com/android/launcher3/model/GridSizeMigrationTask.java @@ -12,6 +12,7 @@ import android.database.Cursor; import android.graphics.Point; import android.net.Uri; import android.util.Log; + import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.ItemInfo; import com.android.launcher3.LauncherAppState; @@ -109,6 +110,7 @@ public class GridSizeMigrationTask { /** * Applied all the pending DB operations + * * @return true if any DB operation was commited. */ private boolean applyOperations() throws Exception { @@ -135,6 +137,7 @@ public class GridSizeMigrationTask { * entries is more than what can fit in the new hotseat, we drop the entries with least weight. * For weight calculation {@see #WT_SHORTCUT}, {@see #WT_APPLICATION} * & {@see #WT_FOLDER_FACTOR}. + * * @return true if any DB change was made */ protected boolean migrateHotseat() throws Exception { @@ -235,7 +238,8 @@ public class GridSizeMigrationTask { int screenId = allScreens.get(i); v.put(LauncherSettings.WorkspaceScreens._ID, screenId); v.put(LauncherSettings.WorkspaceScreens.SCREEN_RANK, i); - mUpdateOperations.add(ContentProviderOperation.newInsert(uri).withValues(v).build()); + mUpdateOperations.add(ContentProviderOperation.newInsert(uri).withValues( + v).build()); } } return applyOperations(); @@ -254,8 +258,7 @@ public class GridSizeMigrationTask { protected void migrateScreen(int screenId) { // If we are migrating the first screen, do not touch the first row. int startY = - (FeatureFlags.getInstance(mContext).isQsbOnFirstScreenEnabled() - && screenId == Workspace.FIRST_SCREEN_ID) + (FeatureFlags.QSB_ON_FIRST_SCREEN.get() && screenId == Workspace.FIRST_SCREEN_ID) ? 1 : 0; ArrayList<DbEntry> items = loadWorkspaceEntries(screenId); @@ -280,9 +283,11 @@ public class GridSizeMigrationTask { for (int y = mSrcY - 1; y >= startY; y--) { // Use a deep copy when trying out a particular combination as it can change // the underlying object. - ArrayList<DbEntry> itemsOnScreen = tryRemove(x, y, startY, deepCopy(items), outLoss); + ArrayList<DbEntry> itemsOnScreen = tryRemove(x, y, startY, deepCopy(items), + outLoss); - if ((outLoss[0] < removeWt) || ((outLoss[0] == removeWt) && (outLoss[1] < moveWt))) { + if ((outLoss[0] < removeWt) || ((outLoss[0] == removeWt) && (outLoss[1] + < moveWt))) { removeWt = outLoss[0]; moveWt = outLoss[1]; removedCol = mShouldRemoveX ? x : removedCol; @@ -363,6 +368,7 @@ public class GridSizeMigrationTask { /** * Tries the remove the provided row and column. + * * @param items all the items on the screen under operation * @param outLoss array of size 2. The first entry is filled with weight loss, and the second * with the overall item movement. @@ -438,6 +444,7 @@ public class GridSizeMigrationTask { /** * Recursively finds a placement for the provided items. + * * @param index the position in {@link #itemsToPlace} to start looking at. * @param weightLoss total weight loss upto this point * @param moveCost total move cost upto this point @@ -550,7 +557,8 @@ public class GridSizeMigrationTask { for (int x = 0; x < mTrgX; x++) { if (!occupied.cells[x][y]) { int dist = ignoreMove ? 0 : - ((me.cellX - x) * (me.cellX - x) + (me.cellY - y) * (me.cellY - y)); + ((me.cellX - x) * (me.cellX - x) + (me.cellY - y) * (me.cellY + - y)); if (dist < newDistance) { newX = x; newY = y; @@ -815,7 +823,8 @@ public class GridSizeMigrationTask { public float weight; - public DbEntry() { } + public DbEntry() { + } public DbEntry copy() { DbEntry entry = new DbEntry(); @@ -887,6 +896,7 @@ public class GridSizeMigrationTask { /** * Migrates the workspace and hotseat in case their sizes changed. + * * @return false if the migration failed. */ public static boolean migrateGridIfNeeded(Context context) { @@ -896,7 +906,8 @@ public class GridSizeMigrationTask { String gridSizeString = getPointString(idp.numColumns, idp.numRows); if (gridSizeString.equals(prefs.getString(KEY_MIGRATION_SRC_WORKSPACE_SIZE, "")) && - idp.numHotseatIcons == prefs.getInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT, idp.numHotseatIcons)) { + idp.numHotseatIcons == prefs.getInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT, + idp.numHotseatIcons)) { // Skip if workspace and hotseat sizes have not changed. return true; } @@ -907,7 +918,8 @@ public class GridSizeMigrationTask { HashSet<String> validPackages = getValidPackages(context); // Hotseat - int srcHotseatCount = prefs.getInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT, idp.numHotseatIcons); + int srcHotseatCount = prefs.getInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT, + idp.numHotseatIcons); if (srcHotseatCount != idp.numHotseatIcons) { // Migrate hotseat. @@ -920,7 +932,8 @@ public class GridSizeMigrationTask { Point sourceSize = parsePoint(prefs.getString( KEY_MIGRATION_SRC_WORKSPACE_SIZE, gridSizeString)); - if (new MultiStepMigrationTask(validPackages, context).migrate(sourceSize, targetSize)) { + if (new MultiStepMigrationTask(validPackages, context).migrate(sourceSize, + targetSize)) { dbChanged = true; } @@ -970,9 +983,11 @@ public class GridSizeMigrationTask { /** * Removes any broken item from the hotseat. + * * @return a map with occupied hotseat position set to non-null value. */ - public static IntSparseArrayMap<Object> removeBrokenHotseatItems(Context context) throws Exception { + public static IntSparseArrayMap<Object> removeBrokenHotseatItems(Context context) + throws Exception { GridSizeMigrationTask task = new GridSizeMigrationTask( context, LauncherAppState.getIDP(context), getValidPackages(context), Integer.MAX_VALUE, Integer.MAX_VALUE); diff --git a/src/com/android/launcher3/model/LoaderCursor.java b/src/com/android/launcher3/model/LoaderCursor.java index bb3a7606f..94cf5c286 100644 --- a/src/com/android/launcher3/model/LoaderCursor.java +++ b/src/com/android/launcher3/model/LoaderCursor.java @@ -441,7 +441,7 @@ public class LoaderCursor extends CursorWrapper { // Mark the first row as occupied (if the feature is enabled) // in order to account for the QSB. screen.markCells(0, 0, countX + 1, 1, - FeatureFlags.getInstance(mContext).isQsbOnFirstScreenEnabled()); + FeatureFlags.QSB_ON_FIRST_SCREEN.get()); } occupied.put(item.screenId, screen); } diff --git a/src/com/android/launcher3/provider/ImportDataTask.java b/src/com/android/launcher3/provider/ImportDataTask.java index 4edd30f35..e1b26980c 100644 --- a/src/com/android/launcher3/provider/ImportDataTask.java +++ b/src/com/android/launcher3/provider/ImportDataTask.java @@ -136,7 +136,7 @@ public class ImportDataTask { .getSerialNumberForUser(Process.myUserHandle())); boolean createEmptyRowOnFirstScreen; - if (FeatureFlags.getInstance(mContext).isQsbOnFirstScreenEnabled()) { + if (FeatureFlags.QSB_ON_FIRST_SCREEN.get()) { try (Cursor c = mContext.getContentResolver().query(mOtherFavoritesUri, null, // get items on the first row of the first screen "profileId = ? AND container = -100 AND screen = ? AND cellY = 0", diff --git a/src/com/android/launcher3/qsb/QsbContainerView.java b/src/com/android/launcher3/qsb/QsbContainerView.java index 82ab15c29..ac1fafb42 100644 --- a/src/com/android/launcher3/qsb/QsbContainerView.java +++ b/src/com/android/launcher3/qsb/QsbContainerView.java @@ -213,7 +213,7 @@ public class QsbContainerView extends FrameLayout { } public boolean isQsbEnabled() { - return FeatureFlags.getInstance(getContext()).isQsbOnFirstScreenEnabled(); + return FeatureFlags.QSB_ON_FIRST_SCREEN.get(); } protected Bundle createBindOptions() { diff --git a/src_flags/com/android/launcher3/config/FeatureFlags.java b/src_flags/com/android/launcher3/config/FeatureFlags.java index f02f2271e..73c699633 100644 --- a/src_flags/com/android/launcher3/config/FeatureFlags.java +++ b/src_flags/com/android/launcher3/config/FeatureFlags.java @@ -22,11 +22,7 @@ import android.content.Context; * Defines a set of flags used to control various launcher behaviors */ public final class FeatureFlags extends BaseFlags { - private static FeatureFlags instance = new FeatureFlags(); - - public static FeatureFlags getInstance(Context context) { - return instance; + private FeatureFlags() { + // Prevent instantiation } - - private FeatureFlags() {} } |