Merge "NFC support in work profile"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index f367b6f..e10b17d 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -325,6 +325,17 @@
                 android:value="true" />
         </activity>
 
+        <activity android:name=".Settings$AdaptiveBrightnessActivity"
+            android:label="@string/auto_brightness_title"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.settings.ADAPTIVE_BRIGHTNESS_SETTINGS" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
+                android:value="com.android.settings.display.AutoBrightnessSettings"/>
+        </activity>
+
         <activity
             android:name="Settings$ConfigureWifiSettingsActivity"
             android:label="@string/wifi_configure_settings_preference_title"
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 404207d..fdaa7c0 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -322,4 +322,6 @@
      * Activity for AppDashboard.
      */
     public static class AppDashboardActivity extends SettingsActivity {}
+
+    public static class AdaptiveBrightnessActivity extends SettingsActivity { /* empty */ }
 }
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index d0fb7ab..0ba389e 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -84,6 +84,7 @@
 import com.android.settings.deviceinfo.aboutphone.MyDeviceInfoFragment;
 import com.android.settings.deviceinfo.firmwareversion.FirmwareVersionSettings;
 import com.android.settings.deviceinfo.legal.ModuleLicensesDashboard;
+import com.android.settings.display.AutoBrightnessSettings;
 import com.android.settings.display.NightDisplaySettings;
 import com.android.settings.display.SmartAutoRotatePreferenceFragment;
 import com.android.settings.display.darkmode.DarkModeSettingsFragment;
@@ -313,7 +314,8 @@
             MediaControlsSettings.class.getName(),
             NetworkProviderSettings.class.getName(),
             AlarmsAndRemindersDetails.class.getName(),
