Migrate usage of BluetoothAdapter#getDefaultAdapter to BluetoothManager#GetAdapter

Bug: 195587287
Test: atest CarServiceUnitTest
Change-Id: Ia323570c1a090af23b13d9ebbeb251a8f0132806
diff --git a/service/src/com/android/car/bluetooth/BluetoothDeviceConnectionPolicy.java b/service/src/com/android/car/bluetooth/BluetoothDeviceConnectionPolicy.java
index 1af5b29..265734a 100644
--- a/service/src/com/android/car/bluetooth/BluetoothDeviceConnectionPolicy.java
+++ b/service/src/com/android/car/bluetooth/BluetoothDeviceConnectionPolicy.java
@@ -18,6 +18,7 @@
 
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothManager;
 import android.car.VehicleAreaSeat;
 import android.car.VehicleAreaType;
 import android.car.VehiclePropertyIds;
@@ -306,7 +307,9 @@
         mContext = Objects.requireNonNull(context);
         mCarBluetoothService = bluetoothService;
         mBluetoothBroadcastReceiver = new BluetoothBroadcastReceiver();
-        mBluetoothAdapter = Objects.requireNonNull(BluetoothAdapter.getDefaultAdapter());
+        BluetoothManager bluetoothManager =
+                Objects.requireNonNull(mContext.getSystemService(BluetoothManager.class));
+        mBluetoothAdapter = Objects.requireNonNull(bluetoothManager.getAdapter());
         mCarHelper = new CarServicesHelper();
         mUserManager = mContext.getSystemService(UserManager.class);
     }
diff --git a/service/src/com/android/car/bluetooth/BluetoothProfileDeviceManager.java b/service/src/com/android/car/bluetooth/BluetoothProfileDeviceManager.java
index 73dbafd..ba63919 100644
--- a/service/src/com/android/car/bluetooth/BluetoothProfileDeviceManager.java
+++ b/service/src/com/android/car/bluetooth/BluetoothProfileDeviceManager.java
@@ -26,6 +26,7 @@
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothHeadsetClient;
+import android.bluetooth.BluetoothManager;
 import android.bluetooth.BluetoothMapClient;
 import android.bluetooth.BluetoothPan;
 import android.bluetooth.BluetoothPbapClient;
@@ -329,7 +330,9 @@
         mProfileTriggers = bpi.mProfileTriggers;
 
         mBluetoothBroadcastReceiver = new BluetoothBroadcastReceiver();
-        mBluetoothAdapter = Objects.requireNonNull(BluetoothAdapter.getDefaultAdapter());
+        BluetoothManager bluetoothManager =
+                Objects.requireNonNull(mContext.getSystemService(BluetoothManager.class));
+        mBluetoothAdapter = Objects.requireNonNull(bluetoothManager.getAdapter());
     }
 
     /**
diff --git a/service/src/com/android/car/bluetooth/BluetoothProfileInhibitManager.java b/service/src/com/android/car/bluetooth/BluetoothProfileInhibitManager.java
index 7fa1a5e..d3c2680 100644
--- a/service/src/com/android/car/bluetooth/BluetoothProfileInhibitManager.java
+++ b/service/src/com/android/car/bluetooth/BluetoothProfileInhibitManager.java
@@ -20,6 +20,7 @@
 
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothManager;
 import android.bluetooth.BluetoothProfile;
 import android.car.ICarBluetoothUserService;
 import android.car.builtin.util.Slog;
@@ -54,6 +55,7 @@
     private static final long RESTORE_BACKOFF_MILLIS = 1000L;
 
     private final Context mContext;
+    private final BluetoothAdapter mBluetoothAdapter;
 
     // Per-User information
     private final int mUserId;
@@ -84,7 +86,7 @@
      *    device - the device we're connecting to, can be null
      *    profile - the profile we're connecting on, can be null
      */
