• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2018 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 package com.android.settings.connecteddevice;
17 
18 import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE;
19 import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
20 
21 import static com.google.common.truth.Truth.assertThat;
22 
23 import static org.mockito.ArgumentMatchers.any;
24 import static org.mockito.ArgumentMatchers.anyString;
25 import static org.mockito.Mockito.doReturn;
26 import static org.mockito.Mockito.spy;
27 import static org.mockito.Mockito.verify;
28 import static org.mockito.Mockito.when;
29 
30 import android.bluetooth.BluetoothDevice;
31 import android.bluetooth.BluetoothProfile;
32 import android.content.Context;
33 import android.content.pm.PackageManager;
34 import android.media.AudioManager;
35 
36 import androidx.appcompat.app.AlertDialog;
37 import androidx.fragment.app.FragmentActivity;
38 import androidx.preference.Preference;
39 import androidx.preference.PreferenceGroup;
40 import androidx.preference.PreferenceManager;
41 import androidx.preference.PreferenceScreen;
42 
43 import com.android.settings.R;
44 import com.android.settings.bluetooth.AvailableMediaBluetoothDeviceUpdater;
45 import com.android.settings.bluetooth.Utils;
46 import com.android.settings.dashboard.DashboardFragment;
47 import com.android.settings.testutils.shadow.ShadowAlertDialogCompat;
48 import com.android.settings.testutils.shadow.ShadowAudioManager;
49 import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
50 import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
51 import com.android.settings.utils.ActivityControllerWrapper;
52 import com.android.settingslib.bluetooth.BluetoothCallback;
53 import com.android.settingslib.bluetooth.BluetoothEventManager;
54 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
55 import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
56 import com.android.settingslib.bluetooth.HearingAidInfo;
57 import com.android.settingslib.bluetooth.LocalBluetoothManager;
58 
59 import org.junit.Before;
60 import org.junit.Test;
61 import org.junit.runner.RunWith;
62 import org.mockito.Answers;
63 import org.mockito.Mock;
64 import org.mockito.MockitoAnnotations;
65 import org.robolectric.Robolectric;
66 import org.robolectric.RobolectricTestRunner;
67 import org.robolectric.RuntimeEnvironment;
68 import org.robolectric.annotation.Config;
69 
70 /** Tests for {@link AvailableMediaDeviceGroupController}. */
71 @RunWith(RobolectricTestRunner.class)
72 @Config(shadows = {ShadowAudioManager.class, ShadowBluetoothAdapter.class,
73         ShadowBluetoothUtils.class})
74 public class AvailableMediaDeviceGroupControllerTest {
75 
76     private static final String TEST_DEVICE_ADDRESS = "00:A1:A1:A1:A1:A1";
77     private static final String PREFERENCE_KEY_1 = "pref_key_1";
78 
79     @Mock
80     private DashboardFragment mDashboardFragment;
81     @Mock
82     private AvailableMediaBluetoothDeviceUpdater mAvailableMediaBluetoothDeviceUpdater;
83     @Mock
84     private PreferenceScreen mPreferenceScreen;
85     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
86     private PreferenceManager mPreferenceManager;
87     @Mock
88     private PackageManager mPackageManager;
89     @Mock
90     private BluetoothEventManager mEventManager;
91     @Mock
92     private LocalBluetoothManager mLocalBluetoothManager;
93     @Mock
94     private CachedBluetoothDeviceManager mCachedDeviceManager;
95     @Mock
96     private CachedBluetoothDevice mCachedBluetoothDevice;
97 
98     private PreferenceGroup mPreferenceGroup;
99     private Context mContext;
100     private Preference mPreference;
101     private AvailableMediaDeviceGroupController mAvailableMediaDeviceGroupController;
102     private AudioManager mAudioManager;
103 
104     @Before
setUp()105     public void setUp() {
106         MockitoAnnotations.initMocks(this);
107 
108         mContext = spy(RuntimeEnvironment.application);
109         mPreference = new Preference(mContext);
110         mPreference.setKey(PREFERENCE_KEY_1);
111         mPreferenceGroup = spy(new PreferenceScreen(mContext, null));
112 
113         final FragmentActivity mActivity = (FragmentActivity) ActivityControllerWrapper.setup(
114                 Robolectric.buildActivity(FragmentActivity.class)).get();
115 
116         when(mPreferenceGroup.getPreferenceManager()).thenReturn(mPreferenceManager);
117         doReturn(mContext).when(mDashboardFragment).getContext();
118         doReturn(mPackageManager).when(mContext).getPackageManager();
119         doReturn(true).when(mPackageManager).hasSystemFeature(PackageManager.FEATURE_BLUETOOTH);
120         when(mDashboardFragment.getParentFragmentManager()).thenReturn(
121                 mActivity.getSupportFragmentManager());
122 
123         ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBluetoothManager;
124         mLocalBluetoothManager = Utils.getLocalBtManager(mContext);
125         mAudioManager = mContext.getSystemService(AudioManager.class);
126         doReturn(mEventManager).when(mLocalBluetoothManager).getEventManager();
127         when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(mCachedDeviceManager);
128         when(mCachedDeviceManager.findDevice(any(BluetoothDevice.class))).thenReturn(
129                 mCachedBluetoothDevice);
130         when(mCachedBluetoothDevice.getAddress()).thenReturn(TEST_DEVICE_ADDRESS);
131 
132         mAvailableMediaDeviceGroupController = spy(
133                 new AvailableMediaDeviceGroupController(mContext));
134         mAvailableMediaDeviceGroupController.
135                 setBluetoothDeviceUpdater(mAvailableMediaBluetoothDeviceUpdater);
136         mAvailableMediaDeviceGroupController.mPreferenceGroup = mPreferenceGroup;
137     }
138 
139     @Test
onDeviceAdded_firstAdd_becomeVisibleAndPreferenceAdded()140     public void onDeviceAdded_firstAdd_becomeVisibleAndPreferenceAdded() {
141         mAvailableMediaDeviceGroupController.onDeviceAdded(mPreference);
142 
143         assertThat(mPreferenceGroup.isVisible()).isTrue();
144         assertThat((Preference) mPreferenceGroup.findPreference(PREFERENCE_KEY_1))
145                 .isEqualTo(mPreference);
146     }
147 
148     @Test
onDeviceRemoved_lastRemove_becomeInvisibleAndPreferenceRemoved()149     public void onDeviceRemoved_lastRemove_becomeInvisibleAndPreferenceRemoved() {
150         mPreferenceGroup.addPreference(mPreference);
151 
152         mAvailableMediaDeviceGroupController.onDeviceRemoved(mPreference);
153 
154         assertThat(mPreferenceGroup.isVisible()).isFalse();
155         assertThat(mPreferenceGroup.getPreferenceCount()).isEqualTo(0);
156     }
157 
158     @Test
onDeviceRemoved_notLastRemove_stillVisible()159     public void onDeviceRemoved_notLastRemove_stillVisible() {
160         mPreferenceGroup.setVisible(true);
161         mPreferenceGroup.addPreference(mPreference);
162         mPreferenceGroup.addPreference(new Preference(mContext));
163 
164         mAvailableMediaDeviceGroupController.onDeviceRemoved(mPreference);
165 
166         assertThat(mPreferenceGroup.isVisible()).isTrue();
167     }
168 
169     @Test
displayPreference_becomeInvisible()170     public void displayPreference_becomeInvisible() {
171         doReturn(mPreferenceGroup).when(mPreferenceScreen).findPreference(anyString());
172 
173         mAvailableMediaDeviceGroupController.displayPreference(mPreferenceScreen);
174 
175         assertThat(mPreferenceGroup.isVisible()).isFalse();
176     }
177 
178     @Test
testRegister()179     public void testRegister() {
180         // register the callback in onStart()
181         mAvailableMediaDeviceGroupController.onStart();
182 
183         verify(mAvailableMediaBluetoothDeviceUpdater).registerCallback();
184         verify(mLocalBluetoothManager.getEventManager()).registerCallback(
185                 any(BluetoothCallback.class));
186         verify(mAvailableMediaBluetoothDeviceUpdater).refreshPreference();
187     }
188 
189     @Test
testUnregister()190     public void testUnregister() {
191         // unregister the callback in onStop()
192         mAvailableMediaDeviceGroupController.onStop();
193         verify(mAvailableMediaBluetoothDeviceUpdater).unregisterCallback();
194         verify(mLocalBluetoothManager.getEventManager()).unregisterCallback(
195                 any(BluetoothCallback.class));
196     }
197 
198     @Test
testGetAvailabilityStatus_noBluetoothFeature_returnUnSupported()199     public void testGetAvailabilityStatus_noBluetoothFeature_returnUnSupported() {
200         doReturn(false).when(mPackageManager).hasSystemFeature(PackageManager.FEATURE_BLUETOOTH);
201 
202         assertThat(mAvailableMediaDeviceGroupController.getAvailabilityStatus()).isEqualTo(
203                 UNSUPPORTED_ON_DEVICE);
204     }
205 
206     @Test
testGetAvailabilityStatus_BluetoothFeature_returnSupported()207     public void testGetAvailabilityStatus_BluetoothFeature_returnSupported() {
208         doReturn(true).when(mPackageManager).hasSystemFeature(PackageManager.FEATURE_BLUETOOTH);
209 
210         assertThat(mAvailableMediaDeviceGroupController.getAvailabilityStatus()).isEqualTo(
211                 AVAILABLE_UNSEARCHABLE);
212     }
213 
214     @Test
setTitle_inCallState_showCallStateTitle()215     public void setTitle_inCallState_showCallStateTitle() {
216         mAudioManager.setMode(AudioManager.MODE_IN_CALL);
217         mAvailableMediaDeviceGroupController.onAudioModeChanged();
218 
219         assertThat(mPreferenceGroup.getTitle()).isEqualTo(
220                 mContext.getText(R.string.connected_device_call_device_title));
221     }
222 
223     @Test
setTitle_notInCallState_showMediaStateTitle()224     public void setTitle_notInCallState_showMediaStateTitle() {
225         mAudioManager.setMode(AudioManager.MODE_NORMAL);
226         mAvailableMediaDeviceGroupController.onAudioModeChanged();
227 
228         assertThat(mPreferenceGroup.getTitle()).isEqualTo(
229                 mContext.getText(R.string.connected_device_media_device_title));
230     }
231 
232     @Test
onStart_localBluetoothManagerNull_shouldNotCrash()233     public void onStart_localBluetoothManagerNull_shouldNotCrash() {
234         mAvailableMediaDeviceGroupController.mLocalBluetoothManager = null;
235 
236         // Shouldn't crash
237         mAvailableMediaDeviceGroupController.onStart();
238     }
239 
240     @Test
onStop_localBluetoothManagerNull_shouldNotCrash()241     public void onStop_localBluetoothManagerNull_shouldNotCrash() {
242         mAvailableMediaDeviceGroupController.mLocalBluetoothManager = null;
243 
244         // Shouldn't crash
245         mAvailableMediaDeviceGroupController.onStop();
246     }
247 
248     @Test
249     @Config(shadows = ShadowAlertDialogCompat.class)
onActiveDeviceChanged_hearingAidProfile_launchHearingAidPairingDialog()250     public void onActiveDeviceChanged_hearingAidProfile_launchHearingAidPairingDialog() {
251         when(mCachedBluetoothDevice.isConnectedAshaHearingAidDevice()).thenReturn(true);
252         when(mCachedBluetoothDevice.getDeviceMode()).thenReturn(
253                 HearingAidInfo.DeviceMode.MODE_BINAURAL);
254         when(mCachedBluetoothDevice.getDeviceSide()).thenReturn(
255                 HearingAidInfo.DeviceSide.SIDE_LEFT);
256         mAvailableMediaDeviceGroupController.init(mDashboardFragment);
257 
258         mAvailableMediaDeviceGroupController.onActiveDeviceChanged(mCachedBluetoothDevice,
259                 BluetoothProfile.HEARING_AID);
260 
261         final AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
262         assertThat(dialog.isShowing()).isTrue();
263     }
264 }
265