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; 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.Mockito.doReturn; 24 import static org.mockito.Mockito.spy; 25 import static org.mockito.Mockito.verify; 26 import static org.mockito.Mockito.when; 27 28 import android.bluetooth.BluetoothAdapter; 29 import android.bluetooth.BluetoothDevice; 30 import android.bluetooth.BluetoothManager; 31 import android.content.Context; 32 import android.content.pm.PackageManager; 33 import android.graphics.drawable.Drawable; 34 import android.platform.test.flag.junit.CheckFlagsRule; 35 import android.platform.test.flag.junit.DeviceFlagsValueProvider; 36 import android.util.Pair; 37 38 import androidx.lifecycle.LifecycleOwner; 39 import androidx.preference.PreferenceCategory; 40 import androidx.preference.PreferenceGroup; 41 import androidx.preference.PreferenceManager; 42 43 import com.android.settings.bluetooth.BluetoothDevicePreference; 44 import com.android.settings.bluetooth.BluetoothDeviceUpdater; 45 import com.android.settings.connecteddevice.dock.DockUpdater; 46 import com.android.settings.dashboard.DashboardFragment; 47 import com.android.settingslib.bluetooth.CachedBluetoothDevice; 48 import com.android.settingslib.core.lifecycle.Lifecycle; 49 50 import org.junit.Before; 51 import org.junit.Rule; 52 import org.junit.Test; 53 import org.junit.runner.RunWith; 54 import org.mockito.Mock; 55 import org.mockito.MockitoAnnotations; 56 import org.robolectric.RobolectricTestRunner; 57 import org.robolectric.RuntimeEnvironment; 58 59 import java.util.ArrayList; 60 import java.util.List; 61 62 @RunWith(RobolectricTestRunner.class) 63 public class SavedDeviceGroupControllerTest { 64 65 private static final String FAKE_ADDRESS_1 = "AA:AA:AA:AA:AA:01"; 66 private static final String FAKE_ADDRESS_2 = "AA:AA:AA:AA:AA:02"; 67 private static final String FAKE_ADDRESS_3 = "AA:AA:AA:AA:AA:03"; 68 69 @Rule 70 public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); 71 72 @Mock 73 private DashboardFragment mDashboardFragment; 74 @Mock 75 private BluetoothDeviceUpdater mBluetoothDeviceUpdater; 76 @Mock 77 private DockUpdater mSavedDockUpdater; 78 @Mock 79 private PackageManager mPackageManager; 80 @Mock private BluetoothManager mBluetoothManager; 81 @Mock private BluetoothAdapter mBluetoothAdapter; 82 @Mock private CachedBluetoothDevice mCachedDevice1; 83 @Mock private CachedBluetoothDevice mCachedDevice2; 84 @Mock private CachedBluetoothDevice mCachedDevice3; 85 @Mock private BluetoothDevice mBluetoothDevice1; 86 @Mock private BluetoothDevice mBluetoothDevice2; 87 @Mock private BluetoothDevice mBluetoothDevice3; 88 @Mock private Drawable mDrawable; 89 @Mock private PreferenceManager mPreferenceManager; 90 91 private Context mContext; 92 private SavedDeviceGroupController mSavedDeviceGroupController; 93 private LifecycleOwner mLifecycleOwner; 94 private Lifecycle mLifecycle; 95 private PreferenceGroup mPreferenceGroup; 96 97 @Before setUp()98 public void setUp() { 99 MockitoAnnotations.initMocks(this); 100 Pair<Drawable, String> pairs = new Pair<>(mDrawable, "fake_device"); 101 mContext = spy(RuntimeEnvironment.application); 102 mLifecycleOwner = () -> mLifecycle; 103 mLifecycle = new Lifecycle(mLifecycleOwner); 104 doReturn(mContext).when(mDashboardFragment).getContext(); 105 doReturn(mPackageManager).when(mContext).getPackageManager(); 106 107 when(mCachedDevice1.getDevice()).thenReturn(mBluetoothDevice1); 108 when(mCachedDevice1.getAddress()).thenReturn(FAKE_ADDRESS_1); 109 when(mCachedDevice1.getDrawableWithDescription()).thenReturn(pairs); 110 when(mCachedDevice2.getDevice()).thenReturn(mBluetoothDevice2); 111 when(mCachedDevice2.getAddress()).thenReturn(FAKE_ADDRESS_2); 112 when(mCachedDevice2.getDrawableWithDescription()).thenReturn(pairs); 113 when(mCachedDevice3.getDevice()).thenReturn(mBluetoothDevice3); 114 when(mCachedDevice3.getAddress()).thenReturn(FAKE_ADDRESS_3); 115 when(mCachedDevice3.getDrawableWithDescription()).thenReturn(pairs); 116 final List<BluetoothDevice> mMostRecentlyConnectedDevices = new ArrayList<>(); 117 mMostRecentlyConnectedDevices.add(mBluetoothDevice1); 118 mMostRecentlyConnectedDevices.add(mBluetoothDevice2); 119 mMostRecentlyConnectedDevices.add(mBluetoothDevice3); 120 when(mContext.getSystemService(BluetoothManager.class)).thenReturn(mBluetoothManager); 121 when(mBluetoothManager.getAdapter()).thenReturn(mBluetoothAdapter); 122 when(mBluetoothAdapter.getMostRecentlyConnectedDevices()) 123 .thenReturn(mMostRecentlyConnectedDevices); 124 125 mPreferenceGroup = spy(new PreferenceCategory(mContext)); 126 when(mPreferenceGroup.getPreferenceManager()).thenReturn(mPreferenceManager); 127 mSavedDeviceGroupController = new SavedDeviceGroupController(mContext); 128 mSavedDeviceGroupController.setBluetoothDeviceUpdater(mBluetoothDeviceUpdater); 129 mSavedDeviceGroupController.setSavedDockUpdater(mSavedDockUpdater); 130 mSavedDeviceGroupController.setPreferenceGroup(mPreferenceGroup); 131 } 132 133 @Test testRegister()134 public void testRegister() { 135 // register the callback in onStart() 136 mSavedDeviceGroupController.onStart(); 137 138 verify(mBluetoothDeviceUpdater).registerCallback(); 139 verify(mSavedDockUpdater).registerCallback(); 140 verify(mBluetoothDeviceUpdater).refreshPreference(); 141 } 142 143 @Test testUnregister()144 public void testUnregister() { 145 // unregister the callback in onStop() 146 mSavedDeviceGroupController.onStop(); 147 verify(mBluetoothDeviceUpdater).unregisterCallback(); 148 verify(mSavedDockUpdater).unregisterCallback(); 149 } 150 151 @Test testGetAvailabilityStatus_noBluetoothDockFeature_returnUnSupported()152 public void testGetAvailabilityStatus_noBluetoothDockFeature_returnUnSupported() { 153 doReturn(false).when(mPackageManager).hasSystemFeature(PackageManager.FEATURE_BLUETOOTH); 154 mSavedDeviceGroupController.setSavedDockUpdater(null); 155 156 assertThat(mSavedDeviceGroupController.getAvailabilityStatus()).isEqualTo( 157 UNSUPPORTED_ON_DEVICE); 158 } 159 160 @Test testGetAvailabilityStatus_BluetoothFeature_returnSupported()161 public void testGetAvailabilityStatus_BluetoothFeature_returnSupported() { 162 doReturn(true).when(mPackageManager).hasSystemFeature(PackageManager.FEATURE_BLUETOOTH); 163 mSavedDeviceGroupController.setSavedDockUpdater(null); 164 165 assertThat(mSavedDeviceGroupController.getAvailabilityStatus()).isEqualTo( 166 AVAILABLE); 167 } 168 169 @Test getAvailabilityStatus_haveDockFeature_returnSupported()170 public void getAvailabilityStatus_haveDockFeature_returnSupported() { 171 when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)).thenReturn(false); 172 173 assertThat(mSavedDeviceGroupController.getAvailabilityStatus()).isEqualTo( 174 AVAILABLE); 175 } 176 177 @Test updatePreferenceGroup_bluetoothIsEnable_shouldOrderByMostRecentlyConnected()178 public void updatePreferenceGroup_bluetoothIsEnable_shouldOrderByMostRecentlyConnected() { 179 when(mBluetoothAdapter.isEnabled()).thenReturn(true); 180 final BluetoothDevicePreference preference3 = 181 new BluetoothDevicePreference( 182 mContext, 183 mCachedDevice3, 184 true, 185 BluetoothDevicePreference.SortType.TYPE_NO_SORT); 186 final BluetoothDevicePreference preference2 = 187 new BluetoothDevicePreference( 188 mContext, 189 mCachedDevice2, 190 true, 191 BluetoothDevicePreference.SortType.TYPE_NO_SORT); 192 final BluetoothDevicePreference preference1 = 193 new BluetoothDevicePreference( 194 mContext, 195 mCachedDevice1, 196 true, 197 BluetoothDevicePreference.SortType.TYPE_NO_SORT); 198 mSavedDeviceGroupController.onDeviceAdded(preference3); 199 mSavedDeviceGroupController.onDeviceAdded(preference2); 200 mSavedDeviceGroupController.onDeviceAdded(preference1); 201 202 mSavedDeviceGroupController.updatePreferenceGroup(); 203 204 // Refer to the order of {@link #mMostRecentlyConnectedDevices} 205 assertThat(mPreferenceGroup.isVisible()).isTrue(); 206 assertThat(mPreferenceGroup.getPreferenceCount()).isEqualTo(3); 207 assertThat(preference1.getOrder()).isEqualTo(0); 208 assertThat(preference2.getOrder()).isEqualTo(1); 209 assertThat(preference3.getOrder()).isEqualTo(2); 210 } 211 212 @Test updatePreferenceGroup_bluetoothIsDisable_shouldShowNoPreference()213 public void updatePreferenceGroup_bluetoothIsDisable_shouldShowNoPreference() { 214 when(mBluetoothAdapter.isEnabled()).thenReturn(false); 215 final BluetoothDevicePreference preference3 = 216 new BluetoothDevicePreference( 217 mContext, 218 mCachedDevice3, 219 true, 220 BluetoothDevicePreference.SortType.TYPE_NO_SORT); 221 final BluetoothDevicePreference preference2 = 222 new BluetoothDevicePreference( 223 mContext, 224 mCachedDevice2, 225 true, 226 BluetoothDevicePreference.SortType.TYPE_NO_SORT); 227 final BluetoothDevicePreference preference1 = 228 new BluetoothDevicePreference( 229 mContext, 230 mCachedDevice2, 231 true, 232 BluetoothDevicePreference.SortType.TYPE_NO_SORT); 233 mSavedDeviceGroupController.onDeviceAdded(preference3); 234 mSavedDeviceGroupController.onDeviceAdded(preference2); 235 mSavedDeviceGroupController.onDeviceAdded(preference1); 236 237 mSavedDeviceGroupController.updatePreferenceGroup(); 238 239 assertThat(mPreferenceGroup.isVisible()).isFalse(); 240 } 241 } 242