Merge "Sort in slot selectable subscriptions first" into main
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 9ae77b2..14879e2 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -5192,6 +5192,18 @@
             android:theme="@style/Theme.SpaLib.Dialog">
         </activity>
 
+        <activity android:name="Settings$BluetoothDashboardActivity"
+            android:label="@string/bluetooth_settings_title"
+            android:permission="android.permission.BLUETOOTH_CONNECT"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.settings.BLUETOOTH_DASHBOARD_SETTINGS" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
+                android:value="com.android.settings.connecteddevice.BluetoothDashboardFragment"/>
+        </activity>
+
         <activity
             android:name="com.android.settings.connecteddevice.audiosharing.AudioSharingActivity"
             android:label="@string/audio_sharing_title"
diff --git a/res/xml/bluetooth_le_audio_sharing.xml b/res/xml/bluetooth_le_audio_sharing.xml
index 8ba6c07..15c38b3 100644
--- a/res/xml/bluetooth_le_audio_sharing.xml
+++ b/res/xml/bluetooth_le_audio_sharing.xml
@@ -34,7 +34,7 @@
         android:key="calls_and_alarms"
         android:summary=""
         android:title="@string/audio_sharing_call_audio_title"
-        settings:controller="com.android.settings.connecteddevice.audiosharing.CallsAndAlarmsPreferenceController" />
+        settings:controller="com.android.settings.connecteddevice.audiosharing.AudioSharingCallAudioPreferenceController" />
 
     <Preference
         android:icon="@drawable/ic_audio_play_sample"
@@ -68,14 +68,14 @@
 
     <PreferenceCategory
         android:key="audio_streams_settings_category"
-        android:title="@string/audio_streams_category_title"
+        android:title="@string/audio_sharing_nearby_audio_title"
         settings:controller="com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamsCategoryController">
 
         <Preference
             android:fragment="com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamsDashboardFragment"
             android:icon="@drawable/ic_chevron_right_24dp"
             android:key="audio_streams_settings"
-            android:title="@string/audio_streams_pref_title" />
+            android:title="@string/audio_streams_main_page_title" />
 
     </PreferenceCategory>
 </PreferenceScreen>
\ No newline at end of file
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 9ebc124..3367bf1 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -47,6 +47,7 @@
 
     public static class MemtagPageActivity extends SettingsActivity { /* empty */}
     public static class BluetoothSettingsActivity extends SettingsActivity { /* empty */ }
+    public static class BluetoothDashboardActivity extends SettingsActivity { /* empty */ }
     public static class CreateShortcutActivity extends SettingsActivity { /* empty */ }
     public static class FaceSettingsActivity extends SettingsActivity { /* empty */ }
     /** Container for {@link FaceSettings} to use with a pre-defined task affinity. */
diff --git a/src/com/android/settings/connecteddevice/audiosharing/CallsAndAlarmsDialogFragment.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioDialogFragment.java
similarity index 93%
rename from src/com/android/settings/connecteddevice/audiosharing/CallsAndAlarmsDialogFragment.java
rename to src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioDialogFragment.java
index df94694..db82619 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/CallsAndAlarmsDialogFragment.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioDialogFragment.java
@@ -32,7 +32,7 @@
 import java.util.List;
 
 /** Provides a dialog to choose the active device for calls and alarms. */
-public class CallsAndAlarmsDialogFragment extends InstrumentedDialogFragment {
+public class AudioSharingCallAudioDialogFragment extends InstrumentedDialogFragment {
     private static final String TAG = "CallsAndAlarmsDialog";
     private static final String BUNDLE_KEY_DEVICE_ITEMS = "bundle_key_device_items";
 
@@ -55,7 +55,7 @@
     }
 
     /**
-     * Display the {@link CallsAndAlarmsDialogFragment} dialog.
+     * Display the {@link AudioSharingCallAudioDialogFragment} dialog.
      *
      * @param host The Fragment this dialog will be hosted.
      * @param deviceItems The connected device items in audio sharing session.
@@ -71,7 +71,8 @@
         if (manager.findFragmentByTag(TAG) == null) {
             final Bundle bundle = new Bundle();
             bundle.putParcelableList(BUNDLE_KEY_DEVICE_ITEMS, deviceItems);
-            final CallsAndAlarmsDialogFragment dialog = new CallsAndAlarmsDialogFragment();
+            final AudioSharingCallAudioDialogFragment dialog =
+                    new AudioSharingCallAudioDialogFragment();
             dialog.setArguments(bundle);
             dialog.show(manager, TAG);
         }
diff --git a/src/com/android/settings/connecteddevice/audiosharing/CallsAndAlarmsPreferenceController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceController.java
similarity index 96%
rename from src/com/android/settings/connecteddevice/audiosharing/CallsAndAlarmsPreferenceController.java
rename to src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceController.java
index 8aaebc6..e848f88 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/CallsAndAlarmsPreferenceController.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceController.java
@@ -51,6 +51,8 @@
 import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
 import com.android.settingslib.utils.ThreadUtils;
 
+import com.google.common.collect.ImmutableList;
+
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -60,7 +62,7 @@
 import java.util.concurrent.atomic.AtomicBoolean;
 
 /** PreferenceController to control the dialog to choose the active device for calls and alarms */
-public class CallsAndAlarmsPreferenceController extends AudioSharingBasePreferenceController
+public class AudioSharingCallAudioPreferenceController extends AudioSharingBasePreferenceController
         implements BluetoothCallback {
     private static final String TAG = "CallsAndAlarmsPreferenceController";
     private static final String PREF_KEY = "calls_and_alarms";
@@ -131,7 +133,7 @@
                 }
             };
 
