Merge "Crop avatar to circle when syncing from Contacts." into tm-qpr-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 8334466..564d5c2 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -2976,6 +2976,7 @@
                   android:taskAffinity="com.android.settings.FallbackHome"
                   android:exported="true"
                   android:theme="@style/FallbackHome"
+                  android:permission="android.permission.DEVICE_POWER"
                   android:configChanges="keyboardHidden">
             <intent-filter android:priority="-1000">
                 <action android:name="android.intent.action.MAIN" />
diff --git a/res/drawable/volume_dialog_button_background_outline.xml b/res/drawable/volume_dialog_button_background_outline.xml
index 78f3fcf..efbaec6 100644
--- a/res/drawable/volume_dialog_button_background_outline.xml
+++ b/res/drawable/volume_dialog_button_background_outline.xml
@@ -14,18 +14,21 @@
      See the License for the specific language governing permissions and
      limitations under the License.
   -->
-
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
-       android:shape="rectangle">
-    <stroke
-        android:color="?androidprv:attr/colorAccentPrimaryVariant"
-        android:width="1dp"/>
-    <corners android:radius="24dp"/>
-    <padding
-        android:left="16dp"
-        android:right="16dp"
-        android:top="8dp"
-        android:bottom="8dp" />
-    <solid android:color="@android:color/transparent" />
-</shape>
\ No newline at end of file
+       android:insetTop="6dp"
+       android:insetBottom="6dp">
+    <shape
+           android:shape="rectangle">
+        <stroke
+            android:color="?androidprv:attr/colorAccentPrimaryVariant"
+            android:width="1dp"/>
+        <corners android:radius="24dp"/>
+        <padding
+            android:left="16dp"
+            android:right="16dp"
+            android:top="8dp"
+            android:bottom="8dp" />
+        <solid android:color="@android:color/transparent" />
+    </shape>
+</inset>
\ No newline at end of file
diff --git a/res/drawable/volume_dialog_button_background_solid.xml b/res/drawable/volume_dialog_button_background_solid.xml
index 1fa8f20..697131d 100644
--- a/res/drawable/volume_dialog_button_background_solid.xml
+++ b/res/drawable/volume_dialog_button_background_solid.xml
@@ -15,17 +15,20 @@
      limitations under the License.
   -->
 
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
-       android:shape="rectangle">
-    <stroke
-        android:color="@android:color/transparent"
-        android:width="1dp"/>
-    <corners android:radius="20dp"/>
-    <padding
-        android:left="16dp"
-        android:right="16dp"
-        android:top="8dp"
-        android:bottom="8dp" />
-    <solid android:color="?androidprv:attr/colorAccentPrimary" />
-</shape>
\ No newline at end of file
+       android:insetTop="6dp"
+       android:insetBottom="6dp">
+    <shape android:shape="rectangle">
+        <stroke
+            android:color="@android:color/transparent"
+            android:width="1dp"/>
+        <corners android:radius="20dp"/>
+        <padding
+            android:left="16dp"
+            android:right="16dp"
+            android:top="8dp"
+            android:bottom="8dp" />
+        <solid android:color="?androidprv:attr/colorAccentPrimary" />
+    </shape>
+</inset>
\ No newline at end of file
diff --git a/res/layout/panel_layout.xml b/res/layout/panel_layout.xml
index 2b9daeb..f154abc 100644
--- a/res/layout/panel_layout.xml
+++ b/res/layout/panel_layout.xml
@@ -117,7 +117,7 @@
                 android:id="@+id/see_more"
                 style="@style/PanelOptionRoundedOutlinedButton"
                 android:layout_width="wrap_content"
-                android:layout_height="36dp"
+                android:layout_height="wrap_content"
                 android:minWidth="0dp"
                 android:text="@string/settings_button"/>
 
@@ -130,7 +130,7 @@
                 android:id="@+id/done"
                 style="@style/PanelOptionRoundedSolidButton"
                 android:layout_width="wrap_content"
-                android:layout_height="36dp"
+                android:layout_height="wrap_content"
                 android:minWidth="0dp"
                 android:text="@string/done"/>
         </LinearLayout>
diff --git a/res/layout/sfps_enroll_finish_base.xml b/res/layout/sfps_enroll_finish_base.xml
index 6e468c6..1773337 100644
--- a/res/layout/sfps_enroll_finish_base.xml
+++ b/res/layout/sfps_enroll_finish_base.xml
@@ -30,12 +30,14 @@
         android:clipToPadding="false"
         android:clipChildren="false">
 
-        <LinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="0dp"
-            android:layout_weight="1"
-            android:gravity="center"
-            android:orientation="vertical">
+            <com.android.settings.biometrics.fingerprint.FingerprintRequireScreenOnToAuthToggle
+                style="@style/SudSwitchStyle"
+                android:id="@+id/require_screen_on_to_auth_toggle"
+                android:layout_gravity="start"
+                android:paddingLeft="0dp"
+                android:paddingStart="0dp"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content" />
 
             <com.google.android.setupdesign.view.FillContentLayout
                 android:layout_width="@dimen/sfps_enrollment_finished_icon_max_size"
@@ -54,17 +56,6 @@
                     android:importantForAccessibility="no"
                     android:src="@drawable/sfps_enroll_finish" />
             </com.google.android.setupdesign.view.FillContentLayout>
-
-            <!-- Added to align elements with fingerprint_enroll_enrolling_base -->
-            <TextView
-                style="@style/TextAppearance.ErrorText"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_gravity="center_horizontal|bottom"
-                android:visibility="invisible" />
-
-        </LinearLayout>
-
     </LinearLayout>
 
 </com.google.android.setupdesign.GlifLayout>
diff --git a/res/layout/sfps_require_screen_on_to_auth_toggle.xml b/res/layout/sfps_require_screen_on_to_auth_toggle.xml
new file mode 100644
index 0000000..02bb979
--- /dev/null
+++ b/res/layout/sfps_require_screen_on_to_auth_toggle.xml
@@ -0,0 +1,62 @@
+<!--
+  ~ Copyright (C) 2022 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.
+  -->
+
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:layout_gravity="start"
+    style="?attr/fingerprint_layout_theme">
+
+    <!-- Title -->
+    <com.google.android.setupdesign.view.RichTextView
+        android:id="@+id/title"
+        android:paddingTop="8dp"
+        android:paddingBottom="4dp"
+        android:layout_alignParentStart="true"
+        android:textAlignment="viewStart"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/security_settings_require_screen_on_to_auth_title"
+        android:textColor="?android:attr/textColorPrimary"
+        android:textSize="@dimen/sud_description_text_size"
+    />
+
+    <!-- Subtitle -->
+    <TextView
+        android:id="@+id/subtitle"
+        android:paddingBottom="8dp"
+        android:layout_alignParentStart="true"
+        android:textAlignment="viewStart"
+        android:layout_toStartOf="@+id/toggle"
+        android:layout_below="@+id/title"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/security_settings_require_screen_on_to_auth_description"
+        android:textColor="?android:attr/textColorSecondary"/>
+
+    <!-- Toggle -->
+    <Switch
+        android:layout_alignParentEnd="true"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:id="@+id/toggle"
+        android:layout_centerVertical="true"
+        android:checked="false"
+        style="@style/SudSwitchStyle"/>
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 03a103e..96ffb8d 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1012,6 +1012,8 @@
     <!-- Note: Update FingerprintEnrollParentalConsent.CONSENT_STRING_RESOURCES when any _consent_ strings are added or removed. -->
     <!-- Title shown for menu item that launches fingerprint settings or enrollment [CHAR LIMIT=22] -->
     <string name="security_settings_fingerprint_preference_title">Fingerprint</string>
+    <!-- Title for a category shown for the fingerprint settings page, followed by items that the user can toggle on/off to require/disable. [CHAR LIMIT=50] -->
+    <string name="security_settings_fingerprint_settings_preferences_category">When using Fingerprint Unlock</string>
     <!-- Fingerprint enrollment and settings --><skip />
     <!-- Title shown for work menu item that launches fingerprint settings or enrollment [CHAR LIMIT=22] -->
     <string name="security_settings_work_fingerprint_preference_title">Fingerprint for work</string>
