Merge "Only show DeveloperOptionsController for admin" into main
diff --git a/Android.bp b/Android.bp
index b456a72..9b4cfde 100644
--- a/Android.bp
+++ b/Android.bp
@@ -107,13 +107,12 @@
 
     plugins: ["androidx.room_room-compiler-plugin"],
 
-    // TODO: b/307330031 - Re-enable the nullaway plugin when the issue is fixed.
-    // errorprone: {
-    //     extra_check_modules: ["//external/nullaway:nullaway_plugin"],
-    //     javacflags: [
-    //         "-XepOpt:NullAway:AnnotatedPackages=com.android.settings",
-    //     ],
-    // },
+    errorprone: {
+        extra_check_modules: ["//external/nullaway:nullaway_plugin"],
+        javacflags: [
+            "-XepOpt:NullAway:AnnotatedPackages=com.android.settings",
+        ],
+    },
 
     libs: [
         "telephony-common",
diff --git a/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java b/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java
index 630acbb..27001d6 100644
--- a/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java
+++ b/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java
@@ -28,9 +28,9 @@
 import com.android.settings.SettingsActivity;
 import com.android.settings.Utils;
 import com.android.settings.connecteddevice.audiosharing.AudioSharingDevicePreferenceController;
+import com.android.settings.connecteddevice.audiosharing.AudioSharingUtils;
 import com.android.settings.core.SettingsUIDeviceConfig;
 import com.android.settings.dashboard.DashboardFragment;
-import com.android.settings.flags.Flags;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.overlay.SurveyFeatureProvider;
 import com.android.settings.search.BaseSearchIndexProvider;
@@ -87,7 +87,7 @@
                             + ", action : "
                             + action);
         }
-        if (Flags.enableLeAudioSharing()) {
+        if (AudioSharingUtils.isFeatureEnabled()) {
             use(AudioSharingDevicePreferenceController.class).init(this);
         }
         use(AvailableMediaDeviceGroupController.class).init(this);
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingBasePreferenceController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingBasePreferenceController.java
index 90cf779..8497c9d 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingBasePreferenceController.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingBasePreferenceController.java
@@ -27,7 +27,6 @@
 
 import com.android.settings.bluetooth.Utils;
 import com.android.settings.core.BasePreferenceController;
-import com.android.settings.flags.Flags;
 import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
 import com.android.settingslib.utils.ThreadUtils;
@@ -51,7 +50,7 @@
 
     @Override
     public int getAvailabilityStatus() {
-        return Flags.enableLeAudioSharing() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
+        return AudioSharingUtils.isFeatureEnabled() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
     }
 
     @Override
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java
index 7a2f26f..483a74b 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java
@@ -24,7 +24,6 @@
 import android.bluetooth.BluetoothLeBroadcastReceiveState;
 import android.bluetooth.BluetoothProfile;
 import android.content.Context;
-import android.content.pm.PackageManager;
 import android.util.Log;
 
 import androidx.annotation.NonNull;
@@ -39,7 +38,6 @@
 import com.android.settings.connecteddevice.DevicePreferenceCallback;
 import com.android.settings.core.BasePreferenceController;
 import com.android.settings.dashboard.DashboardFragment;
-import com.android.settings.flags.Flags;
 import com.android.settingslib.bluetooth.BluetoothCallback;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 import com.android.settingslib.bluetooth.LeAudioProfile;
@@ -309,9 +307,7 @@
 
     @Override
     public int getAvailabilityStatus() {
-        return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)
-                        && Flags.enableLeAudioSharing()
-                        && mBluetoothDeviceUpdater != null
+        return AudioSharingUtils.isFeatureEnabled() && mBluetoothDeviceUpdater != null
                 ? AVAILABLE_UNSEARCHABLE
                 : UNSUPPORTED_ON_DEVICE;
     }
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragment.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragment.java
index bdf7f03..5cd86b4 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragment.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragment.java
@@ -32,7 +32,6 @@
 import com.android.internal.widget.RecyclerView;
 import com.android.settings.R;
 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
