Merge "Enable Safety Center & Security unit tests on presubmit." into main
diff --git a/res/values/config.xml b/res/values/config.xml
index 433620d..9d71671 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -709,7 +709,7 @@
     <bool name="default_allow_sensitive_lockscreen_content">true</bool>
 
     <!-- Whether to enable the app battery usage list page feature. -->
-    <bool name="config_app_battery_usage_list_enabled">true</bool>
+    <bool name="config_app_battery_usage_list_enabled">false</bool>
 
     <!-- Whether sim related information is visible to the end user. -->
     <bool name="config_show_sim_info">true</bool>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index caf3e7f..707bc69 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1269,7 +1269,7 @@
     <!-- Header in hide Private Space settings page to access Private Space when hidden. [CHAR LIMIT=60] -->
     <string name="privatespace_access_header">Access private space when hidden</string>
     <!-- Text in hide Private Space settings page on how to search Private Space when hidden. [CHAR LIMIT=60] -->
-    <string name="privatespace_search_description">From your apps list, enter \'private space\' in the search bar</string>
+    <string name="privatespace_search_description">From your apps list, enter \"private space\" in the search bar</string>
     <!-- Text in hide Private Space settings page to tap on Private Space tile. [CHAR LIMIT=60] -->
     <string name="privatespace_tap_tile_description">Tap the private space tile</string>
     <!-- Text in hide Private Space settings page to Unlock Private Space. [CHAR LIMIT=60] -->
@@ -1373,18 +1373,6 @@
     <!-- Header for private space choose your pattern screen [CHAR LIMIT=40] -->
     <string name="private_space_choose_your_pattern_header">Set a pattern for your private space</string>
 
-    <!-- TODO(b/309950257): Remove below strings once QSTIle fulfillment is complete. -->
-    <!-- Header in hide Private Space settings page to unhide Private Space. [CHAR LIMIT=90] -->
-    <string name="privatespace_unhide_header">To show private space (Not final UX)</string>
-    <!-- Text in hide Private Space settings page on how to open Private Space setting. [CHAR LIMIT=NONE] -->
-    <string name="privatespace_open_settings">Open the Settings App</string>
-    <!-- Text in hide Private Space settings page on how to open Private Space setting. [CHAR LIMIT=NONE] -->
-    <string name="privatespace_tap_settings">Tap on Security &amp; privacy > private space > Hide private space when locked</string>
-    <!-- Text in hide Private Space settings page to off hide toggle. [CHAR LIMIT=90] -->
-    <string name="privatespace_turnoff_hide">Turn off \‘Hide private space when locked\’ toggle</string>
-    <!-- Note in hide Private Space settings page to inform that this is a development feature. [CHAR LIMIT=NONE] -->
-    <string name="privatespace_development_note">Note to Googlers: The development of this feature is still in progress</string>
-
     <!-- Text shown when "Add fingerprint" button is disabled -->
     <string name="fingerprint_add_max">You can add up to <xliff:g id="count" example="5">%d</xliff:g> fingerprints</string>
     <!-- Text shown when users has enrolled a maximum number of fingerprints [CHAR LIMIT=NONE] -->
@@ -11625,9 +11613,9 @@
       other   {# SIMs are available on this device, but only one can be used at a time}
     }</string>
     <!-- String indicating that we are activating the profile [CHAR LIMIT=NONE] -->
-    <string name="choose_sim_activating">Activating<xliff:g id="ellipsis" example="...">&#8230;</xliff:g></string>
+    <string name="choose_sim_activating">Turning on<xliff:g id="ellipsis" example="...">&#8230;</xliff:g></string>
     <!-- String indicating that we failed to activate the selected profile [CHAR LIMIT=NONE] -->
-    <string name="choose_sim_could_not_activate">Couldn\u2019t activate this SIM right now</string>
+    <string name="choose_sim_could_not_activate">Couldn\u2019t turn on this SIM right now</string>
 
     <!-- Strings for switch SIM confirmation dialog. -->
     <!--  The title text of switch SIM confirmation dialog. [CHAR LIMIT=NONE] -->
@@ -12894,4 +12882,7 @@
 
     <!-- Authority of the content provider that support methods restartPhoneProcess and restartRild. Will be overlaid by OEM.-->
     <string name="reset_telephony_stack_content_provider_authority" translatable="false"></string>