@@ -1293,6 +1295,12 @@
     <string name="security_settings_fingerprint_enroll_finish_v2_message" product="device">Now you can use your fingerprint to unlock your device or verify it\u2019s you, like when you sign in to apps</string>
     <!-- Message shown in fingerprint enrollment dialog once enrollment is completed (default) [CHAR LIMIT=NONE] -->
     <string name="security_settings_fingerprint_enroll_finish_v2_message" product="default">Now you can use your fingerprint to unlock your phone or verify it\u2019s you, like when you sign in to apps</string>
+    <!-- Title for require screen on to auth toggle shown in fingerprint enrollment dialog once enrollment is completed. [CHAR LIMIT=NONE] -->
+    <string name="security_settings_require_screen_on_to_auth_title">Unlock only when screen is on</string>
+    <!-- Description for require screen on to auth toggle shown in fingerprint enrollment dialog once enrollment is completed. [CHAR LIMIT=NONE] -->
+    <string name="security_settings_require_screen_on_to_auth_description">The screen must be on before you can unlock with your fingerprint. This makes accidental unlocking less likely.</string>
+    <!-- Description for require screen on to auth toggle shown in fingerprint enrollment dialog once enrollment is completed. [CHAR LIMIT=NONE] -->
+    <string name="security_settings_require_screen_on_to_auth_keywords">Screen, Unlock</string>
     <!-- Button text to skip enrollment of fingerprint [CHAR LIMIT=40] -->
     <string name="security_settings_fingerprint_enroll_enrolling_skip">Do it later</string>
     <!-- Accessibility message for fingerprint enrollment asking the user to place the tip of their finger on the fingerprint sensor [CHAR LIMIT=NONE] -->
diff --git a/res/xml/security_settings_fingerprint.xml b/res/xml/security_settings_fingerprint.xml
index 804ef88..a4ce545 100644
--- a/res/xml/security_settings_fingerprint.xml
+++ b/res/xml/security_settings_fingerprint.xml
@@ -16,5 +16,20 @@
 
 <PreferenceScreen
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:title="@string/security_settings_fingerprint_preference_title"/>
+    xmlns:settings="http://schemas.android.com/apk/res-auto"
+    android:title="@string/security_settings_fingerprint_preference_title">
 
+    <PreferenceCategory
+        android:key="security_settings_fingerprint_unlock_category"
+        android:title="@string/security_settings_fingerprint_settings_preferences_category"
+        settings:controller="com.android.settings.biometrics.fingerprint.FingerprintUnlockCategoryPreferenceController">
+
+        <com.android.settingslib.RestrictedSwitchPreference
+            android:key="security_settings_require_screen_on_to_auth"
+            android:title="@string/security_settings_require_screen_on_to_auth_title"
+            android:summary="@string/security_settings_require_screen_on_to_auth_description"
+            settings:keywords="@string/security_settings_require_screen_on_to_auth_keywords"
+            settings:controller="com.android.settings.biometrics.fingerprint.FingerprintSettingsRequireScreenOnToAuthPreferenceController" />
+    </PreferenceCategory>
+
+</PreferenceScreen>
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFinish.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFinish.java
index 0c7ef98..4506310 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFinish.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFinish.java
@@ -25,6 +25,7 @@
 import android.os.Bundle;
 import android.util.Log;
 import android.view.View;
+import android.widget.CompoundButton;
 
 import androidx.annotation.VisibleForTesting;
 
@@ -44,16 +45,24 @@
 public class FingerprintEnrollFinish extends BiometricEnrollBase {
 
     private static final String TAG = "FingerprintEnrollFinish";
+    private static final String KEY_REQUIRE_SCREEN_ON_TO_AUTH = "require_screen_on_to_auth_toggle";
     private static final String ACTION_FINGERPRINT_SETTINGS =
             "android.settings.FINGERPRINT_SETTINGS";
     @VisibleForTesting
     static final String FINGERPRINT_SUGGESTION_ACTIVITY =
             "com.android.settings.SetupFingerprintSuggestionActivity";
+
     private FingerprintManager mFingerprintManager;
+
+    private FingerprintSettingsRequireScreenOnToAuthPreferenceController
+            mRequireScreenOnToAuthPreferenceController;
+    private FingerprintRequireScreenOnToAuthToggle mRequireScreenOnToAuthToggle;
     private boolean mCanAssumeSfps;
 
     private boolean mIsAddAnotherOrFinish;
 
+    private CompoundButton.OnCheckedChangeListener mRequireScreenOnToAuthToggleListener;
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -63,6 +72,11 @@
         mCanAssumeSfps = props != null && props.size() == 1 && props.get(0).isAnySidefpsType();
         if (mCanAssumeSfps) {
             setContentView(R.layout.sfps_enroll_finish);
+            mRequireScreenOnToAuthPreferenceController =
+                    new FingerprintSettingsRequireScreenOnToAuthPreferenceController(
+                            getApplicationContext(),
+                            KEY_REQUIRE_SCREEN_ON_TO_AUTH
+                    );
         } else {
             setContentView(R.layout.fingerprint_enroll_finish);
         }
@@ -90,6 +104,20 @@
                         .setTheme(R.style.SudGlifButton_Primary)
                         .build()
         );
+
+        if (mCanAssumeSfps) {
+            mRequireScreenOnToAuthToggleListener =
+                (buttonView, isChecked) -> {
+                    mRequireScreenOnToAuthPreferenceController.setChecked(isChecked);
+                };
+            mRequireScreenOnToAuthToggle = findViewById(R.id.require_screen_on_to_auth_toggle);
+            mRequireScreenOnToAuthToggle.setChecked(
+                    mRequireScreenOnToAuthPreferenceController.isChecked());
+            mRequireScreenOnToAuthToggle.setListener(mRequireScreenOnToAuthToggleListener);
+            mRequireScreenOnToAuthToggle.setOnClickListener(v -> {
+                mRequireScreenOnToAuthToggle.getSwitch().toggle();
+            });
+        }
     }
 
     @Override
