1 /* 2 * Copyright (C) 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 17 package com.android.settings; 18 19 import static android.hardware.biometrics.SensorProperties.STRENGTH_CONVENIENCE; 20 import static android.hardware.biometrics.SensorProperties.STRENGTH_STRONG; 21 import static android.hardware.biometrics.SensorProperties.STRENGTH_WEAK; 22 23 import static com.google.common.truth.Truth.assertThat; 24 25 import static org.junit.Assert.assertNull; 26 import static org.junit.Assert.assertThrows; 27 import static org.mockito.ArgumentMatchers.anyInt; 28 import static org.mockito.ArgumentMatchers.anyString; 29 import static org.mockito.ArgumentMatchers.eq; 30 import static org.mockito.Mockito.RETURNS_DEEP_STUBS; 31 import static org.mockito.Mockito.doReturn; 32 import static org.mockito.Mockito.mock; 33 import static org.mockito.Mockito.spy; 34 import static org.mockito.Mockito.verify; 35 import static org.mockito.Mockito.when; 36 37 import android.app.ActionBar; 38 import android.app.admin.DevicePolicyManager; 39 import android.app.admin.DevicePolicyResourcesManager; 40 import android.content.ComponentName; 41 import android.content.Context; 42 import android.content.pm.ApplicationInfo; 43 import android.content.pm.PackageManager; 44 import android.content.pm.UserInfo; 45 import android.graphics.Bitmap; 46 import android.graphics.Color; 47 import android.graphics.drawable.BitmapDrawable; 48 import android.graphics.drawable.ColorDrawable; 49 import android.graphics.drawable.VectorDrawable; 50 import android.hardware.face.FaceManager; 51 import android.hardware.face.FaceSensorProperties; 52 import android.hardware.face.FaceSensorPropertiesInternal; 53 import android.net.ConnectivityManager; 54 import android.net.LinkAddress; 55 import android.net.LinkProperties; 56 import android.net.Network; 57 import android.net.wifi.WifiManager; 58 import android.os.Bundle; 59 import android.os.UserHandle; 60 import android.os.UserManager; 61 import android.os.storage.DiskInfo; 62 import android.os.storage.StorageManager; 63 import android.os.storage.VolumeInfo; 64 import android.util.IconDrawableFactory; 65 import android.widget.EditText; 66 import android.widget.ScrollView; 67 import android.widget.TextView; 68 69 import androidx.core.graphics.drawable.IconCompat; 70 import androidx.fragment.app.FragmentActivity; 71 72 import com.android.internal.widget.LockPatternUtils; 73 import com.android.settings.testutils.shadow.ShadowLockPatternUtils; 74 75 import org.junit.After; 76 import org.junit.Before; 77 import org.junit.Test; 78 import org.junit.runner.RunWith; 79 import org.mockito.Mock; 80 import org.mockito.MockitoAnnotations; 81 import org.robolectric.Robolectric; 82 import org.robolectric.RobolectricTestRunner; 83 import org.robolectric.RuntimeEnvironment; 84 import org.robolectric.annotation.Config; 85 import org.robolectric.shadows.ShadowBinder; 86 87 import java.net.InetAddress; 88 import java.util.ArrayList; 89 import java.util.List; 90 91 @RunWith(RobolectricTestRunner.class) 92 @Config(shadows = ShadowLockPatternUtils.class) 93 public class UtilsTest { 94 95 private static final String PACKAGE_NAME = "com.android.app"; 96 private static final int USER_ID = 1; 97 98 @Mock 99 private WifiManager wifiManager; 100 @Mock 101 private Network network; 102 @Mock 103 private ConnectivityManager connectivityManager; 104 @Mock 105 private DevicePolicyManager mDevicePolicyManager; 106 @Mock 107 private DevicePolicyResourcesManager mDevicePolicyResourcesManager; 108 @Mock 109 private UserManager mMockUserManager; 110 @Mock 111 private PackageManager mPackageManager; 112 @Mock 113 private IconDrawableFactory mIconDrawableFactory; 114 @Mock 115 private ApplicationInfo mApplicationInfo; 116 private Context mContext; 117 private UserManager mUserManager; 118 private static final int FLAG_SYSTEM = 0x00000000; 119 private static final int FLAG_MAIN = 0x00004000; 120 121 @Before setUp()122 public void setUp() { 123 MockitoAnnotations.initMocks(this); 124 125 mContext = spy(RuntimeEnvironment.application); 126 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 127 when(mContext.getSystemService(WifiManager.class)).thenReturn(wifiManager); 128 when(mContext.getSystemService(Context.CONNECTIVITY_SERVICE)) 129 .thenReturn(connectivityManager); 130 when(mContext.getPackageManager()).thenReturn(mPackageManager); 131 } 132 133 @After tearDown()134 public void tearDown() { 135 ShadowLockPatternUtils.reset(); 136 } 137 138 @Test getWifiIpAddresses_succeeds()139 public void getWifiIpAddresses_succeeds() throws Exception { 140 when(wifiManager.getCurrentNetwork()).thenReturn(network); 141 LinkAddress address = new LinkAddress(InetAddress.getByName("127.0.0.1"), 0); 142 LinkProperties lp = new LinkProperties(); 143 lp.addLinkAddress(address); 144 when(connectivityManager.getLinkProperties(network)).thenReturn(lp); 145 146 assertThat(Utils.getWifiIpAddresses(mContext)).isEqualTo("127.0.0.1"); 147 } 148 149 @Test getWifiIpAddresses_nullLinkProperties()150 public void getWifiIpAddresses_nullLinkProperties() { 151 when(wifiManager.getCurrentNetwork()).thenReturn(network); 152 // Explicitly set the return value to null for readability sake. 153 when(connectivityManager.getLinkProperties(network)).thenReturn(null); 154 155 assertThat(Utils.getWifiIpAddresses(mContext)).isNull(); 156 } 157 158 @Test getWifiIpAddresses_nullNetwork()159 public void getWifiIpAddresses_nullNetwork() { 160 // Explicitly set the return value to null for readability sake. 161 when(wifiManager.getCurrentNetwork()).thenReturn(null); 162 163 assertThat(Utils.getWifiIpAddresses(mContext)).isNull(); 164 } 165 166 @Test initializeVolumeDoesntBreakOnNullVolume()167 public void initializeVolumeDoesntBreakOnNullVolume() { 168 VolumeInfo info = new VolumeInfo("id", 0, new DiskInfo("id", 0), ""); 169 StorageManager storageManager = mock(StorageManager.class, RETURNS_DEEP_STUBS); 170 when(storageManager.findVolumeById(anyString())).thenReturn(info); 171 172 Utils.maybeInitializeVolume(storageManager, new Bundle()); 173 } 174 175 @Test isProfileOrDeviceOwner_deviceOwnerApp_returnTrue()176 public void isProfileOrDeviceOwner_deviceOwnerApp_returnTrue() { 177 when(mDevicePolicyManager.isDeviceOwnerAppOnAnyUser(PACKAGE_NAME)).thenReturn(true); 178 179 assertThat( 180 Utils.isProfileOrDeviceOwner(mMockUserManager, mDevicePolicyManager, PACKAGE_NAME)) 181 .isTrue(); 182 } 183 184 @Test isProfileOrDeviceOwner_profileOwnerApp_returnTrue()185 public void isProfileOrDeviceOwner_profileOwnerApp_returnTrue() { 186 final List<UserInfo> userInfos = new ArrayList<>(); 187 userInfos.add(new UserInfo()); 188 189 when(mMockUserManager.getUsers()).thenReturn(userInfos); 190 when(mDevicePolicyManager.getProfileOwnerAsUser(userInfos.get(0).id)) 191 .thenReturn(new ComponentName(PACKAGE_NAME, "")); 192 193 assertThat( 194 Utils.isProfileOrDeviceOwner(mMockUserManager, mDevicePolicyManager, PACKAGE_NAME)) 195 .isTrue(); 196 } 197 198 @Test setEditTextCursorPosition_shouldGetExpectedEditTextLenght()199 public void setEditTextCursorPosition_shouldGetExpectedEditTextLenght() { 200 final EditText editText = new EditText(mContext); 201 final CharSequence text = "test"; 202 editText.setText(text, TextView.BufferType.EDITABLE); 203 final int length = editText.getText().length(); 204 Utils.setEditTextCursorPosition(editText); 205 206 assertThat(editText.getSelectionEnd()).isEqualTo(length); 207 } 208 209 @Test createIconWithDrawable_BitmapDrawable()210 public void createIconWithDrawable_BitmapDrawable() { 211 final Bitmap bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); 212 final BitmapDrawable drawable = new BitmapDrawable(mContext.getResources(), bitmap); 213 214 final IconCompat icon = Utils.createIconWithDrawable(drawable); 215 216 assertThat(icon.getBitmap()).isNotNull(); 217 } 218 219 @Test createIconWithDrawable_ColorDrawable()220 public void createIconWithDrawable_ColorDrawable() { 221 final ColorDrawable drawable = new ColorDrawable(Color.BLACK); 222 223 final IconCompat icon = Utils.createIconWithDrawable(drawable); 224 225 assertThat(icon.getBitmap()).isNotNull(); 226 } 227 228 @Test createIconWithDrawable_VectorDrawable()229 public void createIconWithDrawable_VectorDrawable() { 230 final VectorDrawable drawable = VectorDrawable.create(mContext.getResources(), 231 R.drawable.ic_settings_accent); 232 233 final IconCompat icon = Utils.createIconWithDrawable(drawable); 234 235 assertThat(icon.getBitmap()).isNotNull(); 236 } 237 238 @Test getBadgedIcon_usePackageNameAndUserId()239 public void getBadgedIcon_usePackageNameAndUserId() 240 throws PackageManager.NameNotFoundException { 241 doReturn(mApplicationInfo).when(mPackageManager).getApplicationInfoAsUser( 242 PACKAGE_NAME, PackageManager.GET_META_DATA, USER_ID); 243 244 Utils.getBadgedIcon(mIconDrawableFactory, mPackageManager, PACKAGE_NAME, USER_ID); 245 246 // Verify that it uses the correct user id 247 verify(mPackageManager).getApplicationInfoAsUser(eq(PACKAGE_NAME), anyInt(), eq(USER_ID)); 248 verify(mIconDrawableFactory).getBadgedIcon(mApplicationInfo, USER_ID); 249 } 250 251 @Test isPackageEnabled_appEnabled_returnTrue()252 public void isPackageEnabled_appEnabled_returnTrue() 253 throws PackageManager.NameNotFoundException{ 254 mApplicationInfo.enabled = true; 255 when(mPackageManager.getApplicationInfo(PACKAGE_NAME, 0)).thenReturn(mApplicationInfo); 256 257 assertThat(Utils.isPackageEnabled(mContext, PACKAGE_NAME)).isTrue(); 258 } 259 260 @Test isPackageEnabled_appDisabled_returnTrue()261 public void isPackageEnabled_appDisabled_returnTrue() 262 throws PackageManager.NameNotFoundException{ 263 mApplicationInfo.enabled = false; 264 when(mPackageManager.getApplicationInfo(PACKAGE_NAME, 0)).thenReturn(mApplicationInfo); 265 266 assertThat(Utils.isPackageEnabled(mContext, PACKAGE_NAME)).isFalse(); 267 } 268 269 @Test isPackageEnabled_noApp_returnFalse()270 public void isPackageEnabled_noApp_returnFalse() { 271 assertThat(Utils.isPackageEnabled(mContext, PACKAGE_NAME)).isFalse(); 272 } 273 274 @Test setActionBarShadowAnimation_nullParameters_shouldNotCrash()275 public void setActionBarShadowAnimation_nullParameters_shouldNotCrash() { 276 // no crash here 277 Utils.setActionBarShadowAnimation(null, null, null); 278 } 279 280 @Test setActionBarShadowAnimation_shouldSetElevationToZero()281 public void setActionBarShadowAnimation_shouldSetElevationToZero() { 282 final FragmentActivity activity = Robolectric.setupActivity(FragmentActivity.class); 283 final ActionBar actionBar = activity.getActionBar(); 284 285 Utils.setActionBarShadowAnimation(activity, activity.getLifecycle(), 286 new ScrollView(mContext)); 287 288 assertThat(actionBar.getElevation()).isEqualTo(0.f); 289 } 290 291 @Test isSettingsIntelligence_IsSI_returnTrue()292 public void isSettingsIntelligence_IsSI_returnTrue() { 293 final String siPackageName = mContext.getString( 294 R.string.config_settingsintelligence_package_name); 295 ShadowBinder.setCallingUid(USER_ID); 296 when(mPackageManager.getPackagesForUid(USER_ID)).thenReturn(new String[]{siPackageName}); 297 298 assertThat(Utils.isSettingsIntelligence(mContext)).isTrue(); 299 } 300 301 @Test isSettingsIntelligence_IsNotSI_returnFalse()302 public void isSettingsIntelligence_IsNotSI_returnFalse() { 303 ShadowBinder.setCallingUid(USER_ID); 304 when(mPackageManager.getPackagesForUid(USER_ID)).thenReturn(new String[]{PACKAGE_NAME}); 305 306 assertThat(Utils.isSettingsIntelligence(mContext)).isFalse(); 307 } 308 309 @Test canCurrentUserDream_isMainUser_returnTrue()310 public void canCurrentUserDream_isMainUser_returnTrue() { 311 Context mockContext = mock(Context.class); 312 UserManager mockUserManager = mock(UserManager.class); 313 314 when(mockContext.getSystemService(UserManager.class)).thenReturn(mockUserManager); 315 316 // mock MainUser 317 UserHandle mainUser = new UserHandle(10); 318 when(mockUserManager.getMainUser()).thenReturn(mainUser); 319 when(mockUserManager.isUserForeground()).thenReturn(true); 320 321 when(mockContext.createContextAsUser(mainUser, 0)).thenReturn(mockContext); 322 323 assertThat(Utils.canCurrentUserDream(mockContext)).isTrue(); 324 } 325 326 @Test canCurrentUserDream_nullMainUser_returnFalse()327 public void canCurrentUserDream_nullMainUser_returnFalse() { 328 Context mockContext = mock(Context.class); 329 UserManager mockUserManager = mock(UserManager.class); 330 331 when(mockContext.getSystemService(UserManager.class)).thenReturn(mockUserManager); 332 when(mockUserManager.getMainUser()).thenReturn(null); 333 334 assertThat(Utils.canCurrentUserDream(mockContext)).isFalse(); 335 } 336 337 @Test canCurrentUserDream_notMainUser_returnFalse()338 public void canCurrentUserDream_notMainUser_returnFalse() { 339 Context mockContext = mock(Context.class); 340 UserManager mockUserManager = mock(UserManager.class); 341 342 when(mockContext.getSystemService(UserManager.class)).thenReturn(mockUserManager); 343 when(mockUserManager.isUserForeground()).thenReturn(false); 344 345 assertThat(Utils.canCurrentUserDream(mockContext)).isFalse(); 346 } 347 348 @Test checkUserOwnsFrpCredential_userOwnsFrpCredential_returnUserId()349 public void checkUserOwnsFrpCredential_userOwnsFrpCredential_returnUserId() { 350 ShadowLockPatternUtils.setUserOwnsFrpCredential(true); 351 352 assertThat(Utils.checkUserOwnsFrpCredential(mContext, 123)).isEqualTo(123); 353 } 354 355 @Test checkUserOwnsFrpCredential_userNotOwnsFrpCredential_returnUserId()356 public void checkUserOwnsFrpCredential_userNotOwnsFrpCredential_returnUserId() { 357 ShadowLockPatternUtils.setUserOwnsFrpCredential(false); 358 359 assertThrows( 360 SecurityException.class, 361 () -> Utils.checkUserOwnsFrpCredential(mContext, 123)); 362 } 363 364 @Test getConfirmCredentialStringForUser_Pin_shouldReturnCorrectString()365 public void getConfirmCredentialStringForUser_Pin_shouldReturnCorrectString() { 366 setUpForConfirmCredentialString(false /* isEffectiveUserManagedProfile */); 367 368 when(mContext.getString(R.string.lockpassword_confirm_your_pin_generic)) 369 .thenReturn("PIN"); 370 371 String confirmCredentialString = Utils.getConfirmCredentialStringForUser(mContext, 372 USER_ID, LockPatternUtils.CREDENTIAL_TYPE_PIN); 373 374 assertThat(confirmCredentialString).isEqualTo("PIN"); 375 } 376 377 @Test getConfirmCredentialStringForUser_Pattern_shouldReturnCorrectString()378 public void getConfirmCredentialStringForUser_Pattern_shouldReturnCorrectString() { 379 setUpForConfirmCredentialString(false /* isEffectiveUserManagedProfile */); 380 381 when(mContext.getString(R.string.lockpassword_confirm_your_pattern_generic)) 382 .thenReturn("PATTERN"); 383 384 String confirmCredentialString = Utils.getConfirmCredentialStringForUser(mContext, 385 USER_ID, LockPatternUtils.CREDENTIAL_TYPE_PATTERN); 386 387 assertThat(confirmCredentialString).isEqualTo("PATTERN"); 388 } 389 390 @Test getConfirmCredentialStringForUser_Password_shouldReturnCorrectString()391 public void getConfirmCredentialStringForUser_Password_shouldReturnCorrectString() { 392 setUpForConfirmCredentialString(false /* isEffectiveUserManagedProfile */); 393 394 when(mContext.getString(R.string.lockpassword_confirm_your_password_generic)) 395 .thenReturn("PASSWORD"); 396 397 String confirmCredentialString = Utils.getConfirmCredentialStringForUser(mContext, 398 USER_ID, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD); 399 400 assertThat(confirmCredentialString).isEqualTo("PASSWORD"); 401 } 402 403 @Test getConfirmCredentialStringForUser_workPin_shouldReturnNull()404 public void getConfirmCredentialStringForUser_workPin_shouldReturnNull() { 405 setUpForConfirmCredentialString(true /* isEffectiveUserManagedProfile */); 406 407 String confirmCredentialString = Utils.getConfirmCredentialStringForUser(mContext, 408 USER_ID, LockPatternUtils.CREDENTIAL_TYPE_PIN); 409 410 assertNull(confirmCredentialString); 411 } 412 413 @Test getConfirmCredentialStringForUser_workPattern_shouldReturnNull()414 public void getConfirmCredentialStringForUser_workPattern_shouldReturnNull() { 415 setUpForConfirmCredentialString(true /* isEffectiveUserManagedProfile */); 416 417 String confirmCredentialString = Utils.getConfirmCredentialStringForUser(mContext, 418 USER_ID, LockPatternUtils.CREDENTIAL_TYPE_PATTERN); 419 420 assertNull(confirmCredentialString); 421 } 422 423 @Test getConfirmCredentialStringForUser_workPassword_shouldReturnNull()424 public void getConfirmCredentialStringForUser_workPassword_shouldReturnNull() { 425 setUpForConfirmCredentialString(true /* isEffectiveUserManagedProfile */); 426 427 String confirmCredentialString = Utils.getConfirmCredentialStringForUser(mContext, 428 USER_ID, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD); 429 430 assertNull(confirmCredentialString); 431 } 432 433 @Test getConfirmCredentialStringForUser_credentialTypeNone_shouldReturnNull()434 public void getConfirmCredentialStringForUser_credentialTypeNone_shouldReturnNull() { 435 setUpForConfirmCredentialString(false /* isEffectiveUserManagedProfile */); 436 437 String confirmCredentialString = Utils.getConfirmCredentialStringForUser(mContext, 438 USER_ID, LockPatternUtils.CREDENTIAL_TYPE_NONE); 439 440 assertNull(confirmCredentialString); 441 } 442 443 @Test isFaceNotConvenienceBiometric_faceStrengthStrong_shouldReturnTrue()444 public void isFaceNotConvenienceBiometric_faceStrengthStrong_shouldReturnTrue() { 445 FaceManager mockFaceManager = mock(FaceManager.class); 446 when(mContext.getSystemService(Context.FACE_SERVICE)).thenReturn(mockFaceManager); 447 doReturn(true).when(mPackageManager).hasSystemFeature(anyString()); 448 List<FaceSensorPropertiesInternal> props = List.of(new FaceSensorPropertiesInternal( 449 0 /* id */, 450 STRENGTH_STRONG, 451 1 /* maxTemplatesAllowed */, 452 new ArrayList<>() /* componentInfo */, 453 FaceSensorProperties.TYPE_UNKNOWN, 454 true /* supportsFaceDetection */, 455 true /* supportsSelfIllumination */, 456 false /* resetLockoutRequiresChallenge */)); 457 doReturn(props).when(mockFaceManager).getSensorPropertiesInternal(); 458 459 assertThat(Utils.isFaceNotConvenienceBiometric(mContext)).isTrue(); 460 } 461 462 @Test isFaceNotConvenienceBiometric_faceStrengthWeak_shouldReturnTrue()463 public void isFaceNotConvenienceBiometric_faceStrengthWeak_shouldReturnTrue() { 464 FaceManager mockFaceManager = mock(FaceManager.class); 465 when(mContext.getSystemService(Context.FACE_SERVICE)).thenReturn(mockFaceManager); 466 doReturn(true).when(mPackageManager).hasSystemFeature(anyString()); 467 List<FaceSensorPropertiesInternal> props = List.of(new FaceSensorPropertiesInternal( 468 0 /* id */, 469 STRENGTH_WEAK, 470 1 /* maxTemplatesAllowed */, 471 new ArrayList<>() /* componentInfo */, 472 FaceSensorProperties.TYPE_UNKNOWN, 473 true /* supportsFaceDetection */, 474 true /* supportsSelfIllumination */, 475 false /* resetLockoutRequiresChallenge */)); 476 doReturn(props).when(mockFaceManager).getSensorPropertiesInternal(); 477 478 assertThat(Utils.isFaceNotConvenienceBiometric(mContext)).isTrue(); 479 } 480 481 @Test isFaceNotConvenienceBiometric_faceStrengthConvenience_shouldReturnFalse()482 public void isFaceNotConvenienceBiometric_faceStrengthConvenience_shouldReturnFalse() { 483 FaceManager mockFaceManager = mock(FaceManager.class); 484 when(mContext.getSystemService(Context.FACE_SERVICE)).thenReturn(mockFaceManager); 485 doReturn(true).when(mPackageManager).hasSystemFeature(anyString()); 486 List<FaceSensorPropertiesInternal> props = List.of(new FaceSensorPropertiesInternal( 487 0 /* id */, 488 STRENGTH_CONVENIENCE, 489 1 /* maxTemplatesAllowed */, 490 new ArrayList<>() /* componentInfo */, 491 FaceSensorProperties.TYPE_UNKNOWN, 492 true /* supportsFaceDetection */, 493 true /* supportsSelfIllumination */, 494 false /* resetLockoutRequiresChallenge */)); 495 doReturn(props).when(mockFaceManager).getSensorPropertiesInternal(); 496 497 assertThat(Utils.isFaceNotConvenienceBiometric(mContext)).isFalse(); 498 } 499 500 @Test isFaceNotConvenienceBiometric_faceManagerNull_shouldReturnFalse()501 public void isFaceNotConvenienceBiometric_faceManagerNull_shouldReturnFalse() { 502 when(mContext.getSystemService(Context.FACE_SERVICE)).thenReturn(null); 503 assertThat(Utils.isFaceNotConvenienceBiometric(mContext)).isFalse(); 504 } 505 setUpForConfirmCredentialString(boolean isEffectiveUserManagedProfile)506 private void setUpForConfirmCredentialString(boolean isEffectiveUserManagedProfile) { 507 when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mMockUserManager); 508 when(mMockUserManager.getCredentialOwnerProfile(USER_ID)).thenReturn(USER_ID); 509 when(mMockUserManager.isManagedProfile(USER_ID)).thenReturn(isEffectiveUserManagedProfile); 510 } 511 } 512