-    public static class BluetoothConnection {
+    public class BluetoothConnection {
         // Examples:
         // 01:23:45:67:89:AB/9
         // null/0
@@ -95,6 +97,33 @@
         private final BluetoothDevice mBluetoothDevice;
         private final Integer mBluetoothProfile;
 
+        /**
+         * Creates a {@link BluetoothConnection} from a previous output of {@link #encode()}.
+         *
+         * @param flattenedParams A flattened string representation of a {@link BluetoothConnection}
+         */
+        public BluetoothConnection(String flattenedParams) {
+            if (!flattenedParams.matches(FLATTENED_PATTERN)) {
+                throw new IllegalArgumentException("Bad format for flattened BluetoothConnection");
+            }
+
+            BluetoothDevice device = null;
+            Integer profile = null;
+
+            if (mBluetoothAdapter != null) {
+                String[] parts = flattenedParams.split("/");
+                if (!"null".equals(parts[0])) {
+                    device = mBluetoothAdapter.getRemoteDevice(parts[0]);
+                }
+                if (!"null".equals(parts[1])) {
+                    profile = Integer.valueOf(parts[1]);
+                }
+            }
+
+            mBluetoothDevice = device;
+            mBluetoothProfile = profile;
+        }
+
         public BluetoothConnection(Integer profile, BluetoothDevice device) {
             mBluetoothProfile = profile;
             mBluetoothDevice = device;
@@ -139,40 +168,6 @@
         public String encode() {
             return mBluetoothDevice + "/" + mBluetoothProfile;
         }
-
-        /**
-         * Creates a {@link BluetoothConnection} from a previous output of {@link #encode()}.
-         *
-         * @param flattenedParams A flattened string representation of a {@link BluetoothConnection}
-         */
-        public static BluetoothConnection decode(String flattenedParams) {
-            if (!flattenedParams.matches(FLATTENED_PATTERN)) {
-                throw new IllegalArgumentException("Bad format for flattened BluetoothConnection");
-            }
-
-            BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
-            if (adapter == null) {
-                return new BluetoothConnection(null, null);
-            }
-
-            String[] parts = flattenedParams.split("/");
-
-            BluetoothDevice device;
-            if (!"null".equals(parts[0])) {
-                device = adapter.getRemoteDevice(parts[0]);
-            } else {
-                device = null;
-            }
-
-            Integer profile;
-            if (!"null".equals(parts[1])) {
-                profile = Integer.valueOf(parts[1]);
-            } else {
-                profile = null;
-            }
-
-            return new BluetoothConnection(profile, device);
-        }
     }
 
     private class InhibitRecord implements IBinder.DeathRecipient {
@@ -233,6 +228,8 @@
         mContext = context;
         mUserId = userId;
         mBluetoothUserProxies = bluetoothUserProxies;
+        BluetoothManager bluetoothManager = mContext.getSystemService(BluetoothManager.class);
+        mBluetoothAdapter = bluetoothManager.getAdapter();
     }
 
     /**
@@ -250,7 +247,7 @@
 
         for (String paramsStr : savedBluetoothConnection.split(SETTINGS_DELIMITER)) {
             try {
-                BluetoothConnection params = BluetoothConnection.decode(paramsStr);
+                BluetoothConnection params = new BluetoothConnection(paramsStr);
                 InhibitRecord record = new InhibitRecord(params, RESTORED_PROFILE_INHIBIT_TOKEN);
                 mProfileInhibits.put(params, record);
                 mRestoredInhibits.add(record);
diff --git a/service/src/com/android/car/bluetooth/FastPairGattServer.java b/service/src/com/android/car/bluetooth/FastPairGattServer.java
index 29ec577..8e1b6ba 100644
--- a/service/src/com/android/car/bluetooth/FastPairGattServer.java
+++ b/service/src/com/android/car/bluetooth/FastPairGattServer.java
@@ -94,7 +94,7 @@
 
     private ArrayList<AccountKey> mKeys = new ArrayList<>();
     private BluetoothGattServer mBluetoothGattServer;
-    private BluetoothManager mBluetoothManager;
+    private final BluetoothAdapter mBluetoothAdapter;
     private int mPairingPasskey = -1;
     private int mFailureCount = 0;
     private int mSuccessCount = 0;
@@ -274,12 +274,12 @@
         mCallbacks = callbacks;
         mPrivateAntiSpoof = antiSpoof;
         mAutomaticPasskeyConfirmation = automaticAcceptance;
-        mBluetoothManager = context.getSystemService(BluetoothManager.class);
-
-        mBluetoothGattServer = mBluetoothManager
+        BluetoothManager bluetoothManager = context.getSystemService(BluetoothManager.class);
+        mBluetoothAdapter = bluetoothManager.getAdapter();
+        mBluetoothGattServer = bluetoothManager
                 .openGattServer(context, mBluetoothGattServerCallback);
         if (DBG) {
-            Log.d(TAG, "mBTManager: " + mBluetoothManager.toString() + " GATT: "
+            Log.d(TAG, "mBTManager: " + bluetoothManager.toString() + " GATT: "
                     + mBluetoothGattServer);
         }
         ByteBuffer modelIdBytes = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(
@@ -476,14 +476,12 @@
         }
         // Check that the request is either a Key-based Pairing Request or an Action Request
         if (decryptedRequest[0] == 0 || decryptedRequest[0] == 0x10) {
-            String localAddress = BluetoothAdapter.getDefaultAdapter().getAddress();
+            String localAddress = mBluetoothAdapter.getAddress();
             byte[] localAddressBytes = FastPairUtils.getBytesFromAddress(localAddress);
             // Extract the remote address bytes from the message
             byte[] remoteAddressBytes = Arrays.copyOfRange(decryptedRequest, 2, 8);
-            BluetoothDevice localDevice = BluetoothAdapter.getDefaultAdapter()
-                    .getRemoteDevice(localAddress);
-            BluetoothDevice reportedDevice = BluetoothAdapter.getDefaultAdapter()
-                    .getRemoteDevice(remoteAddressBytes);
+            BluetoothDevice localDevice = mBluetoothAdapter.getRemoteDevice(localAddress);
+            BluetoothDevice reportedDevice = mBluetoothAdapter.getRemoteDevice(remoteAddressBytes);
             if (DBG) {
                 Log.d(TAG, "Local RPA = " + mLocalRpaDevice);
                 Log.d(TAG, "Decrypted, LocalMacAddress" + localAddress + "remoteAddress"
@@ -609,7 +607,7 @@
                 new BluetoothGattCharacteristic(DEVICE_NAME_CHARACTERISTIC_CONFIG.getUuid(),
                         BluetoothGattCharacteristic.PROPERTY_READ,
                         BluetoothGattCharacteristic.PERMISSION_READ);
-        mDeviceNameCharacteristic.setValue(BluetoothAdapter.getDefaultAdapter().getName());
+        mDeviceNameCharacteristic.setValue(mBluetoothAdapter.getName());
         mFastPairService.addCharacteristic(mDeviceNameCharacteristic);
     }
 
diff --git a/tests/carservice_unit_test/src/com/android/car/bluetooth/AbstractExtendedMockitoBluetoothTestCase.java b/tests/carservice_unit_test/src/com/android/car/bluetooth/AbstractExtendedMockitoBluetoothTestCase.java
index 5366106..c61ccae 100644
--- a/tests/carservice_unit_test/src/com/android/car/bluetooth/AbstractExtendedMockitoBluetoothTestCase.java
+++ b/tests/carservice_unit_test/src/com/android/car/bluetooth/AbstractExtendedMockitoBluetoothTestCase.java
@@ -22,7 +22,6 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.bluetooth.BluetoothAdapter;
 import android.car.test.mocks.AbstractExtendedMockitoTestCase;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
@@ -50,6 +49,7 @@
 import org.mockito.session.MockitoSessionBuilder;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 
 /**
@@ -175,19 +175,6 @@
     }
 
     /**
-     * Mocks a call to {@link BluetoothAdapter#getDefaultAdapter()}.
-     *
-     * @throws IllegalStateException if class didn't override {@link #newSessionBuilder()} and
-     * called {@code spyStatic(BluetoothAdapter.class)} on the session passed to it.
-     */
-    protected final void mockGetDefaultAdapter(@NonNull BluetoothAdapter adapter) {
-        if (VERBOSE) Log.v(TAG, "mockGetDefaultAdapter()");
-        assertSpied(BluetoothAdapter.class);
-
-        doReturn(adapter).when(() -> BluetoothAdapter.getDefaultAdapter());
-    }
-
-    /**
      * Mocks a call to {@link CarLocalServices#getService(Class)}.
      *
      * @throws IllegalStateException if class didn't override {@link #newSessionBuilder()} and
@@ -209,12 +196,15 @@
         private MockContentResolver mContentResolver;
         private FakeSettingsProvider mContentProvider;
 
+        private final HashMap<String, Object> mMockedServices;
+
         MockContext(Context base) {
             super(base);
             FakeSettingsProvider.clearSettingsProvider();
             mContentResolver = new MockContentResolver(this);
             mContentProvider = new FakeSettingsProvider();
             mContentResolver.addProvider(Settings.AUTHORITY, mContentProvider);
+            mMockedServices = new HashMap<String, Object>();
         }
 
         public void release() {
@@ -234,11 +224,20 @@
             return super.registerReceiver(receiver, filter);
         }
 
+        public void addMockedSystemService(Class<?> serviceClass, Object service) {
+            if (service == null) return;
+            String name = getSystemServiceName(serviceClass);
+            if (name == null) return;
+            mMockedServices.put(name, service);
+        }
+
         @Override
         public @Nullable Object getSystemService(String name) {
             if ((name != null) && name.equals(getSystemServiceName(UserManager.class))) {
                 when(mMockUserManager.isUserUnlocked(mUserId)).thenReturn(true);
                 return mMockUserManager;
+            } else if ((name != null) && mMockedServices.containsKey(name)) {
+                return mMockedServices.get(name);
             }
             return super.getSystemService(name);
         }
diff --git a/tests/carservice_unit_test/src/com/android/car/bluetooth/BluetoothDeviceConnectionPolicyTest.java b/tests/carservice_unit_test/src/com/android/car/bluetooth/BluetoothDeviceConnectionPolicyTest.java
index 6b5b0e9..0d04b76 100644
--- a/tests/carservice_unit_test/src/com/android/car/bluetooth/BluetoothDeviceConnectionPolicyTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/bluetooth/BluetoothDeviceConnectionPolicyTest.java
@@ -32,6 +32,7 @@
 import static org.mockito.Mockito.when;
 
 import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothManager;
 import android.car.VehicleAreaSeat;
 import android.car.VehiclePropertyIds;
 import android.car.VehicleSeatOccupancyState;
@@ -40,6 +41,7 @@
 import android.car.hardware.power.CarPowerPolicy;
 import android.car.hardware.property.CarPropertyEvent;
 import android.car.hardware.property.ICarPropertyEventListener;
+import android.content.Context;
 import android.content.Intent;
 import android.provider.Settings;
 import android.util.Log;
@@ -88,6 +90,7 @@
 
     private MockContext mMockContext;
     @Mock private BluetoothAdapter mMockBluetoothAdapter;
+    @Mock private BluetoothManager mMockBluetoothManager;
     @Mock private CarBluetoothService mMockBluetoothService;
     @Mock private IVoiceInteractionManagerService mMockVoiceService;
     @Mock private SystemInterface mMockSystemInterface;
@@ -95,6 +98,9 @@
     @Mock private CarPropertyService mMockCarPropertyService;
     @Mock private CarDrivingStateService mMockCarDrivingStateService;
 
+    private Context mTargetContext;
+    private BluetoothAdapter mBluetoothAdapter;
+
     private BluetoothDeviceConnectionPolicy mPolicy;
     @Captor private ArgumentCaptor<ICarPropertyEventListener> mSeatListenerCaptor;
 
@@ -109,7 +115,6 @@
 
     @Override
     protected void onSessionBuilder(CustomMockitoSessionBuilder session) {
-        session.spyStatic(BluetoothAdapter.class);
         session.spyStatic(CarLocalServices.class);
     }
 
@@ -119,9 +124,16 @@
 
     @Before
     public void setUp() {
-        mMockContext = new MockContext(InstrumentationRegistry.getTargetContext());
+        mTargetContext = InstrumentationRegistry.getTargetContext();
+        mMockContext = new MockContext(mTargetContext);
+        BluetoothManager bluetoothManager =
+                mTargetContext.getSystemService(BluetoothManager.class);
+        mBluetoothAdapter = bluetoothManager.getAdapter();
+        Assert.assertTrue(mBluetoothAdapter != null);
 
-        mockGetDefaultAdapter(mMockBluetoothAdapter);
+        mMockContext.addMockedSystemService(BluetoothManager.class, mMockBluetoothManager);
+        when(mMockBluetoothManager.getAdapter()).thenReturn(mMockBluetoothAdapter);
+
         /**
          * Mocks {@code mBluetoothAdapter.enable()}
          */
@@ -177,12 +189,10 @@
 
     @After
     public void tearDown() {
-        mPolicy.release();
-        CarLocalServices.removeServiceForTest(CarPowerManagementService.class);
-        if (mMockContext != null) {
-            mMockContext.release();
-            mMockContext = null;
+        if (mPolicy != null) {
+            mPolicy.release();
         }
+        CarLocalServices.removeServiceForTest(CarPowerManagementService.class);
     }
 
     //--------------------------------------------------------------------------------------------//
diff --git a/tests/carservice_unit_test/src/com/android/car/bluetooth/BluetoothFastPairTest.java b/tests/carservice_unit_test/src/com/android/car/bluetooth/BluetoothFastPairTest.java
index d7a8f3b..c649123 100644
--- a/tests/carservice_unit_test/src/com/android/car/bluetooth/BluetoothFastPairTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/bluetooth/BluetoothFastPairTest.java
@@ -187,8 +187,6 @@
                 .strictness(Strictness.WARN)
                 .spyStatic(BluetoothAdapter.class)
                 .startMocking();
-        ExtendedMockito.doReturn(mMockBluetoothAdapter).when(() ->
-                BluetoothAdapter.getDefaultAdapter());
 
         mTestFastPairAdvertiser = new FastPairAdvertiser(mMockContext, TEST_MODEL_ID, null);
         mTestFastPairProvider = new FastPairProvider(mMockContext);
diff --git a/tests/carservice_unit_test/src/com/android/car/bluetooth/BluetoothProfileDeviceManagerTest.java b/tests/carservice_unit_test/src/com/android/car/bluetooth/BluetoothProfileDeviceManagerTest.java
index 943227c..5656e86 100644
--- a/tests/carservice_unit_test/src/com/android/car/bluetooth/BluetoothProfileDeviceManagerTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/bluetooth/BluetoothProfileDeviceManagerTest.java
@@ -35,9 +35,11 @@
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothHeadsetClient;
+import android.bluetooth.BluetoothManager;
 import android.bluetooth.BluetoothProfile;
 import android.bluetooth.BluetoothUuid;
 import android.car.ICarBluetoothUserService;
+import android.content.Context;
 import android.content.Intent;
 import android.os.Handler;
 import android.os.Looper;
@@ -125,30 +127,32 @@
     private Handler mHandler;
     private static final Object HANDLER_TOKEN = new Object();
 
+    private Context mTargetContext;
     private MockContext mMockContext;
 
     @Mock private BluetoothAdapter mMockBluetoothAdapter;
+    @Mock private BluetoothManager mMockBluetoothManager;
     private BluetoothAdapter mBluetoothAdapter;
 
-    @Override
-    protected void onSessionBuilder(CustomMockitoSessionBuilder session) {
-        session.spyStatic(BluetoothAdapter.class);
-    }
-
     //--------------------------------------------------------------------------------------------//
     // Setup/TearDown                                                                             //
     //--------------------------------------------------------------------------------------------//
 
     @Before
     public void setUp() {
-        mMockContext = new MockContext(InstrumentationRegistry.getTargetContext());
+        mTargetContext = InstrumentationRegistry.getTargetContext();
+        mMockContext = new MockContext(mTargetContext);
         setSettingsDeviceList("");
         assertSettingsContains("");
 
-        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+        BluetoothManager bluetoothManager =
+                mTargetContext.getSystemService(BluetoothManager.class);
+        mBluetoothAdapter = bluetoothManager.getAdapter();
         Assert.assertTrue(mBluetoothAdapter != null);
 
-        mockGetDefaultAdapter(mMockBluetoothAdapter);
+        mMockContext.addMockedSystemService(BluetoothManager.class, mMockBluetoothManager);
+        when(mMockBluetoothManager.getAdapter()).thenReturn(mMockBluetoothAdapter);
+
         /**
          * Mocks {@link BluetoothAdapter#getRemoteDevice(boolean)}
          */
diff --git a/tests/carservice_unit_test/src/com/android/car/bluetooth/CarBluetoothServiceTest.java b/tests/carservice_unit_test/src/com/android/car/bluetooth/CarBluetoothServiceTest.java
index 44687d1..0b91f57 100644
--- a/tests/carservice_unit_test/src/com/android/car/bluetooth/CarBluetoothServiceTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/bluetooth/CarBluetoothServiceTest.java
@@ -20,6 +20,8 @@
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.when;
 
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothManager;
 import android.car.IPerUserCarService;
 import android.content.Context;
 import android.content.pm.PackageManager;
@@ -69,6 +71,9 @@
     private MockContentProvider mMockContentProvider;
     @Mock private PackageManager mMockPackageManager;
 
+    @Mock private BluetoothManager mMockBluetoothManager;
+    @Mock private BluetoothAdapter mMockBluetoothAdapter;
+
     @Mock private PerUserCarServiceHelper mMockUserSwitchService;
     @Mock private IPerUserCarService mMockPerUserCarService;
     @Mock private CarBluetoothUserService mMockBluetoothUserService;
@@ -96,6 +101,9 @@
         when(mMockContext.getContentResolver()).thenReturn(mMockContentResolver);
         when(mMockContext.getApplicationContext()).thenReturn(mMockContext);
         when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
+        when(mMockContext.getSystemService(BluetoothManager.class))
+                .thenReturn(mMockBluetoothManager);
+        when(mMockBluetoothManager.getAdapter()).thenReturn(mMockBluetoothAdapter);
 
         // Make sure we grab and store CarBluetoothService's user switch callback so we can
         // invoke it at any time.