Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6a725edd authored by Tianjie Xu's avatar Tianjie Xu Committed by Automerger Merge Worker
Browse files

Merge "Add a unittest to cover the retry of load escrow data" am: b13ad077 am: dc579c19

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1614001

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: Ic070c015b8213e4a134908edfc7f3e77a435955b
parents 5915aad5 dc579c19
Loading
Loading
Loading
Loading
+13 −5
Original line number Diff line number Diff line
@@ -193,6 +193,17 @@ class RebootEscrowManager {
                    0);
        }

        public int getLoadEscrowDataRetryLimit() {
            return DeviceConfig.getInt(DeviceConfig.NAMESPACE_OTA,
                    "load_escrow_data_retry_count", DEFAULT_LOAD_ESCROW_DATA_RETRY_COUNT);
        }

        public int getLoadEscrowDataRetryIntervalSeconds() {
            return DeviceConfig.getInt(DeviceConfig.NAMESPACE_OTA,
                    "load_escrow_data_retry_interval_seconds",
                    DEFAULT_LOAD_ESCROW_DATA_RETRY_INTERVAL_SECONDS);
        }

        public void reportMetric(boolean success) {
            // TODO(b/179105110) design error code; and report the true value for other fields.
            FrameworkStatsLog.write(FrameworkStatsLog.REBOOT_ESCROW_RECOVERY_REPORTED, 0, 1, 1,
@@ -251,11 +262,8 @@ class RebootEscrowManager {
            List<UserInfo> users, List<UserInfo> rebootEscrowUsers) {
        Objects.requireNonNull(retryHandler);

        final int retryLimit = DeviceConfig.getInt(DeviceConfig.NAMESPACE_OTA,
                "load_escrow_data_retry_count", DEFAULT_LOAD_ESCROW_DATA_RETRY_COUNT);
        final int retryIntervalInSeconds = DeviceConfig.getInt(DeviceConfig.NAMESPACE_OTA,
                "load_escrow_data_retry_interval_seconds",
                DEFAULT_LOAD_ESCROW_DATA_RETRY_INTERVAL_SECONDS);
        final int retryLimit = mInjector.getLoadEscrowDataRetryLimit();
        final int retryIntervalInSeconds = mInjector.getLoadEscrowDataRetryIntervalSeconds();

        if (attemptNumber < retryLimit) {
            Slog.i(TAG, "Scheduling loadRebootEscrowData retry number: " + attemptNumber);
+54 −0
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ import android.content.ContextWrapper;
import android.content.pm.UserInfo;
import android.hardware.rebootescrow.IRebootEscrow;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
import android.os.UserManager;
@@ -62,6 +63,7 @@ import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import javax.crypto.SecretKey;
@@ -180,6 +182,18 @@ public class RebootEscrowManagerTests {
            return mInjected.getBootCount();
        }

        @Override
        public int getLoadEscrowDataRetryLimit() {
            // Try two times
            return 2;
        }

        @Override
        public int getLoadEscrowDataRetryIntervalSeconds() {
            // Retry in 1 seconds
            return 1;
        }

        @Override
        public void reportMetric(boolean success) {
            mInjected.reportMetric(success);
@@ -447,6 +461,46 @@ public class RebootEscrowManagerTests {
        verify(mKeyStoreManager).clearKeyStoreEncryptionKey();
    }

    @Test
    public void loadRebootEscrowDataIfAvailable_ServerBased_RetrySuccess() throws Exception {
        setServerBasedRebootEscrowProvider();

        when(mInjected.getBootCount()).thenReturn(0);
        RebootEscrowListener mockListener = mock(RebootEscrowListener.class);
        mService.setRebootEscrowListener(mockListener);
        mService.prepareRebootEscrow();

        clearInvocations(mServiceConnection);
        mService.callToRebootEscrowIfNeeded(PRIMARY_USER_ID, FAKE_SP_VERSION, FAKE_AUTH_TOKEN);
        verify(mockListener).onPreparedForReboot(eq(true));
        verify(mServiceConnection, never()).wrapBlob(any(), anyLong(), anyLong());

        // Use x -> x for both wrap & unwrap functions.
        when(mServiceConnection.wrapBlob(any(), anyLong(), anyLong()))
                .thenAnswer(invocation -> invocation.getArgument(0));
        assertTrue(mService.armRebootEscrowIfNeeded());
        verify(mServiceConnection).wrapBlob(any(), anyLong(), anyLong());
        assertTrue(mStorage.hasRebootEscrowServerBlob());

        // pretend reboot happens here
        when(mInjected.getBootCount()).thenReturn(1);
        ArgumentCaptor<Boolean> metricsSuccessCaptor = ArgumentCaptor.forClass(Boolean.class);
        doNothing().when(mInjected).reportMetric(metricsSuccessCaptor.capture());

        when(mServiceConnection.unwrap(any(), anyLong()))
                .thenThrow(new IOException())
                .thenAnswer(invocation -> invocation.getArgument(0));

        HandlerThread thread = new HandlerThread("RebootEscrowManagerTest");
        thread.start();
        mService.loadRebootEscrowDataIfAvailable(new Handler(thread.getLooper()));
        // Sleep 5s for the retry to complete
        Thread.sleep(5 * 1000);
        verify(mServiceConnection, times(2)).unwrap(any(), anyLong());
        assertTrue(metricsSuccessCaptor.getValue());
        verify(mKeyStoreManager).clearKeyStoreEncryptionKey();
    }

    @Test
    public void loadRebootEscrowDataIfAvailable_TooManyBootsInBetween_NoMetrics() throws Exception {
        when(mInjected.getBootCount()).thenReturn(0);