-</resources>
\ No newline at end of file
+
+    <!--Text for Stylus Pointer Icon preference -->
+    <string name="show_stylus_pointer_icon">Show pointer while hovering</string>
+</resources>
diff --git a/res/xml/power_usage_summary.xml b/res/xml/power_usage_summary.xml
index e62f5c0..1af8a8c 100644
--- a/res/xml/power_usage_summary.xml
+++ b/res/xml/power_usage_summary.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2023 The Android Open Source Project
+<!-- 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.
@@ -51,6 +51,13 @@
         settings:keywords="@string/keywords_battery_saver"
         settings:controller="com.android.settings.fuelgauge.BatterySaverController" />
 
+    <Preference
+        android:fragment="com.android.settings.fuelgauge.SmartBatterySettings"
+        android:key="smart_battery_manager"
+        android:title="@string/smart_battery_manager_title"
+        settings:controller="com.android.settings.fuelgauge.batterytip.BatteryManagerPreferenceController"
+        settings:keywords="@string/keywords_battery_adaptive_preferences" />
+
     <SwitchPreferenceCompat
         android:key="battery_percentage"
         android:title="@string/battery_percentage"
diff --git a/res/xml/privatespace_hide_locked.xml b/res/xml/privatespace_hide_locked.xml
index f26d207..f453d75 100644
--- a/res/xml/privatespace_hide_locked.xml
+++ b/res/xml/privatespace_hide_locked.xml
@@ -34,33 +34,27 @@
         android:selectable="false"
         settings:searchable="false" />
 
-        <Preference
-        android:key="private_space_note"
-        android:summary="@string/privatespace_development_note"
-        android:selectable="false"
-        settings:searchable="false" />
-
     <PreferenceCategory
-        android:title="@string/privatespace_unhide_header">
+        android:title="@string/privatespace_access_header">
 
         <Preference
         android:key="search_when_locked_footer"
         android:icon="@drawable/counter_1_24dp"
-        android:title="@string/privatespace_open_settings"
+        android:title="@string/privatespace_search_description"
         android:selectable="false"
         settings:searchable="false" />
 
         <Preference
             android:key="tap_tile_footer"
             android:icon="@drawable/counter_2_24dp"
-            android:title="@string/privatespace_tap_settings"
+            android:title="@string/privatespace_tap_tile_description"
             android:selectable="false"
             settings:searchable="false" />
 
         <Preference
-            android:key="turn_off_footer"
+            android:key="unlock_profile_footer"
             android:icon="@drawable/counter_3_24dp"
-            android:title="@string/privatespace_turnoff_hide"
+            android:title="@string/privatespace_unlock_description"
             android:selectable="false"
             settings:searchable="false" />
 
diff --git a/src/com/android/settings/connecteddevice/stylus/StylusDevicesController.java b/src/com/android/settings/connecteddevice/stylus/StylusDevicesController.java
index d8e8887..cd23103 100644
--- a/src/com/android/settings/connecteddevice/stylus/StylusDevicesController.java
+++ b/src/com/android/settings/connecteddevice/stylus/StylusDevicesController.java
@@ -24,6 +24,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.UserInfo;
+import android.hardware.input.InputSettings;
 import android.os.Process;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -73,6 +74,8 @@
     static final String KEY_IGNORE_BUTTON = "ignore_button";
     @VisibleForTesting
     static final String KEY_DEFAULT_NOTES = "default_notes";
+    @VisibleForTesting
+    static final String KEY_SHOW_STYLUS_POINTER_ICON = "show_stylus_pointer_icon";
 
     private static final String TAG = "StylusDevicesController";
 
@@ -181,6 +184,26 @@
         return pref;
     }
 
+    @Nullable
+    private SwitchPreferenceCompat createShowStylusPointerIconPreference(
+            SwitchPreferenceCompat preference) {
+        if (!mContext.getResources()
+                .getBoolean(com.android.internal.R.bool.config_enableStylusPointerIcon)) {
+            // If the config is not enabled, no need to show the preference to user
+            return null;
+        }
+        SwitchPreferenceCompat pref = preference == null ? new SwitchPreferenceCompat(mContext)
+                : preference;
+        pref.setKey(KEY_SHOW_STYLUS_POINTER_ICON);
+        pref.setTitle(mContext.getString(R.string.show_stylus_pointer_icon));
+        pref.setIcon(R.drawable.ic_stylus);
+        pref.setOnPreferenceClickListener(this);
+        pref.setChecked(Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.STYLUS_POINTER_ICON_ENABLED,
+                InputSettings.DEFAULT_STYLUS_POINTER_ICON_ENABLED) == 1);
+        return pref;
+    }
+
     @Override
     public boolean onPreferenceClick(Preference preference) {
         String key = preference.getKey();
@@ -213,6 +236,11 @@
                         Secure.STYLUS_BUTTONS_ENABLED,
                         ((TwoStatePreference) preference).isChecked() ? 0 : 1);
                 break;