-import com.android.settings.flags.Flags;
 
 import java.util.ArrayList;
 import java.util.Locale;
@@ -73,7 +72,7 @@
             Fragment host,
             ArrayList<AudioSharingDeviceItem> deviceItems,
             DialogEventListener listener) {
-        if (!Flags.enableLeAudioSharing()) return;
+        if (!AudioSharingUtils.isFeatureEnabled()) return;
         final FragmentManager manager = host.getChildFragmentManager();
         sListener = listener;
         if (manager.findFragmentByTag(TAG) == null) {
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDisconnectDialogFragment.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDisconnectDialogFragment.java
index 1840f58..365aed5 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDisconnectDialogFragment.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDisconnectDialogFragment.java
@@ -32,7 +32,6 @@
 import com.android.internal.widget.RecyclerView;
 import com.android.settings.R;
 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
-import com.android.settings.flags.Flags;
 
 import java.util.ArrayList;
 
@@ -66,13 +65,16 @@
      * Display the {@link AudioSharingDisconnectDialogFragment} dialog.
      *
      * @param host The Fragment this dialog will be hosted.
+     * @param deviceItems The existing connected device items in audio sharing session.
+     * @param newDeviceName The name of the latest connected device triggered this dialog.
+     * @param listener The callback to handle the user action on this dialog.
      */
     public static void show(
             Fragment host,
             ArrayList<AudioSharingDeviceItem> deviceItems,
             String newDeviceName,
             DialogEventListener listener) {
-        if (!Flags.enableLeAudioSharing()) return;
+        if (!AudioSharingUtils.isFeatureEnabled()) return;
         final FragmentManager manager = host.getChildFragmentManager();
         sListener = listener;
         if (manager.findFragmentByTag(TAG) == null) {
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingJoinDialogFragment.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingJoinDialogFragment.java
index b9646ac..589c955 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingJoinDialogFragment.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingJoinDialogFragment.java
@@ -30,7 +30,6 @@
 
 import com.android.settings.R;
 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
-import com.android.settings.flags.Flags;
 
 import java.util.ArrayList;
 import java.util.Locale;
@@ -69,7 +68,7 @@
             ArrayList<AudioSharingDeviceItem> deviceItems,
             String newDeviceName,
             DialogEventListener listener) {
-        if (!Flags.enableLeAudioSharing()) return;
+        if (!AudioSharingUtils.isFeatureEnabled()) return;
         final FragmentManager manager = host.getChildFragmentManager();
         sListener = listener;
         if (manager.findFragmentByTag(TAG) == null) {
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingPreferenceController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingPreferenceController.java
index b6b4568..294e8b2 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingPreferenceController.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingPreferenceController.java
@@ -19,7 +19,6 @@
 import android.content.Context;
 
 import com.android.settings.core.BasePreferenceController;
-import com.android.settings.flags.Flags;
 
 public class AudioSharingPreferenceController extends BasePreferenceController {
     private static final String TAG = "AudioSharingPreferenceController";
@@ -33,6 +32,6 @@
 
     @Override
     public int getAvailabilityStatus() {
-        return Flags.enableLeAudioSharing() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
+        return AudioSharingUtils.isFeatureEnabled() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
     }
 }
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingStopDialogFragment.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingStopDialogFragment.java
index 495fad3..13416aa 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingStopDialogFragment.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingStopDialogFragment.java
@@ -25,7 +25,6 @@
 import androidx.fragment.app.FragmentManager;
 
 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
-import com.android.settings.flags.Flags;
 
 public class AudioSharingStopDialogFragment extends InstrumentedDialogFragment {
     private static final String TAG = "AudioSharingStopDialog";
@@ -50,9 +49,11 @@
      * Display the {@link AudioSharingStopDialogFragment} dialog.
      *
      * @param host The Fragment this dialog will be hosted.
+     * @param newDeviceName The name of the latest connected device triggered this dialog.
+     * @param listener The callback to handle the user action on this dialog.
      */
     public static void show(Fragment host, String newDeviceName, DialogEventListener listener) {
-        if (!Flags.enableLeAudioSharing()) return;
+        if (!AudioSharingUtils.isFeatureEnabled()) return;
         final FragmentManager manager = host.getChildFragmentManager();
         sListener = listener;
         if (manager.findFragmentByTag(TAG) == null) {
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarController.java
index 469a387..dc04bee 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarController.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarController.java
@@ -38,7 +38,6 @@
 import com.android.settings.bluetooth.Utils;
 import com.android.settings.core.BasePreferenceController;
 import com.android.settings.dashboard.DashboardFragment;
-import com.android.settings.flags.Flags;
 import com.android.settings.widget.SettingsMainSwitchBar;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
@@ -315,7 +314,7 @@
 
     @Override
     public int getAvailabilityStatus() {
-        return Flags.enableLeAudioSharing() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
+        return AudioSharingUtils.isFeatureEnabled() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
     }
 
     /**
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java
index a43e098..10cac42 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java
@@ -20,10 +20,12 @@
 import android.bluetooth.BluetoothCsipSetCoordinator;
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothLeBroadcastReceiveState;
+import android.bluetooth.BluetoothStatusCodes;
 import android.content.Context;
 import android.util.Log;
 import android.widget.Toast;
 
+import com.android.settings.flags.Flags;
 import com.android.settingslib.bluetooth.BluetoothUtils;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
@@ -244,9 +246,8 @@
             Log.w(TAG, "getActiveSinksOnAssistant(): LocalBluetoothManager is null!");
             return Optional.empty();
         }
-        var groupedDevices = AudioSharingUtils.fetchConnectedDevicesByGroupId(manager);
-        var leadDevices =
-                AudioSharingUtils.buildOrderedConnectedLeadDevices(manager, groupedDevices, false);
+        var groupedDevices = fetchConnectedDevicesByGroupId(manager);
+        var leadDevices = buildOrderedConnectedLeadDevices(manager, groupedDevices, false);
 
         if (!leadDevices.isEmpty() && AudioSharingUtils.isActiveLeAudioDevice(leadDevices.get(0))) {
             return Optional.of(leadDevices.get(0));
@@ -262,6 +263,16 @@
                 () -> Toast.makeText(context, message, Toast.LENGTH_LONG).show());
     }
 
+    /** Returns if the le audio sharing is enabled. */
+    public static boolean isFeatureEnabled() {
+        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+        return Flags.enableLeAudioSharing()
+                && adapter.isLeAudioBroadcastSourceSupported()
+                        == BluetoothStatusCodes.FEATURE_SUPPORTED
+                && adapter.isLeAudioBroadcastAssistantSupported()
+                        == BluetoothStatusCodes.FEATURE_SUPPORTED;
+    }
+
     /** Automatically update active device if needed. */
     public static void updateActiveDeviceIfNeeded(LocalBluetoothManager localBtManager) {
         if (localBtManager == null) return;
diff --git a/src/com/android/settings/connecteddevice/audiosharing/CallsAndAlarmsDialogFragment.java b/src/com/android/settings/connecteddevice/audiosharing/CallsAndAlarmsDialogFragment.java
index 47f70c7..e47e141 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/CallsAndAlarmsDialogFragment.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/CallsAndAlarmsDialogFragment.java
@@ -26,7 +26,6 @@
 
 import com.android.settings.R;
 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
-import com.android.settings.flags.Flags;
 
 import java.util.ArrayList;
 
@@ -64,7 +63,7 @@
             Fragment host,
             ArrayList<AudioSharingDeviceItem> deviceItems,
             DialogEventListener listener) {
-        if (!Flags.enableLeAudioSharing()) return;
+        if (!AudioSharingUtils.isFeatureEnabled()) return;
         final FragmentManager manager = host.getChildFragmentManager();
         sListener = listener;
         if (manager.findFragmentByTag(TAG) == null) {