@@ -103,6 +131,12 @@
     @Override
     protected void onResume() {
         super.onResume();
+        if (mCanAssumeSfps) {
+            mRequireScreenOnToAuthToggleListener.onCheckedChanged(
+                    mRequireScreenOnToAuthToggle.getSwitch(),
+                    mRequireScreenOnToAuthToggle.isChecked()
+            );
+        }
 
         FooterButton addButton = mFooterBarMixin.getSecondaryButton();
 
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintRequireScreenOnToAuthToggle.java b/src/com/android/settings/biometrics/fingerprint/FingerprintRequireScreenOnToAuthToggle.java
new file mode 100644
index 0000000..f88c9aa
--- /dev/null
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintRequireScreenOnToAuthToggle.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2022 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.settings.biometrics.fingerprint;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.widget.CompoundButton;
+import android.widget.LinearLayout;
+import android.widget.Switch;
+
+import com.android.settings.R;
+
+/**
+ * A layout that contains a start-justified title, and an end-justified switch.
+ */
+public class FingerprintRequireScreenOnToAuthToggle extends LinearLayout {
+    private Switch mSwitch;
+
+    public FingerprintRequireScreenOnToAuthToggle(Context context) {
+        this(context, null /* attrs */);
+    }
+
+    public FingerprintRequireScreenOnToAuthToggle(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public FingerprintRequireScreenOnToAuthToggle(
+            Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+
+        LayoutInflater.from(context).inflate(R.layout.sfps_require_screen_on_to_auth_toggle,
+                this, true /* attachToRoot */);
+
+        mSwitch = findViewById(R.id.toggle);
+        mSwitch.setClickable(true);
+        mSwitch.setFocusable(false);
+    }
+
+    public boolean isChecked() {
+        return mSwitch.isChecked();
+    }
+
+    /**
+     *
+     * @param checked
+     */
+    public void setChecked(boolean checked) {
+        mSwitch.setChecked(checked);
+    }
+
+    /**
+     *
+     * @param listener
+     */
+    public void setListener(CompoundButton.OnCheckedChangeListener listener) {
+        mSwitch.setOnCheckedChangeListener(listener);
+    }
+
+    public Switch getSwitch() {
+        return mSwitch;
+    }
+}
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java b/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java
index c031fe6..2cbef99 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java
@@ -56,21 +56,24 @@
 import androidx.preference.PreferenceGroup;
 import androidx.preference.PreferenceScreen;
 import androidx.preference.PreferenceViewHolder;
+import androidx.preference.SwitchPreference;
 
 import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
 import com.android.settings.SubSettings;
 import com.android.settings.Utils;
 import com.android.settings.biometrics.BiometricEnrollBase;
 import com.android.settings.biometrics.BiometricUtils;
 import com.android.settings.core.SettingsBaseActivity;
 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.password.ChooseLockGeneric;
 import com.android.settings.password.ChooseLockSettingsHelper;
 import com.android.settingslib.HelpUtils;
 import com.android.settingslib.RestrictedLockUtils;
 import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
 import com.android.settingslib.RestrictedLockUtilsInternal;
+import com.android.settingslib.RestrictedSwitchPreference;
+import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.transition.SettingsTransitionHelper;
 import com.android.settingslib.widget.FooterPreference;
 import com.android.settingslib.widget.TwoTargetPreference;
@@ -115,7 +118,26 @@
         setTitle(msg);
     }
 
-    public static class FingerprintSettingsFragment extends SettingsPreferenceFragment
+    /**
+     * @param context
+     * @return true if the Fingerprint hardware is detected.
+     */
+    public static boolean isFingerprintHardwareDetected(Context context) {
+        FingerprintManager manager = Utils.getFingerprintManagerOrNull(context);
+        boolean isHardwareDetected = false;
+        if (manager == null) {
+            Log.d(TAG, "FingerprintManager is null");
+        } else {
+            isHardwareDetected = manager.isHardwareDetected();
+            Log.d(TAG, "FingerprintManager is not null. Hardware detected: " + isHardwareDetected);
+        }
+        return manager != null && isHardwareDetected;
+    }
+
+    /**
+     *
+     */
+    public static class FingerprintSettingsFragment extends DashboardFragment
             implements OnPreferenceChangeListener, FingerprintPreference.OnDeleteClickListener {
 
         private static class FooterColumn {
@@ -134,6 +156,8 @@
         private static final String KEY_LAUNCHED_CONFIRM = "launched_confirm";
         private static final String KEY_HAS_FIRST_ENROLLED = "has_first_enrolled";
         private static final String KEY_IS_ENROLLING = "is_enrolled";
+        private static final String KEY_REQUIRE_SCREEN_ON_TO_AUTH =
+                "security_settings_require_screen_on_to_auth";
 
         private static final int MSG_REFRESH_FINGERPRINT_TEMPLATES = 1000;
         private static final int MSG_FINGER_AUTH_SUCCESS = 1001;
@@ -149,6 +173,11 @@
 
         protected static final boolean DEBUG = false;
 
+        private List<AbstractPreferenceController> mControllers;
+        private FingerprintSettingsRequireScreenOnToAuthPreferenceController
+                mRequireScreenOnToAuthPreferenceController;
+        private RestrictedSwitchPreference mRequireScreenOnToAuthPreference;
+
         private FingerprintManager mFingerprintManager;
         private FingerprintUpdater mFingerprintUpdater;
         private List<FingerprintSensorPropertiesInternal> mSensorProperties;
@@ -214,6 +243,9 @@
                     }
 
                     private void updateDialog() {
+                        if (isSfps()) {
+                            setRequireScreenOnToAuthVisibility();
+                        }
                         RenameDialog renameDialog = (RenameDialog) getFragmentManager().
                                 findFragmentByTag(RenameDialog.class.getName());
                         if (renameDialog != null) {
@@ -425,6 +457,15 @@
             return false;
         }
 
+        private boolean isSfps() {
+            for (FingerprintSensorPropertiesInternal prop : mSensorProperties) {
+                if (prop.isAnySidefpsType()) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
         protected void removeFingerprintPreference(int fingerprintId) {
             String name = genKey(fingerprintId);
             Preference prefToRemove = findPreference(name);
@@ -448,13 +489,40 @@
             if (root != null) {
                 root.removeAll();
             }
-            addPreferencesFromResource(R.xml.security_settings_fingerprint);
             root = getPreferenceScreen();
             addFingerprintItemPreferences(root);
+            addPreferencesFromResource(getPreferenceScreenResId());
+            mRequireScreenOnToAuthPreference = findPreference(KEY_REQUIRE_SCREEN_ON_TO_AUTH);
+            for (AbstractPreferenceController controller : mControllers) {
+                ((FingerprintSettingsPreferenceController) controller).setUserId(mUserId);
+            }
+            mRequireScreenOnToAuthPreference.setChecked(
+                    mRequireScreenOnToAuthPreferenceController.isChecked());
+            mRequireScreenOnToAuthPreference.setOnPreferenceChangeListener(
+                    (preference, newValue) -> {
+                        boolean isChecked = ((SwitchPreference) preference).isChecked();
+                        mRequireScreenOnToAuthPreferenceController.setChecked(!isChecked);
+                        return true;
+                    });
+            mRequireScreenOnToAuthPreference.setVisible(false);
+            if (isSfps()) {
+                setRequireScreenOnToAuthVisibility();
+            }
             setPreferenceScreen(root);
             return root;
         }
 
+        private void setRequireScreenOnToAuthVisibility() {
+            int fingerprintsEnrolled = mFingerprintManager.getEnrolledFingerprints(mUserId).size();
+            final boolean removalInProgress = mRemovalSidecar.inProgress();
+            // Removing last remaining fingerprint
+            if (fingerprintsEnrolled == 0 && removalInProgress) {
+                mRequireScreenOnToAuthPreference.setVisible(false);
+            } else {
+                mRequireScreenOnToAuthPreference.setVisible(true);
+            }
+        }
+
         private void addFingerprintItemPreferences(PreferenceGroup root) {
             root.removeAll();
             final List<Fingerprint> items = mFingerprintManager.getEnrolledFingerprints(mUserId);
@@ -477,6 +545,7 @@
                 root.addPreference(pref);
                 pref.setOnPreferenceChangeListener(this);
             }
+
             Preference addPreference = new Preference(root.getContext());
             addPreference.setKey(KEY_FINGERPRINT_ADD);
             addPreference.setTitle(R.string.fingerprint_add_title);
@@ -569,6 +638,16 @@
         }
 
         @Override
+        protected int getPreferenceScreenResId() {
+            return R.xml.security_settings_fingerprint;
+        }
+
+        @Override
+        protected String getLogTag() {
+            return TAG;
+        }
+
+        @Override
         public void onSaveInstanceState(final Bundle outState) {
             outState.putByteArray(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN,
                     mToken);
@@ -663,6 +742,27 @@
         }
 
         @Override
+        protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
+            if (!isFingerprintHardwareDetected(context)) {
+                return null;
+            }
+
+            mControllers = buildPreferenceControllers(context);
+            return mControllers;
+        }
+
+        private List<AbstractPreferenceController> buildPreferenceControllers(Context context) {
+            final List<AbstractPreferenceController> controllers = new ArrayList<>();
+            mRequireScreenOnToAuthPreferenceController =
+                    new FingerprintSettingsRequireScreenOnToAuthPreferenceController(
+                            context,
+                            KEY_REQUIRE_SCREEN_ON_TO_AUTH
+                    );
+            controllers.add(mRequireScreenOnToAuthPreferenceController);
+            return controllers;
+        }
+
+        @Override
         public void onActivityResult(int requestCode, int resultCode, Intent data) {
             super.onActivityResult(requestCode, resultCode, data);
             if (requestCode == CONFIRM_REQUEST || requestCode == CHOOSE_LOCK_GENERIC_REQUEST) {
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintSettingsPreferenceController.java b/src/com/android/settings/biometrics/fingerprint/FingerprintSettingsPreferenceController.java
new file mode 100644
index 0000000..2ca5da8
--- /dev/null
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintSettingsPreferenceController.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2022 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.settings.biometrics.fingerprint;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+
+import com.android.settings.core.TogglePreferenceController;
+import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+import com.android.settingslib.RestrictedLockUtilsInternal;
+
+/**
+ * Abstract base class for all fingerprint settings toggles.
+ */
+public abstract class FingerprintSettingsPreferenceController extends TogglePreferenceController {
+
+    private int mUserId;
+
+    public FingerprintSettingsPreferenceController(Context context, String preferenceKey) {
+        super(context, preferenceKey);
+    }
+
+    public void setUserId(int userId) {
+        mUserId = userId;
+    }
+
+    protected int getUserId() {
+        return mUserId;
+    }
+
+    protected EnforcedAdmin getRestrictingAdmin() {
+        return RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled(
+                mContext, DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT, mUserId);
+    }
+
+    @Override
+    public final boolean isSliceable() {
+        return false;
+    }
+
+    @Override
+    public int getSliceHighlightMenuRes() {
+        // not needed since it's not sliceable
+        return NO_RES;
+    }
+}
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintSettingsRequireScreenOnToAuthPreferenceController.java b/src/com/android/settings/biometrics/fingerprint/FingerprintSettingsRequireScreenOnToAuthPreferenceController.java
new file mode 100644
index 0000000..5b183c1
--- /dev/null
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintSettingsRequireScreenOnToAuthPreferenceController.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2022 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.settings.biometrics.fingerprint;
+
+import android.content.Context;
+import android.hardware.fingerprint.FingerprintManager;
+import android.os.UserHandle;
+import android.provider.Settings;
+
+import androidx.preference.Preference;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.settings.Utils;
+
+/**
+ * Preference controller that controls whether a SFPS device is required to be interactive for
+ * fingerprint authentication to unlock the device.
+ */
+public class FingerprintSettingsRequireScreenOnToAuthPreferenceController
+        extends FingerprintSettingsPreferenceController {
+    private static final String TAG =
+            "FingerprintSettingsRequireScreenOnToAuthPreferenceController";
+
+    @VisibleForTesting
+    protected FingerprintManager mFingerprintManager;
+
+    public FingerprintSettingsRequireScreenOnToAuthPreferenceController(
+            Context context, String prefKey) {
+        super(context, prefKey);
+        mFingerprintManager = Utils.getFingerprintManagerOrNull(context);
+    }
+
+    @Override
+    public boolean isChecked() {
+        if (!FingerprintSettings.isFingerprintHardwareDetected(mContext)) {
+            return false;
+        } else if (getRestrictingAdmin() != null) {
+            return false;
+        }
+        int defaultValue = mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_requireScreenOnToAuthEnabled) ? 1 : 0;
+
+        return Settings.Secure.getIntForUser(
+                mContext.getContentResolver(),
+                Settings.Secure.SFPS_REQUIRE_SCREEN_ON_TO_AUTH_ENABLED,
+                defaultValue,
+                getUserHandle()) != 0;
+    }
+
+    @Override
+    public boolean setChecked(boolean isChecked) {
+        Settings.Secure.putIntForUser(
+                mContext.getContentResolver(),
+                Settings.Secure.SFPS_REQUIRE_SCREEN_ON_TO_AUTH_ENABLED,
+                isChecked ? 1 : 0,
+                getUserHandle());
+        return true;
+    }
+
+    @Override
+    public void updateState(Preference preference) {
+        super.updateState(preference);
+        if (!FingerprintSettings.isFingerprintHardwareDetected(mContext)) {
+            preference.setEnabled(false);
+        } else if (!mFingerprintManager.hasEnrolledTemplates(getUserId())) {
+            preference.setEnabled(false);
+        } else {
+            preference.setEnabled(true);
+        }
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        if (mFingerprintManager != null
+                && mFingerprintManager.isHardwareDetected()
+                && mFingerprintManager.isPowerbuttonFps()) {
+            return mFingerprintManager.hasEnrolledTemplates(getUserId())
+                    ? AVAILABLE : DISABLED_DEPENDENT_SETTING;
+        } else {
+            return UNSUPPORTED_ON_DEVICE;
+        }
+    }
+
+    private int getUserHandle() {
+        return UserHandle.of(getUserId()).getIdentifier();
+    }
+
+}
diff --git a/src/com/android/settings/bluetooth/BluetoothPermissionRequest.java b/src/com/android/settings/bluetooth/BluetoothPermissionRequest.java
index 8542fcd..a62bbe1 100644
--- a/src/com/android/settings/bluetooth/BluetoothPermissionRequest.java
+++ b/src/com/android/settings/bluetooth/BluetoothPermissionRequest.java
@@ -24,6 +24,7 @@
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager.NameNotFoundException;
 import android.os.PowerManager;
 import android.os.UserManager;
 import android.util.Log;
@@ -125,8 +126,15 @@
                 // Create an intent triggered by clicking on the
                 // "Clear All Notifications" button
 
+                String bluetoothName;
+                try {
+                    bluetoothName = Utils.findBluetoothPackageName(context);
+                } catch (NameNotFoundException e) {
+                    e.printStackTrace();
+                    return;
+                }
                 Intent deleteIntent = new Intent(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY);
-                deleteIntent.setPackage("com.android.bluetooth");
+                deleteIntent.setPackage(bluetoothName);
                 deleteIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice);
                 deleteIntent.putExtra(BluetoothDevice.EXTRA_CONNECTION_ACCESS_RESULT,
                         BluetoothDevice.CONNECTION_ACCESS_NO);
diff --git a/src/com/android/settings/bluetooth/Utils.java b/src/com/android/settings/bluetooth/Utils.java
old mode 100755
new mode 100644
index ca8f9d3..24fe4e1
--- a/src/com/android/settings/bluetooth/Utils.java
+++ b/src/com/android/settings/bluetooth/Utils.java
@@ -16,11 +16,18 @@
 
 package com.android.settings.bluetooth;
 
+import static android.os.Process.BLUETOOTH_UID;
+
 import android.app.settings.SettingsEnums;
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothProfile;
 import android.content.Context;
 import android.content.DialogInterface;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.UserHandle;
 import android.provider.DeviceConfig;
 import android.provider.Settings;
 import android.text.TextUtils;
@@ -189,4 +196,48 @@
         }
         return false;
     }
+
+    /**
+     * Returns the Bluetooth Package name
+     */
+    public static String findBluetoothPackageName(Context context)
+            throws NameNotFoundException {
+        // this activity will always be in the package where the rest of Bluetooth lives
+        String sentinelActivity = "com.android.bluetooth.opp.BluetoothOppLauncherActivity";
+        PackageManager packageManager = context.createContextAsUser(UserHandle.SYSTEM, 0)
+                .getPackageManager();
+        String[] allPackages = packageManager.getPackagesForUid(BLUETOOTH_UID);
+        String matchedPackage = null;
+        for (String candidatePackage : allPackages) {
+            PackageInfo packageInfo;
+            try {
+                packageInfo =
+                        packageManager.getPackageInfo(
+                                candidatePackage,
+                                PackageManager.GET_ACTIVITIES
+                                        | PackageManager.MATCH_ANY_USER
+                                        | PackageManager.MATCH_UNINSTALLED_PACKAGES
+                                        | PackageManager.MATCH_DISABLED_COMPONENTS);
+            } catch (NameNotFoundException e) {
+                // rethrow
+                throw e;
+            }
+            if (packageInfo.activities == null) {
+                continue;
+            }
+            for (ActivityInfo activity : packageInfo.activities) {
+                if (sentinelActivity.equals(activity.name)) {
+                    if (matchedPackage == null) {
+                        matchedPackage = candidatePackage;
+                    } else {
+                        throw new NameNotFoundException("multiple main bluetooth packages found");
+                    }
+                }
+            }
+        }
+        if (matchedPackage != null) {
+            return matchedPackage;
+        }
+        throw new NameNotFoundException("Could not find main bluetooth package");
+    }
 }
