1 /* 2 * Copyright (C) 2021 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.uwb; 18 19 import static android.uwb.UwbManager.AdapterStateCallback.STATE_CHANGED_REASON_SYSTEM_POLICY; 20 import static android.uwb.UwbManager.AdapterStateCallback.STATE_CHANGED_REASON_SYSTEM_REGULATION; 21 import static android.uwb.UwbManager.AdapterStateCallback.STATE_DISABLED; 22 import static android.uwb.UwbManager.AdapterStateCallback.STATE_ENABLED_ACTIVE; 23 import static android.uwb.UwbManager.AdapterStateCallback.STATE_ENABLED_INACTIVE; 24 25 import static com.google.common.truth.Truth.assertThat; 26 27 import static org.mockito.Mockito.any; 28 import static org.mockito.Mockito.anyString; 29 import static org.mockito.Mockito.clearInvocations; 30 import static org.mockito.Mockito.doReturn; 31 import static org.mockito.Mockito.mock; 32 import static org.mockito.Mockito.never; 33 import static org.mockito.Mockito.times; 34 import static org.mockito.Mockito.verify; 35 import static org.mockito.Mockito.when; 36 37 import android.content.BroadcastReceiver; 38 import android.content.Context; 39 import android.content.Intent; 40 import android.content.pm.PackageManager; 41 import android.content.res.Resources; 42 import android.os.test.TestLooper; 43 import android.uwb.UwbManager; 44 45 import androidx.preference.Preference; 46 import androidx.preference.PreferenceScreen; 47 48 import com.android.settings.R; 49 import com.android.settings.core.BasePreferenceController; 50 51 import org.junit.Before; 52 import org.junit.Rule; 53 import org.junit.Test; 54 import org.junit.runner.RunWith; 55 import org.mockito.ArgumentCaptor; 56 import org.mockito.Mock; 57 import org.mockito.junit.MockitoJUnit; 58 import org.mockito.junit.MockitoRule; 59 import org.robolectric.RobolectricTestRunner; 60 61 /** Unit tests for UWB preference toggle. */ 62 @RunWith(RobolectricTestRunner.class) 63 public class UwbPreferenceControllerTest { 64 private static final String TEST_SUMMARY = "uwb"; 65 private static final String TEST_AIRPLANE_SUMMARY = "apm_uwb"; 66 private static final String TEST_NO_UWB_REGULATORY_SUMMARY = "regulatory_uwb"; 67 @Rule 68 public MockitoRule rule = MockitoJUnit.rule(); 69 70 @Mock 71 private Context mContext; 72 @Mock 73 private PackageManager mPackageManager; 74 private UwbPreferenceController mController; 75 private ArgumentCaptor<UwbManager.AdapterStateCallback> mAdapterStateCallbackArgumentCaptor = 76 ArgumentCaptor.forClass(UwbManager.AdapterStateCallback.class); 77 private ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverArgumentCaptor = 78 ArgumentCaptor.forClass(BroadcastReceiver.class); 79 private TestLooper mTestLooper; 80 @Mock 81 private UwbManager mUwbManager; 82 @Mock 83 private UwbUtils mUwbUtils; 84 @Mock 85 private Preference mPreference; 86 @Mock 87 private PreferenceScreen mPreferenceScreen; 88 @Mock 89 private Resources mResources; 90 91 @Before setUp()92 public void setUp() throws Exception { 93 mTestLooper = new TestLooper(); 94 doReturn(mPackageManager).when(mContext).getPackageManager(); 95 doReturn(true).when(mPackageManager) 96 .hasSystemFeature(PackageManager.FEATURE_UWB); 97 when(mResources.getString(R.string.uwb_settings_summary)) 98 .thenReturn(TEST_SUMMARY); 99 when(mResources.getString(R.string.uwb_settings_summary_airplane_mode)) 100 .thenReturn(TEST_AIRPLANE_SUMMARY); 101 when(mResources.getString(R.string.uwb_settings_summary_no_uwb_regulatory)) 102 .thenReturn(TEST_NO_UWB_REGULATORY_SUMMARY); 103 when(mContext.getMainLooper()).thenReturn(mTestLooper.getLooper()); 104 when(mContext.getSystemService(UwbManager.class)).thenReturn(mUwbManager); 105 when(mContext.getResources()).thenReturn(mResources); 106 when(mUwbUtils.isAirplaneModeOn(any())).thenReturn(false); 107 doReturn(STATE_ENABLED_ACTIVE).when(mUwbManager).getAdapterState(); 108 mController = new UwbPreferenceController(mContext, "uwb_settings", mUwbUtils); 109 when(mPreferenceScreen.findPreference(anyString())).thenReturn(mPreference); 110 mController.displayPreference(mPreferenceScreen); 111 } 112 startControllerAndCaptureCallbacks()113 private void startControllerAndCaptureCallbacks() { 114 mController.onStart(); 115 verify(mContext).registerReceiver( 116 mBroadcastReceiverArgumentCaptor.capture(), any(), any(), any()); 117 verify(mUwbManager).registerAdapterStateCallback( 118 any(), mAdapterStateCallbackArgumentCaptor.capture()); 119 } 120 121 @Test getAvailabilityStatus_uwbDisabled_shouldReturnDisabled()122 public void getAvailabilityStatus_uwbDisabled_shouldReturnDisabled() throws Exception { 123 when(mUwbUtils.isAirplaneModeOn(any())).thenReturn(true); 124 startControllerAndCaptureCallbacks(); 125 assertThat(mController.getAvailabilityStatus()) 126 .isEqualTo(BasePreferenceController.DISABLED_DEPENDENT_SETTING); 127 } 128 129 @Test getAvailabilityStatus_uwbShown_shouldReturnAvailable()130 public void getAvailabilityStatus_uwbShown_shouldReturnAvailable() throws Exception { 131 when(mUwbUtils.isAirplaneModeOn(any())).thenReturn(false); 132 startControllerAndCaptureCallbacks(); 133 assertThat(mController.getAvailabilityStatus()) 134 .isEqualTo(BasePreferenceController.AVAILABLE); 135 } 136 137 @Test getAvailabilityStatus_uwbNotShown_shouldReturnUnsupported()138 public void getAvailabilityStatus_uwbNotShown_shouldReturnUnsupported() { 139 doReturn(false).when(mPackageManager) 140 .hasSystemFeature(PackageManager.FEATURE_UWB); 141 142 mController.onStart(); 143 verify(mContext, never()).registerReceiver(any(), any(), any(), any()); 144 verify(mUwbManager, never()).registerAdapterStateCallback(any(), any()); 145 assertThat(mController.getAvailabilityStatus()) 146 .isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE); 147 } 148 149 @Test isChecked_uwbEnabled_shouldReturnTrue()150 public void isChecked_uwbEnabled_shouldReturnTrue() { 151 doReturn(STATE_ENABLED_ACTIVE).when(mUwbManager).getAdapterState(); 152 153 startControllerAndCaptureCallbacks(); 154 assertThat(mController.isChecked()).isTrue(); 155 } 156 157 @Test isChecked_uwbDisabled_shouldReturnFalse()158 public void isChecked_uwbDisabled_shouldReturnFalse() { 159 doReturn(STATE_DISABLED).when(mUwbManager).getAdapterState(); 160 161 startControllerAndCaptureCallbacks(); 162 assertThat(mController.isChecked()).isFalse(); 163 } 164 165 @Test setChecked_uwbDisabled_shouldEnableUwb()166 public void setChecked_uwbDisabled_shouldEnableUwb() { 167 clearInvocations(mUwbManager); 168 169 startControllerAndCaptureCallbacks(); 170 mController.setChecked(true); 171 172 verify(mUwbManager).setUwbEnabled(true); 173 verify(mUwbManager, never()).setUwbEnabled(false); 174 } 175 176 @Test setChecked_uwbEnabled_shouldDisableUwb()177 public void setChecked_uwbEnabled_shouldDisableUwb() { 178 clearInvocations(mUwbManager); 179 180 startControllerAndCaptureCallbacks(); 181 mController.setChecked(false); 182 183 verify(mUwbManager).setUwbEnabled(false); 184 verify(mUwbManager, never()).setUwbEnabled(true); 185 } 186 187 @Test updateStateAndSummary_uwbDisabledAndEnabled()188 public void updateStateAndSummary_uwbDisabledAndEnabled() { 189 startControllerAndCaptureCallbacks(); 190 clearInvocations(mUwbManager, mPreference); 191 192 mAdapterStateCallbackArgumentCaptor.getValue().onStateChanged( 193 STATE_DISABLED, STATE_CHANGED_REASON_SYSTEM_POLICY); 194 195 verify(mPreference).setEnabled(true); 196 assertThat(mController.isChecked()).isFalse(); 197 verify(mPreference, times(2)).setSummary(TEST_SUMMARY); 198 199 mAdapterStateCallbackArgumentCaptor.getValue().onStateChanged( 200 STATE_ENABLED_INACTIVE, STATE_CHANGED_REASON_SYSTEM_POLICY); 201 202 verify(mPreference, times(2)).setEnabled(true); 203 assertThat(mController.isChecked()).isTrue(); 204 verify(mPreference, times(4)).setSummary(TEST_SUMMARY); 205 } 206 207 @Test updateStateAndSummary_apmEnabledAndDisabled()208 public void updateStateAndSummary_apmEnabledAndDisabled() { 209 startControllerAndCaptureCallbacks(); 210 clearInvocations(mUwbManager, mPreference); 211 212 when(mUwbUtils.isAirplaneModeOn(any())).thenReturn(true); 213 mBroadcastReceiverArgumentCaptor.getValue().onReceive( 214 mock(Context.class), mock(Intent.class)); 215 216 verify(mPreference).setEnabled(false); 217 verify(mPreference, times(2)).setSummary(TEST_AIRPLANE_SUMMARY); 218 219 when(mUwbUtils.isAirplaneModeOn(any())).thenReturn(false); 220 mBroadcastReceiverArgumentCaptor.getValue().onReceive( 221 mock(Context.class), mock(Intent.class)); 222 223 verify(mPreference).setEnabled(true); 224 verify(mPreference, times(2)).setSummary(TEST_SUMMARY); 225 } 226 227 @Test updateStateAndSummary_uwbDisabledDueToRegulatory()228 public void updateStateAndSummary_uwbDisabledDueToRegulatory() { 229 startControllerAndCaptureCallbacks(); 230 clearInvocations(mUwbManager, mPreference); 231 232 mAdapterStateCallbackArgumentCaptor.getValue().onStateChanged( 233 STATE_DISABLED, STATE_CHANGED_REASON_SYSTEM_REGULATION); 234 235 assertThat(mController.getAvailabilityStatus()) 236 .isEqualTo(BasePreferenceController.CONDITIONALLY_UNAVAILABLE); 237 verify(mPreference, times(2)).setSummary(TEST_NO_UWB_REGULATORY_SUMMARY); 238 } 239 } 240 241