DO NOT MERGE: Use connected devices for bluetooth connection state.

Fixes: 160278468
Test: manually, atest UiBluetoothMonitorTest TelecomActivityViewModelTest HfpDeviceListLiveDataTest -v
Change-Id: If307b9f1d108facd3bd557fa9ac566b361eef6fc
diff --git a/src/com/android/car/dialer/bluetooth/UiBluetoothMonitor.java b/src/com/android/car/dialer/bluetooth/UiBluetoothMonitor.java
index d232216..9031a6d 100644
--- a/src/com/android/car/dialer/bluetooth/UiBluetoothMonitor.java
+++ b/src/com/android/car/dialer/bluetooth/UiBluetoothMonitor.java
@@ -23,7 +23,6 @@
 import androidx.lifecycle.Observer;
 import androidx.lifecycle.Transformations;
 
-import com.android.car.dialer.livedata.BluetoothHfpStateLiveData;
 import com.android.car.dialer.livedata.BluetoothPairListLiveData;
 import com.android.car.dialer.livedata.BluetoothStateLiveData;
 import com.android.car.dialer.livedata.HfpDeviceListLiveData;
@@ -39,7 +38,6 @@
 
     private final Context mContext;
 
-    private BluetoothHfpStateLiveData mHfpStateLiveData;
     private BluetoothPairListLiveData mPairListLiveData;
     private BluetoothStateLiveData mBluetoothStateLiveData;
     private HfpDeviceListLiveData mHfpDeviceListLiveData;