diff --git a/src/com/android/settings/development/BluetoothMaxConnectedAudioDevicesPreferenceController.java b/src/com/android/settings/development/BluetoothMaxConnectedAudioDevicesPreferenceController.java
index bd8169a..f1677f2 100644
--- a/src/com/android/settings/development/BluetoothMaxConnectedAudioDevicesPreferenceController.java
+++ b/src/com/android/settings/development/BluetoothMaxConnectedAudioDevicesPreferenceController.java
@@ -16,9 +16,8 @@
 
 package com.android.settings.development;
 
+import android.bluetooth.BluetoothManager;
 import android.content.Context;
-import android.content.pm.PackageManager;
-import android.content.res.Resources;
 import android.os.SystemProperties;
 
 import androidx.annotation.VisibleForTesting;
@@ -42,18 +41,15 @@
 
     private int mDefaultMaxConnectedAudioDevices = 0;
 
+    private final BluetoothManager mBluetoothManager;
+
     public BluetoothMaxConnectedAudioDevicesPreferenceController(Context context) {
         super(context);
 
-        try {
-            Resources res = context.getPackageManager().getResourcesForApplication(
-                    "com.android.bluetooth");
-            mDefaultMaxConnectedAudioDevices = res.getInteger(res.getIdentifier(
-                    "config_bluetooth_max_connected_audio_devices",
-                    "integer", "com.android.bluetooth"));
-        } catch (PackageManager.NameNotFoundException e) {
-            e.printStackTrace();
-        }
+        mBluetoothManager = context.getSystemService(BluetoothManager.class);
+
+        mDefaultMaxConnectedAudioDevices =
+              mBluetoothManager.getAdapter().getMaxConnectedAudioDevices();
     }
 
     @Override
