diff --git a/OWNERS b/OWNERS
index dd2d00eb048a688a80b9a54ed4df97c1698ad0b2..654493f80762e34b8a9b23cf2f7e55a6bbd5c6ec 100644
--- a/OWNERS
+++ b/OWNERS
@@ -45,3 +45,6 @@ zakcohen@google.com
 
 per-file FeatureFlags.java, globs = set noparent
 per-file FeatureFlags.java = sunnygoyal@google.com, winsonc@google.com, adamcohen@google.com, hyunyoungs@google.com, captaincole@google.com
+
+per-file DeviceConfigWrapper.java, globs = set noparent
+per-file DeviceConfigWrapper.java = sunnygoyal@google.com, winsonc@google.com, adamcohen@google.com, hyunyoungs@google.com
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index be532b4047b52767c87aaf4af9a0761114e6fcdd..0697f47cda65dd6cdbf69c1e3b1918a3f6243d2e 100644
--- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
@@ -173,6 +173,7 @@ import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map.Entry;
 
 /**
  * Manages the opening and closing app transitions from Launcher
diff --git a/quickstep/src/com/android/launcher3/uioverrides/flags/DevOptionsUiHelper.kt b/quickstep/src/com/android/launcher3/uioverrides/flags/DevOptionsUiHelper.kt
new file mode 100644
index 0000000000000000000000000000000000000000..6b44ca78a287c7a2299aaacf8ff370b486d94771
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/uioverrides/flags/DevOptionsUiHelper.kt
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2024 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.uioverrides.flags
+
+import android.os.Handler
+import android.provider.DeviceConfig
+import android.text.Html
+import android.view.inputmethod.EditorInfo
+import androidx.preference.Preference
+import androidx.preference.PreferenceGroup
+import androidx.preference.PreferenceViewHolder
+import androidx.preference.SwitchPreference
+import com.android.launcher3.ExtendedEditText
+import com.android.launcher3.R
+import com.android.quickstep.util.DeviceConfigHelper
+import com.android.quickstep.util.DeviceConfigHelper.Companion.NAMESPACE_LAUNCHER
+import com.android.quickstep.util.DeviceConfigHelper.DebugInfo
+
+/** Helper class to generate UI for Device Config */
+class DevOptionsUiHelper {
+
+    /** Inflates preferences for all server flags in the provider PreferenceGroup */
+    fun inflateServerFlags(parent: PreferenceGroup) {
+        val prefs = DeviceConfigHelper.prefs
+        // Sort the keys in the order of modified first followed by natural order
+        val allProps =
+            DeviceConfigHelper.allProps.values
+                .toList()
+                .sortedWith(
+                    Comparator.comparingInt { prop: DebugInfo<*> ->
+                            if (prefs.contains(prop.key)) 0 else 1
+                        }
+                        .thenComparing { prop: DebugInfo<*> -> prop.key }
+                )
+
+        // First add boolean flags
+        allProps.forEach {
+            if (it.isInt) return@forEach
+            val info = it as DebugInfo<Boolean>
+
+            val preference =
+                object : SwitchPreference(parent.context) {
+                    override fun onBindViewHolder(holder: PreferenceViewHolder) {
+                        super.onBindViewHolder(holder)
+                        holder.itemView.setOnLongClickListener {
+                            prefs.edit().remove(key).apply()
+                            setChecked(info.getBoolValue())
+                            summary = info.getSummary()
+                            true
+                        }
+                    }
+                }
+            preference.key = info.key
+            preference.isPersistent = false
+            preference.title = info.key
+            preference.summary = info.getSummary()
+            preference.setChecked(prefs.getBoolean(info.key, info.getBoolValue()))
+            preference.setOnPreferenceChangeListener { _, newVal ->
+                DeviceConfigHelper.prefs.edit().putBoolean(info.key, newVal as Boolean).apply()
+                preference.summary = info.getSummary()
+                true
+            }
+            parent.addPreference(preference)
+        }
+
+        // Apply Int flags
+        allProps.forEach {
+            if (!it.isInt) return@forEach
+            val info = it as DebugInfo<Int>
+
+            val preference =
+                object : Preference(parent.context) {
+                    override fun onBindViewHolder(holder: PreferenceViewHolder) {
+                        super.onBindViewHolder(holder)
+                        val textView = holder.findViewById(R.id.pref_edit_text) as ExtendedEditText
+                        textView.setText(info.getIntValueAsString())
+                        textView.setOnEditorActionListener { _, actionId, _ ->
+                            if (actionId == EditorInfo.IME_ACTION_DONE) {
+                                DeviceConfigHelper.prefs
+                                    .edit()
+                                    .putInt(key, textView.text.toString().toInt())
+                                    .apply()
+                                Handler().post { summary = info.getSummary() }
+                                true
+                            }
+                            false
+                        }
+                        textView.setOnBackKeyListener {
+                            textView.setText(info.getIntValueAsString())
+                            true
+                        }
+
+                        holder.itemView.setOnLongClickListener {
+                            prefs.edit().remove(key).apply()
+                            textView.setText(info.getIntValueAsString())
+                            summary = info.getSummary()
+                            true
+                        }
+                    }
+                }
+            preference.key = info.key
+            preference.isPersistent = false
+            preference.title = info.key
+            preference.summary = info.getSummary()
+            preference.widgetLayoutResource = R.layout.develop_options_edit_text
+            parent.addPreference(preference)
+        }
+    }
+
+    /**
+     * Returns the summary to show the description and whether the flag overrides the default value.
+     */
+    private fun DebugInfo<*>.getSummary() =
+        Html.fromHtml(
+            (if (DeviceConfigHelper.prefs.contains(this.key))
+                "<font color='red'><b>[OVERRIDDEN]</b></font><br>"
+            else "") + this.desc
+        )
+
+    private fun DebugInfo<Boolean>.getBoolValue() =
+        DeviceConfigHelper.prefs.getBoolean(
+            this.key,
+            DeviceConfig.getBoolean(NAMESPACE_LAUNCHER, this.key, this.valueInCode)
+        )
+
+    private fun DebugInfo<Int>.getIntValueAsString() =
+        DeviceConfigHelper.prefs
+            .getInt(this.key, DeviceConfig.getInt(NAMESPACE_LAUNCHER, this.key, this.valueInCode))
+            .toString()
+
+    companion object {
+        const val TAG = "DeviceConfigUIHelper"
+    }
+}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsUI.java b/quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsUI.java
index 6713964ada5ab9b7c21a432019ef7bad193ff05b..fd6bf4daf4c64bf4002031e2baf64515f7c543e4 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsUI.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsUI.java
@@ -20,19 +20,8 @@ import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
 import static android.view.View.GONE;
 import static android.view.View.VISIBLE;
 
-import static com.android.launcher3.LauncherPrefs.ALL_APPS_OVERVIEW_THRESHOLD;
-import static com.android.launcher3.LauncherPrefs.PRIVATE_SPACE_APPS;
-import static com.android.launcher3.config.FeatureFlags.LPNH_EXTRA_TOUCH_WIDTH_DP;
-import static com.android.launcher3.config.FeatureFlags.LPNH_HAPTIC_HINT_DELAY;
-import static com.android.launcher3.config.FeatureFlags.LPNH_HAPTIC_HINT_END_SCALE_PERCENT;
-import static com.android.launcher3.config.FeatureFlags.LPNH_HAPTIC_HINT_ITERATIONS;
-import static com.android.launcher3.config.FeatureFlags.LPNH_HAPTIC_HINT_SCALE_EXPONENT;
-import static com.android.launcher3.config.FeatureFlags.LPNH_HAPTIC_HINT_START_SCALE_PERCENT;
-import static com.android.launcher3.config.FeatureFlags.LPNH_SLOP_PERCENTAGE;
-import static com.android.launcher3.config.FeatureFlags.LPNH_TIMEOUT_MS;
 import static com.android.launcher3.settings.SettingsActivity.EXTRA_FRAGMENT_HIGHLIGHT_KEY;
 import static com.android.launcher3.uioverrides.plugins.PluginManagerWrapper.PLUGIN_CHANGED;
-import static com.android.launcher3.uioverrides.plugins.PluginManagerWrapper.pluginEnabledKey;
 import static com.android.launcher3.util.OnboardingPrefs.ALL_APPS_VISITED_COUNT;
 import static com.android.launcher3.util.OnboardingPrefs.HOME_BOUNCE_COUNT;
 import static com.android.launcher3.util.OnboardingPrefs.HOME_BOUNCE_SEEN;
@@ -51,7 +40,6 @@ import android.provider.Settings;
 import android.text.Editable;
 import android.text.TextWatcher;
 import android.util.ArrayMap;
-import android.util.Log;
 import android.util.Pair;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -61,21 +49,18 @@ import android.widget.Toast;
 
 import androidx.preference.Preference;
 import androidx.preference.PreferenceCategory;