@@ -77,7 +75,6 @@
 
     private UiBluetoothMonitor(Context applicationContext) {
         mContext = applicationContext;
-        mHfpStateLiveData = new BluetoothHfpStateLiveData(mContext);
         mPairListLiveData = new BluetoothPairListLiveData(mContext);
         mBluetoothStateLiveData = new BluetoothStateLiveData(mContext);
         mHfpDeviceListLiveData = new HfpDeviceListLiveData(mContext);
@@ -87,7 +84,6 @@
         mBluetoothStateObserver = o -> L.i(TAG, "BluetoothState is updated");
         mHfpDeviceListObserver = o -> L.i(TAG, "HfpDeviceList is updated");
 
-        mHfpStateLiveData.observeForever(mHfpStateObserver);
         mPairListLiveData.observeForever(mPairListObserver);
         mBluetoothStateLiveData.observeForever(mBluetoothStateObserver);
         mHfpDeviceListLiveData.observeForever(mHfpDeviceListObserver);
@@ -98,7 +94,6 @@
      * {@link #get()} won't return a valid {@link UiBluetoothMonitor} after calling this function.
      */
     public void tearDown() {
-        removeObserver(mHfpStateLiveData, mHfpStateObserver);
         removeObserver(mPairListLiveData, mPairListObserver);
         removeObserver(mBluetoothStateLiveData, mBluetoothStateObserver);
         removeObserver(mHfpDeviceListLiveData, mHfpDeviceListObserver);
@@ -107,13 +102,6 @@
     }
 
     /**
-     * Returns a LiveData which monitors the HFP profile state changes.
-     */
-    public BluetoothHfpStateLiveData getHfpStateLiveData() {
-        return mHfpStateLiveData;
-    }
-
-    /**
      * Returns a LiveData which monitors the paired device list changes.
      */
     public BluetoothPairListLiveData getPairListLiveData() {
diff --git a/src/com/android/car/dialer/livedata/BluetoothErrorStringLiveData.java b/src/com/android/car/dialer/livedata/BluetoothErrorStringLiveData.java
index 0bb9da9..2b474dc 100644
--- a/src/com/android/car/dialer/livedata/BluetoothErrorStringLiveData.java
+++ b/src/com/android/car/dialer/livedata/BluetoothErrorStringLiveData.java
@@ -18,7 +18,6 @@
 
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothProfile;
 import android.content.Context;
 
 import androidx.lifecycle.MediatorLiveData;
@@ -27,6 +26,7 @@
 import com.android.car.dialer.bluetooth.UiBluetoothMonitor;
 import com.android.car.dialer.log.L;
 
+import java.util.List;
 import java.util.Set;
 
 /**
@@ -40,7 +40,7 @@
 
     private Context mContext;
 
-    private BluetoothHfpStateLiveData mHfpStateLiveData;
+    private HfpDeviceListLiveData mHfpDeviceListLiveData;
     private BluetoothPairListLiveData mPairListLiveData;
     private BluetoothStateLiveData mBluetoothStateLiveData;
 
@@ -61,17 +61,17 @@
         } else {
             setValue(NO_BT_ERROR);
             UiBluetoothMonitor uiBluetoothMonitor = UiBluetoothMonitor.get();
-            mHfpStateLiveData = uiBluetoothMonitor.getHfpStateLiveData();
+            mHfpDeviceListLiveData = uiBluetoothMonitor.getHfpDeviceListLiveData();
             mPairListLiveData = uiBluetoothMonitor.getPairListLiveData();
             mBluetoothStateLiveData = uiBluetoothMonitor.getBluetoothStateLiveData();
 
-            addSource(mHfpStateLiveData, this::onHfpStateChanged);
+            addSource(mHfpDeviceListLiveData, this::onHfpDevicesChanged);
             addSource(mPairListLiveData, this::onPairListChanged);
             addSource(mBluetoothStateLiveData, this::onBluetoothStateChanged);
         }
     }
 
-    private void onHfpStateChanged(Integer state) {
+    private void onHfpDevicesChanged(List<BluetoothDevice> bluetoothDevices) {
         update();
     }
 
@@ -108,8 +108,8 @@
     }
 
     private boolean isHfpConnected() {
-        Integer hfpState = mHfpStateLiveData.getValue();
-        return hfpState == null || hfpState == BluetoothProfile.STATE_CONNECTED;
+        List<BluetoothDevice> mHfpDeviceList = mHfpDeviceListLiveData.getValue();
+        return mHfpDeviceList != null && !mHfpDeviceList.isEmpty();
     }
 
     private boolean isBluetoothEnabled() {
diff --git a/src/com/android/car/dialer/livedata/BluetoothHfpStateLiveData.java b/src/com/android/car/dialer/livedata/BluetoothHfpStateLiveData.java
deleted file mode 100644
index 4257d59..0000000
--- a/src/com/android/car/dialer/livedata/BluetoothHfpStateLiveData.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2018 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.car.dialer.livedata;
-
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothHeadsetClient;
-import android.bluetooth.BluetoothProfile;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-
-import com.android.car.dialer.log.L;
-
-import androidx.lifecycle.LiveData;
-
-/**
- * Provides the connectivity state of HFP Bluetooth profile. States can be one of:
- * <ul>
- * <li>{@link BluetoothProfile#STATE_DISCONNECTED},
- * <li>{@link BluetoothProfile#STATE_CONNECTING},
- * <li>{@link BluetoothProfile#STATE_CONNECTED},
- * <li>{@link BluetoothProfile#STATE_DISCONNECTING}
- * </ul>
- */
-public class BluetoothHfpStateLiveData extends LiveData<Integer> {
-    private static final String TAG = "CD.BluetoothHfpStateLiveData";
-
-    private final BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
-    private final Context mContext;
-    private final IntentFilter mIntentFilter = new IntentFilter();
-
-    private BroadcastReceiver mBluetoothStateReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            updateState();
-        }
-    };
-
-    /** Creates a new {@link BluetoothHfpStateLiveData}. Call on main thread. */
-    public BluetoothHfpStateLiveData(Context context) {
-        mContext = context;
-        mIntentFilter.addAction(BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED);
-    }
-
-    @Override
-    protected void onActive() {
-        if (mBluetoothAdapter != null) {
-            updateState();
-            mContext.registerReceiver(mBluetoothStateReceiver, mIntentFilter);
-        }
-    }
-
-    @Override
-    protected void onInactive() {
-        if (mBluetoothAdapter != null) {
-            mContext.unregisterReceiver(mBluetoothStateReceiver);
-        }
-    }
-
-    private void updateState() {
-        int state = mBluetoothAdapter.getProfileConnectionState(
-                BluetoothProfile.HEADSET_CLIENT);
-        if (getValue() == null || state != getValue()) {
-            L.d(TAG, "updateState to %s", state);
-            setValue(state);
-        }
-    }
-}
diff --git a/src/com/android/car/dialer/livedata/HfpDeviceListLiveData.java b/src/com/android/car/dialer/livedata/HfpDeviceListLiveData.java
index 54794d5..fc444b6 100644
--- a/src/com/android/car/dialer/livedata/HfpDeviceListLiveData.java
+++ b/src/com/android/car/dialer/livedata/HfpDeviceListLiveData.java
@@ -28,6 +28,7 @@
 import androidx.lifecycle.LiveData;
 import androidx.lifecycle.MutableLiveData;
 
+import java.util.Collections;
 import java.util.List;
 
 /** {@link LiveData} that monitors the hfp connected devices. */
@@ -88,6 +89,8 @@
     private void update() {
         if (mBluetoothHeadsetClient != null) {
             setValue(mBluetoothHeadsetClient.getConnectedDevices());
+        } else {
+            setValue(Collections.emptyList());
         }
     }
 }