diff --git a/src/com/android/settings/notification/NotificationVolumePreferenceController.java b/src/com/android/settings/notification/NotificationVolumePreferenceController.java
index 322bb6c..112debc 100644
--- a/src/com/android/settings/notification/NotificationVolumePreferenceController.java
+++ b/src/com/android/settings/notification/NotificationVolumePreferenceController.java
@@ -16,6 +16,7 @@
 
 package com.android.settings.notification;
 
+import android.app.ActivityThread;
 import android.app.INotificationManager;
 import android.app.NotificationManager;
 import android.content.BroadcastReceiver;
@@ -29,26 +30,32 @@
 import android.os.Message;
 import android.os.ServiceManager;
 import android.os.Vibrator;
+import android.provider.DeviceConfig;
 import android.service.notification.NotificationListenerService;
 import android.text.TextUtils;
 import android.util.Log;
 
 import androidx.lifecycle.OnLifecycleEvent;
+import androidx.preference.PreferenceScreen;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
 import com.android.settings.R;
 import com.android.settings.Utils;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 
 import java.util.Objects;
+import java.util.Set;
 
 /**
- * Update notification volume icon in Settings in response to user adjusting volume
+ * Update notification volume icon in Settings in response to user adjusting volume.
  */
 public class NotificationVolumePreferenceController extends VolumeSeekBarPreferenceController {
 
     private static final String TAG = "NotificationVolumePreferenceController";
     private static final String KEY_NOTIFICATION_VOLUME = "notification_volume";
+    private static final boolean CONFIG_DEFAULT_VAL = false;
+    private boolean mSeparateNotification;
 
     private Vibrator mVibrator;
     private int mRingerMode = AudioManager.RINGER_MODE_NORMAL;
@@ -56,39 +63,74 @@
     private final RingReceiver mReceiver = new RingReceiver();
     private final H mHandler = new H();
     private INotificationManager mNoMan;
-
-
     private int mMuteIcon;
     private final int mNormalIconId =  R.drawable.ic_notifications;
     private final int mVibrateIconId = R.drawable.ic_volume_ringer_vibrate;
     private final int mSilentIconId = R.drawable.ic_notifications_off_24dp;
 
-    private final boolean mRingNotificationAliased;
-
-
     public NotificationVolumePreferenceController(Context context) {
         this(context, KEY_NOTIFICATION_VOLUME);
     }
 
     public NotificationVolumePreferenceController(Context context, String key) {
         super(context, key);
+
         mVibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
         if (mVibrator != null && !mVibrator.hasVibrator()) {
             mVibrator = null;
         }
 
-        mRingNotificationAliased = mContext.getResources().getBoolean(
-                com.android.internal.R.bool.config_alias_ring_notif_stream_types);
         updateRingerMode();
     }
 
+    /**
+     * Allow for notification slider to be enabled in the scenario where the config switches on
+     * while settings page is already on the screen by always configuring the preference, even if it
+     * is currently inactive.
+     */
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        if (mPreference == null) {
+            setupVolPreference(screen);
+        }
+        mSeparateNotification = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, CONFIG_DEFAULT_VAL);
+        if (mPreference != null) {
+            mPreference.setVisible(getAvailabilityStatus() == AVAILABLE);
+        }
+        updateEffectsSuppressor();
+        updatePreferenceIconAndSliderState();
+    }
+
+    /**
+     * Only display the notification slider when the corresponding device config flag is set
+     */
+    private void onDeviceConfigChange(DeviceConfig.Properties properties) {
+        Set<String> changeSet = properties.getKeyset();
+
+        if (changeSet.contains(SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION)) {
+            boolean newVal = properties.getBoolean(
+                    SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, CONFIG_DEFAULT_VAL);
+            if (newVal != mSeparateNotification) {
+                mSeparateNotification = newVal;
+                // manually hiding the preference because being unavailable does not do the job
+                if (mPreference != null) {
+                    mPreference.setVisible(getAvailabilityStatus() == AVAILABLE);
+                }
+            }
+        }
+    }
+
+
     @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
     @Override
     public void onResume() {
         super.onResume();
         mReceiver.register(true);
-        updateEffectsSuppressor();
-        updatePreferenceIconAndSliderState();
+        DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI,
+                ActivityThread.currentApplication().getMainExecutor(),
+                this::onDeviceConfigChange);
     }
 
     @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
@@ -96,16 +138,17 @@
     public void onPause() {
         super.onPause();
         mReceiver.register(false);
+        DeviceConfig.removeOnPropertiesChangedListener(this::onDeviceConfigChange);
     }
 
     @Override
     public int getAvailabilityStatus() {
+        boolean separateNotification = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, false);
 
-        // Show separate notification slider if ring/notification are not aliased by AudioManager --
-        // if they are, notification volume is controlled by RingVolumePreferenceController.
         return mContext.getResources().getBoolean(R.bool.config_show_notification_volume)
-                && (!mRingNotificationAliased || !Utils.isVoiceCapable(mContext))
                 && !mHelper.isSingleVolume()
+                && (separateNotification || !Utils.isVoiceCapable(mContext))
                 ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
     }
 
diff --git a/src/com/android/settings/notification/RingVolumePreferenceController.java b/src/com/android/settings/notification/RingVolumePreferenceController.java
index a78689f..7fdb1e1 100644
--- a/src/com/android/settings/notification/RingVolumePreferenceController.java
+++ b/src/com/android/settings/notification/RingVolumePreferenceController.java
@@ -16,6 +16,7 @@
 
 package com.android.settings.notification;
 
+import android.app.ActivityThread;
 import android.app.INotificationManager;
 import android.app.NotificationManager;
 import android.content.BroadcastReceiver;
@@ -29,6 +30,7 @@
 import android.os.Message;
 import android.os.ServiceManager;
 import android.os.Vibrator;