-    public CallsAndAlarmsPreferenceController(Context context) {
+    public AudioSharingCallAudioPreferenceController(Context context) {
         super(context, PREF_KEY);
         mBtManager = Utils.getLocalBtManager(mContext);
         mProfileManager = mBtManager == null ? null : mBtManager.getProfileManager();
@@ -176,16 +178,13 @@
                         }
                         updateDeviceItemsInSharingSession();
                         if (mDeviceItemsInSharingSession.size() >= 1) {
-                            CallsAndAlarmsDialogFragment.show(
+                            AudioSharingCallAudioDialogFragment.show(
                                     mFragment,
                                     mDeviceItemsInSharingSession,
                                     (AudioSharingDeviceItem item) -> {
-                                        if (!mGroupedConnectedDevices.containsKey(
-                                                item.getGroupId())) {
-                                            return;
-                                        }
                                         List<CachedBluetoothDevice> devices =
-                                                mGroupedConnectedDevices.get(item.getGroupId());
+                                                mGroupedConnectedDevices.getOrDefault(
+                                                        item.getGroupId(), ImmutableList.of());
                                         @Nullable
                                         CachedBluetoothDevice lead =
                                                 AudioSharingUtils.getLeadDevice(devices);
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDashboardFragment.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDashboardFragment.java
index 275d197..c3248c7 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDashboardFragment.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDashboardFragment.java
@@ -33,7 +33,7 @@
     SettingsMainSwitchBar mMainSwitchBar;
     private AudioSharingSwitchBarController mSwitchBarController;
     private AudioSharingDeviceVolumeGroupController mAudioSharingDeviceVolumeGroupController;
-    private CallsAndAlarmsPreferenceController mCallsAndAlarmsPreferenceController;
+    private AudioSharingCallAudioPreferenceController mAudioSharingCallAudioPreferenceController;
     private AudioSharingPlaySoundPreferenceController mAudioSharingPlaySoundPreferenceController;
     private AudioStreamsCategoryController mAudioStreamsCategoryController;
 
@@ -67,8 +67,9 @@
         mAudioSharingDeviceVolumeGroupController =
                 use(AudioSharingDeviceVolumeGroupController.class);
         mAudioSharingDeviceVolumeGroupController.init(this);
-        mCallsAndAlarmsPreferenceController = use(CallsAndAlarmsPreferenceController.class);
-        mCallsAndAlarmsPreferenceController.init(this);
+        mAudioSharingCallAudioPreferenceController =
+                use(AudioSharingCallAudioPreferenceController.class);
+        mAudioSharingCallAudioPreferenceController.init(this);
         mAudioSharingPlaySoundPreferenceController =
                 use(AudioSharingPlaySoundPreferenceController.class);
         mAudioStreamsCategoryController = use(AudioStreamsCategoryController.class);
@@ -100,7 +101,7 @@
 
     private void updateVisibilityForAttachedPreferences() {
         mAudioSharingDeviceVolumeGroupController.updateVisibility();
-        mCallsAndAlarmsPreferenceController.updateVisibility();
+        mAudioSharingCallAudioPreferenceController.updateVisibility();
         mAudioSharingPlaySoundPreferenceController.updateVisibility();
         mAudioStreamsCategoryController.updateVisibility();
     }
diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamMediaService.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamMediaService.java
index 2e4930c..ea5eede 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamMediaService.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamMediaService.java
@@ -42,6 +42,7 @@
 import com.android.settings.connecteddevice.audiosharing.AudioSharingUtils;
 import com.android.settingslib.bluetooth.BluetoothCallback;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
 import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
 import com.android.settingslib.bluetooth.VolumeControlProfile;
@@ -60,6 +61,7 @@
     private static final String LEAVE_BROADCAST_ACTION = "leave_broadcast_action";
     private static final String LEAVE_BROADCAST_TEXT = "Leave Broadcast";
     private static final String CHANNEL_ID = "bluetooth_notification_channel";
+    private static final String DEFAULT_DEVICE_NAME = "";
     private static final int STATIC_PLAYBACK_DURATION = 100;
     private static final int STATIC_PLAYBACK_POSITION = 30;
     private static final int ZERO_PLAYBACK_SPEED = 0;
@@ -355,16 +357,34 @@
         return mIsMuted ? mPlayStatePausingBuilder.build() : mPlayStatePlayingBuilder.build();
     }
 
+    private String getDeviceName() {
+        if (mDevices == null || mDevices.isEmpty() || mLocalBtManager == null) {
+            return DEFAULT_DEVICE_NAME;
+        }
+
+        CachedBluetoothDeviceManager manager = mLocalBtManager.getCachedDeviceManager();
+        if (manager == null) {
+            return DEFAULT_DEVICE_NAME;
+        }
+
+        CachedBluetoothDevice device = manager.findDevice(mDevices.get(0));
+        return device != null ? device.getName() : DEFAULT_DEVICE_NAME;
+    }
+
     private Notification buildNotification() {
+        String deviceName = getDeviceName();
+        Notification.MediaStyle mediaStyle =
+                new Notification.MediaStyle()
+                        .setMediaSession(
+                                mLocalSession != null ? mLocalSession.getSessionToken() : null);
+        if (deviceName != null && !deviceName.isEmpty()) {
+            mediaStyle.setRemotePlaybackInfo(
+                    deviceName, com.android.internal.R.drawable.ic_bt_headset_hfp, null);
+        }
         Notification.Builder notificationBuilder =
                 new Notification.Builder(this, CHANNEL_ID)
                         .setSmallIcon(com.android.settingslib.R.drawable.ic_bt_le_audio_sharing)
-                        .setStyle(
-                                new Notification.MediaStyle()
-                                        .setMediaSession(
-                                                mLocalSession != null
-                                                        ? mLocalSession.getSessionToken()
-                                                        : null))
+                        .setStyle(mediaStyle)
                         .setContentText(this.getString(BROADCAST_CONTENT_TEXT))
                         .setSilent(true);
         return notificationBuilder.build();
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index 7c601c0..1c14712 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -86,6 +86,7 @@
 import com.android.settings.bugreporthandler.BugReportHandlerPicker;
 import com.android.settings.communal.CommunalDashboardFragment;
 import com.android.settings.connecteddevice.AdvancedConnectedDeviceDashboardFragment;
+import com.android.settings.connecteddevice.BluetoothDashboardFragment;
 import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment;
 import com.android.settings.connecteddevice.NfcAndPaymentFragment;
 import com.android.settings.connecteddevice.PreviouslyConnectedDeviceDashboardFragment;
@@ -213,6 +214,7 @@
             AdvancedConnectedDeviceDashboardFragment.class.getName(),
             CreateShortcut.class.getName(),
             BluetoothPairingDetail.class.getName(),
+            BluetoothDashboardFragment.class.getName(),
             WifiNetworkDetailsFragment.class.getName(),
             ConfigureWifiSettings.class.getName(),
             SavedAccessPointsWifiSettings2.class.getName(),
diff --git a/src/com/android/settings/fuelgauge/BatterySettingsStorage.java b/src/com/android/settings/fuelgauge/BatterySettingsStorage.java
index 99edbec..4c8b9b8 100644
--- a/src/com/android/settings/fuelgauge/BatterySettingsStorage.java
+++ b/src/com/android/settings/fuelgauge/BatterySettingsStorage.java
@@ -57,7 +57,8 @@
 
 /** An implementation to backup and restore battery configurations. */
 public final class BatterySettingsStorage extends ObservableBackupRestoreStorage {
-    public static final String TAG = "BatteryBackupHelper";
+    private static final String NAME = "BatteryBackupHelper";
+    private static final String TAG = "BatterySettingsStorage";
 
     // Definition for the device build information.
     public static final String KEY_BUILD_BRAND = "device_build_brand";
@@ -89,7 +90,7 @@
      */
     public static @NonNull BatterySettingsStorage get(@NonNull Context context) {
         return (BatterySettingsStorage)
-                BackupRestoreStorageManager.getInstance(context).getOrThrow(TAG);
+                BackupRestoreStorageManager.getInstance(context).getOrThrow(NAME);
     }
 
     public BatterySettingsStorage(@NonNull Context context) {
@@ -99,7 +100,7 @@
     @NonNull
     @Override
     public String getName() {
-        return TAG;
+        return NAME;
     }
 
     @Override
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/CallsAndAlarmsDialogFragmentTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioDialogFragmentTest.java
similarity index 95%
rename from tests/robotests/src/com/android/settings/connecteddevice/audiosharing/CallsAndAlarmsDialogFragmentTest.java
rename to tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioDialogFragmentTest.java
index 53e0d71..4477fa3 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/CallsAndAlarmsDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioDialogFragmentTest.java
@@ -51,7 +51,7 @@
             ShadowAlertDialogCompat.class,
             ShadowBluetoothAdapter.class,
         })
-public class CallsAndAlarmsDialogFragmentTest {
+public class AudioSharingCallAudioDialogFragmentTest {
     @Rule public final MockitoRule mocks = MockitoJUnit.rule();
     @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
 
@@ -64,7 +64,7 @@
             new AudioSharingDeviceItem(TEST_DEVICE_NAME2, /* groupId= */ 1, /* isActive= */ true);
 
     private Fragment mParent;
-    private CallsAndAlarmsDialogFragment mFragment;
+    private AudioSharingCallAudioDialogFragment mFragment;
     private ShadowBluetoothAdapter mShadowBluetoothAdapter;
 
     @Before
@@ -76,7 +76,7 @@
                 BluetoothStatusCodes.FEATURE_SUPPORTED);
         mShadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
                 BluetoothStatusCodes.FEATURE_SUPPORTED);
-        mFragment = new CallsAndAlarmsDialogFragment();
+        mFragment = new AudioSharingCallAudioDialogFragment();
         mParent = new Fragment();
         FragmentController.setupFragment(
                 mParent, FragmentActivity.class, /* containerViewId= */ 0, /* bundle= */ null);
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/CallsAndAlarmsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceControllerTest.java
similarity index 98%
rename from tests/robotests/src/com/android/settings/connecteddevice/audiosharing/CallsAndAlarmsPreferenceControllerTest.java
rename to tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceControllerTest.java
index 614cb5b..bdfc71f 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/CallsAndAlarmsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceControllerTest.java
@@ -88,7 +88,7 @@
             ShadowBluetoothUtils.class,
             ShadowThreadUtils.class,
         })
-public class CallsAndAlarmsPreferenceControllerTest {
+public class AudioSharingCallAudioPreferenceControllerTest {
     private static final String PREF_KEY = "calls_and_alarms";
     private static final String TEST_DEVICE_NAME1 = "test1";
     private static final String TEST_DEVICE_NAME2 = "test2";
@@ -118,7 +118,7 @@
     @Mock private CachedBluetoothDevice mCachedDevice3;
     @Mock private BluetoothLeBroadcastReceiveState mState;
     @Mock private ContentResolver mContentResolver;
-    private CallsAndAlarmsPreferenceController mController;
+    private AudioSharingCallAudioPreferenceController mController;
     @Spy private ContentObserver mContentObserver;
     private ShadowBluetoothAdapter mShadowBluetoothAdapter;
     private LocalBluetoothManager mBtManager;
@@ -151,7 +151,7 @@
         bisSyncState.add(1L);
         when(mState.getBisSyncState()).thenReturn(bisSyncState);
         when(mContext.getContentResolver()).thenReturn(mContentResolver);
-        mController = new CallsAndAlarmsPreferenceController(mContext);
+        mController = new AudioSharingCallAudioPreferenceController(mContext);
         mController.init(null);
         mContentObserver = mController.getSettingsObserver();
         mPreference = new Preference(mContext);
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/db/AppUsageEventEntityTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/db/AppUsageEventEntityTest.java
index eb72b96..dc9b51d 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/db/AppUsageEventEntityTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/db/AppUsageEventEntityTest.java
@@ -27,7 +27,7 @@
 public final class AppUsageEventEntityTest {
     @Test
     public void testBuilder_returnsExpectedResult() {
-        final long uid = 101L;
+        final int uid = 101;
         final long userId = 1001L;
         final long timestamp = 10001L;
         final int appUsageEventType = 1;
diff --git a/tests/robotests/src/com/android/settings/testutils/BatteryTestUtils.java b/tests/robotests/src/com/android/settings/testutils/BatteryTestUtils.java
index 915231f..10b17a7 100644
--- a/tests/robotests/src/com/android/settings/testutils/BatteryTestUtils.java
+++ b/tests/robotests/src/com/android/settings/testutils/BatteryTestUtils.java
@@ -169,7 +169,7 @@
             Context context, long userId, long timestamp, String packageName, boolean multiple) {
         final AppUsageEventEntity entity =
                 new AppUsageEventEntity(
-                        /* uid= */ 101L,
+                        /* uid= */ 101,
                         userId,
                         timestamp,
                         /* appUsageEventType= */ 2,