+            case KEY_SHOW_STYLUS_POINTER_ICON:
+                Settings.Secure.putInt(mContext.getContentResolver(),
+                        Secure.STYLUS_POINTER_ICON_ENABLED,
+                        ((SwitchPreferenceCompat) preference).isChecked() ? 1 : 0);
+                break;
         }
         return true;
     }
@@ -268,6 +296,13 @@
         if (buttonPref == null) {
             mPreferencesContainer.addPreference(createButtonPressPreference());
         }
+        SwitchPreferenceCompat currShowStylusPointerIconPref = mPreferencesContainer
+                .findPreference(KEY_SHOW_STYLUS_POINTER_ICON);
+        Preference showStylusPointerIconPref =
+                createShowStylusPointerIconPreference(currShowStylusPointerIconPref);
+        if (currShowStylusPointerIconPref == null && showStylusPointerIconPref != null) {
+            mPreferencesContainer.addPreference(showStylusPointerIconPref);
+        }
     }
 
     private boolean currentInputMethodSupportsHandwriting() {
diff --git a/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java b/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java
index 0bc6176..a04d8f8 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java
@@ -98,6 +98,12 @@
     /** Checks whether we should show usage information by slots or not */
     boolean isChartGraphSlotsEnabled(Context context);
 
+    /** Checks whether adaptive charging feature is supported in this device */
+    boolean isAdaptiveChargingSupported();
+
+    /** Checks whether battery manager feature is supported in this device */
+    boolean isBatteryManagerSupported();
+
     /** Returns {@code true} if current defender mode is extra defend */
     boolean isExtraDefend();
 
diff --git a/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java b/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java
index a8a2f75..75ebabb 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java
@@ -149,6 +149,16 @@
     }
 
     @Override
+    public boolean isAdaptiveChargingSupported() {
+        return false;
+    }
+
+    @Override
+    public boolean isBatteryManagerSupported() {
+        return true;
+    }
+
+    @Override
     public Intent getResumeChargeIntent(boolean isDockDefender) {
         return null;
     }
diff --git a/src/com/android/settings/fuelgauge/batterytip/BatteryManagerPreferenceController.java b/src/com/android/settings/fuelgauge/batterytip/BatteryManagerPreferenceController.java
new file mode 100644
index 0000000..7448003
--- /dev/null
+++ b/src/com/android/settings/fuelgauge/batterytip/BatteryManagerPreferenceController.java
@@ -0,0 +1,85 @@
+/*
+ * 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.settings.fuelgauge.batterytip;
+
+import android.app.AppOpsManager;
+import android.content.Context;
+import android.os.UserManager;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.fuelgauge.PowerUsageFeatureProvider;
+import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.utils.StringUtil;
+
+/** Preference controller to control the battery manager */
+public class BatteryManagerPreferenceController extends BasePreferenceController {
+    private static final String KEY_BATTERY_MANAGER = "smart_battery_manager";
+
+    private PowerUsageFeatureProvider mPowerUsageFeatureProvider;
+    private AppOpsManager mAppOpsManager;
+    private UserManager mUserManager;
+    private boolean mEnableAppBatteryUsagePage;
+
+    public BatteryManagerPreferenceController(Context context) {
+        super(context, KEY_BATTERY_MANAGER);
+        mPowerUsageFeatureProvider = FeatureFactory.getFeatureFactory()
+                .getPowerUsageFeatureProvider();
+        mAppOpsManager = context.getSystemService(AppOpsManager.class);
+        mUserManager = context.getSystemService(UserManager.class);
+        mEnableAppBatteryUsagePage =
+                mContext.getResources().getBoolean(R.bool.config_app_battery_usage_list_enabled);
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        if (!mPowerUsageFeatureProvider.isBatteryManagerSupported()) {
+            return UNSUPPORTED_ON_DEVICE;
+        }
+        if (!mContext.getResources().getBoolean(R.bool.config_battery_manager_consider_ac)) {
+            return AVAILABLE_UNSEARCHABLE;
+        }
+        return mPowerUsageFeatureProvider.isAdaptiveChargingSupported()
+                ? AVAILABLE_UNSEARCHABLE : UNSUPPORTED_ON_DEVICE;
+    }
+
+    @Override
+    public void updateState(Preference preference) {
+        super.updateState(preference);
+        if (!mEnableAppBatteryUsagePage) {
+            final int num = BatteryTipUtils.getRestrictedAppsList(mAppOpsManager,
+                    mUserManager).size();
+            updateSummary(preference, num);
+        }
+    }
+
+    @VisibleForTesting
+    void updateSummary(Preference preference, int num) {
+        if (num > 0) {
+            preference.setSummary(StringUtil.getIcuPluralsString(mContext, num,
+                    R.string.battery_manager_app_restricted));
+        } else {
+            preference.setSummary(
+                    mPowerUsageFeatureProvider.isAdaptiveChargingSupported()
+                            ? R.string.battery_manager_summary
+                            : R.string.battery_manager_summary_unsupported);
+        }
+    }
+}
diff --git a/src/com/android/settings/network/telephony/ConvertToEsimPreferenceController.java b/src/com/android/settings/network/telephony/ConvertToEsimPreferenceController.java
index 441c249..08e993b 100644
--- a/src/com/android/settings/network/telephony/ConvertToEsimPreferenceController.java
+++ b/src/com/android/settings/network/telephony/ConvertToEsimPreferenceController.java
@@ -20,6 +20,7 @@
 import static androidx.lifecycle.Lifecycle.Event.ON_STOP;
 
 import android.Manifest;