+import android.provider.DeviceConfig;
 import android.service.notification.NotificationListenerService;
 import android.text.TextUtils;
 import android.util.Log;
@@ -36,11 +38,13 @@
 import androidx.lifecycle.OnLifecycleEvent;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
 import com.android.settings.R;
 import com.android.settings.Utils;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 
 import java.util.Objects;
+import java.util.Set;
 
 /**
  * This slider can represent both ring and notification, if the corresponding streams are aliased,
@@ -59,24 +63,21 @@
 
     private int mMuteIcon;
 
-    /*
-     * Whether ring and notification streams are aliased together by AudioManager.
-     * If they are, we'll present one volume control for both.
-     * If not, we'll present separate volume controls.
-     */
-    private final boolean mRingAliasNotif;
-
-    private final int mNormalIconId;
+    private int mNormalIconId;
     @VisibleForTesting
-    final int mVibrateIconId;
+    int mVibrateIconId;
     @VisibleForTesting
-    final int mSilentIconId;
+    int mSilentIconId;
 
     @VisibleForTesting
-    final int mTitleId;
+    int mTitleId;
+
+    private boolean mSeparateNotification;
 
     private INotificationManager mNoMan;
 
+    private static final boolean CONFIG_DEFAULT_VAL = false;
+
     public RingVolumePreferenceController(Context context) {
         this(context, KEY_RING_VOLUME);
     }
@@ -87,29 +88,56 @@
         if (mVibrator != null && !mVibrator.hasVibrator()) {
             mVibrator = null;
         }
-
-        mRingAliasNotif = isRingAliasNotification();
-        if (mRingAliasNotif) {
-            mTitleId = R.string.ring_volume_option_title;
-
-            mNormalIconId = R.drawable.ic_notifications;
-            mSilentIconId = R.drawable.ic_notifications_off_24dp;
-        } else {
-            mTitleId = R.string.separate_ring_volume_option_title;
-
-            mNormalIconId = R.drawable.ic_ring_volume;
-            mSilentIconId = R.drawable.ic_ring_volume_off;
-        }
-        // todo: set a distinct vibrate icon for ring vs notification
-        mVibrateIconId = R.drawable.ic_volume_ringer_vibrate;
-
+        mSeparateNotification = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, CONFIG_DEFAULT_VAL);
+        loadPreferenceIconResources(mSeparateNotification);
         updateRingerMode();
     }
 
-    @VisibleForTesting
-    boolean isRingAliasNotification() {
-        return mContext.getResources().getBoolean(
-                com.android.internal.R.bool.config_alias_ring_notif_stream_types);
+    private void loadPreferenceIconResources(boolean separateNotification) {
+        if (separateNotification) {
+            mTitleId = R.string.separate_ring_volume_option_title;
+            mNormalIconId = R.drawable.ic_ring_volume;
+            mSilentIconId = R.drawable.ic_ring_volume_off;
+        } else {
+            mTitleId = R.string.ring_volume_option_title;
+            mNormalIconId = R.drawable.ic_notifications;
+            mSilentIconId = R.drawable.ic_notifications_off_24dp;
+        }
+        // todo: set a distinct vibrate icon for ring vs notification
+        mVibrateIconId = R.drawable.ic_volume_ringer_vibrate;
+    }
+
+    /**
+     * As the responsibility of this slider changes, so should its title & icon
+     */
+    public void onDeviceConfigChange(DeviceConfig.Properties properties) {
+        Set<String> changeSet = properties.getKeyset();
+        if (changeSet.contains(SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION)) {
+            boolean valueUpdated = readSeparateNotificationVolumeConfig();
+            if (valueUpdated) {
+                updateEffectsSuppressor();
+                selectPreferenceIconState();
+                setPreferenceTitle();
+            }
+        }
+    }
+
+    /**
+     * side effect: updates the cached value of the config, and also the icon
+     * @return has the config changed?
+     */
+    private boolean readSeparateNotificationVolumeConfig() {
+        boolean newVal = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, CONFIG_DEFAULT_VAL);
+
+        boolean valueUpdated = newVal != mSeparateNotification;
+        if (valueUpdated) {
+            mSeparateNotification = newVal;
+            loadPreferenceIconResources(newVal);
+        }
+
+        return valueUpdated;
     }
 
     @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
@@ -117,8 +145,11 @@
     public void onResume() {
         super.onResume();
         mReceiver.register(true);
+        readSeparateNotificationVolumeConfig();
+        DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI,
+                ActivityThread.currentApplication().getMainExecutor(), this::onDeviceConfigChange);
         updateEffectsSuppressor();
-        updatePreferenceIcon();
+        selectPreferenceIconState();
         setPreferenceTitle();
     }
 
@@ -127,6 +158,7 @@
     public void onPause() {
         super.onPause();
         mReceiver.register(false);
+        DeviceConfig.removeOnPropertiesChangedListener(this::onDeviceConfigChange);
     }
 
     @Override
@@ -170,7 +202,7 @@
         final int ringerMode = mHelper.getRingerModeInternal();
         if (mRingerMode == ringerMode) return;
         mRingerMode = ringerMode;
-        updatePreferenceIcon();
+        selectPreferenceIconState();
     }
 
     private void updateEffectsSuppressor() {
@@ -190,7 +222,8 @@
             return;
         }
 
-        if (hintsMatch(hints, mRingAliasNotif)) {
+        if (hintsMatch(hints, DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, false))) {
             mSuppressor = suppressor;
             if (mPreference != null) {
                 final String text = SuppressorHelper.getSuppressionText(mContext, suppressor);
@@ -200,11 +233,11 @@
     }
 
     @VisibleForTesting
-    boolean hintsMatch(int hints, boolean ringNotificationAliased) {
+    boolean hintsMatch(int hints, boolean notificationSeparated) {
         return (hints & NotificationListenerService.HINT_HOST_DISABLE_CALL_EFFECTS) != 0
                 || (hints & NotificationListenerService.HINT_HOST_DISABLE_EFFECTS) != 0
                 || ((hints & NotificationListenerService.HINT_HOST_DISABLE_NOTIFICATION_EFFECTS)
-                != 0 && ringNotificationAliased);
+                != 0 && !notificationSeparated);
     }
 
     @VisibleForTesting
@@ -217,7 +250,7 @@
         mVibrator = vibrator;
     }
 
