Show bluetooth error page from settings page

This change also fixes the issue that TelecomActivity being created
twice by changing error page to overlay fragment which causes bug
DIAL intent not handled properly.

TelecomActivity and DialerSettingsActivity will monitor connected hfp
device and if there are no hfp devices connected, show the
OverlayFragment that hosts the NoHfpFragment.

Fixes: 153467502
Fixes: 161998213
Test: manually
Change-Id: Iec32dfeef45b54a80f9c5686d010c71f81ab0064
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index eed8a1e..98f1963 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -98,11 +98,6 @@
                   android:label="@string/setting_title">
         </activity>
 
-        <activity android:name=".ui.NoHfpActivity"
-                  android:launchMode="singleTask"
-                  android:theme="@style/Theme.Dialer.ErrorActivity">
-        </activity>
-
         <service android:name="com.android.car.dialer.telecom.InCallServiceImpl"
                  android:permission="android.permission.BIND_INCALL_SERVICE"
                  android:exported="true">
diff --git a/res/values/themes.xml b/res/values/themes.xml
index 3638b14..327ae4d 100644
--- a/res/values/themes.xml
+++ b/res/values/themes.xml
@@ -36,8 +36,4 @@
 
     <style name="Theme.Dialer.Setting"/>
 
-    <style name="Theme.Dialer.ErrorActivity">
-        <item name="carUiToolbar">false</item>
-    </style>
-
 </resources>
diff --git a/src/com/android/car/dialer/bluetooth/UiBluetoothMonitor.java b/src/com/android/car/dialer/bluetooth/UiBluetoothMonitor.java
index 1f17142..af8c739 100644
--- a/src/com/android/car/dialer/bluetooth/UiBluetoothMonitor.java
+++ b/src/com/android/car/dialer/bluetooth/UiBluetoothMonitor.java
@@ -131,6 +131,12 @@
                         : null);
     }
 