+import android.app.Activity;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -143,6 +144,7 @@
         Intent intent = new Intent(EuiccManager.ACTION_CONVERT_TO_EMBEDDED_SUBSCRIPTION);
         intent.putExtra("subId", mSubId);
         mContext.startActivity(intent);
+        ((Activity) mContext).finish();
         return true;
     }
 
diff --git a/src/com/android/settings/safetycenter/BiometricsSafetySource.java b/src/com/android/settings/safetycenter/BiometricsSafetySource.java
index 94db71f..8e1c786 100644
--- a/src/com/android/settings/safetycenter/BiometricsSafetySource.java
+++ b/src/com/android/settings/safetycenter/BiometricsSafetySource.java
@@ -62,6 +62,16 @@
         }
         final Context profileParentContext =
                 context.createContextAsUser(profileParentUserHandle, 0);
+        if (android.os.Flags.allowPrivateProfile() && userManager.isPrivateProfile()) {
+            // SC always expects a response from the source if the broadcast has been sent for this
+            // source, therefore, we need to send a null SafetySourceData.
+            SafetyCenterManagerWrapper.get().setSafetySourceData(
+                    context,
+                    SAFETY_SOURCE_ID,
+                    /* safetySourceData= */ null,
+                    safetyEvent);
+            return;
+        }
 
         final BiometricNavigationUtils biometricNavigationUtils =
                 new BiometricNavigationUtils(userId);
diff --git a/src/com/android/settings/safetycenter/SafetyCenterManagerWrapper.java b/src/com/android/settings/safetycenter/SafetyCenterManagerWrapper.java
index e720526..55eb4f1 100644
--- a/src/com/android/settings/safetycenter/SafetyCenterManagerWrapper.java
+++ b/src/com/android/settings/safetycenter/SafetyCenterManagerWrapper.java
@@ -22,6 +22,8 @@
 import android.safetycenter.SafetySourceData;
 import android.util.Log;
 
+import androidx.annotation.Nullable;
+
 import com.android.internal.annotations.VisibleForTesting;
 
 /** A wrapper for the SafetyCenterManager system service. */
@@ -49,7 +51,7 @@
 
     /** Sets the latest safety source data for Safety Center. */
     public void setSafetySourceData(Context context, String safetySourceId,
-            SafetySourceData safetySourceData,
+            @Nullable SafetySourceData safetySourceData,
             SafetyEvent safetyEvent) {
         SafetyCenterManager safetyCenterManager =
                 context.getSystemService(SafetyCenterManager.class);
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/stylus/StylusDevicesControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/stylus/StylusDevicesControllerTest.java
index a540d28..135be4b 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/stylus/StylusDevicesControllerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/stylus/StylusDevicesControllerTest.java
@@ -221,7 +221,7 @@
 
         showScreen(controller);
 
-        assertThat(mPreferenceContainer.getPreferenceCount()).isEqualTo(3);
+        assertThat(mPreferenceContainer.getPreferenceCount()).isEqualTo(4);
     }
 
     @Test