-    private void updatePreferenceIcon() {
+    private void selectPreferenceIconState() {
         if (mPreference != null) {
             if (mRingerMode == AudioManager.RINGER_MODE_NORMAL) {
                 mPreference.showIcon(mNormalIconId);
diff --git a/src/com/android/settings/notification/VolumeSeekBarPreferenceController.java b/src/com/android/settings/notification/VolumeSeekBarPreferenceController.java
index d170159..0414565 100644
--- a/src/com/android/settings/notification/VolumeSeekBarPreferenceController.java
+++ b/src/com/android/settings/notification/VolumeSeekBarPreferenceController.java
@@ -55,13 +55,17 @@
     public void displayPreference(PreferenceScreen screen) {
         super.displayPreference(screen);
         if (isAvailable()) {
-            mPreference = screen.findPreference(getPreferenceKey());
-            mPreference.setCallback(mVolumePreferenceCallback);
-            mPreference.setStream(getAudioStream());
-            mPreference.setMuteIcon(getMuteIcon());
+            setupVolPreference(screen);
         }
     }
 
+    protected void setupVolPreference(PreferenceScreen screen) {
+        mPreference = screen.findPreference(getPreferenceKey());
+        mPreference.setCallback(mVolumePreferenceCallback);
+        mPreference.setStream(getAudioStream());
+        mPreference.setMuteIcon(getMuteIcon());
+    }
+
     @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
     public void onResume() {
         if (mPreference != null) {
diff --git a/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintSettingsRequireScreenOnToAuthPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintSettingsRequireScreenOnToAuthPreferenceControllerTest.java
new file mode 100644
index 0000000..ff74d59
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintSettingsRequireScreenOnToAuthPreferenceControllerTest.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2022 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.settings.biometrics.fingerprint;
+
+import static com.android.settings.core.BasePreferenceController.AVAILABLE;
+import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING;
+import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.hardware.fingerprint.FingerprintManager;
+import android.provider.Settings;
+
+import com.android.settings.testutils.shadow.ShadowUtils;
+import com.android.settingslib.RestrictedSwitchPreference;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(shadows = {ShadowUtils.class})
+public class FingerprintSettingsRequireScreenOnToAuthPreferenceControllerTest {
+
+    @Mock
+    private FingerprintManager mFingerprintManager;
+    @Mock
+    private PackageManager mPackageManager;
+    @Mock
+    private RestrictedSwitchPreference mPreference;
+
+    private Context mContext;
+    private FingerprintSettingsRequireScreenOnToAuthPreferenceController mController;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = spy(RuntimeEnvironment.application);
+        when(mContext.getSystemService(eq(Context.FINGERPRINT_SERVICE))).thenReturn(
+                mFingerprintManager);
+        when(mContext.getPackageManager()).thenReturn(mPackageManager);
+
+        mController = spy(new FingerprintSettingsRequireScreenOnToAuthPreferenceController(mContext,
+                "test_key"));
+        ReflectionHelpers.setField(mController, "mFingerprintManager", mFingerprintManager);
+    }
+
+    @After
+    public void tearDown() {
+        ShadowUtils.reset();
+    }
+
+    @Test
+    public void onPreferenceChange_settingIsUpdated() {
+        boolean state = Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.SFPS_REQUIRE_SCREEN_ON_TO_AUTH_ENABLED, 1) != 0;
+
+        assertThat(mController.isChecked()).isFalse();
+        assertThat(mController.onPreferenceChange(mPreference, !state)).isTrue();
+        boolean newState = Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.SFPS_REQUIRE_SCREEN_ON_TO_AUTH_ENABLED, 1) != 0;
+        assertThat(newState).isEqualTo(!state);
+    }
+
+    @Test
+    public void isAvailable_isEnabled_whenSfpsHardwareDetected_AndHasEnrolledFingerprints() {
+        assertThat(mController.isAvailable()).isEqualTo(false);
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
+        configure_hardwareDetected_isSfps_hasEnrolledTemplates(
+                true /* isHardwareDetected */,
+                true /* isPowerbuttonFps */,
+                true /* hasEnrolledTemplates */);
+        assertThat(mController.isAvailable()).isEqualTo(true);
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
+    }
+
+    @Test
+    public void isAvailable_isDisabled_whenSfpsHardwareDetected_AndNoEnrolledFingerprints() {
+        assertThat(mController.isAvailable()).isEqualTo(false);
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
+        configure_hardwareDetected_isSfps_hasEnrolledTemplates(
+                true /* isHardwareDetected */,
+                true /* isPowerbuttonFps */,
+                false /* hasEnrolledTemplates */);
+        assertThat(mController.isAvailable()).isEqualTo(true);
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING);
+    }
+
+    @Test
+    public void isUnavailable_whenHardwareNotDetected() {
+        assertThat(mController.isAvailable()).isFalse();
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
+        configure_hardwareDetected_isSfps_hasEnrolledTemplates(
+                false /* isHardwareDetected */,
+                true /* isPowerbuttonFps */,
+                true /* hasEnrolledTemplates */);
+        assertThat(mController.isAvailable()).isFalse();
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
+    }
+
+    @Test
+    public void isUnavailable_onNonSfpsDevice() {
+        assertThat(mController.isAvailable()).isFalse();
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
+        configure_hardwareDetected_isSfps_hasEnrolledTemplates(
+                true /* isHardwareDetected */,
+                false /* isPowerbuttonFps */,
+                true /* hasEnrolledTemplates */);
+        assertThat(mController.isAvailable()).isFalse();
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
+    }
+
+    private void configure_hardwareDetected_isSfps_hasEnrolledTemplates(
+            boolean isHardwareDetected, boolean isPowerbuttonFps, boolean hasEnrolledTemplates) {
+        when(mFingerprintManager.isHardwareDetected()).thenReturn(isHardwareDetected);
+        when(mFingerprintManager.isPowerbuttonFps()).thenReturn(isPowerbuttonFps);
+        when(mFingerprintManager.hasEnrolledTemplates(anyInt())).thenReturn(hasEnrolledTemplates);
+    }
+
+
+}
diff --git a/tests/robotests/src/com/android/settings/development/BluetoothMaxConnectedAudioDevicesPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/BluetoothMaxConnectedAudioDevicesPreferenceControllerTest.java
index 72477b9..7ab311f 100644
--- a/tests/robotests/src/com/android/settings/development/BluetoothMaxConnectedAudioDevicesPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/BluetoothMaxConnectedAudioDevicesPreferenceControllerTest.java
@@ -24,9 +24,9 @@
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.when;
 
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothManager;
 import android.content.Context;
-import android.content.pm.PackageManager;
-import android.content.res.Resources;
 
 import android.os.SystemProperties;
 
@@ -54,6 +54,11 @@
   @Spy
   private Context mSpyContext = RuntimeEnvironment.application;
 
+  @Mock
+  private BluetoothManager mBluetoothManager;
+  @Mock
+  private BluetoothAdapter mBluetoothAdapter;
+
   private ListPreference mPreference;
   private BluetoothMaxConnectedAudioDevicesPreferenceController mController;
 
@@ -63,19 +68,15 @@
   @Before
   public void setup() {
     MockitoAnnotations.initMocks(this);
+    doReturn(mBluetoothManager).when(mSpyContext).getSystemService(BluetoothManager.class);
+    doReturn(mBluetoothAdapter).when(mBluetoothManager).getAdapter();
     // Get XML values without mock
     // Setup test list preference using XML values
     mPreference = new ListPreference(mSpyContext);
     mPreference.setEntries(R.array.bluetooth_max_connected_audio_devices);
     mPreference.setEntryValues(R.array.bluetooth_max_connected_audio_devices_values);
-    // Retrieve default max connected audio devices to a test controlled value
-    try {
-      Resources res = mSpyContext.getPackageManager().getResourcesForApplication("com.android.bluetooth");
-      TEST_MAX_CONNECTED_AUDIO_DEVICES = res.getInteger(res.getIdentifier("config_bluetooth_max_connected_audio_devices", "integer", "com.android.bluetooth"));
-    } catch (PackageManager.NameNotFoundException e) {
-      e.printStackTrace();
-    }
-
+    doReturn(TEST_MAX_CONNECTED_AUDIO_DEVICES).when(mBluetoothAdapter)
+        .getMaxConnectedAudioDevices();
     // Init the actual controller
     mController = new BluetoothMaxConnectedAudioDevicesPreferenceController(mSpyContext);
     // Construct preference in the controller via a mocked preference screen object
diff --git a/tests/robotests/src/com/android/settings/notification/NotificationVolumePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/NotificationVolumePreferenceControllerTest.java
index 96b9e62..7e7ad10 100644
--- a/tests/robotests/src/com/android/settings/notification/NotificationVolumePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/NotificationVolumePreferenceControllerTest.java
@@ -18,6 +18,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
 
@@ -25,10 +26,17 @@
 import android.content.res.Resources;
 import android.media.AudioManager;
 import android.os.Vibrator;
+import android.provider.DeviceConfig;
 import android.service.notification.NotificationListenerService;
 import android.telephony.TelephonyManager;
 
-import com.android.internal.R;
+import androidx.preference.PreferenceManager;
+import androidx.preference.PreferenceScreen;
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.testutils.shadow.ShadowDeviceConfig;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -37,11 +45,12 @@
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
+import org.robolectric.Shadows;
 import org.robolectric.annotation.Config;
 
 @RunWith(RobolectricTestRunner.class)
+@Config(shadows = {ShadowDeviceConfig.class})
 public class NotificationVolumePreferenceControllerTest {
-
     @Mock
     private AudioHelper mHelper;
     @Mock
@@ -52,6 +61,11 @@
     private Vibrator mVibrator;
     @Mock
     private Resources mResources;
+    @Mock
+    private PreferenceManager mPreferenceManager;
+
+    private static final String READ_DEVICE_CONFIG_PERMISSION =
+            "android.permission.READ_DEVICE_CONFIG";
 
     private Context mContext;
     private NotificationVolumePreferenceController mController;
@@ -87,7 +101,9 @@
     public void isAvailable_voiceCapable_aliasedWithRing_shouldReturnFalse() {
         when(mResources.getBoolean(
                 com.android.settings.R.bool.config_show_notification_volume)).thenReturn(true);
-        when(mResources.getBoolean(R.bool.config_alias_ring_notif_stream_types)).thenReturn(true);
+
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, "false", false);
 
         NotificationVolumePreferenceController controller =
                 new NotificationVolumePreferenceController(mContext);
@@ -105,7 +121,9 @@
     public void isAvailable_voiceCapable_separatedFromRing_shouldReturnTrue() {
         when(mResources.getBoolean(
                 com.android.settings.R.bool.config_show_notification_volume)).thenReturn(true);
-        when(mResources.getBoolean(R.bool.config_alias_ring_notif_stream_types)).thenReturn(false);
+
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, "true", false);
 
         NotificationVolumePreferenceController controller =
                 new NotificationVolumePreferenceController(mContext);
@@ -170,4 +188,70 @@
                 .isTrue();
     }
 
+    @Test
+    public void enableSeparateNotificationConfig_controllerBecomesAvailable() {
+        PreferenceScreen screen = spy(new PreferenceScreen(mContext, null));
+        VolumeSeekBarPreference volumeSeekBarPreference = mock(VolumeSeekBarPreference.class);
+        when(screen.getPreferenceManager()).thenReturn(mPreferenceManager);
+        when(screen.getContext()).thenReturn(mContext);
+        when(mResources.getBoolean(
+                com.android.settings.R.bool.config_show_notification_volume)).thenReturn(true);
+        // block the alternative condition to enable controller
+        when(mTelephonyManager.isVoiceCapable()).thenReturn(true);
+
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, "false", false);
+
+        NotificationVolumePreferenceController controller =
+                new NotificationVolumePreferenceController(mContext);
+        when(screen.findPreference(controller.getPreferenceKey()))
+                .thenReturn(volumeSeekBarPreference);
+
+        // allow the controller to subscribe
+        Shadows.shadowOf((android.app.Application) ApplicationProvider.getApplicationContext())
+                .grantPermissions(READ_DEVICE_CONFIG_PERMISSION);
+        controller.onResume();
+        controller.displayPreference(screen);
+
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, Boolean.toString(true),
+                false);
+
+        assertThat(controller.getAvailabilityStatus()
+                == BasePreferenceController.AVAILABLE).isTrue();
+    }
+
+    @Test
+    public void disableSeparateNotificationConfig_controllerBecomesUnavailable() {
+        PreferenceScreen screen = spy(new PreferenceScreen(mContext, null));
+        VolumeSeekBarPreference volumeSeekBarPreference = mock(VolumeSeekBarPreference.class);
+        when(screen.getPreferenceManager()).thenReturn(mPreferenceManager);
+        when(screen.getContext()).thenReturn(mContext);
+        when(mResources.getBoolean(
+                com.android.settings.R.bool.config_show_notification_volume)).thenReturn(true);
+
+        // block the alternative condition to enable controller
+        when(mTelephonyManager.isVoiceCapable()).thenReturn(true);
+
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, "true", false);
+
+        NotificationVolumePreferenceController controller =
+                new NotificationVolumePreferenceController(mContext);
+
+        when(screen.findPreference(controller.getPreferenceKey()))
+                .thenReturn(volumeSeekBarPreference);
+
+        Shadows.shadowOf((android.app.Application) ApplicationProvider.getApplicationContext())
+                .grantPermissions(READ_DEVICE_CONFIG_PERMISSION);
+        controller.onResume();
+        controller.displayPreference(screen);
+
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, "false", false);
+
+        assertThat(controller.getAvailabilityStatus()
+                == BasePreferenceController.UNSUPPORTED_ON_DEVICE).isTrue();
+    }
+
 }