+    /** Returns a {@link LiveData} which monitors if there are any connected HFP devices. */
+    public LiveData<Boolean> hasHfpDeviceConnected() {
+        return Transformations.map(mHfpDeviceListLiveData,
+                devices -> devices != null && !devices.isEmpty());
+    }
+
     private void removeObserver(LiveData liveData, Observer observer) {
         if (liveData != null && liveData.hasObservers()) {
             liveData.removeObserver(observer);
diff --git a/src/com/android/car/dialer/ui/NoHfpActivity.java b/src/com/android/car/dialer/ui/NoHfpActivity.java
deleted file mode 100644
index 9c9e588..0000000
--- a/src/com/android/car/dialer/ui/NoHfpActivity.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2020 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.ui;
-
-import android.content.Intent;
-import android.os.Bundle;
-
-import androidx.fragment.app.Fragment;
-import androidx.fragment.app.FragmentActivity;
-import androidx.lifecycle.ViewModelProvider;
-
-import com.android.car.dialer.livedata.BluetoothErrorStringLiveData;
-import com.android.car.dialer.ui.warning.NoHfpFragment;
-
-/**
- * An activity to host {@link NoHfpFragment} and
- * {@link com.android.car.dialer.ui.dialpad.DialpadFragment#newEmergencyDialpad()}.
- */
-public class NoHfpActivity extends FragmentActivity {
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        BluetoothErrorStringLiveData errorStringLiveData = (new ViewModelProvider(this))
-                .get(NoHfpActivityViewModel.class)
-                .getBluetoothErrorStringLiveData();
-
-        errorStringLiveData.observe(this, (String error) -> {
-            if (BluetoothErrorStringLiveData.NO_BT_ERROR.equals(error)) {
-                startActivity(new Intent(this, TelecomActivity.class));
-                finish();
-            } else {
-                Fragment currentFragment = getSupportFragmentManager()
-                        .findFragmentById(android.R.id.content);
-                if (currentFragment instanceof NoHfpFragment) {
-                    ((NoHfpFragment) currentFragment).setErrorMessage(error);
-                }
-            }
-        });
-
-        if (savedInstanceState == null) {
-            getSupportFragmentManager().beginTransaction()
-                    .replace(android.R.id.content,
-                            NoHfpFragment.newInstance(errorStringLiveData.getValue()))
-                    .commit();
-        }
-    }
-}
diff --git a/src/com/android/car/dialer/ui/NoHfpActivityViewModel.java b/src/com/android/car/dialer/ui/NoHfpActivityViewModel.java
index 9474e8d..40e55eb 100644
--- a/src/com/android/car/dialer/ui/NoHfpActivityViewModel.java
+++ b/src/com/android/car/dialer/ui/NoHfpActivityViewModel.java
@@ -20,21 +20,29 @@
 
 import androidx.annotation.NonNull;
 import androidx.lifecycle.AndroidViewModel;
+import androidx.lifecycle.LiveData;
 
+import com.android.car.dialer.bluetooth.UiBluetoothMonitor;
 import com.android.car.dialer.livedata.BluetoothErrorStringLiveData;
 
-/** View model for {@link NoHfpActivity} */
+/** View model for {@link NoHfpFragment} */
 public class NoHfpActivityViewModel extends AndroidViewModel {
 
-    private final BluetoothErrorStringLiveData mBluetoothErrorStringLiveData;
+    private final LiveData<Boolean> mHasHfpDeviceConnectedLiveData;
+    private final LiveData<String> mBluetoothErrorStringLiveData;
 
     public NoHfpActivityViewModel(@NonNull Application application) {
         super(application);
-
+        mHasHfpDeviceConnectedLiveData = UiBluetoothMonitor.get().hasHfpDeviceConnected();
         mBluetoothErrorStringLiveData = BluetoothErrorStringLiveData.get(application);
     }
 
-    public BluetoothErrorStringLiveData getBluetoothErrorStringLiveData() {
+    public LiveData<String> getBluetoothErrorStringLiveData() {
         return mBluetoothErrorStringLiveData;
     }
+
+    /** Returns a {@link LiveData} which monitors if there are any connected HFP devices. */
+    public LiveData<Boolean> hasHfpDeviceConnected() {
+        return mHasHfpDeviceConnectedLiveData;
+    }
 }
diff --git a/src/com/android/car/dialer/ui/TelecomActivity.java b/src/com/android/car/dialer/ui/TelecomActivity.java
index e327458..8e84718 100644
--- a/src/com/android/car/dialer/ui/TelecomActivity.java
+++ b/src/com/android/car/dialer/ui/TelecomActivity.java
@@ -35,7 +35,6 @@
 import com.android.car.apps.common.util.Themes;
 import com.android.car.dialer.Constants;
 import com.android.car.dialer.R;
-import com.android.car.dialer.livedata.BluetoothErrorStringLiveData;
 import com.android.car.dialer.log.L;
 import com.android.car.dialer.notification.NotificationService;
 import com.android.car.dialer.telecom.UiCallManager;
@@ -45,6 +44,7 @@
 import com.android.car.dialer.ui.dialpad.DialpadFragment;
 import com.android.car.dialer.ui.search.ContactResultsFragment;
 import com.android.car.dialer.ui.settings.DialerSettingsActivity;
+import com.android.car.dialer.ui.warning.OverlayFragment;
 import com.android.car.ui.baselayout.Insets;
 import com.android.car.ui.baselayout.InsetsChangedListener;
 import com.android.car.ui.core.CarUi;
@@ -63,7 +63,6 @@
 public class TelecomActivity extends FragmentActivity implements
         DialerBaseFragment.DialerFragmentParent, InsetsChangedListener {
     private static final String TAG = "CD.TelecomActivity";
-    private LiveData<String> mBluetoothErrorMsgLiveData;
     private LiveData<List<Call>> mOngoingCallListLiveData;
     private LiveData<Boolean> mRefreshUiLiveData;
     // View objects for this activity.
@@ -88,11 +87,10 @@
         mRefreshUiLiveData = viewModel.getRefreshTabsLiveData();
         mRefreshUiLiveData.observe(this, v -> refreshUi());
 
-        mBluetoothErrorMsgLiveData = viewModel.getErrorMessage();
-        mBluetoothErrorMsgLiveData.observe(this, (String error) -> {
-            if (!BluetoothErrorStringLiveData.NO_BT_ERROR.equals(error)) {
-                startActivity(new Intent(this, NoHfpActivity.class));
-                finish();
+        LiveData<Boolean> hasHfpDeviceConnectedLiveData = viewModel.hasHfpDeviceConnected();
+        hasHfpDeviceConnectedLiveData.observe(this, hasHfpDeviceConnected -> {
+            if (!Boolean.TRUE.equals(hasHfpDeviceConnected)) {
+                new OverlayFragment().show(getSupportFragmentManager(), null);
             }
         });
 
diff --git a/src/com/android/car/dialer/ui/TelecomActivityViewModel.java b/src/com/android/car/dialer/ui/TelecomActivityViewModel.java
index 5a09ca1..066c0e5 100644
--- a/src/com/android/car/dialer/ui/TelecomActivityViewModel.java
+++ b/src/com/android/car/dialer/ui/TelecomActivityViewModel.java
@@ -21,7 +21,6 @@
 import android.bluetooth.BluetoothDevice;
 import android.content.Context;
 
-import androidx.annotation.IntDef;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
@@ -31,12 +30,9 @@
 import androidx.lifecycle.MutableLiveData;
 
 import com.android.car.dialer.bluetooth.UiBluetoothMonitor;
-import com.android.car.dialer.livedata.BluetoothErrorStringLiveData;
 import com.android.car.dialer.log.L;
 import com.android.car.dialer.ui.common.SingleLiveEvent;
 
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
 import java.util.List;
 
 /**
@@ -44,28 +40,14 @@
  */
 public class TelecomActivityViewModel extends AndroidViewModel {
     private static final String TAG = "CD.TelecomActivityViewModel";
-    /**
-     * A constant which indicates that there's no Bluetooth error.
-     */
 
     private final Context mApplicationContext;
-    private final LiveData<String> mErrorStringLiveData;
     private RefreshUiEvent mRefreshTabsLiveData;
 
     private final ToolbarTitleLiveData mToolbarTitleLiveData;
     private final MutableLiveData<Integer> mToolbarTitleMode;
 
-    /**
-     * App state indicates if bluetooth is connected or it should just show the content fragments.
-     */
-    @IntDef({DialerAppState.DEFAULT, DialerAppState.BLUETOOTH_ERROR,
-            DialerAppState.EMERGENCY_DIALPAD})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface DialerAppState {
-        int DEFAULT = 0;
-        int BLUETOOTH_ERROR = 1;
-        int EMERGENCY_DIALPAD = 2;
-    }
+    private final LiveData<Boolean> mHasHfpDeviceConnectedLiveData;
 
     public TelecomActivityViewModel(Application application) {
         super(application);
@@ -73,12 +55,13 @@
 
         mToolbarTitleMode = new MediatorLiveData<>();
         mToolbarTitleLiveData = new ToolbarTitleLiveData(mApplicationContext, mToolbarTitleMode);
-        mErrorStringLiveData = BluetoothErrorStringLiveData.get(mApplicationContext);
 
         if (BluetoothAdapter.getDefaultAdapter() != null) {
             mRefreshTabsLiveData = new RefreshUiEvent(
                     UiBluetoothMonitor.get().getHfpDeviceListLiveData());
         }
+
+        mHasHfpDeviceConnectedLiveData = UiBluetoothMonitor.get().hasHfpDeviceConnected();
     }
 
     /**
@@ -98,20 +81,17 @@
     }
 
     /**
-     * Returns a LiveData which provides the warning string based on Bluetooth states. Returns
-     * {@link BluetoothErrorStringLiveData#NO_BT_ERROR} if there's no error.
-     */
-    public LiveData<String> getErrorMessage() {
-        return mErrorStringLiveData;
-    }
-
-    /**
      * Returns the live data which monitors whether to refresh Dialer.
      */
     public LiveData<Boolean> getRefreshTabsLiveData() {
         return mRefreshTabsLiveData;
     }
 
+    /** Returns a {@link LiveData} which monitors if there are any connected HFP devices. */
+    public LiveData<Boolean> hasHfpDeviceConnected() {
+        return mHasHfpDeviceConnectedLiveData;
+    }
+
     /**
      * This is an event live data to determine if the Ui needs to be refreshed.
      */
diff --git a/src/com/android/car/dialer/ui/settings/DialerSettingsActivity.java b/src/com/android/car/dialer/ui/settings/DialerSettingsActivity.java
index eb9f24f..9a017a7 100644
--- a/src/com/android/car/dialer/ui/settings/DialerSettingsActivity.java
+++ b/src/com/android/car/dialer/ui/settings/DialerSettingsActivity.java
@@ -19,6 +19,8 @@
 import android.os.Bundle;
 
 import androidx.fragment.app.FragmentActivity;
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.ViewModelProvider;
 
 import com.android.car.dialer.log.L;
 
@@ -33,6 +35,16 @@
         super.onCreate(savedInstanceState);
         L.d(TAG, "onCreate");
 
+        LiveData<Boolean> hasHfpDeviceConnectedLiveData = new ViewModelProvider(this)
+                .get(DialerSettingsViewModel.class)
+                .hasHfpDeviceConnected();
+        hasHfpDeviceConnectedLiveData.observe(this, hasHfpDeviceConnected -> {
+            if (!Boolean.TRUE.equals(hasHfpDeviceConnected)) {
+                // Simply finishes settings activity and returns to main activity to show error.
+                finish();
+            }
+        });
+
         if (savedInstanceState == null) {
             getSupportFragmentManager().beginTransaction()
                     .replace(android.R.id.content, new DialerSettingsFragment())
diff --git a/src/com/android/car/dialer/ui/settings/DialerSettingsViewModel.java b/src/com/android/car/dialer/ui/settings/DialerSettingsViewModel.java
index 13f2f8b..ee6488d 100644
--- a/src/com/android/car/dialer/ui/settings/DialerSettingsViewModel.java
+++ b/src/com/android/car/dialer/ui/settings/DialerSettingsViewModel.java
@@ -32,10 +32,12 @@
 public class DialerSettingsViewModel extends AndroidViewModel {
     private static final String EMPTY_STRING = "";
     private final LiveData<BluetoothDevice> mFirstHfpDeviceLiveData;
+    private final LiveData<Boolean> mHasHfpDeviceConnectedLiveData;
 
     public DialerSettingsViewModel(@NonNull Application application) {
         super(application);
         mFirstHfpDeviceLiveData = UiBluetoothMonitor.get().getFirstHfpConnectedDevice();
+        mHasHfpDeviceConnectedLiveData = UiBluetoothMonitor.get().hasHfpDeviceConnected();
     }
 
     /**
@@ -46,4 +48,10 @@
         return Transformations.map(mFirstHfpDeviceLiveData, (device) ->
                 device != null ? device.getName() : EMPTY_STRING);
     }
+
+    /** Returns a {@link LiveData} which monitors if there are any connected HFP devices. */
+    public LiveData<Boolean> hasHfpDeviceConnected() {
+        return mHasHfpDeviceConnectedLiveData;
+    }
+
 }
diff --git a/src/com/android/car/dialer/ui/warning/NoHfpFragment.java b/src/com/android/car/dialer/ui/warning/NoHfpFragment.java
index 2e4ef09..a704656 100644
--- a/src/com/android/car/dialer/ui/warning/NoHfpFragment.java
+++ b/src/com/android/car/dialer/ui/warning/NoHfpFragment.java
@@ -21,19 +21,22 @@
 import android.car.drivingstate.CarUxRestrictions;
 import android.content.Intent;
 import android.os.Bundle;
-import android.text.TextUtils;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.TextView;
 
 import androidx.fragment.app.Fragment;
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.ViewModelProvider;
 
 import com.android.car.apps.common.UxrButton;
 import com.android.car.apps.common.util.CarPackageManagerUtils;
 import com.android.car.apps.common.util.ViewUtils;
 import com.android.car.dialer.R;
+import com.android.car.dialer.livedata.BluetoothErrorStringLiveData;
 import com.android.car.dialer.telecom.UiCallManager;
+import com.android.car.dialer.ui.NoHfpActivityViewModel;
 import com.android.car.dialer.ui.dialpad.DialpadFragment;
 
 /**
@@ -41,37 +44,18 @@
  * phone calls.
  */
 public class NoHfpFragment extends Fragment {
-    private static final String ERROR_MESSAGE_KEY = "ERROR_MESSAGE_KEY";
     private static final String Bluetooth_Setting_ACTION = "android.settings.BLUETOOTH_SETTINGS";
     private static final String Bluetooth_Setting_CATEGORY = "android.intent.category.DEFAULT";
 
     private TextView mErrorMessageView;
-    private String mErrorMessage;
 
     private Car mCar;
     private CarPackageManager mCarPackageManager;
 
-    /**
-     * Returns an instance of the {@link NoHfpFragment} with the given error message as the one to
-     * display.
-     */
-    public static NoHfpFragment newInstance(String errorMessage) {
-        NoHfpFragment fragment = new NoHfpFragment();
-
-        Bundle args = new Bundle();
-        args.putString(ERROR_MESSAGE_KEY, errorMessage);
-        fragment.setArguments(args);
-
-        return fragment;
-    }
-
+    @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        Bundle args = getArguments();
-        if (args != null) {
-            mErrorMessage = args.getString(ERROR_MESSAGE_KEY);
-        }
         mCar = Car.createCar(getActivity());
         mCarPackageManager = (CarPackageManager) mCar.getCarManager(Car.PACKAGE_SERVICE);
     }
@@ -82,29 +66,22 @@
         super.onDestroy();
     }
 
-    /**
-     * Sets the given error message to be displayed.
-     */
-    public void setErrorMessage(String errorMessage) {
-        mErrorMessage = errorMessage;
-
-        // If this method is called before the error message view is available, then no need to
-        // set the message. Instead, it will be set in onCreateView().
-        if (mErrorMessageView != null && !TextUtils.isEmpty(mErrorMessage)) {
-            mErrorMessageView.setText(mErrorMessage);
-        }
-    }
-
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
             Bundle savedInstanceState) {
         View view = inflater.inflate(R.layout.no_hfp, container, false);
         mErrorMessageView = view.findViewById(R.id.error_string);
 
-        // If no error message is set, the default string from the layout will be used.
-        if (!TextUtils.isEmpty(mErrorMessage)) {
-            mErrorMessageView.setText(mErrorMessage);
-        }
+        LiveData<String> errorStringLiveData = new ViewModelProvider(getActivity())
+                .get(NoHfpActivityViewModel.class)
+                .getBluetoothErrorStringLiveData();
+
+        errorStringLiveData.observe(this, error -> {
+            // Do not set the NO_BT_ERROR message to avoid UI jankiness
+            if (!BluetoothErrorStringLiveData.NO_BT_ERROR.equals(error)) {
+                mErrorMessageView.setText(error);
+            }
+        });
 
         View emergencyButton = view.findViewById(R.id.emergency_call_button);
         ViewUtils.setVisible(emergencyButton, UiCallManager.get().isEmergencyCallSupported());
diff --git a/src/com/android/car/dialer/ui/warning/OverlayFragment.java b/src/com/android/car/dialer/ui/warning/OverlayFragment.java
new file mode 100644
index 0000000..9cd260f
--- /dev/null
+++ b/src/com/android/car/dialer/ui/warning/OverlayFragment.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2020 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.ui.warning;
+
+import android.app.Dialog;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.Nullable;
+import androidx.fragment.app.DialogFragment;
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.ViewModelProvider;
+
+import com.android.car.dialer.R;
+
+/**
+ * A fullscreen {@link DialogFragment} that hosts the {@link NoHfpFragment} as an overlay of dialer
+ * activities.
+ */
+public class OverlayFragment extends DialogFragment {
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setStyle(DialogFragment.STYLE_NO_FRAME, R.style.Theme_Dialer);
+
+        LiveData<Boolean> hasHfpDeviceConnectedLiveData = new ViewModelProvider(getActivity())
+                .get(NoHfpViewModel.class)
+                .hasHfpDeviceConnected();
+        hasHfpDeviceConnectedLiveData.observe(this, hasHfpDeviceConnected -> {
+            if (Boolean.TRUE.equals(hasHfpDeviceConnected)) {
+                dismiss();
+            }
+        });
+    }
+
+    @Override
+    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
+        return new Dialog(this.requireContext(), this.getTheme()) {
+            @Override
+            public void onBackPressed() {
+                if (getChildFragmentManager().popBackStackImmediate()) {
+                    return;
+                }
+                // Exit dialer when press back button
+                getActivity().finishAffinity();
+            }
+        };
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+            Bundle savedInstanceState) {
+        getChildFragmentManager()
+                .beginTransaction()
+                .replace(android.R.id.content, new NoHfpFragment())
+                .commit();
+        return null;
+    }
+}
diff --git a/tests/robotests/src/com/android/car/dialer/ui/TelecomActivityViewModelTest.java b/tests/robotests/src/com/android/car/dialer/ui/NoHfpActivityViewModelTest.java
similarity index 87%
rename from tests/robotests/src/com/android/car/dialer/ui/TelecomActivityViewModelTest.java
rename to tests/robotests/src/com/android/car/dialer/ui/NoHfpActivityViewModelTest.java
index 824d14c..780156e 100644
--- a/tests/robotests/src/com/android/car/dialer/ui/TelecomActivityViewModelTest.java
+++ b/tests/robotests/src/com/android/car/dialer/ui/NoHfpActivityViewModelTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -49,9 +49,9 @@
 
 @RunWith(CarDialerRobolectricTestRunner.class)
 @Config(shadows = ShadowBluetoothAdapterForDialer.class)
-public class TelecomActivityViewModelTest {
+public class NoHfpActivityViewModelTest {
 
-    private TelecomActivityViewModel mTelecomActivityViewModel;
+    private NoHfpActivityViewModel mNoHfpActivityViewModel;
     private Context mContext;
     private HfpDeviceListLiveData mHfpDeviceListLiveData;
     private BluetoothPairListLiveData mPairedListLiveData;
@@ -74,7 +74,7 @@
         ShadowBluetoothAdapterForDialer.setBluetoothAvailable(false);
         initializeViewModel();
 
-        assertThat(mTelecomActivityViewModel.getErrorMessage().getValue()).isEqualTo(
+        assertThat(mNoHfpActivityViewModel.getBluetoothErrorStringLiveData().getValue()).isEqualTo(
                 mContext.getString(R.string.bluetooth_unavailable));
     }
 
@@ -88,7 +88,7 @@
 
         assertThat(mBluetoothStateLiveData.getValue()).isEqualTo(
                 BluetoothStateLiveData.BluetoothState.DISABLED);
-        assertThat(mTelecomActivityViewModel.getErrorMessage().getValue()).isEqualTo(
+        assertThat(mNoHfpActivityViewModel.getBluetoothErrorStringLiveData().getValue()).isEqualTo(
                 mContext.getString(R.string.bluetooth_disabled));
     }
 
@@ -105,7 +105,7 @@
                 BluetoothStateLiveData.BluetoothState.ENABLED);
 
         assertThat(mPairedListLiveData.getValue().isEmpty()).isTrue();
-        assertThat(mTelecomActivityViewModel.getErrorMessage().getValue()).isEqualTo(
+        assertThat(mNoHfpActivityViewModel.getBluetoothErrorStringLiveData().getValue()).isEqualTo(
                 mContext.getString(R.string.bluetooth_unpaired));
     }
 
@@ -125,12 +125,12 @@
         assertThat(mPairedListLiveData.getValue().isEmpty()).isFalse();
 
         assertThat(mHfpDeviceListLiveData.getValue().isEmpty()).isTrue();
-        assertThat(mTelecomActivityViewModel.getErrorMessage().getValue()).isEqualTo(
+        assertThat(mNoHfpActivityViewModel.getBluetoothErrorStringLiveData().getValue()).isEqualTo(
                 mContext.getString(R.string.no_hfp));
     }
 
     @Test
-    public void testDialerAppState_bluetoothAllSet_dialerAppStateDefault() {
+    public void testDialerAppState_bluetoothAllSet_dialerAppNoError() {
         ShadowBluetoothAdapterForDialer.setBluetoothAvailable(true);
         BluetoothDevice mockBluetoothDevice = mock(BluetoothDevice.class);
         ShadowBluetoothAdapterForDialer shadowBluetoothAdapter = Shadow.extract(
@@ -144,7 +144,7 @@
 
         initializeViewModel();
 
-        assertThat(mTelecomActivityViewModel.getErrorMessage().getValue()).isEqualTo(
+        assertThat(mNoHfpActivityViewModel.getBluetoothErrorStringLiveData().getValue()).isEqualTo(
                 BluetoothErrorStringLiveData.NO_BT_ERROR);
     }
 
@@ -153,9 +153,9 @@
         mHfpDeviceListLiveData = UiBluetoothMonitor.get().getHfpDeviceListLiveData();
         mPairedListLiveData = UiBluetoothMonitor.get().getPairListLiveData();
         mBluetoothStateLiveData = UiBluetoothMonitor.get().getBluetoothStateLiveData();
-        mTelecomActivityViewModel = new TelecomActivityViewModel((Application) mContext);
+        mNoHfpActivityViewModel = new NoHfpActivityViewModel((Application) mContext);
         // Observers needed so that the liveData's internal initialization is triggered
-        mTelecomActivityViewModel.getErrorMessage().observeForever(s -> {
+        mNoHfpActivityViewModel.getBluetoothErrorStringLiveData().observeForever(o -> {
         });
     }
 }
diff --git a/tests/robotests/src/com/android/car/dialer/ui/warning/NoHfpFragmentTest.java b/tests/robotests/src/com/android/car/dialer/ui/warning/NoHfpFragmentTest.java
index 11c1456..90d744a 100644
--- a/tests/robotests/src/com/android/car/dialer/ui/warning/NoHfpFragmentTest.java
+++ b/tests/robotests/src/com/android/car/dialer/ui/warning/NoHfpFragmentTest.java
@@ -37,8 +37,6 @@
 
 @RunWith(CarDialerRobolectricTestRunner.class)
 public class NoHfpFragmentTest {
-    private static final String ERROR_MSG = "ERROR!!!";
-    private static final String UPDATED_ERROR_MSG = "ANOTHER ERROR!!!!";
 
     private NoHfpFragment mNoHfpFragment;
     private FragmentTestActivity mFragmentTestActivity;
@@ -50,7 +48,7 @@
         ((TestDialerApplication) RuntimeEnvironment.application).initUiCallManager();
         UiBluetoothMonitor.init(RuntimeEnvironment.application);
 
-        mNoHfpFragment = NoHfpFragment.newInstance(ERROR_MSG);
+        mNoHfpFragment = new NoHfpFragment();
         mFragmentTestActivity = Robolectric.buildActivity(
                 FragmentTestActivity.class).create().start().resume().get();
         mFragmentTestActivity.setFragment(mNoHfpFragment);
@@ -65,16 +63,8 @@
     public void createView_displayErrorMsg() {
         View rootView = mNoHfpFragment.getView();
         TextView errorMsgView = rootView.findViewById(R.id.error_string);
-        assertThat(errorMsgView.getText()).isEqualTo(ERROR_MSG);
-    }
-
-    @Test
-    public void setErrorMsg_updateErrorMsgView() {
-        mNoHfpFragment.setErrorMessage(UPDATED_ERROR_MSG);
-
-        View rootView = mNoHfpFragment.getView();
-        TextView errorMsgView = rootView.findViewById(R.id.error_string);
-        assertThat(errorMsgView.getText()).isEqualTo(UPDATED_ERROR_MSG);
+        assertThat(errorMsgView.getText()).isEqualTo(
+                mNoHfpFragment.getString(R.string.bluetooth_disabled));
     }
 
     @After