-            MediaManagementAppsDetails.class.getName()
+            MediaManagementAppsDetails.class.getName(),
+            AutoBrightnessSettings.class.getName()
     };
 
     public static final String[] SETTINGS_FOR_RESTRICTED = {
@@ -344,6 +346,8 @@
             Settings.ConfigureNotificationSettingsActivity.class.getName(),
             Settings.ManageApplicationsActivity.class.getName(),
             Settings.PaymentSettingsActivity.class.getName(),
+            // Home page > Display
+            Settings.AdaptiveBrightnessActivity.class.getName(),
             // Home page > Security & screen lock
             Settings.LocationSettingsActivity.class.getName(),
             // Home page > System
diff --git a/src/com/android/settings/development/bluetooth/AbstractBluetoothDialogPreferenceController.java b/src/com/android/settings/development/bluetooth/AbstractBluetoothDialogPreferenceController.java
index d66b8d8..765c5f8 100644
--- a/src/com/android/settings/development/bluetooth/AbstractBluetoothDialogPreferenceController.java
+++ b/src/com/android/settings/development/bluetooth/AbstractBluetoothDialogPreferenceController.java
@@ -219,11 +219,17 @@
      */
     public void onHDAudioEnabled(boolean enabled) {}
 
-    static int getHighestCodec(BluetoothCodecConfig[] configs) {
+    static int getHighestCodec(BluetoothA2dp bluetoothA2dp, BluetoothDevice activeDevice,
+            BluetoothCodecConfig[] configs) {
         if (configs == null) {
             Log.d(TAG, "Unable to get highest codec. Configs are empty");
             return BluetoothCodecConfig.SOURCE_CODEC_TYPE_INVALID;
         }
+        // If HD audio is not enabled, SBC is the only one available codec.
+        if (bluetoothA2dp.isOptionalCodecsEnabled(activeDevice)
+                != BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED) {
+            return BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC;
+        }
         for (int i = 0; i < CODEC_TYPES.length; i++) {
             for (int j = 0; j < configs.length; j++) {
                 if ((configs[j].getCodecType() == CODEC_TYPES[i])) {
diff --git a/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceController.java b/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceController.java
index 6b243c6..b1b58e5 100644
--- a/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceController.java
+++ b/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceController.java
@@ -93,8 +93,9 @@
         int codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT;
         switch (index) {
             case 0:
-                codecTypeValue = getHighestCodec(getSelectableConfigs(
-                    mBluetoothA2dp.getActiveDevice()));
+                final BluetoothDevice activeDevice = mBluetoothA2dp.getActiveDevice();
+                codecTypeValue = getHighestCodec(mBluetoothA2dp, activeDevice,
+                        getSelectableConfigs(activeDevice));
                 codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST;
                 break;
             case 1:
@@ -147,6 +148,11 @@
         mCallback.onBluetoothCodecChanged();
     }
 
+    @Override
+    public void onHDAudioEnabled(boolean enabled) {
+        writeConfigurationValues(/* index= */ 0);
+    }
+
     private List<Integer> getIndexFromConfig(BluetoothCodecConfig[] configs) {
         List<Integer> indexArray = new ArrayList<>();
         for (int i = 0; i < configs.length; i++) {
diff --git a/src/com/android/settings/fuelgauge/ConvertUtils.java b/src/com/android/settings/fuelgauge/ConvertUtils.java
index 001e9e9..da84631 100644
--- a/src/com/android/settings/fuelgauge/ConvertUtils.java
+++ b/src/com/android/settings/fuelgauge/ConvertUtils.java
@@ -24,6 +24,8 @@
 
 import androidx.annotation.VisibleForTesting;
 
+import com.android.settings.overlay.FeatureFactory;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.text.SimpleDateFormat;
@@ -288,7 +290,7 @@
         }
         insert24HoursData(BatteryChartView.SELECTED_INDEX_ALL, resultMap);
         if (purgeLowPercentageAndFakeData) {
-            purgeLowPercentageAndFakeData(resultMap);
+            purgeLowPercentageAndFakeData(context, resultMap);
         }
         return resultMap;
     }
@@ -327,7 +329,12 @@
 
     // Removes low percentage data and fake usage data, which will be zero value.
     private static void purgeLowPercentageAndFakeData(
+            final Context context,
             final Map<Integer, List<BatteryDiffEntry>> indexedUsageMap) {
+        final List<CharSequence> backgroundUsageTimeHideList =
+                FeatureFactory.getFactory(context)
+                        .getPowerUsageFeatureProvider(context)
+                        .getHideBackgroundUsageTimeList(context);
         for (List<BatteryDiffEntry> entries : indexedUsageMap.values()) {
             final Iterator<BatteryDiffEntry> iterator = entries.iterator();
             while (iterator.hasNext()) {
@@ -336,6 +343,12 @@
                         || FAKE_PACKAGE_NAME.equals(entry.getPackageName())) {
                     iterator.remove();
                 }
+                final String packageName = entry.getPackageName();
+                if (packageName != null
+                        && !backgroundUsageTimeHideList.isEmpty()
+                        && backgroundUsageTimeHideList.contains(packageName)) {
+                  entry.mBackgroundUsageTimeInMs = 0;
+                }
             }
         }
     }
diff --git a/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java b/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java
index 61abe6b..eff538f 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java
@@ -23,6 +23,7 @@
 import com.android.internal.os.BatterySipper;
 import com.android.settingslib.fuelgauge.Estimate;
 
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -141,4 +142,9 @@
      * Returns battery history data with corresponding timestamp key.
      */
     Map<Long, Map<String, BatteryHistEntry>> getBatteryHistory(Context context);
+
+    /**
+     * Returns {@link List} for hidding applications background usage time.
+     */
+    List<CharSequence> getHideBackgroundUsageTimeList(Context context);
 }
diff --git a/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java b/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java
index 1dcdab0..7f1bef0 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java
@@ -26,6 +26,8 @@
 import com.android.internal.util.ArrayUtils;
 import com.android.settingslib.fuelgauge.Estimate;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
 
 public class PowerUsageFeatureProviderImpl implements PowerUsageFeatureProvider {
@@ -167,4 +169,9 @@
     public Map<Long, Map<String, BatteryHistEntry>> getBatteryHistory(Context context) {
         return null;
     }
+
+    @Override
+    public List<CharSequence> getHideBackgroundUsageTimeList(Context context) {
+        return new ArrayList<>();
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceControllerTest.java
index 7dd2906..0f01e00 100644
--- a/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceControllerTest.java
@@ -19,6 +19,7 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -108,6 +109,8 @@
         BluetoothCodecConfig[] mCodecConfigs = {mCodecConfigAAC, mCodecConfigSBC};
         mCodecStatus = new BluetoothCodecStatus(mCodecConfigSBC, null, mCodecConfigs);
         when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus);
+        when(mBluetoothA2dp.isOptionalCodecsEnabled(mActiveDevice)).thenReturn(
+                BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED);
         mController.onBluetoothServiceConnected(mBluetoothA2dp);
 
         mController.writeConfigurationValues(0);
@@ -172,4 +175,37 @@
 
         verify(mCallback).onBluetoothCodecChanged();
     }
+
+    @Test
+    public void onHDAudioEnabled_optionalCodecEnabled_setsCodecTypeAsAAC() {
+        BluetoothCodecConfig[] mCodecConfigs = {mCodecConfigAAC, mCodecConfigSBC};
+        mCodecStatus = new BluetoothCodecStatus(mCodecConfigAAC,
+                /* codecsLocalCapabilities= */ null,
+                mCodecConfigs);
+        when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus);
+        when(mBluetoothA2dp.isOptionalCodecsEnabled(mActiveDevice)).thenReturn(
+                BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED);
+        mController.onBluetoothServiceConnected(mBluetoothA2dp);
+
+        mController.onHDAudioEnabled(/* enabled= */ true);
+
+        verify(mBluetoothA2dpConfigStore, atLeastOnce()).setCodecType(
+                eq(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC));
+    }
+    @Test
+    public void onHDAudioEnabled_optionalCodecDisabled_setsCodecTypeAsSBC() {
+        BluetoothCodecConfig[] mCodecConfigs = {mCodecConfigAAC, mCodecConfigSBC};
+        mCodecStatus = new BluetoothCodecStatus(mCodecConfigAAC,
+                /* codecsLocalCapabilities= */ null,
+                mCodecConfigs);
+        when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus);
+        when(mBluetoothA2dp.isOptionalCodecsEnabled(mActiveDevice)).thenReturn(
+                BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED);
+        mController.onBluetoothServiceConnected(mBluetoothA2dp);
+
+        mController.onHDAudioEnabled(/* enabled= */ false);
+
+        verify(mBluetoothA2dpConfigStore, atLeastOnce()).setCodecType(
+                eq(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC));
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/ConvertUtilsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/ConvertUtilsTest.java
index 0b1a1e3..1b9e05b 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/ConvertUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/ConvertUtilsTest.java
@@ -50,8 +50,11 @@
 public final class ConvertUtilsTest {
 
     private Context mContext;
-    @Mock private BatteryUsageStats mBatteryUsageStats;
-    @Mock private BatteryEntry mockBatteryEntry;
+
+    @Mock
+    private BatteryUsageStats mBatteryUsageStats;
+    @Mock
+    private BatteryEntry mockBatteryEntry;
 
     private FakeFeatureFactory mFeatureFactory;
     private PowerUsageFeatureProvider mPowerUsageFeatureProvider;
@@ -301,7 +304,7 @@
         final Map<Integer, List<BatteryDiffEntry>> purgedResultMap =
             ConvertUtils.getIndexedUsageMap(
                 mContext, timeSlotSize, batteryHistoryKeys, batteryHistoryMap,
-                 /*purgeLowPercentageAndFakeData=*/ true);
+                /*purgeLowPercentageAndFakeData=*/ true);
 
         assertThat(purgedResultMap).hasSize(2);
         final List<BatteryDiffEntry> entryList = purgedResultMap.get(0);
@@ -383,6 +386,38 @@
     }
 
     @Test
+    public void testGetIndexedUsageMap_hideBackgroundUsageTime_returnsExpectedResult() {
+        final long[] batteryHistoryKeys = new long[] {101L, 102L, 103L};
+        final Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap = new HashMap<>();
+        final BatteryHistEntry fakeEntry = createBatteryHistEntry(
+            ConvertUtils.FAKE_PACKAGE_NAME, "fake_label", 0, 0L, 0L, 0L);
+        // Adds the index = 0 data.
+        Map<String, BatteryHistEntry> entryMap = new HashMap<>();
+        entryMap.put(fakeEntry.getKey(), fakeEntry);
+        batteryHistoryMap.put(Long.valueOf(batteryHistoryKeys[0]), entryMap);
+        // Adds the index = 1 data.
+        entryMap = new HashMap<>();
+        entryMap.put(fakeEntry.getKey(), fakeEntry);
+        batteryHistoryMap.put(Long.valueOf(batteryHistoryKeys[1]), entryMap);
+        // Adds the index = 2 data.
+        entryMap = new HashMap<>();
+        final BatteryHistEntry entry = createBatteryHistEntry(
+            "package3", "label3", 500, 5L, 3600000L, 7200000L);
+        entryMap.put(entry.getKey(), entry);
+        batteryHistoryMap.put(Long.valueOf(batteryHistoryKeys[2]), entryMap);
+        when(mPowerUsageFeatureProvider.getHideBackgroundUsageTimeList(mContext))
+            .thenReturn(Arrays.asList((CharSequence) "package3"));
+
+        final Map<Integer, List<BatteryDiffEntry>> purgedResultMap =
+            ConvertUtils.getIndexedUsageMap(
+                mContext, /*timeSlotSize=*/ 1, batteryHistoryKeys, batteryHistoryMap,
+                /*purgeLowPercentageAndFakeData=*/ true);
+
+        final BatteryDiffEntry resultEntry = purgedResultMap.get(0).get(0);
+        assertThat(resultEntry.mBackgroundUsageTimeInMs).isEqualTo(0);
+    }
+
+    @Test
     public void getLocale_nullContext_returnDefaultLocale() {
         assertThat(ConvertUtils.getLocale(/*context=*/ null))
             .isEqualTo(Locale.getDefault());