1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.settings.accessibility;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import static org.mockito.Mockito.doReturn;
22 import static org.mockito.Mockito.spy;
23 import static org.mockito.Mockito.verify;
24 import static org.mockito.Mockito.when;
25 import static org.robolectric.Shadows.shadowOf;
26 
27 import android.app.settings.SettingsEnums;
28 import android.bluetooth.BluetoothAdapter;
29 import android.bluetooth.BluetoothDevice;
30 import android.bluetooth.BluetoothProfile;
31 import android.content.Context;
32 import android.content.DialogInterface;
33 import android.content.Intent;
34 import android.os.Bundle;
35 
36 import androidx.appcompat.app.AlertDialog;
37 import androidx.fragment.app.FragmentActivity;
38 import androidx.fragment.app.FragmentManager;
39 import androidx.test.core.app.ApplicationProvider;
40 
41 import com.android.settings.R;
42 import com.android.settings.SettingsActivity;
43 import com.android.settings.bluetooth.BluetoothPairingDetail;
44 import com.android.settings.bluetooth.HearingAidPairingDialogFragment;
45 import com.android.settings.bluetooth.Utils;
46 import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
47 import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
48 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
49 import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
50 import com.android.settingslib.bluetooth.HearingAidInfo;
51 import com.android.settingslib.bluetooth.LocalBluetoothManager;
52 
53 import org.junit.Before;
54 import org.junit.Rule;
55 import org.junit.Test;
56 import org.junit.runner.RunWith;
57 import org.mockito.Mock;
58 import org.mockito.junit.MockitoJUnit;
59 import org.mockito.junit.MockitoRule;
60 import org.robolectric.Robolectric;
61 import org.robolectric.RobolectricTestRunner;
62 import org.robolectric.annotation.Config;
63 import org.robolectric.shadow.api.Shadow;
64 import org.robolectric.shadows.ShadowLooper;
65 
66 /** Tests for {@link HearingAidPairingDialogFragment}. */
67 @RunWith(RobolectricTestRunner.class)
68 @Config(shadows = {
69         com.android.settings.testutils.shadow.ShadowAlertDialogCompat.class,
70         com.android.settings.testutils.shadow.ShadowBluetoothAdapter.class,
71         com.android.settings.testutils.shadow.ShadowBluetoothUtils.class,
72         com.android.settings.testutils.shadow.ShadowFragment.class,
73 })
74 public class HearingAidPairingDialogFragmentTest {
75 
76     @Rule
77     public final MockitoRule mockito = MockitoJUnit.rule();
78 
79     private static final String TEST_DEVICE_ADDRESS = "00:A1:A1:A1:A1:A1";
80     private static final int TEST_LAUNCH_PAGE = SettingsEnums.SETTINGS_CONNECTED_DEVICE_CATEGORY;
81 
82     private final Context mContext = ApplicationProvider.getApplicationContext();
83     @Mock
84     private CachedBluetoothDevice mCachedBluetoothDevice;
85     @Mock
86     private CachedBluetoothDevice mCachedSubBluetoothDevice;
87     @Mock
88     private LocalBluetoothManager mLocalBluetoothManager;
89     @Mock
90     private CachedBluetoothDeviceManager mCachedDeviceManager;
91     private BluetoothAdapter mBluetoothAdapter;
92     private FragmentActivity mActivity;
93     private HearingAidPairingDialogFragment mFragment;
94     private ShadowBluetoothAdapter mShadowBluetoothAdapter;
95     private BluetoothDevice mBluetoothDevice;
96     private FragmentManager mFragmentManager;
97 
98     @Before
setUp()99     public void setUp() {
100         setupEnvironment();
101         setupDialog(TEST_LAUNCH_PAGE);
102     }
103 
104     @Test
newInstance_deviceSideRight_argumentSideRight()105     public void newInstance_deviceSideRight_argumentSideRight() {
106         when(mCachedBluetoothDevice.getDeviceSide()).thenReturn(
107                 HearingAidInfo.DeviceSide.SIDE_RIGHT);
108         final AlertDialog dialog = (AlertDialog) mFragment.onCreateDialog(Bundle.EMPTY);
109         dialog.show();
110 
111         final String pairLeftString = mContext.getText(
112                 R.string.bluetooth_pair_other_ear_dialog_left_ear_positive_button).toString();
113         assertThat(dialog.getButton(
114                 DialogInterface.BUTTON_POSITIVE).getText().toString()).isEqualTo(pairLeftString);
115     }
116 
117     @Test
dialogPositiveButtonClick_intentToBluetoothPairingPage()118     public void dialogPositiveButtonClick_intentToBluetoothPairingPage() {
119         setupDialog(SettingsEnums.SETTINGS_CONNECTED_DEVICE_CATEGORY);
120         final AlertDialog dialog = (AlertDialog) mFragment.onCreateDialog(Bundle.EMPTY);
121         dialog.show();
122 
123         dialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick();
124         ShadowLooper.idleMainLooper();
125 
126         final Intent intent = shadowOf(mActivity).getNextStartedActivity();
127         assertThat(intent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT))
128                 .isEqualTo(BluetoothPairingDetail.class.getName());
129     }
130 
131     @Test
dialogPositiveButtonClick_intentToA11yPairingPage()132     public void dialogPositiveButtonClick_intentToA11yPairingPage() {
133         setupDialog(SettingsEnums.ACCESSIBILITY);
134         final AlertDialog dialog = (AlertDialog) mFragment.onCreateDialog(Bundle.EMPTY);
135         dialog.show();
136 
137         dialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick();
138         ShadowLooper.idleMainLooper();
139 
140         final Intent intent = shadowOf(mActivity).getNextStartedActivity();
141         assertThat(intent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT))
142                 .isEqualTo(HearingDevicePairingFragment.class.getName());
143     }
144 
145     @Test
dialogNegativeButtonClick_dismissDialog()146     public void dialogNegativeButtonClick_dismissDialog() {
147         final AlertDialog dialog = (AlertDialog) mFragment.onCreateDialog(Bundle.EMPTY);
148         dialog.show();
149 
150         dialog.getButton(DialogInterface.BUTTON_NEGATIVE).performClick();
151         ShadowLooper.idleMainLooper();
152 
153         assertThat(dialog.isShowing()).isFalse();
154     }
155 
156     @Test
getMetricsCategory_returnsCorrectCategory()157     public void getMetricsCategory_returnsCorrectCategory() {
158         assertThat(mFragment.getMetricsCategory()).isEqualTo(
159                 SettingsEnums.DIALOG_ACCESSIBILITY_HEARING_AID_PAIR_ANOTHER);
160     }
161 
162     @Test
onDeviceAttributesChanged_subAshaHearingAidDeviceConnected_dialogDismiss()163     public void onDeviceAttributesChanged_subAshaHearingAidDeviceConnected_dialogDismiss() {
164         when(mCachedSubBluetoothDevice.isConnectedAshaHearingAidDevice()).thenReturn(true);
165         when(mCachedBluetoothDevice.getSubDevice()).thenReturn(mCachedSubBluetoothDevice);
166 
167         mFragment.onDeviceAttributesChanged();
168 
169         verify(mFragment).dismiss();
170     }
171 
setupDialog(int launchPage)172     private void setupDialog(int launchPage) {
173         mFragment = spy(
174                 HearingAidPairingDialogFragment.newInstance(TEST_DEVICE_ADDRESS, launchPage));
175         mActivity = Robolectric.setupActivity(FragmentActivity.class);
176         mFragmentManager = mActivity.getSupportFragmentManager();
177         when(mFragment.getActivity()).thenReturn(mActivity);
178         doReturn(mFragmentManager).when(mFragment).getParentFragmentManager();
179         mFragment.onAttach(mContext);
180     }
181 
setupEnvironment()182     private void setupEnvironment() {
183         ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBluetoothManager;
184         mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
185         mLocalBluetoothManager = Utils.getLocalBtManager(mContext);
186         mShadowBluetoothAdapter = Shadow.extract(mBluetoothAdapter);
187         mBluetoothDevice = mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS);
188         mShadowBluetoothAdapter.addSupportedProfiles(BluetoothProfile.HEARING_AID);
189         when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(mCachedDeviceManager);
190         when(mCachedDeviceManager.findDevice(mBluetoothDevice)).thenReturn(mCachedBluetoothDevice);
191         when(mCachedBluetoothDevice.getAddress()).thenReturn(TEST_DEVICE_ADDRESS);
192     }
193 }
194