diff --git a/tests/robotests/src/com/android/car/dialer/bluetooth/UiBluetoothMonitorTest.java b/tests/robotests/src/com/android/car/dialer/bluetooth/UiBluetoothMonitorTest.java
index eac78e5..fe43694 100644
--- a/tests/robotests/src/com/android/car/dialer/bluetooth/UiBluetoothMonitorTest.java
+++ b/tests/robotests/src/com/android/car/dialer/bluetooth/UiBluetoothMonitorTest.java
@@ -22,7 +22,6 @@
 
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothProfile;
 import android.content.Context;
 
 import com.android.car.dialer.CarDialerRobolectricTestRunner;
@@ -39,8 +38,7 @@
 import org.robolectric.annotation.Config;
 import org.robolectric.shadow.api.Shadow;
 
-import java.util.HashSet;
-import java.util.Set;
+import java.util.Collections;
 
 @RunWith(CarDialerRobolectricTestRunner.class)
 @Config(shadows = ShadowBluetoothAdapterForDialer.class)
@@ -59,16 +57,12 @@
 
         ShadowBluetoothAdapterForDialer shadowBluetoothAdapter = Shadow.extract(
                 BluetoothAdapter.getDefaultAdapter());
-        // Sets up Bluetooth Hfp state
-        shadowBluetoothAdapter.setState(BluetoothAdapter.STATE_ON);
-        shadowBluetoothAdapter.setProfileConnectionState(BluetoothProfile.HEADSET_CLIENT,
-                BluetoothProfile.STATE_CONNECTED);
         // Sets up Bluetooth pair list
-        Set<BluetoothDevice> bondedDevices = new HashSet<BluetoothDevice>();
-        bondedDevices.add(mMockbluetoothDevice);
-        shadowBluetoothAdapter.setBondedDevices(bondedDevices);
+        shadowBluetoothAdapter.setBondedDevices(Collections.singleton(mMockbluetoothDevice));
         // Sets up Bluetooth state
         shadowBluetoothAdapter.setEnabled(true);
+        // Sets up Bluetooth Hfp connected devices
+        shadowBluetoothAdapter.setHfpDevices(Collections.singletonList(mMockbluetoothDevice));
 
         mUiBluetoothMonitor = UiBluetoothMonitor.init(mContext);
     }
@@ -84,14 +78,6 @@
     }
 
     @Test