@@ -249,11 +249,12 @@
     @Test
     public void btStylusInputDevice_showsAllPreferences() {
         showScreen(mController);
+
         Preference defaultNotesPref = mPreferenceContainer.getPreference(0);
         Preference handwritingPref = mPreferenceContainer.getPreference(1);
         Preference buttonPref = mPreferenceContainer.getPreference(2);
+        Preference stylusPointerIconPref = mPreferenceContainer.getPreference(3);
 
-        assertThat(mPreferenceContainer.getPreferenceCount()).isEqualTo(3);
         assertThat(defaultNotesPref.getTitle().toString()).isEqualTo(
                 mContext.getString(R.string.stylus_default_notes_app));
         assertThat(defaultNotesPref.isVisible()).isTrue();
@@ -263,6 +264,9 @@
         assertThat(buttonPref.getTitle().toString()).isEqualTo(
                 mContext.getString(R.string.stylus_ignore_button));
         assertThat(buttonPref.isVisible()).isTrue();
+        assertThat(stylusPointerIconPref.getTitle().toString()).isEqualTo(
+                mContext.getString(R.string.show_stylus_pointer_icon));
+        assertThat(stylusPointerIconPref.isVisible()).isTrue();
     }
 
     @Test
@@ -551,6 +555,46 @@
                 Secure.STYLUS_BUTTONS_ENABLED, -1)).isEqualTo(1);
     }
 
+    @Test
+    public void stylusPointerIconPreference_checkedWhenFlagTrue() {
+        Settings.Secure.putInt(mContext.getContentResolver(),
+                Settings.Secure.STYLUS_POINTER_ICON_ENABLED, 1);
+
+        showScreen(mController);
+        SwitchPreferenceCompat stylusPointerIconPref =
+                (SwitchPreferenceCompat) mPreferenceContainer.getPreference(3);
+
+        assertThat(stylusPointerIconPref.isChecked()).isEqualTo(true);
+    }
+
+    @Test
+    public void stylusPointerIconPreference_uncheckedWhenFlagFalse() {
+        Settings.Secure.putInt(mContext.getContentResolver(),
+                Settings.Secure.STYLUS_POINTER_ICON_ENABLED, 0);
+
+        showScreen(mController);
+        SwitchPreferenceCompat stylusPointerIconPref =
+                (SwitchPreferenceCompat) mPreferenceContainer.getPreference(3);
+
+        assertThat(stylusPointerIconPref.isChecked()).isEqualTo(false);
+    }
+
+    @Test
+    public void stylusPointerIconPreference_updatesFlagOnClick() {
+        Settings.Secure.putInt(mContext.getContentResolver(),
+                Settings.Secure.STYLUS_POINTER_ICON_ENABLED, 0);
+
+        showScreen(mController);
+        SwitchPreferenceCompat stylusPointerIconPref =
+                (SwitchPreferenceCompat) mPreferenceContainer.getPreference(3);
+
+        stylusPointerIconPref.performClick();
+
+        assertThat(stylusPointerIconPref.isChecked()).isEqualTo(true);
+        assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
+                Secure.STYLUS_POINTER_ICON_ENABLED, -1)).isEqualTo(1);
+    }
+
     private void showScreen(StylusDevicesController controller) {
         controller.displayPreference(mScreen);
     }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImplTest.java
index 0131330..db4c359 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImplTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImplTest.java
@@ -134,6 +134,11 @@
     }
 
     @Test
+    public void testIsAdaptiveChargingSupported_returnFalse() {
+        assertThat(mPowerFeatureProvider.isAdaptiveChargingSupported()).isFalse();
+    }
+
+    @Test
     public void testGetResumeChargeIntentWithoutDockDefender_returnNull() {
         assertThat(mPowerFeatureProvider.getResumeChargeIntent(false)).isNull();
     }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryManagerPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryManagerPreferenceControllerTest.java
new file mode 100644
index 0000000..f7469c7
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryManagerPreferenceControllerTest.java
@@ -0,0 +1,129 @@
+/*
+ * 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.settings.fuelgauge.batterytip;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.app.AppOpsManager;
+import android.content.Context;
+import android.provider.Settings;
+
+import androidx.preference.Preference;
+
+import com.android.settings.R;
+import com.android.settings.fuelgauge.PowerUsageFeatureProvider;
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.shadow.SettingsShadowResources;
+
+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;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(shadows = SettingsShadowResources.class)
+public class BatteryManagerPreferenceControllerTest {
+    private static final int ON = 1;
+    private static final int OFF = 0;
+
+    @Mock
+    private AppOpsManager mAppOpsManager;
+
+    private Context mContext;
+    private Preference mPreference;
+    private FakeFeatureFactory mFeatureFactory;
+    private PowerUsageFeatureProvider mPowerUsageFeatureProvider;
+    private BatteryManagerPreferenceController mController;
+
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        mContext = spy(RuntimeEnvironment.application);
+        when(mContext.getSystemService(AppOpsManager.class)).thenReturn(mAppOpsManager);
+        mFeatureFactory = FakeFeatureFactory.setupForTest();
+        mPreference = new Preference(mContext);
+        mController = new BatteryManagerPreferenceController(mContext);
+        mPowerUsageFeatureProvider = mFeatureFactory.powerUsageFeatureProvider;
+    }
+
+    @Test
+    public void updateState_smartBatteryWithRestrictApps_showSummary() {
+        mController.updateSummary(mPreference, 2);
+
+        assertThat(mPreference.getSummary()).isEqualTo("2 apps restricted");
+    }
+
+    @Test
+    public void updateState_smartBatteryWithoutRestriction_showSummary() {
+        when(mPowerUsageFeatureProvider.isSmartBatterySupported()).thenReturn(true);
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED, ON);
+
+        mController.updateState(mPreference);
+
+        assertThat(mPreference.getSummary()).isEqualTo("Detecting when apps drain battery");
+    }
+
+    @Test
+    public void getAvailabilityStatus_supportBatteryManager_showPrefPage() {
+        SettingsShadowResources.overrideResource(
+                R.bool.config_battery_manager_consider_ac, true);
+        when(mPowerUsageFeatureProvider.isBatteryManagerSupported()).thenReturn(true);
+        when(mPowerUsageFeatureProvider.isAdaptiveChargingSupported()).thenReturn(true);
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(
+                BatteryManagerPreferenceController.AVAILABLE_UNSEARCHABLE);
+    }
+
+    @Test
+    public void getAvailabilityStatus_notSupportBatteryManager_notShowPrefPage() {
+        when(mPowerUsageFeatureProvider.isBatteryManagerSupported()).thenReturn(false);
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(
+                BatteryManagerPreferenceController.UNSUPPORTED_ON_DEVICE);
+    }
+
+    @Test
+    public void getAvailabilityStatus_supportBatteryManagerWithoutAC_notShowPrefPage() {
+        SettingsShadowResources.overrideResource(
+                R.bool.config_battery_manager_consider_ac, true);
+        when(mPowerUsageFeatureProvider.isBatteryManagerSupported()).thenReturn(true);
+        when(mPowerUsageFeatureProvider.isAdaptiveChargingSupported()).thenReturn(false);
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(
+                BatteryManagerPreferenceController.UNSUPPORTED_ON_DEVICE);
+    }
+
+    @Test
+    public void getAvailabilityStatus_ignoreBatteryManagerWithoutAC_showPrefPage() {
+        SettingsShadowResources.overrideResource(
+                R.bool.config_battery_manager_consider_ac, false);
+        when(mPowerUsageFeatureProvider.isBatteryManagerSupported()).thenReturn(true);
+        when(mPowerUsageFeatureProvider.isAdaptiveChargingSupported()).thenReturn(false);
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(
+                BatteryManagerPreferenceController.AVAILABLE_UNSEARCHABLE);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/nfc/NfcForegroundPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/nfc/NfcForegroundPreferenceControllerTest.java
index 63fa320..56326ef 100644
--- a/tests/robotests/src/com/android/settings/nfc/NfcForegroundPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/nfc/NfcForegroundPreferenceControllerTest.java
@@ -25,6 +25,9 @@
 import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 
 import androidx.preference.ListPreference;
 import androidx.preference.PreferenceScreen;
@@ -33,6 +36,7 @@
 import com.android.settings.testutils.FakeFeatureFactory;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -43,10 +47,14 @@
 import java.util.ArrayList;
 
 @RunWith(RobolectricTestRunner.class)
+@RequiresFlagsDisabled(android.permission.flags.Flags.FLAG_WALLET_ROLE_ENABLED)
 public class NfcForegroundPreferenceControllerTest {
 
     private static final String PREF_KEY = PaymentSettingsTest.FOREGROUND_KEY;
 
+    @Rule
+    public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
+
     @Mock
     private PaymentBackend mPaymentBackend;
     @Mock