1 /* 2 * Copyright (C) 2019 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.server.recoverysystem; 18 19 import static android.os.RecoverySystem.RESUME_ON_REBOOT_REBOOT_ERROR_INVALID_PACKAGE_NAME; 20 import static android.os.RecoverySystem.RESUME_ON_REBOOT_REBOOT_ERROR_LSKF_NOT_CAPTURED; 21 import static android.os.RecoverySystem.RESUME_ON_REBOOT_REBOOT_ERROR_PROVIDER_PREPARATION_FAILURE; 22 import static android.os.RecoverySystem.RESUME_ON_REBOOT_REBOOT_ERROR_SLOT_MISMATCH; 23 24 import static org.hamcrest.CoreMatchers.is; 25 import static org.junit.Assert.assertEquals; 26 import static org.junit.Assert.assertFalse; 27 import static org.junit.Assert.assertThat; 28 import static org.junit.Assert.assertTrue; 29 import static org.mockito.AdditionalMatchers.not; 30 import static org.mockito.ArgumentMatchers.any; 31 import static org.mockito.ArgumentMatchers.anyBoolean; 32 import static org.mockito.ArgumentMatchers.anyInt; 33 import static org.mockito.ArgumentMatchers.anyLong; 34 import static org.mockito.ArgumentMatchers.anyString; 35 import static org.mockito.ArgumentMatchers.eq; 36 import static org.mockito.Mockito.doNothing; 37 import static org.mockito.Mockito.doReturn; 38 import static org.mockito.Mockito.doThrow; 39 import static org.mockito.Mockito.mock; 40 import static org.mockito.Mockito.never; 41 import static org.mockito.Mockito.times; 42 import static org.mockito.Mockito.verify; 43 import static org.mockito.Mockito.verifyNoMoreInteractions; 44 import static org.mockito.Mockito.when; 45 46 import android.content.Context; 47 import android.content.IntentSender; 48 import android.content.pm.PackageManager; 49 import android.hardware.boot.IBootControl; 50 import android.os.Handler; 51 import android.os.IPowerManager; 52 import android.os.IRecoverySystemProgressListener; 53 import android.os.IThermalService; 54 import android.os.Looper; 55 import android.os.PowerManager; 56 57 import androidx.test.InstrumentationRegistry; 58 import androidx.test.filters.SmallTest; 59 import androidx.test.runner.AndroidJUnit4; 60 61 import com.android.internal.widget.LockSettingsInternal; 62 63 import org.junit.Before; 64 import org.junit.Test; 65 import org.junit.runner.RunWith; 66 67 import java.io.FileWriter; 68 69 /** 70 * atest FrameworksServicesTests:RecoverySystemServiceTest 71 */ 72 @SmallTest 73 @RunWith(AndroidJUnit4.class) 74 public class RecoverySystemServiceTest { 75 private RecoverySystemService mRecoverySystemService; 76 private RecoverySystemServiceTestable.FakeSystemProperties mSystemProperties; 77 private RecoverySystemService.UncryptSocket mUncryptSocket; 78 private Context mContext; 79 private IPowerManager mIPowerManager; 80 private IThermalService mIThermalService; 81 private FileWriter mUncryptUpdateFileWriter; 82 private LockSettingsInternal mLockSettingsInternal; 83 private IBootControl mIBootControl; 84 private RecoverySystemServiceTestable.IMetricsReporter mMetricsReporter; 85 private RecoverySystemService.PreferencesManager mSharedPreferences; 86 87 private static final String FAKE_OTA_PACKAGE_NAME = "fake.ota.package"; 88 private static final String FAKE_OTHER_PACKAGE_NAME = "fake.other.package"; 89 90 @Before setup()91 public void setup() throws Exception { 92 mContext = mock(Context.class); 93 mSystemProperties = new RecoverySystemServiceTestable.FakeSystemProperties(); 94 mUncryptSocket = mock(RecoverySystemService.UncryptSocket.class); 95 mUncryptUpdateFileWriter = mock(FileWriter.class); 96 mLockSettingsInternal = mock(LockSettingsInternal.class); 97 98 doReturn(true).when(mLockSettingsInternal).prepareRebootEscrow(); 99 doReturn(true).when(mLockSettingsInternal).clearRebootEscrow(); 100 doReturn(LockSettingsInternal.ARM_REBOOT_ERROR_NONE).when(mLockSettingsInternal) 101 .armRebootEscrow(); 102 103 Looper looper = InstrumentationRegistry.getContext().getMainLooper(); 104 mIPowerManager = mock(IPowerManager.class); 105 mIThermalService = mock(IThermalService.class); 106 PowerManager powerManager = new PowerManager(mock(Context.class), mIPowerManager, 107 mIThermalService, new Handler(looper)); 108 109 mIBootControl = mock(IBootControl.class); 110 when(mIBootControl.getCurrentSlot()).thenReturn(0); 111 when(mIBootControl.getActiveBootSlot()).thenReturn(1); 112 113 mMetricsReporter = mock(RecoverySystemServiceTestable.IMetricsReporter.class); 114 mSharedPreferences = mock(RecoverySystemService.PreferencesManager.class); 115 116 mRecoverySystemService = new RecoverySystemServiceTestable(mContext, mSystemProperties, 117 powerManager, mUncryptUpdateFileWriter, mUncryptSocket, mLockSettingsInternal, 118 mIBootControl, mMetricsReporter, mSharedPreferences); 119 } 120 121 @Test clearBcb_success()122 public void clearBcb_success() throws Exception { 123 doNothing().when(mContext).enforceCallingOrSelfPermission( 124 eq(android.Manifest.permission.RECOVERY), any()); 125 when(mUncryptSocket.getPercentageUncrypted()).thenReturn(100); 126 127 assertThat(mRecoverySystemService.clearBcb(), is(true)); 128 129 assertThat(mSystemProperties.getCtlStart(), is("clear-bcb")); 130 verify(mUncryptSocket).sendAck(); 131 verify(mUncryptSocket).close(); 132 } 133 134 @Test clearBcb_uncrypt_failure()135 public void clearBcb_uncrypt_failure() throws Exception { 136 doNothing().when(mContext).enforceCallingOrSelfPermission( 137 eq(android.Manifest.permission.RECOVERY), any()); 138 when(mUncryptSocket.getPercentageUncrypted()).thenReturn(0); 139 140 assertThat(mRecoverySystemService.clearBcb(), is(false)); 141 142 assertThat(mSystemProperties.getCtlStart(), is("clear-bcb")); 143 verify(mUncryptSocket).sendAck(); 144 verify(mUncryptSocket).close(); 145 } 146 147 @Test(expected = SecurityException.class) clearBcb_noPerm()148 public void clearBcb_noPerm() { 149 doThrow(SecurityException.class).when(mContext).enforceCallingOrSelfPermission( 150 eq(android.Manifest.permission.RECOVERY), any()); 151 mRecoverySystemService.clearBcb(); 152 } 153 154 @Test setupBcb_success()155 public void setupBcb_success() throws Exception { 156 doNothing().when(mContext).enforceCallingOrSelfPermission( 157 eq(android.Manifest.permission.RECOVERY), any()); 158 when(mUncryptSocket.getPercentageUncrypted()).thenReturn(100); 159 160 assertThat(mRecoverySystemService.setupBcb("foo"), is(true)); 161 162 assertThat(mSystemProperties.getCtlStart(), is("setup-bcb")); 163 verify(mUncryptSocket).sendCommand("foo"); 164 verify(mUncryptSocket).sendAck(); 165 verify(mUncryptSocket).close(); 166 } 167 168 @Test setupBcb_uncrypt_failure()169 public void setupBcb_uncrypt_failure() throws Exception { 170 doNothing().when(mContext).enforceCallingOrSelfPermission( 171 eq(android.Manifest.permission.RECOVERY), any()); 172 when(mUncryptSocket.getPercentageUncrypted()).thenReturn(0); 173 174 assertThat(mRecoverySystemService.setupBcb("foo"), is(false)); 175 176 assertThat(mSystemProperties.getCtlStart(), is("setup-bcb")); 177 verify(mUncryptSocket).sendCommand("foo"); 178 verify(mUncryptSocket).sendAck(); 179 verify(mUncryptSocket).close(); 180 } 181 182 @Test(expected = SecurityException.class) setupBcb_noPerm()183 public void setupBcb_noPerm() { 184 doThrow(SecurityException.class).when(mContext).enforceCallingOrSelfPermission( 185 eq(android.Manifest.permission.RECOVERY), any()); 186 mRecoverySystemService.setupBcb("foo"); 187 } 188 189 @Test rebootRecoveryWithCommand_success()190 public void rebootRecoveryWithCommand_success() throws Exception { 191 doNothing().when(mContext).enforceCallingOrSelfPermission( 192 eq(android.Manifest.permission.RECOVERY), any()); 193 when(mUncryptSocket.getPercentageUncrypted()).thenReturn(100); 194 195 mRecoverySystemService.rebootRecoveryWithCommand("foo"); 196 197 assertThat(mSystemProperties.getCtlStart(), is("setup-bcb")); 198 verify(mUncryptSocket).sendCommand("foo"); 199 verify(mUncryptSocket).sendAck(); 200 verify(mUncryptSocket).close(); 201 verify(mIPowerManager).reboot(anyBoolean(), eq("recovery"), anyBoolean()); 202 } 203 204 @Test rebootRecoveryWithCommand_failure()205 public void rebootRecoveryWithCommand_failure() throws Exception { 206 doNothing().when(mContext).enforceCallingOrSelfPermission( 207 eq(android.Manifest.permission.RECOVERY), any()); 208 when(mUncryptSocket.getPercentageUncrypted()).thenReturn(0); 209 210 mRecoverySystemService.rebootRecoveryWithCommand("foo"); 211 212 assertThat(mSystemProperties.getCtlStart(), is("setup-bcb")); 213 verify(mUncryptSocket).sendCommand("foo"); 214 verify(mUncryptSocket).sendAck(); 215 verify(mUncryptSocket).close(); 216 verifyNoMoreInteractions(mIPowerManager); 217 } 218 219 @Test(expected = SecurityException.class) rebootRecoveryWithCommand_noPerm()220 public void rebootRecoveryWithCommand_noPerm() { 221 doThrow(SecurityException.class).when(mContext).enforceCallingOrSelfPermission( 222 eq(android.Manifest.permission.RECOVERY), any()); 223 mRecoverySystemService.rebootRecoveryWithCommand("foo"); 224 } 225 226 @Test uncrypt_success()227 public void uncrypt_success() throws Exception { 228 doNothing().when(mContext).enforceCallingOrSelfPermission( 229 eq(android.Manifest.permission.RECOVERY), any()); 230 when(mUncryptSocket.getPercentageUncrypted()).thenReturn(0, 5, 25, 50, 90, 99, 100); 231 232 IRecoverySystemProgressListener listener = mock(IRecoverySystemProgressListener.class); 233 assertThat(mRecoverySystemService.uncrypt("foo.zip", listener), is(true)); 234 235 assertThat(mSystemProperties.getCtlStart(), is("uncrypt")); 236 verify(mUncryptSocket, times(7)).getPercentageUncrypted(); 237 verify(mUncryptSocket).sendAck(); 238 verify(mUncryptSocket).close(); 239 } 240 241 @Test(expected = SecurityException.class) requestLskf_protected()242 public void requestLskf_protected() { 243 when(mContext.checkCallingOrSelfPermission(anyString())).thenReturn( 244 PackageManager.PERMISSION_DENIED); 245 mRecoverySystemService.requestLskf(FAKE_OTA_PACKAGE_NAME, null); 246 } 247 248 @Test requestLskf_reportMetrics()249 public void requestLskf_reportMetrics() throws Exception { 250 IntentSender intentSender = mock(IntentSender.class); 251 assertThat(mRecoverySystemService.requestLskf(FAKE_OTA_PACKAGE_NAME, intentSender), 252 is(true)); 253 verify(mMetricsReporter).reportRebootEscrowPreparationMetrics( 254 eq(1000), eq(0) /* need preparation */, eq(1) /* client count */); 255 verify(mSharedPreferences).putLong(eq(FAKE_OTA_PACKAGE_NAME 256 + RecoverySystemService.REQUEST_LSKF_TIMESTAMP_PREF_SUFFIX), eq(100_000L)); 257 } 258 259 @Test requestLskf_success()260 public void requestLskf_success() throws Exception { 261 IntentSender intentSender = mock(IntentSender.class); 262 assertThat(mRecoverySystemService.requestLskf(FAKE_OTA_PACKAGE_NAME, intentSender), 263 is(true)); 264 265 when(mSharedPreferences.getLong(eq(FAKE_OTA_PACKAGE_NAME 266 + RecoverySystemService.REQUEST_LSKF_TIMESTAMP_PREF_SUFFIX), anyLong())) 267 .thenReturn(200_000L).thenReturn(5000L); 268 mRecoverySystemService.onPreparedForReboot(true); 269 verify(mMetricsReporter).reportRebootEscrowLskfCapturedMetrics( 270 eq(1000), eq(1) /* client count */, 271 eq(-1) /* invalid duration */); 272 273 mRecoverySystemService.onPreparedForReboot(true); 274 verify(intentSender).sendIntent(any(), anyInt(), any(), any(), any()); 275 verify(mMetricsReporter).reportRebootEscrowLskfCapturedMetrics( 276 eq(1000), eq(1) /* client count */, eq(95) /* duration */); 277 } 278 279 @Test requestLskf_subsequentRequestNotClearPrepared()280 public void requestLskf_subsequentRequestNotClearPrepared() throws Exception { 281 IntentSender intentSender = mock(IntentSender.class); 282 assertThat(mRecoverySystemService.requestLskf(FAKE_OTA_PACKAGE_NAME, intentSender), 283 is(true)); 284 mRecoverySystemService.onPreparedForReboot(true); 285 verify(intentSender).sendIntent(any(), anyInt(), any(), any(), any()); 286 287 assertThat(mRecoverySystemService.requestLskf(FAKE_OTA_PACKAGE_NAME, null), is(true)); 288 mRecoverySystemService.rebootWithLskf(FAKE_OTA_PACKAGE_NAME, "foobar", true); 289 verify(mIPowerManager).reboot(anyBoolean(), eq("foobar"), anyBoolean()); 290 } 291 292 @Test requestLskf_requestedButNotPrepared()293 public void requestLskf_requestedButNotPrepared() throws Exception { 294 IntentSender intentSender = mock(IntentSender.class); 295 assertThat(mRecoverySystemService.requestLskf(FAKE_OTA_PACKAGE_NAME, intentSender), 296 is(true)); 297 verify(intentSender, never()).sendIntent(any(), anyInt(), any(), any(), any()); 298 verify(mMetricsReporter, never()).reportRebootEscrowLskfCapturedMetrics( 299 anyInt(), anyInt(), anyInt()); 300 } 301 302 @Test requestLskf_lockSettingsError()303 public void requestLskf_lockSettingsError() throws Exception { 304 IntentSender intentSender = mock(IntentSender.class); 305 306 doReturn(false).when(mLockSettingsInternal).prepareRebootEscrow(); 307 assertFalse(mRecoverySystemService.requestLskf(FAKE_OTA_PACKAGE_NAME, intentSender)); 308 } 309 310 @Test isLskfCaptured_requestedButNotPrepared()311 public void isLskfCaptured_requestedButNotPrepared() throws Exception { 312 IntentSender intentSender = mock(IntentSender.class); 313 assertThat(mRecoverySystemService.requestLskf(FAKE_OTA_PACKAGE_NAME, intentSender), 314 is(true)); 315 assertThat(mRecoverySystemService.isLskfCaptured(FAKE_OTA_PACKAGE_NAME), is(false)); 316 } 317 318 @Test isLskfCaptured_Prepared()319 public void isLskfCaptured_Prepared() throws Exception { 320 IntentSender intentSender = mock(IntentSender.class); 321 assertThat(mRecoverySystemService.requestLskf(FAKE_OTA_PACKAGE_NAME, intentSender), 322 is(true)); 323 mRecoverySystemService.onPreparedForReboot(true); 324 verify(intentSender).sendIntent(any(), anyInt(), any(), any(), any()); 325 assertThat(mRecoverySystemService.isLskfCaptured(FAKE_OTA_PACKAGE_NAME), is(true)); 326 } 327 328 @Test(expected = SecurityException.class) clearLskf_protected()329 public void clearLskf_protected() { 330 when(mContext.checkCallingOrSelfPermission(anyString())).thenReturn( 331 PackageManager.PERMISSION_DENIED); 332 mRecoverySystemService.clearLskf(FAKE_OTA_PACKAGE_NAME); 333 } 334 335 @Test clearLskf_requestedThenCleared()336 public void clearLskf_requestedThenCleared() throws Exception { 337 IntentSender intentSender = mock(IntentSender.class); 338 assertThat(mRecoverySystemService.requestLskf(FAKE_OTA_PACKAGE_NAME, intentSender), 339 is(true)); 340 mRecoverySystemService.onPreparedForReboot(true); 341 verify(intentSender).sendIntent(any(), anyInt(), any(), any(), any()); 342 343 assertThat(mRecoverySystemService.clearLskf(FAKE_OTA_PACKAGE_NAME), is(true)); 344 verify(mLockSettingsInternal).clearRebootEscrow(); 345 } 346 347 @Test clearLskf_callerNotRequested_Success()348 public void clearLskf_callerNotRequested_Success() throws Exception { 349 IntentSender intentSender = mock(IntentSender.class); 350 assertThat(mRecoverySystemService.requestLskf(FAKE_OTA_PACKAGE_NAME, intentSender), 351 is(true)); 352 assertThat(mRecoverySystemService.clearLskf(FAKE_OTHER_PACKAGE_NAME), is(true)); 353 verify(mLockSettingsInternal, never()).clearRebootEscrow(); 354 } 355 356 @Test clearLskf_multiClient_BothClientsClear()357 public void clearLskf_multiClient_BothClientsClear() throws Exception { 358 IntentSender intentSender = mock(IntentSender.class); 359 assertThat(mRecoverySystemService.requestLskf(FAKE_OTA_PACKAGE_NAME, intentSender), 360 is(true)); 361 assertThat(mRecoverySystemService.requestLskf(FAKE_OTHER_PACKAGE_NAME, intentSender), 362 is(true)); 363 364 assertThat(mRecoverySystemService.clearLskf(FAKE_OTA_PACKAGE_NAME), is(true)); 365 verify(mLockSettingsInternal, never()).clearRebootEscrow(); 366 assertThat(mRecoverySystemService.clearLskf(FAKE_OTHER_PACKAGE_NAME), is(true)); 367 verify(mLockSettingsInternal).clearRebootEscrow(); 368 } 369 370 @Test startup_setRebootEscrowListener()371 public void startup_setRebootEscrowListener() throws Exception { 372 mRecoverySystemService.onSystemServicesReady(); 373 verify(mLockSettingsInternal).setRebootEscrowListener(any()); 374 } 375 376 @Test(expected = SecurityException.class) rebootWithLskf_protected()377 public void rebootWithLskf_protected() { 378 when(mContext.checkCallingOrSelfPermission(anyString())).thenReturn( 379 PackageManager.PERMISSION_DENIED); 380 mRecoverySystemService.rebootWithLskf(FAKE_OTA_PACKAGE_NAME, null, true); 381 } 382 383 @Test rebootWithLskf_Success()384 public void rebootWithLskf_Success() throws Exception { 385 assertThat(mRecoverySystemService.requestLskf(FAKE_OTA_PACKAGE_NAME, null), is(true)); 386 mRecoverySystemService.onPreparedForReboot(true); 387 388 when(mSharedPreferences.getInt(eq(FAKE_OTA_PACKAGE_NAME 389 + RecoverySystemService.REQUEST_LSKF_COUNT_PREF_SUFFIX), anyInt())).thenReturn(2); 390 when(mSharedPreferences.getInt(eq(RecoverySystemService.LSKF_CAPTURED_COUNT_PREF), 391 anyInt())).thenReturn(3); 392 when(mSharedPreferences.getLong(eq(RecoverySystemService.LSKF_CAPTURED_TIMESTAMP_PREF), 393 anyLong())).thenReturn(40_000L); 394 mRecoverySystemService.rebootWithLskf(FAKE_OTA_PACKAGE_NAME, "ab-update", true); 395 verify(mIPowerManager).reboot(anyBoolean(), eq("ab-update"), anyBoolean()); 396 verify(mMetricsReporter).reportRebootEscrowRebootMetrics(eq(0), eq(1000), 397 eq(1) /* client count */, eq(2) /* request count */, eq(true) /* slot switch */, 398 anyBoolean(), eq(60) /* duration */, eq(3) /* lskf capture count */); 399 } 400 401 402 @Test rebootWithLskf_slotMismatch_Failure()403 public void rebootWithLskf_slotMismatch_Failure() throws Exception { 404 assertThat(mRecoverySystemService.requestLskf(FAKE_OTA_PACKAGE_NAME, null), is(true)); 405 mRecoverySystemService.onPreparedForReboot(true); 406 assertEquals(RESUME_ON_REBOOT_REBOOT_ERROR_SLOT_MISMATCH, 407 mRecoverySystemService.rebootWithLskf(FAKE_OTA_PACKAGE_NAME, "ab-update", false)); 408 } 409 410 @Test rebootWithLskf_withoutPrepare_Failure()411 public void rebootWithLskf_withoutPrepare_Failure() throws Exception { 412 assertEquals(RESUME_ON_REBOOT_REBOOT_ERROR_LSKF_NOT_CAPTURED, 413 mRecoverySystemService.rebootWithLskf(FAKE_OTA_PACKAGE_NAME, null, true)); 414 } 415 416 @Test rebootWithLskf_withNullCallerId_Failure()417 public void rebootWithLskf_withNullCallerId_Failure() throws Exception { 418 assertEquals(RESUME_ON_REBOOT_REBOOT_ERROR_INVALID_PACKAGE_NAME, 419 mRecoverySystemService.rebootWithLskf(null, null, true)); 420 verifyNoMoreInteractions(mIPowerManager); 421 } 422 423 @Test rebootWithLskf_multiClient_ClientASuccess()424 public void rebootWithLskf_multiClient_ClientASuccess() throws Exception { 425 assertThat(mRecoverySystemService.requestLskf(FAKE_OTA_PACKAGE_NAME, null), is(true)); 426 assertThat(mRecoverySystemService.requestLskf(FAKE_OTHER_PACKAGE_NAME, null), is(true)); 427 mRecoverySystemService.onPreparedForReboot(true); 428 429 // Client B's clear won't affect client A's preparation. 430 assertThat(mRecoverySystemService.clearLskf(FAKE_OTHER_PACKAGE_NAME), is(true)); 431 mRecoverySystemService.rebootWithLskf(FAKE_OTA_PACKAGE_NAME, "ab-update", true); 432 verify(mIPowerManager).reboot(anyBoolean(), eq("ab-update"), anyBoolean()); 433 } 434 435 @Test rebootWithLskf_multiClient_success_reportMetrics()436 public void rebootWithLskf_multiClient_success_reportMetrics() throws Exception { 437 assertThat(mRecoverySystemService.requestLskf(FAKE_OTA_PACKAGE_NAME, null), is(true)); 438 assertThat(mRecoverySystemService.requestLskf(FAKE_OTHER_PACKAGE_NAME, null), is(true)); 439 mRecoverySystemService.onPreparedForReboot(true); 440 441 when(mSharedPreferences.getInt(eq(FAKE_OTA_PACKAGE_NAME 442 + RecoverySystemService.REQUEST_LSKF_COUNT_PREF_SUFFIX), anyInt())).thenReturn(2); 443 when(mSharedPreferences.getInt(eq(RecoverySystemService.LSKF_CAPTURED_COUNT_PREF), 444 anyInt())).thenReturn(1); 445 when(mSharedPreferences.getLong(eq(RecoverySystemService.LSKF_CAPTURED_TIMESTAMP_PREF), 446 anyLong())).thenReturn(60_000L); 447 448 mRecoverySystemService.rebootWithLskf(FAKE_OTA_PACKAGE_NAME, "ab-update", true); 449 verify(mIPowerManager).reboot(anyBoolean(), eq("ab-update"), anyBoolean()); 450 verify(mMetricsReporter).reportRebootEscrowRebootMetrics(eq(0), eq(1000), 451 eq(2) /* client count */, eq(2) /* request count */, eq(true) /* slot switch */, 452 anyBoolean(), eq(40), eq(1) /* lskf capture count */); 453 } 454 455 @Test rebootWithLskf_multiClient_ClientBSuccess()456 public void rebootWithLskf_multiClient_ClientBSuccess() throws Exception { 457 assertThat(mRecoverySystemService.requestLskf(FAKE_OTA_PACKAGE_NAME, null), is(true)); 458 mRecoverySystemService.onPreparedForReboot(true); 459 assertThat(mRecoverySystemService.requestLskf(FAKE_OTHER_PACKAGE_NAME, null), is(true)); 460 461 when(mSharedPreferences.getInt(eq(FAKE_OTHER_PACKAGE_NAME 462 + RecoverySystemService.REQUEST_LSKF_COUNT_PREF_SUFFIX), anyInt())).thenReturn(2); 463 when(mSharedPreferences.getInt(eq(RecoverySystemService.LSKF_CAPTURED_COUNT_PREF), 464 anyInt())).thenReturn(1); 465 when(mSharedPreferences.getLong(eq(RecoverySystemService.LSKF_CAPTURED_TIMESTAMP_PREF), 466 anyLong())).thenReturn(60_000L); 467 468 assertThat(mRecoverySystemService.clearLskf(FAKE_OTA_PACKAGE_NAME), is(true)); 469 assertEquals(RESUME_ON_REBOOT_REBOOT_ERROR_LSKF_NOT_CAPTURED, 470 mRecoverySystemService.rebootWithLskf(FAKE_OTA_PACKAGE_NAME, null, true)); 471 verifyNoMoreInteractions(mIPowerManager); 472 verify(mMetricsReporter).reportRebootEscrowRebootMetrics(not(eq(0)), eq(1000), 473 eq(1) /* client count */, anyInt() /* request count */, eq(true) /* slot switch */, 474 anyBoolean(), eq(40), eq(1)/* lskf capture count */); 475 476 assertThat(mRecoverySystemService.requestLskf(FAKE_OTHER_PACKAGE_NAME, null), is(true)); 477 mRecoverySystemService.rebootWithLskf(FAKE_OTHER_PACKAGE_NAME, "ab-update", true); 478 verify(mIPowerManager).reboot(anyBoolean(), eq("ab-update"), anyBoolean()); 479 480 verify(mMetricsReporter).reportRebootEscrowRebootMetrics((eq(0)), eq(2000), 481 eq(1) /* client count */, eq(2) /* request count */, eq(true) /* slot switch */, 482 anyBoolean(), eq(40), eq(1) /* lskf capture count */); 483 } 484 485 @Test rebootWithLskf_multiClient_BothClientsClear_Failure()486 public void rebootWithLskf_multiClient_BothClientsClear_Failure() throws Exception { 487 assertThat(mRecoverySystemService.requestLskf(FAKE_OTA_PACKAGE_NAME, null), is(true)); 488 mRecoverySystemService.onPreparedForReboot(true); 489 assertThat(mRecoverySystemService.requestLskf(FAKE_OTHER_PACKAGE_NAME, null), is(true)); 490 491 // Client A clears 492 assertThat(mRecoverySystemService.clearLskf(FAKE_OTA_PACKAGE_NAME), is(true)); 493 assertEquals(RESUME_ON_REBOOT_REBOOT_ERROR_LSKF_NOT_CAPTURED, 494 mRecoverySystemService.rebootWithLskf(FAKE_OTA_PACKAGE_NAME, null, true)); 495 verifyNoMoreInteractions(mIPowerManager); 496 497 // Client B clears 498 assertThat(mRecoverySystemService.clearLskf(FAKE_OTHER_PACKAGE_NAME), is(true)); 499 verify(mLockSettingsInternal).clearRebootEscrow(); 500 assertEquals(RESUME_ON_REBOOT_REBOOT_ERROR_LSKF_NOT_CAPTURED, 501 mRecoverySystemService.rebootWithLskf(FAKE_OTHER_PACKAGE_NAME, "ab-update", true)); 502 verifyNoMoreInteractions(mIPowerManager); 503 } 504 505 // TODO(xunchang) add more multi client tests 506 507 @Test rebootWithLskf_armEscrowDataFatalError_Failure()508 public void rebootWithLskf_armEscrowDataFatalError_Failure() throws Exception { 509 doReturn(LockSettingsInternal.ARM_REBOOT_ERROR_PROVIDER_MISMATCH) 510 .when(mLockSettingsInternal).armRebootEscrow(); 511 512 assertTrue(mRecoverySystemService.requestLskf(FAKE_OTA_PACKAGE_NAME, null)); 513 mRecoverySystemService.onPreparedForReboot(true); 514 assertTrue(mRecoverySystemService.isLskfCaptured(FAKE_OTA_PACKAGE_NAME)); 515 516 when(mSharedPreferences.getInt(eq(FAKE_OTA_PACKAGE_NAME 517 + RecoverySystemService.REQUEST_LSKF_COUNT_PREF_SUFFIX), anyInt())).thenReturn(1); 518 when(mSharedPreferences.getInt(eq(RecoverySystemService.LSKF_CAPTURED_COUNT_PREF), 519 anyInt())).thenReturn(1); 520 assertEquals(RESUME_ON_REBOOT_REBOOT_ERROR_PROVIDER_PREPARATION_FAILURE, 521 mRecoverySystemService.rebootWithLskf(FAKE_OTA_PACKAGE_NAME, "ab-update", true)); 522 // Verify that the RoR preparation state has been cleared. 523 assertFalse(mRecoverySystemService.isLskfCaptured(FAKE_OTA_PACKAGE_NAME)); 524 verify(mMetricsReporter).reportRebootEscrowRebootMetrics(eq(5004 /* provider mismatch */), 525 eq(1000), eq(1) /* client count */, eq(1) /* request count */, 526 eq(true) /* slot switch */, anyBoolean(), anyInt(), 527 eq(1) /* lskf capture count */); 528 } 529 } 530