RebootEscrowManager: always report success metric

In the process of OTAing from a build that does not have the armed
status marker, all metrics are going to be lost. Since a success is
a sure indication that reboot escrow was prepared before reboot, then
we should mark it as a success always.

On the other side, a failure could be a manual reboot if we did not
have the armed marker.

(cherry picked from commit bdb3cdc497)

Bug: 149833390
Test: atest RebootEscrowManagerTests
Merged-In: Iaa179039eb7f587a6596a70176d42761e09b0fac
Change-Id: Iaa179039eb7f587a6596a70176d42761e09b0fac
This commit is contained in:
Kenny Root
2020-03-03 11:00:24 -08:00
parent e2ab8ed00e
commit 1eb8ead904
2 changed files with 64 additions and 8 deletions

View File

@@ -181,15 +181,13 @@ class RebootEscrowManager {
}
private void onEscrowRestoreComplete(boolean success) {
int previousBootCount = mStorage.getInt(REBOOT_ESCROW_ARMED_KEY, 0, USER_SYSTEM);
int previousBootCount = mStorage.getInt(REBOOT_ESCROW_ARMED_KEY, -1, USER_SYSTEM);
mStorage.removeKey(REBOOT_ESCROW_ARMED_KEY, USER_SYSTEM);
int bootCountDelta = mInjector.getBootCount() - previousBootCount;
if (bootCountDelta > BOOT_COUNT_TOLERANCE) {
return;
if (success || (previousBootCount != -1 && bootCountDelta <= BOOT_COUNT_TOLERANCE)) {
mInjector.reportMetric(success);
}
mInjector.reportMetric(success);
}
private RebootEscrowKey getAndClearRebootEscrowKey() {

View File

@@ -293,9 +293,8 @@ public class RebootEscrowManagerTests {
verify(mRebootEscrow, never()).storeKey(any());
ArgumentCaptor<byte[]> keyByteCaptor = ArgumentCaptor.forClass(byte[].class);
assertTrue(mService.armRebootEscrowIfNeeded());
verify(mRebootEscrow).storeKey(keyByteCaptor.capture());
verify(mRebootEscrow).storeKey(any());
assertTrue(mStorage.hasRebootEscrow(PRIMARY_USER_ID));
assertFalse(mStorage.hasRebootEscrow(NONSECURE_SECONDARY_USER_ID));
@@ -303,13 +302,72 @@ public class RebootEscrowManagerTests {
// pretend reboot happens here
when(mInjected.getBootCount()).thenReturn(10);
when(mRebootEscrow.retrieveKey()).thenAnswer(invocation -> keyByteCaptor.getValue());
when(mRebootEscrow.retrieveKey()).thenReturn(new byte[32]);
mService.loadRebootEscrowDataIfAvailable();
verify(mRebootEscrow).retrieveKey();
verify(mInjected, never()).reportMetric(anyBoolean());
}
@Test
public void loadRebootEscrowDataIfAvailable_ManualReboot_Failure_NoMetrics() throws Exception {
when(mInjected.getBootCount()).thenReturn(0);
RebootEscrowListener mockListener = mock(RebootEscrowListener.class);
mService.setRebootEscrowListener(mockListener);
mService.prepareRebootEscrow();
clearInvocations(mRebootEscrow);
mService.callToRebootEscrowIfNeeded(PRIMARY_USER_ID, FAKE_SP_VERSION, FAKE_AUTH_TOKEN);
verify(mockListener).onPreparedForReboot(eq(true));
verify(mRebootEscrow, never()).storeKey(any());
assertTrue(mStorage.hasRebootEscrow(PRIMARY_USER_ID));
assertFalse(mStorage.hasRebootEscrow(NONSECURE_SECONDARY_USER_ID));
// pretend reboot happens here
when(mInjected.getBootCount()).thenReturn(10);
when(mRebootEscrow.retrieveKey()).thenReturn(new byte[32]);
mService.loadRebootEscrowDataIfAvailable();
verify(mInjected, never()).reportMetric(anyBoolean());
}
@Test
public void loadRebootEscrowDataIfAvailable_OTAFromBeforeArmedStatus_SuccessMetrics()
throws Exception {
when(mInjected.getBootCount()).thenReturn(0);
RebootEscrowListener mockListener = mock(RebootEscrowListener.class);
mService.setRebootEscrowListener(mockListener);
mService.prepareRebootEscrow();
clearInvocations(mRebootEscrow);
mService.callToRebootEscrowIfNeeded(PRIMARY_USER_ID, FAKE_SP_VERSION, FAKE_AUTH_TOKEN);
verify(mockListener).onPreparedForReboot(eq(true));
verify(mRebootEscrow, never()).storeKey(any());
ArgumentCaptor<byte[]> keyByteCaptor = ArgumentCaptor.forClass(byte[].class);
assertTrue(mService.armRebootEscrowIfNeeded());
verify(mRebootEscrow).storeKey(keyByteCaptor.capture());
assertTrue(mStorage.hasRebootEscrow(PRIMARY_USER_ID));
assertFalse(mStorage.hasRebootEscrow(NONSECURE_SECONDARY_USER_ID));
// Delete key to simulate old version that didn't have it.
mStorage.removeKey(RebootEscrowManager.REBOOT_ESCROW_ARMED_KEY, USER_SYSTEM);
// pretend reboot happens here
when(mInjected.getBootCount()).thenReturn(10);
when(mRebootEscrow.retrieveKey()).thenAnswer(invocation -> keyByteCaptor.getValue());
mService.loadRebootEscrowDataIfAvailable();
verify(mInjected).reportMetric(eq(true));
}
@Test
public void loadRebootEscrowDataIfAvailable_RestoreUnsuccessful_Failure() throws Exception {