-    public void testHfpStateLiveData() {
-        assertNotNull(mUiBluetoothMonitor.getHfpStateLiveData());
-        assertThat(mUiBluetoothMonitor.getHfpStateLiveData().hasActiveObservers()).isTrue();
-        assertThat(mUiBluetoothMonitor.getHfpStateLiveData().getValue()).isEqualTo(
-                BluetoothProfile.STATE_CONNECTED);
-    }
-
-    @Test
     public void testPairListLiveData() {
         assertNotNull(mUiBluetoothMonitor.getPairListLiveData());
         assertThat(mUiBluetoothMonitor.getPairListLiveData().hasActiveObservers()).isTrue();
@@ -111,6 +97,7 @@
     public void testHfpDeviceListLiveData() {
         assertNotNull(mUiBluetoothMonitor.getHfpDeviceListLiveData());
         assertThat(mUiBluetoothMonitor.getHfpDeviceListLiveData().hasActiveObservers()).isTrue();
+        assertThat(mUiBluetoothMonitor.getHfpDeviceListLiveData().getValue()).isNotEmpty();
     }
 
     @After
diff --git a/tests/robotests/src/com/android/car/dialer/livedata/BluetoothHfpStateLiveDataTest.java b/tests/robotests/src/com/android/car/dialer/livedata/HfpDeviceListLiveDataTest.java
similarity index 69%
rename from tests/robotests/src/com/android/car/dialer/livedata/BluetoothHfpStateLiveDataTest.java
rename to tests/robotests/src/com/android/car/dialer/livedata/HfpDeviceListLiveDataTest.java
index 4648b28..e23cfc8 100644
--- a/tests/robotests/src/com/android/car/dialer/livedata/BluetoothHfpStateLiveDataTest.java
+++ b/tests/robotests/src/com/android/car/dialer/livedata/HfpDeviceListLiveDataTest.java
@@ -26,8 +26,8 @@
 import static org.mockito.Mockito.when;
 
 import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothHeadsetClient;
-import android.bluetooth.BluetoothProfile;
 import android.content.Context;
 import android.content.Intent;
 
@@ -50,25 +50,29 @@
 import org.robolectric.annotation.Config;
 import org.robolectric.shadow.api.Shadow;
 
+import java.util.Collections;
+
 @RunWith(CarDialerRobolectricTestRunner.class)
 @Config(shadows = ShadowBluetoothAdapterForDialer.class)
-public class BluetoothHfpStateLiveDataTest {
+public class HfpDeviceListLiveDataTest {
     private static final String INTENT_ACTION =
             BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED;
 
-    private BluetoothHfpStateLiveData mBluetoothHfpStateLiveData;
+    private HfpDeviceListLiveData mHfpDeviceListLiveData;
     private LifecycleRegistry mLifecycleRegistry;
     private BroadcastReceiverVerifier mReceiverVerifier;
     @Mock
     private LifecycleOwner mMockLifecycleOwner;
     @Mock
     private LiveDataObserver<Integer> mMockObserver;
+    @Mock
+    private BluetoothDevice mMockBluetoothDevice;
 
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
 
-        mBluetoothHfpStateLiveData = new BluetoothHfpStateLiveData(RuntimeEnvironment.application);
+        mHfpDeviceListLiveData = new HfpDeviceListLiveData(RuntimeEnvironment.application);
         mLifecycleRegistry = new LifecycleRegistry(mMockLifecycleOwner);
         when(mMockLifecycleOwner.getLifecycle()).thenReturn(mLifecycleRegistry);
 
@@ -77,7 +81,7 @@
 
     @Test
     public void testOnActive() {
-        mBluetoothHfpStateLiveData.observe(mMockLifecycleOwner,
+        mHfpDeviceListLiveData.observe(mMockLifecycleOwner,
                 (value) -> mMockObserver.onChanged(value));
         verify(mMockObserver, never()).onChanged(any());
 
@@ -91,36 +95,24 @@
         ArgumentCaptor<Integer> valueCaptor = ArgumentCaptor.forClass(Integer.class);
         doNothing().when(mMockObserver).onChanged(valueCaptor.capture());
 
-        ShadowBluetoothAdapterForDialer shadowBluetoothAdapter =
-                (ShadowBluetoothAdapterForDialer) Shadow.extract(
-                        BluetoothAdapter.getDefaultAdapter());
-        shadowBluetoothAdapter.setState(BluetoothAdapter.STATE_ON);
-        shadowBluetoothAdapter.setProfileConnectionState(BluetoothProfile.HEADSET_CLIENT,
-                BluetoothProfile.STATE_CONNECTED);
+        ShadowBluetoothAdapterForDialer shadowBluetoothAdapter = Shadow.extract(
+                BluetoothAdapter.getDefaultAdapter());
 
-        mBluetoothHfpStateLiveData.observe(mMockLifecycleOwner,
+        shadowBluetoothAdapter.setHfpDevices(Collections.singletonList(mMockBluetoothDevice));
+        mHfpDeviceListLiveData.observe(mMockLifecycleOwner,
                 (value) -> mMockObserver.onChanged(value));
         mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
-        assertThat(BluetoothAdapter.getDefaultAdapter().getProfileConnectionState(
-                BluetoothProfile.HEADSET_CLIENT)).isEqualTo(BluetoothProfile.STATE_CONNECTED);
-        assertThat(mBluetoothHfpStateLiveData.getValue()).isEqualTo(
-                BluetoothProfile.STATE_CONNECTED);
-        assertThat(valueCaptor.getValue()).isEqualTo(BluetoothProfile.STATE_CONNECTED);
+        assertThat(mHfpDeviceListLiveData.getValue()).isNotEmpty();
 
-        shadowBluetoothAdapter.setProfileConnectionState(BluetoothProfile.HEADSET_CLIENT,
-                BluetoothProfile.STATE_DISCONNECTED);
+        shadowBluetoothAdapter.setHfpDevices(Collections.emptyList());
         mReceiverVerifier.getBroadcastReceiverFor(INTENT_ACTION)
                 .onReceive(mock(Context.class), mock(Intent.class));
-        assertThat(BluetoothAdapter.getDefaultAdapter().getProfileConnectionState(
-                BluetoothProfile.HEADSET_CLIENT)).isEqualTo(BluetoothProfile.STATE_DISCONNECTED);
-        assertThat(mBluetoothHfpStateLiveData.getValue()).isEqualTo(
-                BluetoothProfile.STATE_DISCONNECTED);
-        assertThat(valueCaptor.getValue()).isEqualTo(BluetoothProfile.STATE_DISCONNECTED);
+        assertThat(mHfpDeviceListLiveData.getValue()).isEmpty();
     }
 
     @Test
     public void testOnInactiveUnregister() {
-        mBluetoothHfpStateLiveData.observe(mMockLifecycleOwner,
+        mHfpDeviceListLiveData.observe(mMockLifecycleOwner,
                 (value) -> mMockObserver.onChanged(value));
         mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
         int preNumber = mReceiverVerifier.getReceiverNumber();
diff --git a/tests/robotests/src/com/android/car/dialer/testutils/ShadowBluetoothAdapterForDialer.java b/tests/robotests/src/com/android/car/dialer/testutils/ShadowBluetoothAdapterForDialer.java
index 0686dd6..d7adcbf 100644
--- a/tests/robotests/src/com/android/car/dialer/testutils/ShadowBluetoothAdapterForDialer.java
+++ b/tests/robotests/src/com/android/car/dialer/testutils/ShadowBluetoothAdapterForDialer.java
@@ -16,8 +16,14 @@
 
 package com.android.car.dialer.testutils;
 
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothHeadsetClient;
 import android.bluetooth.BluetoothProfile;
+import android.content.Context;
 
 import androidx.annotation.Nullable;
 
@@ -26,6 +32,7 @@
 import org.robolectric.shadows.ShadowApplication;
 
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -40,6 +47,8 @@
 
     private static boolean bluetoothAvailable = true;
     private Map<Integer, Integer> profileConnectionStateData = new HashMap<>();
+    private final BluetoothHeadsetClient mMockBluetoothHeadsetClient = mock(
+            BluetoothHeadsetClient.class);
 
     @Nullable
     @Implementation
@@ -50,10 +59,25 @@
         return (BluetoothAdapter) ShadowApplication.getInstance().getBluetoothAdapter();
     }
 
+    @Implementation
+    public boolean getProfileProxy(Context context, BluetoothProfile.ServiceListener listener,
+            int profile) {
+        if (profile == BluetoothProfile.HEADSET_CLIENT) {
+            listener.onServiceConnected(BluetoothProfile.HEADSET_CLIENT,
+                    mMockBluetoothHeadsetClient);
+            return true;
+        }
+        return false;
+    }
+
     /**
      * Sets if the default Bluetooth Adapter is null
      */
     public static void setBluetoothAvailable(boolean available) {
         bluetoothAvailable = available;
     }
+
+    public void setHfpDevices(List<BluetoothDevice> bluetoothDevices) {
+        when(mMockBluetoothHeadsetClient.getConnectedDevices()).thenReturn(bluetoothDevices);
+    }
 }
diff --git a/tests/robotests/src/com/android/car/dialer/ui/TelecomActivityViewModelTest.java b/tests/robotests/src/com/android/car/dialer/ui/TelecomActivityViewModelTest.java
index 7d96260..824d14c 100644
--- a/tests/robotests/src/com/android/car/dialer/ui/TelecomActivityViewModelTest.java
+++ b/tests/robotests/src/com/android/car/dialer/ui/TelecomActivityViewModelTest.java
@@ -24,7 +24,6 @@
 import android.app.Application;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothProfile;
 import android.content.Context;
 
 import com.android.car.dialer.CarDialerRobolectricTestRunner;
@@ -32,9 +31,9 @@
 import com.android.car.dialer.TestDialerApplication;
 import com.android.car.dialer.bluetooth.UiBluetoothMonitor;
 import com.android.car.dialer.livedata.BluetoothErrorStringLiveData;
-import com.android.car.dialer.livedata.BluetoothHfpStateLiveData;
 import com.android.car.dialer.livedata.BluetoothPairListLiveData;
 import com.android.car.dialer.livedata.BluetoothStateLiveData;
+import com.android.car.dialer.livedata.HfpDeviceListLiveData;
 import com.android.car.dialer.telecom.UiCallManager;
 import com.android.car.dialer.testutils.ShadowBluetoothAdapterForDialer;
 
@@ -44,9 +43,9 @@
 import org.junit.runner.RunWith;
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
+import org.robolectric.shadow.api.Shadow;
 
-import java.util.Arrays;
-import java.util.HashSet;
+import java.util.Collections;
 
 @RunWith(CarDialerRobolectricTestRunner.class)
 @Config(shadows = ShadowBluetoothAdapterForDialer.class)
@@ -54,7 +53,7 @@
 
     private TelecomActivityViewModel mTelecomActivityViewModel;
     private Context mContext;
-    private BluetoothHfpStateLiveData mHfpStateLiveData;
+    private HfpDeviceListLiveData mHfpDeviceListLiveData;
     private BluetoothPairListLiveData mPairedListLiveData;
     private BluetoothStateLiveData mBluetoothStateLiveData;
 
@@ -72,7 +71,7 @@
 
     @Test
     public void testDialerAppState_defaultBluetoothAdapterIsNull_bluetoothError() {
-        initializeBluetoothMonitor(false);
+        ShadowBluetoothAdapterForDialer.setBluetoothAvailable(false);
         initializeViewModel();
 
         assertThat(mTelecomActivityViewModel.getErrorMessage().getValue()).isEqualTo(
@@ -81,7 +80,7 @@
 
     @Test
     public void testDialerAppState_bluetoothNotEnabled_bluetoothError() {
-        initializeBluetoothMonitor(true);
+        ShadowBluetoothAdapterForDialer.setBluetoothAvailable(true);
         ShadowBluetoothAdapterForDialer shadowBluetoothAdapter =
                 (ShadowBluetoothAdapterForDialer) shadowOf(BluetoothAdapter.getDefaultAdapter());
         shadowBluetoothAdapter.setEnabled(false);
@@ -95,11 +94,11 @@
 
     @Test
     public void testDialerAppState_noPairedDevices_bluetoothError() {
-        initializeBluetoothMonitor(true);
-        ShadowBluetoothAdapterForDialer shadowBluetoothAdapter =
-                (ShadowBluetoothAdapterForDialer) shadowOf(BluetoothAdapter.getDefaultAdapter());
+        ShadowBluetoothAdapterForDialer.setBluetoothAvailable(true);
+        ShadowBluetoothAdapterForDialer shadowBluetoothAdapter = Shadow.extract(
+                BluetoothAdapter.getDefaultAdapter());
         shadowBluetoothAdapter.setEnabled(true);
-        shadowBluetoothAdapter.setBondedDevices(new HashSet<BluetoothDevice>());
+        shadowBluetoothAdapter.setBondedDevices(Collections.emptySet());
         initializeViewModel();
 
         assertThat(mBluetoothStateLiveData.getValue()).isEqualTo(
@@ -112,51 +111,48 @@
 
     @Test
     public void testDialerAppState_hfpNoConnected_bluetoothError() {
-        initializeBluetoothMonitor(true);
-        ShadowBluetoothAdapterForDialer shadowBluetoothAdapter =
-                (ShadowBluetoothAdapterForDialer) shadowOf(BluetoothAdapter.getDefaultAdapter());
+        ShadowBluetoothAdapterForDialer.setBluetoothAvailable(true);
+        BluetoothDevice mockBluetoothDevice = mock(BluetoothDevice.class);
+        ShadowBluetoothAdapterForDialer shadowBluetoothAdapter = Shadow.extract(
+                BluetoothAdapter.getDefaultAdapter());
         shadowBluetoothAdapter.setEnabled(true);
-        shadowBluetoothAdapter.setBondedDevices(
-                new HashSet<>(Arrays.asList(mock(BluetoothDevice.class))));
-        shadowBluetoothAdapter.setProfileConnectionState(BluetoothProfile.HEADSET_CLIENT,
-                BluetoothProfile.STATE_DISCONNECTED);
+        shadowBluetoothAdapter.setBondedDevices(Collections.singleton(mockBluetoothDevice));
+        shadowBluetoothAdapter.setHfpDevices(Collections.emptyList());
         initializeViewModel();
 
         assertThat(mBluetoothStateLiveData.getValue()).isEqualTo(
                 BluetoothStateLiveData.BluetoothState.ENABLED);
         assertThat(mPairedListLiveData.getValue().isEmpty()).isFalse();
 
-        assertThat(mHfpStateLiveData.getValue() == BluetoothProfile.STATE_DISCONNECTED).isTrue();
+        assertThat(mHfpDeviceListLiveData.getValue().isEmpty()).isTrue();
         assertThat(mTelecomActivityViewModel.getErrorMessage().getValue()).isEqualTo(
                 mContext.getString(R.string.no_hfp));
     }
 
     @Test
     public void testDialerAppState_bluetoothAllSet_dialerAppStateDefault() {
-        initializeBluetoothMonitor(true);
-        ShadowBluetoothAdapterForDialer shadowBluetoothAdapter =
-                (ShadowBluetoothAdapterForDialer) shadowOf(BluetoothAdapter.getDefaultAdapter());
+        ShadowBluetoothAdapterForDialer.setBluetoothAvailable(true);
+        BluetoothDevice mockBluetoothDevice = mock(BluetoothDevice.class);
+        ShadowBluetoothAdapterForDialer shadowBluetoothAdapter = Shadow.extract(
+                BluetoothAdapter.getDefaultAdapter());
+        // Sets up Bluetooth pair list
+        shadowBluetoothAdapter.setBondedDevices(Collections.singleton(mockBluetoothDevice));
+        // Sets up Bluetooth state
         shadowBluetoothAdapter.setEnabled(true);
-        shadowBluetoothAdapter.setBondedDevices(
-                new HashSet<>(Arrays.asList(mock(BluetoothDevice.class))));
-        shadowBluetoothAdapter.setProfileConnectionState(BluetoothProfile.HEADSET_CLIENT,
-                BluetoothProfile.STATE_CONNECTED);
+        // Sets up Bluetooth Hfp connected devices
+        shadowBluetoothAdapter.setHfpDevices(Collections.singletonList(mockBluetoothDevice));
+
         initializeViewModel();
 
         assertThat(mTelecomActivityViewModel.getErrorMessage().getValue()).isEqualTo(
                 BluetoothErrorStringLiveData.NO_BT_ERROR);
     }
 
-    private void initializeBluetoothMonitor(boolean availability) {
-        ShadowBluetoothAdapterForDialer.setBluetoothAvailable(availability);
-
+    private void initializeViewModel() {
         UiBluetoothMonitor.init(mContext);
-        mHfpStateLiveData = UiBluetoothMonitor.get().getHfpStateLiveData();
+        mHfpDeviceListLiveData = UiBluetoothMonitor.get().getHfpDeviceListLiveData();
         mPairedListLiveData = UiBluetoothMonitor.get().getPairListLiveData();
         mBluetoothStateLiveData = UiBluetoothMonitor.get().getBluetoothStateLiveData();
-    }
-
-    private void initializeViewModel() {
         mTelecomActivityViewModel = new TelecomActivityViewModel((Application) mContext);
         // Observers needed so that the liveData's internal initialization is triggered
         mTelecomActivityViewModel.getErrorMessage().observeForever(s -> {