summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRyan Lothian <rjlothian@google.com>2018-10-12 14:14:16 -0400
committerRyan Lothian <rjlothian@google.com>2018-10-15 17:24:48 -0400
commitfa530cd23f4f8f2d96e74dc169948ad141550550 (patch)
tree6a64018b92e9a98019eac063858113ee5d152ddd
parentcf7715511e4e54bfe15d8a24e68403d6e2e34e7f (diff)
downloadandroid_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.java8
-rw-r--r--res/xml/flag_preferences.xml24
-rw-r--r--res/xml/launcher_preferences.xml6
-rw-r--r--src/com/android/launcher3/Launcher.java7
-rw-r--r--src/com/android/launcher3/LauncherProvider.java5
-rw-r--r--src/com/android/launcher3/MainProcessInitializer.java2
-rw-r--r--src/com/android/launcher3/SettingsActivity.java9
-rw-r--r--src/com/android/launcher3/Workspace.java6
-rw-r--r--src/com/android/launcher3/config/BaseFlags.java143
-rw-r--r--src/com/android/launcher3/config/FlagTogglerPreferenceFragment.java120
-rw-r--r--src/com/android/launcher3/model/GridSizeMigrationTask.java37
-rw-r--r--src/com/android/launcher3/model/LoaderCursor.java2
-rw-r--r--src/com/android/launcher3/provider/ImportDataTask.java2
-rw-r--r--src/com/android/launcher3/qsb/QsbContainerView.java2
-rw-r--r--src_flags/com/android/launcher3/config/FeatureFlags.java8
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() {}
}