-import androidx.preference.PreferenceDataStore;
 import androidx.preference.PreferenceFragmentCompat;
 import androidx.preference.PreferenceGroup;
 import androidx.preference.PreferenceScreen;
 import androidx.preference.PreferenceViewHolder;
-import androidx.preference.SeekBarPreference;
 import androidx.preference.SwitchPreference;
 
-import com.android.launcher3.ConstantItem;
-import com.android.launcher3.Flags;
 import com.android.launcher3.LauncherPrefs;
 import com.android.launcher3.R;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.secondarydisplay.SecondaryDisplayLauncher;
 import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
+import com.android.systemui.shared.plugins.PluginEnabler;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -96,8 +81,6 @@ public class DeveloperOptionsUI {
     private final PreferenceFragmentCompat mFragment;
     private final PreferenceScreen mPreferenceScreen;
 
-    private final FlagTogglerPrefUi mFlagTogglerPrefUi;
-
     private PreferenceCategory mPluginsCategory;
 
     public DeveloperOptionsUI(PreferenceFragmentCompat fragment, PreferenceCategory flags) {
@@ -112,20 +95,14 @@ public class DeveloperOptionsUI {
         parent.addView(topBar, parent.indexOfChild(listView));
         initSearch(topBar.findViewById(R.id.filter_box));
 
-        mFlagTogglerPrefUi = new FlagTogglerPrefUi(mFragment.requireActivity(),
-                topBar.findViewById(R.id.flag_apply_btn));
-        mFlagTogglerPrefUi.applyTo(flags);
+        new FlagTogglerPrefUi(mFragment.requireActivity(), topBar.findViewById(R.id.flag_apply_btn))
+                .applyTo(flags);
+        DevOptionsUiHelper uiHelper = new DevOptionsUiHelper();
+        uiHelper.inflateServerFlags(newCategory("Server flags"));
 
         loadPluginPrefs();
         maybeAddSandboxCategory();
         addOnboardingPrefsCatergory();
-        if (FeatureFlags.ENABLE_ALL_APPS_FROM_OVERVIEW.get()) {
-            addAllAppsFromOverviewCatergory();
-        }
-        addCustomLpnhCategory();
-        if (Flags.enablePrivateSpace()) {
-            addCustomPrivateAppsCategory();
-        }
     }
 
     private void filterPreferences(String query, PreferenceGroup pg) {
@@ -205,7 +182,7 @@ public class DeveloperOptionsUI {
                 new ArrayMap<>();
 
         Set<String> pluginPermissionApps = pm.getPackagesHoldingPermissions(
-                new String[]{PLUGIN_PERMISSION}, MATCH_DISABLED_COMPONENTS)
+                        new String[]{PLUGIN_PERMISSION}, MATCH_DISABLED_COMPONENTS)
                 .stream()
                 .map(pi -> pi.packageName)
                 .collect(Collectors.toSet());
@@ -228,7 +205,7 @@ public class DeveloperOptionsUI {
             }
         }
 
-        PreferenceDataStore enabler = manager.getPluginEnabler();
+        PluginEnabler enabler = manager.getPluginEnabler();
         plugins.forEach((key, si) -> {
             String packageName = key.first;
             List<ComponentName> componentNames = si.stream()
@@ -347,111 +324,10 @@ public class DeveloperOptionsUI {
         return onboardingPref;
     }
 
-    private void addAllAppsFromOverviewCatergory() {
-        PreferenceCategory category = newCategory("All Apps from Overview Config");
-        category.addPreference(createSeekBarPreference("Threshold to open All Apps from Overview",
-                105, 500, 100, ALL_APPS_OVERVIEW_THRESHOLD));
-    }
-
-    private void addCustomLpnhCategory() {
-        PreferenceCategory category = newCategory("Long Press Nav Handle Config");
-        if (FeatureFlags.CUSTOM_LPNH_THRESHOLDS.get()) {
-            category.addPreference(createSeekBarPreference(
-                    "Slop multiplier (applied to edge slop, "
-                            + "which is generally already 50% higher than touch slop)",
-                    25, 200, 100, LPNH_SLOP_PERCENTAGE));
-            category.addPreference(createSeekBarPreference(
-                    "Extra width DP (how far outside the sides of the nav bar to trigger)",
-                    // Stashed taskbar is currently 220dp; -86 (x2) would result in 48dp touch area.
-                    -86, 100, 1, LPNH_EXTRA_TOUCH_WIDTH_DP));
-            category.addPreference(createSeekBarPreference("LPNH timeout",
-                    100, 500, 1, LPNH_TIMEOUT_MS));
-        }
-        if (FeatureFlags.ENABLE_SEARCH_HAPTIC_HINT.get()) {
-            category.addPreference(
-                    createSeekBarPreference("Haptic hint start scale",
-                            0, 100, 100, LPNH_HAPTIC_HINT_START_SCALE_PERCENT));
-            category.addPreference(createSeekBarPreference("Haptic hint end scale",
-                    0, 100, 100, LPNH_HAPTIC_HINT_END_SCALE_PERCENT));
-            category.addPreference(
-                    createSeekBarPreference("Haptic hint scale exponent",
-                            1, 5, 1, LPNH_HAPTIC_HINT_SCALE_EXPONENT));
-            category.addPreference(
-                    createSeekBarPreference("Haptic hint iterations (12 ms each)",
-                            0, 200, 1, LPNH_HAPTIC_HINT_ITERATIONS));
-            category.addPreference(createSeekBarPreference("Haptic hint delay (ms)",
-                    0, 400, 1, LPNH_HAPTIC_HINT_DELAY));
-        }
-    }
-
-    private void addCustomPrivateAppsCategory() {
-        PreferenceCategory category = newCategory("Apps in Private Space Config");
-        category.addPreference(createSeekBarPreference(
-                "Number of Apps to put in private region", 0, 100, 1, PRIVATE_SPACE_APPS));
-    }
-
-    private SeekBarPreference createSeekBarPreference(String title, int min,
-            int max, int scale, FeatureFlags.IntFlag flag) {
-        if (!(flag instanceof IntDebugFlag)) {
-            Log.e(TAG, "Cannot create seekbar preference with IntFlag. Use a launcher preference "
-                    + "flag or pref-backed IntDebugFlag instead");
-            return null;
-        }
-        IntDebugFlag debugflag = (IntDebugFlag) flag;
-        if (debugflag.launcherPrefFlag == null) {
-            Log.e(TAG, "Cannot create seekbar preference with IntDebugFlag. Use a launcher "
-                    + "preference flag or pref-backed IntDebugFlag instead");
-            return null;
-        }
-        SeekBarPreference seekBarPref = createSeekBarPreference(title, min, max, scale,
-                debugflag.launcherPrefFlag);
-        int value = flag.get();
-        seekBarPref.setValue(value);
-        // For some reason the initial value is not triggering the summary update, so call manually.
-        seekBarPref.setSummary(String.valueOf(scale == 1 ? value
-                : value / (float) scale));
-        return seekBarPref;
-    }
-
-    /**
-     * Create a preference with text and a seek bar. Should be added to a PreferenceCategory.
-     *
-     * @param title text to show for this seek bar
-     * @param min min value for the seek bar
-     * @param max max value for the seek bar
-     * @param scale how much to divide the value to convert int to float
-     * @param launcherPref used to store the current value
-     */
-    private SeekBarPreference createSeekBarPreference(String title, int min, int max, int scale,
-            ConstantItem<Integer> launcherPref) {
-        SeekBarPreference seekBarPref = new SeekBarPreference(getContext());
-        seekBarPref.setTitle(title);
-        seekBarPref.setSingleLineTitle(false);
-
-        seekBarPref.setMax(max);
-        seekBarPref.setMin(min);
-        seekBarPref.setUpdatesContinuously(true);
-        seekBarPref.setIconSpaceReserved(false);
-        // Don't directly save to shared prefs, use LauncherPrefs instead.
-        seekBarPref.setPersistent(false);
-        seekBarPref.setOnPreferenceChangeListener((preference, newValue) -> {
-            LauncherPrefs.get(getContext()).put(launcherPref, newValue);
-            preference.setSummary(String.valueOf(scale == 1 ? newValue
-                    : (int) newValue / (float) scale));
-            mFlagTogglerPrefUi.updateMenu();
-            return true;
-        });
-        int value = LauncherPrefs.get(getContext()).get(launcherPref);
-        seekBarPref.setValue(value);
-        // For some reason the initial value is not triggering the summary update, so call manually.
-        seekBarPref.setSummary(String.valueOf(scale == 1 ? value
-                : value / (float) scale));
-        return seekBarPref;
-    }
-
     private String toName(String action) {
         String str = action.replace("com.android.systemui.action.PLUGIN_", "")
                 .replace("com.android.launcher3.action.PLUGIN_", "");
+
         StringBuilder b = new StringBuilder();
         for (String s : str.split("_")) {
             if (b.length() != 0) {
@@ -466,11 +342,11 @@ public class DeveloperOptionsUI {
     private static class PluginPreference extends SwitchPreference {
         private final String mPackageName;
         private final ResolveInfo mSettingsInfo;
-        private final PreferenceDataStore mPluginEnabler;
+        private final PluginEnabler mPluginEnabler;
         private final List<ComponentName> mComponentNames;
 
         PluginPreference(Context prefContext, ResolveInfo pluginInfo,
-                PreferenceDataStore pluginEnabler, List<ComponentName> componentNames) {
+                PluginEnabler pluginEnabler, List<ComponentName> componentNames) {
             super(prefContext);
             PackageManager pm = prefContext.getPackageManager();
             mPackageName = pluginInfo.serviceInfo.applicationInfo.packageName;
@@ -495,14 +371,9 @@ public class DeveloperOptionsUI {
             setWidgetLayoutResource(R.layout.switch_preference_with_settings);
         }
 
-        private boolean isEnabled(ComponentName cn) {
-            return mPluginEnabler.getBoolean(pluginEnabledKey(cn), true);
-
-        }
-
         private boolean isPluginEnabled() {
             for (ComponentName componentName : mComponentNames) {
-                if (!isEnabled(componentName)) {
+                if (!mPluginEnabler.isEnabled(componentName)) {
                     return false;
                 }
             }
@@ -513,8 +384,9 @@ public class DeveloperOptionsUI {
         protected boolean persistBoolean(boolean isEnabled) {
             boolean shouldSendBroadcast = false;
             for (ComponentName componentName : mComponentNames) {
-                if (isEnabled(componentName) != isEnabled) {
-                    mPluginEnabler.putBoolean(pluginEnabledKey(componentName), isEnabled);
+                if (mPluginEnabler.isEnabled(componentName) != isEnabled) {
+                    mPluginEnabler.setDisabled(componentName,
+                            isEnabled ? PluginEnabler.ENABLED : PluginEnabler.DISABLED_MANUALLY);
                     shouldSendBroadcast = true;
                 }
             }
diff --git a/quickstep/src/com/android/launcher3/uioverrides/flags/FlagTogglerPrefUi.java b/quickstep/src/com/android/launcher3/uioverrides/flags/FlagTogglerPrefUi.java
index 4326c67162559e15e8f2206b1c4e383382ae2455..fc39ce42a2e2fa18136886f249a9f90e3febb51e 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/flags/FlagTogglerPrefUi.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/flags/FlagTogglerPrefUi.java
@@ -34,7 +34,6 @@ import androidx.preference.PreferenceGroup;
 import androidx.preference.PreferenceViewHolder;
 import androidx.preference.SwitchPreference;
 
-import com.android.launcher3.LauncherPrefs;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.util.ActivityLifecycleCallbacksAdapter;
 
@@ -162,22 +161,12 @@ public final class FlagTogglerPrefUi implements ActivityLifecycleCallbacksAdapte
         return mDataStore.getBoolean(flag.key, defaultValue);
     }
 
-    private int getIntFlagStateFromSharedPrefs(IntDebugFlag flag) {
-        LauncherPrefs prefs = LauncherPrefs.get(mContext);
-        return flag.launcherPrefFlag == null ? flag.get() : prefs.get(flag.launcherPrefFlag);
-    }
-
     private boolean anyChanged() {
         for (DebugFlag flag : FlagsFactory.getDebugFlags()) {
             if (getFlagStateFromSharedPrefs(flag) != flag.get()) {
                 return true;
             }
         }
-        for (IntDebugFlag flag : FlagsFactory.getIntDebugFlags()) {
-            if (getIntFlagStateFromSharedPrefs(flag) != flag.get()) {
-                return true;
-            }
-        }
         return false;
     }
 }
diff --git a/quickstep/src/com/android/launcher3/uioverrides/flags/FlagsFactory.java b/quickstep/src/com/android/launcher3/uioverrides/flags/FlagsFactory.java
index 686ed64e4f3484cba9f052a9dec57645111aa280..7fd63445bb3c6c5a31d5345dfaef52dfcf2430ed 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/flags/FlagsFactory.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/flags/FlagsFactory.java
@@ -23,8 +23,6 @@ import static com.android.launcher3.config.FeatureFlags.FlagState.DISABLED;
 import static com.android.launcher3.config.FeatureFlags.FlagState.ENABLED;
 import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
 
-import static java.util.Collections.unmodifiableList;
-
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.provider.DeviceConfig;
@@ -32,13 +30,9 @@ import android.provider.DeviceConfig.Properties;
 import android.util.Log;
 
 import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
 
-import com.android.launcher3.ConstantItem;
-import com.android.launcher3.LauncherPrefs;
 import com.android.launcher3.config.FeatureFlags.BooleanFlag;
 import com.android.launcher3.config.FeatureFlags.FlagState;
-import com.android.launcher3.config.FeatureFlags.IntFlag;
 import com.android.launcher3.util.ScreenOnTracker;
 
 import java.io.PrintWriter;
@@ -62,7 +56,6 @@ public class FlagsFactory {
     public static final String NAMESPACE_LAUNCHER = "launcher";
 
     private static final List<DebugFlag> sDebugFlags = new ArrayList<>();
-    private static final List<IntDebugFlag> sIntDebugFlags = new ArrayList<>();
     private static SharedPreferences sSharedPreferences;
 
     static final BooleanFlag TEAMFOOD_FLAG = getReleaseFlag(
@@ -132,42 +125,6 @@ public class FlagsFactory {
         }
     }
 
-    /**
-     * Creates a new integer flag. Integer flags are always release flags
-     */
-    public static IntFlag getIntFlag(
-            int bugId, String key, int defaultValueInCode, String description) {
-        return getIntFlag(bugId, key, defaultValueInCode, description, null);
-    }
-
-    /**
-     * Creates a new integer flag.
-     *
-     * @param launcherPrefFlag Set launcherPrefFlag to non-null if you want
-     * to modify the int flag in Launcher Developer Options and IntDebugFlag
-     * will be backed up by LauncherPrefs. Modified int value will be saved
-     * in LauncherPrefs.
-     */
-    public static IntFlag getIntFlag(
-            int bugId, String key, int defaultValueInCode, String description,
-            @Nullable ConstantItem<Integer> launcherPrefFlag) {
-        INSTANCE.mKeySet.add(key);
-        int defaultValue = DeviceConfig.getInt(NAMESPACE_LAUNCHER, key, defaultValueInCode);
-        if (IS_DEBUG_DEVICE) {
-            int currentValue;
-            if (launcherPrefFlag == null) {
-                currentValue = defaultValue;
-            } else {
-                currentValue = LauncherPrefs.get(currentApplication()).get(launcherPrefFlag);
-            }
-            IntDebugFlag flag = new IntDebugFlag(key, currentValue, defaultValueInCode,
-                    launcherPrefFlag);
-            sIntDebugFlags.add(flag);
-            return flag;
-        } else {
-            return new IntFlag(defaultValue);
-        }
-    }
 
     static List<DebugFlag> getDebugFlags() {
         if (!IS_DEBUG_DEVICE) {
@@ -178,15 +135,6 @@ public class FlagsFactory {
         }
     }
 
-    static List<IntDebugFlag> getIntDebugFlags() {
-        if (!IS_DEBUG_DEVICE) {
-            return unmodifiableList(Collections.emptyList());
-        }
-        synchronized (sIntDebugFlags) {
-            return unmodifiableList(sIntDebugFlags);
-        }
-    }
-
     /** Returns the SharedPreferences instance backing Debug FeatureFlags. */
     @NonNull
     static SharedPreferences getSharedPreferences() {
@@ -214,12 +162,6 @@ public class FlagsFactory {
                 }
             }
         }
-        pw.println("  IntFlags:");
-        synchronized (sIntDebugFlags) {
-            for (IntFlag flag : sIntDebugFlags) {
-                pw.println("    " + flag);
-            }
-        }
         pw.println("  DebugFlags:");
         synchronized (sDebugFlags) {
             for (DebugFlag flag : sDebugFlags) {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/flags/IntDebugFlag.java b/quickstep/src/com/android/launcher3/uioverrides/flags/IntDebugFlag.java
deleted file mode 100644
index 1350aa87a84facf586fdeb33913f3ecb66c71415..0000000000000000000000000000000000000000
--- a/quickstep/src/com/android/launcher3/uioverrides/flags/IntDebugFlag.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2023 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.uioverrides.flags;
-
-import androidx.annotation.Nullable;
-
-import com.android.launcher3.ConstantItem;
-import com.android.launcher3.config.FeatureFlags.IntFlag;
-
-public class IntDebugFlag extends IntFlag {
-    public final String key;
-    private final int mDefaultValueInCode;
-    @Nullable
-    public final ConstantItem<Integer> launcherPrefFlag;
-
-    public IntDebugFlag(String key, int currentValue, int defaultValueInCode,
-            @Nullable ConstantItem<Integer> launcherPrefFlag) {
-        super(currentValue);
-        this.key = key;
-        mDefaultValueInCode = defaultValueInCode;
-        this.launcherPrefFlag = launcherPrefFlag;
-    }
-
-    @Override
-    public String toString() {
-        return key + ": mCurrentValue=" + get() + ", defaultValueInCode=" + mDefaultValueInCode;
-    }
-}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginEnablerImpl.java b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginEnablerImpl.java
index faa900b714fd8ce1572304673caf2c6211deb695..4e09f1fc59f8d19496415869ef6f3c410a5121a6 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginEnablerImpl.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginEnablerImpl.java
@@ -18,12 +18,10 @@ import android.content.ComponentName;
 import android.content.Context;
 import android.content.SharedPreferences;
 
-import androidx.preference.PreferenceDataStore;
-
 import com.android.launcher3.LauncherPrefs;
 import com.android.systemui.shared.plugins.PluginEnabler;
 
-public class PluginEnablerImpl extends PreferenceDataStore implements PluginEnabler {
+public class PluginEnablerImpl implements PluginEnabler {
 
     private static final String PREFIX_PLUGIN_ENABLED = "PLUGIN_ENABLED_";
 
@@ -44,12 +42,12 @@ public class PluginEnablerImpl extends PreferenceDataStore implements PluginEnab
     }
 
     private void setState(ComponentName component, boolean enabled) {
-        putBoolean(pluginEnabledKey(component), enabled);
+        mSharedPrefs.edit().putBoolean(pluginEnabledKey(component), enabled).apply();
     }
 
     @Override
     public boolean isEnabled(ComponentName component) {
-        return getBoolean(pluginEnabledKey(component), true);
+        return mSharedPrefs.getBoolean(pluginEnabledKey(component), true);
     }
 
     @Override
@@ -57,17 +55,7 @@ public class PluginEnablerImpl extends PreferenceDataStore implements PluginEnab
         return isEnabled(componentName) ? ENABLED : DISABLED_MANUALLY;
     }
 
-    @Override
-    public void putBoolean(String key, boolean value) {
-        mSharedPrefs.edit().putBoolean(key, value).apply();
-    }
-
-    @Override
-    public boolean getBoolean(String key, boolean defValue) {
-        return mSharedPrefs.getBoolean(key, defValue);
-    }
-
-    static String pluginEnabledKey(ComponentName cn) {
+    private static String pluginEnabledKey(ComponentName cn) {
         return PREFIX_PLUGIN_ENABLED + cn.flattenToString();
     }
 }
diff --git a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java
index 7f7871380d2f0d549df9406a662c12c254d77a70..a09d0a1df1c71966b0fa1ff76431df156133fd5a 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java
@@ -98,13 +98,6 @@ public class PluginManagerWrapper {
         return new PluginPrefs(mContext).getPluginList();
     }
 
-    /**
-     * Returns the string key used to store plugin enabled/disabled setting
-     */
-    public static String pluginEnabledKey(ComponentName cn) {
-        return PluginEnablerImpl.pluginEnabledKey(cn);
-    }
-
     public static boolean hasPlugins(Context context) {
         return PluginPrefs.hasPlugins(context);
     }
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 62e823aea14d848f767aaa3f051578582c4eb493..7ee77513629d93fff9b54640ff911534e24d526e 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -22,8 +22,8 @@ import static android.view.Surface.ROTATION_90;
 import static android.widget.Toast.LENGTH_SHORT;
 
 import static com.android.app.animation.Interpolators.ACCELERATE_DECELERATE;
-import static com.android.app.animation.Interpolators.EMPHASIZED;
 import static com.android.app.animation.Interpolators.DECELERATE;
+import static com.android.app.animation.Interpolators.EMPHASIZED;
 import static com.android.app.animation.Interpolators.LINEAR;
 import static com.android.app.animation.Interpolators.OVERSHOOT_1_2;
 import static com.android.launcher3.BaseActivity.EVENT_DESTROYED;
@@ -31,7 +31,6 @@ import static com.android.launcher3.BaseActivity.EVENT_STARTED;
 import static com.android.launcher3.BaseActivity.INVISIBLE_BY_STATE_HANDLER;
 import static com.android.launcher3.BaseActivity.STATE_HANDLER_INVISIBILITY_FLAGS;
 import static com.android.launcher3.Flags.enableGridOnlyOverview;
-import static com.android.launcher3.LauncherPrefs.ALL_APPS_OVERVIEW_THRESHOLD;
 import static com.android.launcher3.PagedView.INVALID_PAGE;
 import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND;
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.IGNORE;
@@ -100,7 +99,6 @@ import com.android.internal.jank.Cuj;
 import com.android.internal.util.LatencyTracker;
 import com.android.launcher3.AbstractFloatingView;
 import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.LauncherPrefs;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.anim.AnimationSuccessListener;
@@ -892,7 +890,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
     @UiThread
     @Override
     public void onCurrentShiftUpdated() {
-        float threshold = LauncherPrefs.get(mContext).get(ALL_APPS_OVERVIEW_THRESHOLD) / 100f;
+        float threshold = DeviceConfigWrapper.get().getAllAppsOverviewThreshold() / 100f;
         setIsInAllAppsRegion(mCurrentShift.value >= threshold);
         updateSysUiFlags(mCurrentShift.value);
         applyScrollAndTransform();
diff --git a/quickstep/src/com/android/quickstep/DeviceConfigWrapper.kt b/quickstep/src/com/android/quickstep/DeviceConfigWrapper.kt
new file mode 100644
index 0000000000000000000000000000000000000000..678709c2e208b32b7cbc50630c4e90a81b5ca2c3
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/DeviceConfigWrapper.kt
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2024 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.quickstep
+
+import com.android.quickstep.util.DeviceConfigHelper
+import com.android.quickstep.util.DeviceConfigHelper.PropReader
+import java.io.PrintWriter
+
+/** Various configurations specific to nav-bar functionalities */
+class DeviceConfigWrapper private constructor(propReader: PropReader) {
+
+    val customLpnhThresholds =
+        propReader.get(
+            "CUSTOM_LPNH_THRESHOLDS",
+            true,
+            "Add dev options and server side control to customize the LPNH trigger slop and milliseconds"
+        )
+
+    val customLphThresholds =
+        propReader.get(
+            "CUSTOM_LPH_THRESHOLDS",
+            false,
+            "Server side control to customize LPH timeout and touch slop"
+        )
+
+    val overrideLpnhLphThresholds =
+        propReader.get(
+            "OVERRIDE_LPNH_LPH_THRESHOLDS",
+            false,
+            "Enable AGSA override for LPNH and LPH timeout and touch slop"
+        )
+
+    val lpnhSlopPercentage =
+        propReader.get("LPNH_SLOP_PERCENTAGE", 100, "Controls touch slop percentage for lpnh")
+
+    val animateLpnh = propReader.get("ANIMATE_LPNH", false, "Animates navbar when long pressing")
+
+    val shrinkNavHandleOnPress =
+        propReader.get(
+            "SHRINK_NAV_HANDLE_ON_PRESS",
+            false,
+            "Shrinks navbar when long pressing if ANIMATE_LPNH is enabled"
+        )
+
+    val lpnhTimeoutMs =
+        propReader.get("LPNH_TIMEOUT_MS", 450, "Controls lpnh timeout in milliseconds")
+
+    val enableLongPressNavHandle =
+        propReader.get(
+            "ENABLE_LONG_PRESS_NAV_HANDLE",
+            true,
+            "Enables long pressing on the bottom bar nav handle to trigger events."
+        )
+
+    val enableSearchHapticHint =
+        propReader.get(
+            "ENABLE_SEARCH_HAPTIC_HINT",
+            true,
+            "Enables haptic hint while long pressing on the bottom bar nav handle."
+        )
+
+    val enableSearchHapticCommit =
+        propReader.get(
+            "ENABLE_SEARCH_HAPTIC_COMMIT",
+            true,
+            "Enables haptic hint at end of long pressing on the bottom bar nav handle."
+        )
+
+    val lpnhHapticHintStartScalePercent =
+        propReader.get("LPNH_HAPTIC_HINT_START_SCALE_PERCENT", 0, "Haptic hint start scale.")
+
+    val lpnhHapticHintEndScalePercent =
+        propReader.get("LPNH_HAPTIC_HINT_END_SCALE_PERCENT", 100, "Haptic hint end scale.")
+
+    val lpnhHapticHintScaleExponent =
+        propReader.get("LPNH_HAPTIC_HINT_SCALE_EXPONENT", 1, "Haptic hint scale exponent.")
+
+    val lpnhHapticHintIterations =
+        propReader.get("LPNH_HAPTIC_HINT_ITERATIONS", 50, "Haptic hint number of iterations.")
+
+    val enableLpnhDeepPress =
+        propReader.get(
+            "ENABLE_LPNH_DEEP_PRESS",
+            true,
+            "Long press of nav handle is instantly triggered if deep press is detected."
+        )
+
+    val lpnhHapticHintDelay =
+        propReader.get("LPNH_HAPTIC_HINT_DELAY", 0, "Delay before haptic hint starts.")
+
+    val lpnhExtraTouchWidthDp =
+        propReader.get(
+            "LPNH_EXTRA_TOUCH_WIDTH_DP",
+            0,
+            "Controls extra dp on the nav bar sides to trigger LPNH. Can be negative for a smaller touch region."
+        )
+
+    val allAppsOverviewThreshold =
+        propReader.get(
+            "ALL_APPS_OVERVIEW_THRESHOLD",
+            180,
+            "Threshold to open All Apps from Overview"
+        )
+
+    /** Dump config values. */
+    fun dump(prefix: String, writer: PrintWriter) {
+        writer.println("$prefix DeviceConfigWrapper:")
+        writer.println("$prefix\tcustomLpnhThresholds=$customLpnhThresholds")
+        writer.println("$prefix\tcustomLphThresholds=$customLphThresholds")
+        writer.println("$prefix\toverrideLpnhLphThresholds=$overrideLpnhLphThresholds")
+        writer.println("$prefix\tlpnhSlopPercentage=$lpnhSlopPercentage")
+        writer.println("$prefix\tanimateLpnh=$animateLpnh")
+        writer.println("$prefix\tshrinkNavHandleOnPress=$shrinkNavHandleOnPress")
+        writer.println("$prefix\tlpnhTimeoutMs=$lpnhTimeoutMs")
+        writer.println("$prefix\tenableLongPressNavHandle=$enableLongPressNavHandle")
+        writer.println("$prefix\tenableSearchHapticHint=$enableSearchHapticHint")
+        writer.println("$prefix\tenableSearchHapticCommit=$enableSearchHapticCommit")
+        writer.println("$prefix\tlpnhHapticHintStartScalePercent=$lpnhHapticHintStartScalePercent")
+        writer.println("$prefix\tlpnhHapticHintEndScalePercent=$lpnhHapticHintEndScalePercent")
+        writer.println("$prefix\tlpnhHapticHintScaleExponent=$lpnhHapticHintScaleExponent")
+        writer.println("$prefix\tlpnhHapticHintIterations=$lpnhHapticHintIterations")
+        writer.println("$prefix\tenableLpnhDeepPress=$enableLpnhDeepPress")
+        writer.println("$prefix\tlpnhHapticHintDelay=$lpnhHapticHintDelay")
+        writer.println("$prefix\tlpnhExtraTouchWidthDp=$lpnhExtraTouchWidthDp")
+        writer.println("$prefix\tallAppsOverviewThreshold=$allAppsOverviewThreshold")
+    }
+
+    companion object {
+        val configHelper by lazy { DeviceConfigHelper(::DeviceConfigWrapper) }
+
+        @JvmStatic fun get() = configHelper.config
+    }
+}
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
index c56a6219b212fa31a234c6075ce78ba475bd5016..43e564cadfce2fe8c7d3f9dfd1808b7f2fdbb42c 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
@@ -60,7 +60,6 @@ import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 
-import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.util.DisplayController;
 import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener;
 import com.android.launcher3.util.DisplayController.Info;
@@ -588,9 +587,8 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener, E
                 : QUICKSTEP_TOUCH_SLOP_RATIO_TWO_BUTTON;
         float touchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop();
 
-        if (FeatureFlags.CUSTOM_LPNH_THRESHOLDS.get()) {
-            float customSlopMultiplier =
-                    FeatureFlags.LPNH_SLOP_PERCENTAGE.get() / 100f;
+        if (DeviceConfigWrapper.get().getCustomLpnhThresholds()) {
+            float customSlopMultiplier = DeviceConfigWrapper.get().getLpnhSlopPercentage() / 100f;
             return customSlopMultiplier * slopMultiplier * touchSlop;
         } else {
             return slopMultiplier * touchSlop;
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 66d7144ae085bd9f8c54f53eed361f4a34e2c086..f2ee3f1483e71b4f855518e3ec092a8c0aea200d 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -1456,6 +1456,7 @@ public class TouchInteractionService extends Service {
         pw.println("AssistStateManager:");
         AssistStateManager.INSTANCE.get(this).dump("  ", pw);
         SystemUiProxy.INSTANCE.get(this).dump(pw);
+        DeviceConfigWrapper.get().dump("   ", pw);
     }
 
     private AbsSwipeUpHandler createLauncherSwipeHandler(
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java
index e22703b65914495d9b362d9eed5e1e92d3f4bde2..5ab2fcc1544ae963e4a31e2e9dd7859bf2e52a12 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java
@@ -27,9 +27,9 @@ import android.view.MotionEvent;
 import android.view.ViewConfiguration;
 
 import com.android.launcher3.Utilities;
-import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.logging.StatsLogManager;
 import com.android.launcher3.util.DisplayController;
+import com.android.quickstep.DeviceConfigWrapper;
 import com.android.quickstep.InputConsumer;
 import com.android.quickstep.NavHandle;
 import com.android.quickstep.RecentsAnimationDeviceState;
@@ -64,7 +64,7 @@ public class NavHandleLongPressInputConsumer extends DelegateInputConsumer {
             NavHandle navHandle) {
         super(delegate, inputMonitor);
         mScreenWidth = DisplayController.INSTANCE.get(context).getInfo().currentSize.x;
-        mDeepPressEnabled = FeatureFlags.ENABLE_LPNH_DEEP_PRESS.get();
+        mDeepPressEnabled = DeviceConfigWrapper.get().getEnableLpnhDeepPress();
         AssistStateManager assistStateManager = AssistStateManager.INSTANCE.get(context);
         if (assistStateManager.getLPNHDurationMillis().isPresent()) {
             mLongPressTimeout = assistStateManager.getLPNHDurationMillis().get().intValue();
@@ -181,8 +181,9 @@ public class NavHandleLongPressInputConsumer extends DelegateInputConsumer {
 
     private boolean isInNavBarHorizontalArea(float x) {
         float areaFromMiddle = mNavHandleWidth / 2.0f;
-        if (FeatureFlags.CUSTOM_LPNH_THRESHOLDS.get()) {
-            areaFromMiddle += Utilities.dpToPx(FeatureFlags.LPNH_EXTRA_TOUCH_WIDTH_DP.get());
+        if (DeviceConfigWrapper.get().getCustomLpnhThresholds()) {
+            areaFromMiddle += Utilities.dpToPx(
+                    DeviceConfigWrapper.get().getLpnhExtraTouchWidthDp());
         }
         int minAccessibleSize = Utilities.dpToPx(24);  // Half of 48dp because this is per side.
         if (areaFromMiddle < minAccessibleSize) {
diff --git a/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java b/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java
index 16f206556f5c80b1b351bd33b6b17154ed16771b..561e951362df70b1735b4ae24451c74880b4b68c 100644
--- a/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java
+++ b/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java
@@ -18,7 +18,6 @@ package com.android.quickstep.util;
 import static com.android.app.animation.Interpolators.DECELERATE;
 import static com.android.app.animation.Interpolators.LINEAR;
 import static com.android.launcher3.Flags.enableGridOnlyOverview;
-import static com.android.launcher3.LauncherPrefs.ALL_APPS_OVERVIEW_THRESHOLD;
 import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
 import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION;
 
@@ -35,7 +34,6 @@ import androidx.annotation.Nullable;
 
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherPrefs;
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.anim.AnimatorPlaybackController;
@@ -44,6 +42,7 @@ import com.android.launcher3.statemanager.StateManager;
 import com.android.launcher3.statemanager.StatefulActivity;
 import com.android.launcher3.states.StateAnimationConfig;
 import com.android.launcher3.touch.AllAppsSwipeController;
+import com.android.quickstep.DeviceConfigWrapper;
 import com.android.quickstep.orientation.RecentsPagedOrientationHandler;
 import com.android.quickstep.views.RecentsView;
 
@@ -191,7 +190,7 @@ public class AnimatorControllerWithResistance {
                         recentsOrientedState.getOrientationHandler());
         float dragLengthFactor = (float) dp.heightPx / transitionDragLength;
         // -1s are because 0-1 is reserved for the normal transition.
-        float threshold = LauncherPrefs.get(context).get(ALL_APPS_OVERVIEW_THRESHOLD) / 100f;
+        float threshold = DeviceConfigWrapper.get().getAllAppsOverviewThreshold() / 100f;
         return (threshold - 1) / (dragLengthFactor - 1);
     }
 
diff --git a/quickstep/src/com/android/quickstep/util/DeviceConfigHelper.kt b/quickstep/src/com/android/quickstep/util/DeviceConfigHelper.kt
new file mode 100644
index 0000000000000000000000000000000000000000..f601fee954c7331afe3820493636a28a4f8c9b20
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/util/DeviceConfigHelper.kt
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2024 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.quickstep.util
+
+import android.app.ActivityThread
+import android.content.Context
+import android.content.SharedPreferences
+import android.content.SharedPreferences.*
+import android.provider.DeviceConfig
+import android.provider.DeviceConfig.OnPropertiesChangedListener
+import android.provider.DeviceConfig.Properties
+import androidx.annotation.WorkerThread
+import com.android.launcher3.BuildConfig
+import com.android.launcher3.uioverrides.flags.FlagsFactory
+import com.android.launcher3.util.Executors
+
+/** Utility class to manage a set of device configurations */
+class DeviceConfigHelper<ConfigType>(private val factory: (PropReader) -> ConfigType) {
+
+    var config: ConfigType
+        private set
+    private val allKeys: Set<String>
+    private val propertiesListener = OnPropertiesChangedListener { onDevicePropsChanges(it) }
+    private val sharedPrefChangeListener = OnSharedPreferenceChangeListener { _, _ ->
+        recreateConfig()
+    }
+
+    private val changeListeners = mutableListOf<Runnable>()
+
+    init {
+        // Initialize the default config once.
+        allKeys = HashSet()
+        config =
+            factory(
+                PropReader(
+                    object : PropProvider {
+                        override fun <T : Any> get(key: String, fallback: T): T {
+                            if (fallback is Int)
+                                return DeviceConfig.getInt(NAMESPACE_LAUNCHER, key, fallback) as T
+                            else if (fallback is Boolean)
+                                return DeviceConfig.getBoolean(NAMESPACE_LAUNCHER, key, fallback)
+                                    as T
+                            else return fallback
+                        }
+                    }
+                )
+            )
+
+        DeviceConfig.addOnPropertiesChangedListener(
+            NAMESPACE_LAUNCHER,
+            Executors.UI_HELPER_EXECUTOR,
+            propertiesListener
+        )
+        if (BuildConfig.IS_DEBUG_DEVICE) {
+            prefs.registerOnSharedPreferenceChangeListener(sharedPrefChangeListener)
+        }
+    }
+
+    @WorkerThread
+    private fun onDevicePropsChanges(properties: Properties) {
+        if (NAMESPACE_LAUNCHER != properties.namespace) return
+        if (!allKeys.any(properties.keyset::contains)) return
+        recreateConfig()
+    }
+
+    private fun recreateConfig() {
+        val myProps =
+            DeviceConfig.getProperties(
+                FlagsFactory.NAMESPACE_LAUNCHER,
+                *allKeys.toTypedArray<String>()
+            )
+        config =
+            factory(
+                PropReader(
+                    object : PropProvider {
+                        override fun <T : Any> get(key: String, fallback: T): T {
+                            if (fallback is Int) return myProps.getInt(key, fallback) as T
+                            else if (fallback is Boolean)
+                                return myProps.getBoolean(key, fallback) as T
+                            else return fallback
+                        }
+                    }
+                )
+            )
+        Executors.MAIN_EXECUTOR.execute { changeListeners.forEach(Runnable::run) }
+    }
+
+    /** Adds a listener for property changes */
+    fun addChangeListener(r: Runnable) = changeListeners.add(r)
+
+    /** Removes a previously added listener */
+    fun removeChangeListener(r: Runnable) = changeListeners.remove(r)
+
+    fun close() {
+        DeviceConfig.removeOnPropertiesChangedListener(propertiesListener)
+        if (BuildConfig.IS_DEBUG_DEVICE) {
+            prefs.unregisterOnSharedPreferenceChangeListener(sharedPrefChangeListener)
+        }
+    }
+
+    internal interface PropProvider {
+        fun <T : Any> get(key: String, fallback: T): T
+    }
+
+    /** The reader is sent to the config for initialization */
+    class PropReader internal constructor(private val f: PropProvider) {
+
+        @JvmOverloads
+        fun <T : Any> get(key: String, fallback: T, desc: String? = null): T {
+            val v = f.get(key, fallback)
+            if (BuildConfig.IS_DEBUG_DEVICE && desc != null) {
+                if (v is Int) {
+                    allProps[key] = DebugInfo(key, desc, true, fallback)
+                    return prefs.getInt(key, v) as T
+                } else if (v is Boolean) {
+                    allProps[key] = DebugInfo(key, desc, false, fallback)
+                    return prefs.getBoolean(key, v) as T
+                }
+            }
+            return v
+        }
+    }
+
+    class DebugInfo<T>(
+        val key: String,
+        val desc: String,
+        val isInt: Boolean,
+        val valueInCode: T,
+    )
+
+    companion object {
+        const val NAMESPACE_LAUNCHER = "launcher"
+
+        val allProps = mutableMapOf<String, DebugInfo<*>>()
+
+        private const val FLAGS_PREF_NAME = "featureFlags"
+
+        val prefs: SharedPreferences by lazy {
+            ActivityThread.currentApplication()
+                .createDeviceProtectedStorageContext()
+                .getSharedPreferences(FLAGS_PREF_NAME, Context.MODE_PRIVATE)
+        }
+    }
+}
diff --git a/res/layout/develop_options_edit_text.xml b/res/layout/develop_options_edit_text.xml
new file mode 100644
index 0000000000000000000000000000000000000000..5e44228982bd492b3a37bd61ccff42c48c951351
--- /dev/null
+++ b/res/layout/develop_options_edit_text.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2024 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.
+  -->
+
+<com.android.launcher3.ExtendedEditText
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:minWidth="100dp"
+    android:inputType="numberSigned"
+    android:id="@+id/pref_edit_text"
+    android:selectAllOnFocus="true"
+    android:imeOptions="actionDone"
+    android:maxLines="1" />
\ No newline at end of file
diff --git a/src/com/android/launcher3/LauncherPrefs.kt b/src/com/android/launcher3/LauncherPrefs.kt
index cb19b143a418c1a163b16a1101ef28e03994aeb9..875c407d5dd9ce7072bdfc056bfd097a76136e69 100644
--- a/src/com/android/launcher3/LauncherPrefs.kt
+++ b/src/com/android/launcher3/LauncherPrefs.kt
@@ -297,64 +297,7 @@ class LauncherPrefs(private val encryptedContext: Context) {
         @JvmField
         val ICON_STATE =
             nonRestorableItem("pref_icon_shape_path", "", EncryptionType.MOVE_TO_DEVICE_PROTECTED)
-        @JvmField
-        val ALL_APPS_OVERVIEW_THRESHOLD =
-            nonRestorableItem(
-                "pref_all_apps_overview_threshold",
-                180,
-                EncryptionType.MOVE_TO_DEVICE_PROTECTED
-            )
-        @JvmField
-        val LONG_PRESS_NAV_HANDLE_SLOP_PERCENTAGE =
-            nonRestorableItem("LPNH_SLOP_PERCENTAGE", 100, EncryptionType.MOVE_TO_DEVICE_PROTECTED)
-        @JvmField
-        val LONG_PRESS_NAV_HANDLE_EXTRA_TOUCH_WIDTH_DP =
-            nonRestorableItem(
-                "LPNH_EXTRA_TOUCH_WIDTH_DP",
-                0,
-                EncryptionType.MOVE_TO_DEVICE_PROTECTED
-            )
-        @JvmField
-        val LONG_PRESS_NAV_HANDLE_TIMEOUT_MS =
-            nonRestorableItem(
-                "LPNH_TIMEOUT_MS",
-                450,
-                EncryptionType.MOVE_TO_DEVICE_PROTECTED
-            )
-        @JvmField
-        val LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_START_SCALE_PERCENT =
-            nonRestorableItem(
-                "LPNH_HAPTIC_HINT_START_SCALE_PERCENT",
-                0,
-                EncryptionType.MOVE_TO_DEVICE_PROTECTED
-            )
-        @JvmField
-        val LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_END_SCALE_PERCENT =
-            nonRestorableItem(
-                "LPNH_HAPTIC_HINT_END_SCALE_PERCENT",
-                100,
-                EncryptionType.MOVE_TO_DEVICE_PROTECTED
-            )
-        @JvmField
-        val LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_SCALE_EXPONENT =
-            nonRestorableItem(
-                "LPNH_HAPTIC_HINT_SCALE_EXPONENT",
-                1,
-                EncryptionType.MOVE_TO_DEVICE_PROTECTED
-            )
-        @JvmField
-        val LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_ITERATIONS =
-            nonRestorableItem(
-                "LPNH_HAPTIC_HINT_ITERATIONS",
-                50,
-                EncryptionType.MOVE_TO_DEVICE_PROTECTED
-            )
-        @JvmField
-        val LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_DELAY =
-            nonRestorableItem("LPNH_HAPTIC_HINT_DELAY", 0, EncryptionType.MOVE_TO_DEVICE_PROTECTED)
-        @JvmField
-        val PRIVATE_SPACE_APPS =
-            nonRestorableItem("pref_private_space_apps", 0, EncryptionType.MOVE_TO_DEVICE_PROTECTED)
+
         @JvmField
         val ENABLE_TWOLINE_ALLAPPS_TOGGLE = backedUpItem("pref_enable_two_line_toggle", false)
         @JvmField
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index e47613848746b79377d9c061feed44879a914c7f..d6ce2b364385c260b7926cf4accd8af6b29812b2 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -17,14 +17,6 @@
 package com.android.launcher3.config;
 
 import static com.android.launcher3.BuildConfig.WIDGET_ON_FIRST_SCREEN;
-import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_EXTRA_TOUCH_WIDTH_DP;
-import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_DELAY;
-import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_END_SCALE_PERCENT;
-import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_ITERATIONS;
-import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_SCALE_EXPONENT;
-import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_START_SCALE_PERCENT;
-import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_SLOP_PERCENTAGE;
-import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_TIMEOUT_MS;
 import static com.android.launcher3.config.FeatureFlags.FlagState.DISABLED;
 import static com.android.launcher3.config.FeatureFlags.FlagState.ENABLED;
 import static com.android.launcher3.config.FeatureFlags.FlagState.TEAMFOOD;
@@ -38,10 +30,8 @@ import androidx.annotation.VisibleForTesting;
 
 import com.android.launcher3.BuildConfig;
 import com.android.launcher3.Flags;
-import com.android.launcher3.uioverrides.flags.FlagsFactory;
 
 import java.util.function.Predicate;
-import java.util.function.ToIntFunction;
 
 /**
  * Defines a set of flags used to control various launcher behaviors.
@@ -52,8 +42,6 @@ public final class FeatureFlags {
 
     @VisibleForTesting
     public static Predicate<BooleanFlag> sBooleanReader = f -> f.mCurrentValue;
-    @VisibleForTesting
-    public static ToIntFunction<IntFlag> sIntReader = f -> f.mCurrentValue;
 
     private FeatureFlags() { }
 
@@ -130,42 +118,6 @@ public final class FeatureFlags {
             getDebugFlag(275132633, "ENABLE_ALL_APPS_FROM_OVERVIEW", DISABLED,
                     "Allow entering All Apps from Overview (e.g. long swipe up from app)");
 
-    public static final BooleanFlag CUSTOM_LPNH_THRESHOLDS =
-            getReleaseFlag(301680992, "CUSTOM_LPNH_THRESHOLDS", ENABLED,
-                    "Add dev options and server side control to customize the LPNH "
-                            + "trigger slop and milliseconds");
-
-    public static final BooleanFlag CUSTOM_LPH_THRESHOLDS = getReleaseFlag(331800576,
-            "CUSTOM_LPH_THRESHOLDS", DISABLED,
-            "Server side control to customize LPH timeout and touch slop");
-
-    public static final BooleanFlag OVERRIDE_LPNH_LPH_THRESHOLDS = getReleaseFlag(331799727,
-            "OVERRIDE_LPNH_LPH_THRESHOLDS", DISABLED,
-            "Enable AGSA override for LPNH and LPH timeout and touch slop");
-
-    public static final BooleanFlag ANIMATE_LPNH =
-            getReleaseFlag(308693847, "ANIMATE_LPNH", TEAMFOOD,
-                    "Animates navbar when long pressing");
-
-    public static final BooleanFlag SHRINK_NAV_HANDLE_ON_PRESS =
-            getReleaseFlag(314158312, "SHRINK_NAV_HANDLE_ON_PRESS", DISABLED,
-                    "Shrinks navbar when long pressing if ANIMATE_LPNH is enabled");
-
-    public static final IntFlag LPNH_SLOP_PERCENTAGE =
-            FlagsFactory.getIntFlag(301680992, "LPNH_SLOP_PERCENTAGE", 100,
-                    "Controls touch slop percentage for lpnh",
-                    LONG_PRESS_NAV_HANDLE_SLOP_PERCENTAGE);
-
-    public static final IntFlag LPNH_EXTRA_TOUCH_WIDTH_DP =
-            FlagsFactory.getIntFlag(301680992, "LPNH_EXTRA_TOUCH_WIDTH_DP", 0,
-                    "Controls extra dp on the nav bar sides to trigger LPNH."
-                            + " Can be negative for a smaller touch region.",
-                    LONG_PRESS_NAV_HANDLE_EXTRA_TOUCH_WIDTH_DP);
-
-    public static final IntFlag LPNH_TIMEOUT_MS =
-            FlagsFactory.getIntFlag(301680992, "LPNH_TIMEOUT_MS", 450,
-                    "Controls lpnh timeout in milliseconds", LONG_PRESS_NAV_HANDLE_TIMEOUT_MS);
-
     public static final BooleanFlag ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS = getReleaseFlag(
             270394468, "ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS", ENABLED,
             "Enable option to show keyboard when going to all-apps");
@@ -296,49 +248,6 @@ public final class FeatureFlags {
             "INJECT_FALLBACK_APP_CORPUS_RESULTS", DISABLED,
             "Inject fallback app corpus result when AiAi fails to return it.");
 
-    public static final BooleanFlag ENABLE_LONG_PRESS_NAV_HANDLE =
-            getReleaseFlag(299682306, "ENABLE_LONG_PRESS_NAV_HANDLE", ENABLED,
-                    "Enables long pressing on the bottom bar nav handle to trigger events.");
-
-    public static final BooleanFlag ENABLE_SEARCH_HAPTIC_HINT =
-            getReleaseFlag(314005131, "ENABLE_SEARCH_HAPTIC_HINT", ENABLED,
-                    "Enables haptic hint while long pressing on the bottom bar nav handle.");
-
-    public static final BooleanFlag ENABLE_SEARCH_HAPTIC_COMMIT =
-            getReleaseFlag(314005577, "ENABLE_SEARCH_HAPTIC_COMMIT", ENABLED,
-                    "Enables haptic hint at end of long pressing on the bottom bar nav handle.");
-
-    public static final IntFlag LPNH_HAPTIC_HINT_START_SCALE_PERCENT =
-            FlagsFactory.getIntFlag(309972570,
-                    "LPNH_HAPTIC_HINT_START_SCALE_PERCENT", 0,
-                    "Haptic hint start scale.",
-                    LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_START_SCALE_PERCENT);
-
-    public static final IntFlag LPNH_HAPTIC_HINT_END_SCALE_PERCENT =
-            FlagsFactory.getIntFlag(309972570,
-                    "LPNH_HAPTIC_HINT_END_SCALE_PERCENT", 100,
-                    "Haptic hint end scale.", LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_END_SCALE_PERCENT);
-
-    public static final IntFlag LPNH_HAPTIC_HINT_SCALE_EXPONENT =
-            FlagsFactory.getIntFlag(309972570,
-                    "LPNH_HAPTIC_HINT_SCALE_EXPONENT", 1,
-                    "Haptic hint scale exponent.",
-                    LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_SCALE_EXPONENT);
-
-    public static final IntFlag LPNH_HAPTIC_HINT_ITERATIONS =
-            FlagsFactory.getIntFlag(309972570, "LPNH_HAPTIC_HINT_ITERATIONS",
-                    50,
-                    "Haptic hint number of iterations.",
-                    LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_ITERATIONS);
-
-    public static final BooleanFlag ENABLE_LPNH_DEEP_PRESS =
-            getReleaseFlag(310952290, "ENABLE_LPNH_DEEP_PRESS", ENABLED,
-                    "Long press of nav handle is instantly triggered if deep press is detected.");
-
-    public static final IntFlag LPNH_HAPTIC_HINT_DELAY =
-            FlagsFactory.getIntFlag(309972570, "LPNH_HAPTIC_HINT_DELAY", 0,
-                    "Delay before haptic hint starts.", LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_DELAY);
-
     // TODO(Block 17): Clean up flags
     // Aconfig migration complete for ENABLE_TASKBAR_PINNING.
     private static final BooleanFlag ENABLE_TASKBAR_PINNING = getDebugFlag(296231746,
@@ -514,22 +423,6 @@ public final class FeatureFlags {
         }
     }
 
-    /**
-     * Class representing an integer flag
-     */
-    public static class IntFlag {
-
-        private final int mCurrentValue;
-
-        public IntFlag(int currentValue) {
-            mCurrentValue = currentValue;
-        }
-
-        public int get() {
-            return sIntReader.applyAsInt(this);
-        }
-    }
-
     /**
      * Enabled state for a flag
      */
diff --git a/src/com/android/launcher3/util/VibratorWrapper.java b/src/com/android/launcher3/util/VibratorWrapper.java
index e1695e96c3d06cf6cde5e63a27f42b1cf7a6e78a..cd60c1d1936530692d5bb37f62df5eacd2439e6e 100644
--- a/src/com/android/launcher3/util/VibratorWrapper.java
+++ b/src/com/android/launcher3/util/VibratorWrapper.java
@@ -19,11 +19,6 @@ import static android.os.VibrationEffect.Composition.PRIMITIVE_LOW_TICK;
 import static android.os.VibrationEffect.createPredefined;
 import static android.provider.Settings.System.HAPTIC_FEEDBACK_ENABLED;
 
-import static com.android.launcher3.config.FeatureFlags.LPNH_HAPTIC_HINT_DELAY;
-import static com.android.launcher3.config.FeatureFlags.LPNH_HAPTIC_HINT_END_SCALE_PERCENT;
-import static com.android.launcher3.config.FeatureFlags.LPNH_HAPTIC_HINT_ITERATIONS;
-import static com.android.launcher3.config.FeatureFlags.LPNH_HAPTIC_HINT_SCALE_EXPONENT;
-import static com.android.launcher3.config.FeatureFlags.LPNH_HAPTIC_HINT_START_SCALE_PERCENT;
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
 import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
 
@@ -40,7 +35,6 @@ import android.provider.Settings;
 import androidx.annotation.Nullable;
 
 import com.android.launcher3.Utilities;
-import com.android.launcher3.config.FeatureFlags;
 
 /**
  * Wrapper around {@link Vibrator} to easily perform haptic feedback where necessary.
@@ -71,9 +65,6 @@ public class VibratorWrapper {
     @Nullable
     private final VibrationEffect mBumpEffect;
 
-    @Nullable
-    private final VibrationEffect mSearchEffect;
-
     private long mLastDragTime;
     private final int mThresholdUntilNextDragCallMillis;
 
@@ -133,25 +124,6 @@ public class VibratorWrapper {
             mBumpEffect = null;
             mThresholdUntilNextDragCallMillis = 0;
         }
-
-        if (mVibrator.areAllPrimitivesSupported(
-                VibrationEffect.Composition.PRIMITIVE_QUICK_RISE,
-                VibrationEffect.Composition.PRIMITIVE_TICK)) {
-            if (FeatureFlags.ENABLE_SEARCH_HAPTIC_HINT.get()) {
-                mSearchEffect = VibrationEffect.startComposition()
-                        .addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 1f)
-                        .compose();
-            } else {
-                // quiet ramp, short pause, then sharp tick
-                mSearchEffect = VibrationEffect.startComposition()
-                        .addPrimitive(VibrationEffect.Composition.PRIMITIVE_QUICK_RISE, 0.25f)
-                        .addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 1f, 50)
-                        .compose();
-            }
-        } else {
-            // fallback for devices without composition support
-            mSearchEffect = VibrationEffect.createPredefined(VibrationEffect.EFFECT_HEAVY_CLICK);
-        }
     }
 
     /**
@@ -233,13 +205,6 @@ public class VibratorWrapper {
         }
     }
 
-    /** Indicates that search has been invoked. */
-    public void vibrateForSearch() {
-        if (mSearchEffect != null) {
-            vibrate(mSearchEffect);
-        }
-    }
-
     /** Indicates that Taskbar has been invoked. */
     public void vibrateForTaskbarUnstash() {
         if (Utilities.ATLEAST_S && mVibrator.areAllPrimitivesSupported(PRIMITIVE_LOW_TICK)) {
@@ -251,32 +216,4 @@ public class VibratorWrapper {
             vibrate(primitiveLowTickEffect);
         }
     }
-
-    /** Indicates that search will be invoked if the current gesture is maintained. */
-    public void vibrateForSearchHint() {
-        if (FeatureFlags.ENABLE_SEARCH_HAPTIC_HINT.get() && Utilities.ATLEAST_S
-                && mVibrator.areAllPrimitivesSupported(PRIMITIVE_LOW_TICK)) {
-            float startScale = LPNH_HAPTIC_HINT_START_SCALE_PERCENT.get() / 100f;
-            float endScale = LPNH_HAPTIC_HINT_END_SCALE_PERCENT.get() / 100f;
-            int scaleExponent = LPNH_HAPTIC_HINT_SCALE_EXPONENT.get();
-            int iterations = LPNH_HAPTIC_HINT_ITERATIONS.get();
-            int delayMs = LPNH_HAPTIC_HINT_DELAY.get();
-
-            VibrationEffect.Composition composition = VibrationEffect.startComposition();
-            for (int i = 0; i < iterations; i++) {
-                float t = i / (iterations - 1f);
-                float scale = (float) Math.pow((1 - t) * startScale + t * endScale,
-                        scaleExponent);
-                if (i == 0) {
-                    // Adds a delay before the ramp starts
-                    composition.addPrimitive(PRIMITIVE_LOW_TICK, scale,
-                            delayMs);
-                } else {
-                    composition.addPrimitive(PRIMITIVE_LOW_TICK, scale);
-                }
-            }
-
-            vibrate(composition.compose());
-        }
-    }
 }
diff --git a/src_no_quickstep/com/android/launcher3/uioverrides/flags/FlagsFactory.java b/src_no_quickstep/com/android/launcher3/uioverrides/flags/FlagsFactory.java
index b193d3789597b26db2cb160c67650ca22db78fdd..02e0de02c40c57cf50a885f44df3fa49428fd0c5 100644
--- a/src_no_quickstep/com/android/launcher3/uioverrides/flags/FlagsFactory.java
+++ b/src_no_quickstep/com/android/launcher3/uioverrides/flags/FlagsFactory.java
@@ -18,12 +18,8 @@ package com.android.launcher3.uioverrides.flags;
 
 import static com.android.launcher3.config.FeatureFlags.FlagState.ENABLED;
 
-import androidx.annotation.Nullable;
-
-import com.android.launcher3.ConstantItem;
 import com.android.launcher3.config.FeatureFlags.BooleanFlag;
 import com.android.launcher3.config.FeatureFlags.FlagState;
-import com.android.launcher3.config.FeatureFlags.IntFlag;
 
 import java.io.PrintWriter;
 
@@ -49,23 +45,6 @@ public class FlagsFactory {
         return new BooleanFlag(flagState == ENABLED);
     }
 
-    /**
-     * Creates a new integer flag. Integer flags are always release flags
-     */
-    public static IntFlag getIntFlag(
-            int bugId, String key, int defaultValueInCode, String description) {
-        return new IntFlag(defaultValueInCode);
-    }
-
-    /**
-     * Creates a new debug integer flag and it is saved in LauncherPrefs.
-     */
-    public static IntFlag getIntFlag(
-            int bugId, String key, int defaultValueInCode, String description,
-            @Nullable ConstantItem<Integer> launcherPrefFlag) {
-        return new IntFlag(defaultValueInCode);
-    }
-
     /**
      * Dumps the current flags state to the print writer
      */
diff --git a/tests/multivalentTests/src/com/android/launcher3/util/TestUtil.java b/tests/multivalentTests/src/com/android/launcher3/util/TestUtil.java
index 95444ba3f24f3ec743d18035e9ea8e9bf0dab2db..2a0f614ae0b5964da2ab3ef653d0a1c031660787 100644
--- a/tests/multivalentTests/src/com/android/launcher3/util/TestUtil.java
+++ b/tests/multivalentTests/src/com/android/launcher3/util/TestUtil.java
@@ -48,7 +48,6 @@ import androidx.test.uiautomator.UiDevice;
 
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.config.FeatureFlags.BooleanFlag;
-import com.android.launcher3.config.FeatureFlags.IntFlag;
 import com.android.launcher3.tapl.LauncherInstrumentation;
 import com.android.launcher3.tapl.Workspace;
 import com.android.launcher3.util.rule.TestStabilityRule;
@@ -67,7 +66,6 @@ import java.util.concurrent.FutureTask;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 import java.util.function.Predicate;
-import java.util.function.ToIntFunction;
 
 public class TestUtil {
     private static final String TAG = "TestUtil";
@@ -169,21 +167,6 @@ public class TestUtil {
         };
     }
 
-    /**
-     * Utility class to override a int flag during test. Note that the returned SafeCloseable
-     * must be closed to restore the original state
-     */
-    public static SafeCloseable overrideFlag(IntFlag flag, int value) {
-        ToIntFunction<IntFlag> originalProxy = FeatureFlags.sIntReader;
-        ToIntFunction<IntFlag> testProxy = f -> f == flag ? value : originalProxy.applyAsInt(f);
-        FeatureFlags.sIntReader = testProxy;
-        return () -> {
-            if (FeatureFlags.sIntReader == testProxy) {
-                FeatureFlags.sIntReader = originalProxy;
-            }
-        };
-    }
-
     public static void uninstallDummyApp() throws IOException {
         UiDevice.getInstance(getInstrumentation()).executeShellCommand(
                 "pm uninstall " + DUMMY_PACKAGE);