diff --git a/tests/robotests/src/com/android/settings/notification/RingVolumePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/RingVolumePreferenceControllerTest.java
index 02757d5..1ad26c7 100644
--- a/tests/robotests/src/com/android/settings/notification/RingVolumePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/RingVolumePreferenceControllerTest.java
@@ -27,10 +27,13 @@
 import android.content.res.Resources;
 import android.media.AudioManager;
 import android.os.Vibrator;
+import android.provider.DeviceConfig;
 import android.service.notification.NotificationListenerService;
 import android.telephony.TelephonyManager;
 
+import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
 import com.android.settings.R;
+import com.android.settings.testutils.shadow.ShadowDeviceConfig;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -39,9 +42,11 @@
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
 import org.robolectric.shadows.ShadowApplication;
 
 @RunWith(RobolectricTestRunner.class)
+@Config(shadows = {ShadowDeviceConfig.class})
 public class RingVolumePreferenceControllerTest {
 
     @Mock
@@ -124,9 +129,10 @@
     // todo: verify that the title change is displayed, by examining the underlying preference
     @Test
     public void ringNotificationStreamsNotAliased_sliderTitleSetToRingOnly() {
-        when(mResources.getBoolean(
-                com.android.internal.R.bool.config_alias_ring_notif_stream_types))
-                .thenReturn(false);
+
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, "true", false);
+
         final RingVolumePreferenceController controller =
                 new RingVolumePreferenceController(mContext);
 
@@ -138,8 +144,9 @@
     @Test
     public void ringNotificationStreamsAliased_sliderTitleIncludesBothRingNotification() {
 
-        when(mResources.getBoolean(
-                com.android.internal.R.bool.config_alias_ring_notif_stream_types)).thenReturn(true);
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, "false", false);
+
         final RingVolumePreferenceController control = new RingVolumePreferenceController(mContext);
 
         int expectedTitleId = R.string.ring_volume_option_title;
@@ -150,39 +157,39 @@
     @Test
     public void setHintsRing_aliased_Matches() {
         assertThat(mController.hintsMatch(
-                NotificationListenerService.HINT_HOST_DISABLE_CALL_EFFECTS, true)).isTrue();
+                NotificationListenerService.HINT_HOST_DISABLE_CALL_EFFECTS, false)).isTrue();
     }
 
     @Test
     public void setHintsRingNotification_aliased_Matches() {
         assertThat(mController.hintsMatch(NotificationListenerService.HINT_HOST_DISABLE_EFFECTS,
-                true)).isTrue();
+                false)).isTrue();
     }
 
     @Test
     public void setHintNotification_aliased_Matches() {
         assertThat(mController
                 .hintsMatch(NotificationListenerService.HINT_HOST_DISABLE_NOTIFICATION_EFFECTS,
-                true)).isTrue();
+                false)).isTrue();
     }
 
     @Test
     public void setHintsRing_unaliased_Matches() {
         assertThat(mController.hintsMatch(
-                NotificationListenerService.HINT_HOST_DISABLE_CALL_EFFECTS, false)).isTrue();
+                NotificationListenerService.HINT_HOST_DISABLE_CALL_EFFECTS, true)).isTrue();
     }
 
     @Test
     public void setHintsRingNotification_unaliased_Matches() {
         assertThat(mController.hintsMatch(NotificationListenerService.HINT_HOST_DISABLE_EFFECTS,
-                false)).isTrue();
+                true)).isTrue();
     }
 
     @Test
     public void setHintNotification_unaliased_doesNotMatch() {
         assertThat(mController
                 .hintsMatch(NotificationListenerService.HINT_HOST_DISABLE_NOTIFICATION_EFFECTS,
-                        false)).isFalse();
+                        true)).isFalse();
     }
 
     @Test