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

Commit 3b757a29 authored by Tianjie Xu's avatar Tianjie Xu Committed by Automerger Merge Worker
Browse files

Merge "Report RoR metrics in recovery system" am: b079fe66 am: 7bbf62a9...

Merge "Report RoR metrics in recovery system" am: b079fe66 am: 7bbf62a9 am: 70c9ef04 am: 1358cb77

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

Change-Id: Iabc86ef48046b0a26bd3e39f7cb5119ab842e0e3
parents 1ca746f6 1358cb77
Loading
Loading
Loading
Loading
+113 −7
Original line number Original line Diff line number Diff line
@@ -16,6 +16,8 @@


package com.android.server.recoverysystem;
package com.android.server.recoverysystem;


import static android.os.UserHandle.USER_SYSTEM;

import android.annotation.IntDef;
import android.annotation.IntDef;
import android.content.Context;
import android.content.Context;
import android.content.IntentSender;
import android.content.IntentSender;
@@ -33,12 +35,14 @@ import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ResultReceiver;
import android.os.ShellCallback;
import android.os.ShellCallback;
import android.os.SystemProperties;
import android.os.SystemProperties;
import android.provider.DeviceConfig;
import android.util.ArrayMap;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.ArraySet;
import android.util.Slog;
import android.util.Slog;


import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.widget.LockSettingsInternal;
import com.android.internal.widget.LockSettingsInternal;
import com.android.internal.widget.RebootEscrowListener;
import com.android.internal.widget.RebootEscrowListener;
import com.android.server.LocalServices;
import com.android.server.LocalServices;
@@ -52,6 +56,8 @@ import java.io.FileDescriptor;
import java.io.FileWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;


/**
/**
 * The recovery system service is responsible for coordinating recovery related
 * The recovery system service is responsible for coordinating recovery related
@@ -132,6 +138,24 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo
            ROR_REQUESTED_SKIP_CLEAR})
            ROR_REQUESTED_SKIP_CLEAR})
    private @interface ResumeOnRebootActionsOnClear {}
    private @interface ResumeOnRebootActionsOnClear {}


    /**
     * The error code for reboots initiated by resume on reboot clients.
     */
    private static final int REBOOT_ERROR_NONE = 0;
    private static final int REBOOT_ERROR_UNKNOWN = 1;
    private static final int REBOOT_ERROR_INVALID_PACKAGE_NAME = 2;
    private static final int REBOOT_ERROR_LSKF_NOT_CAPTURED = 3;
    private static final int REBOOT_ERROR_SLOT_MISMATCH = 4;
    private static final int REBOOT_ERROR_ARM_REBOOT_ESCROW_FAILURE = 5;

    @IntDef({ REBOOT_ERROR_NONE,
            REBOOT_ERROR_UNKNOWN,
            REBOOT_ERROR_INVALID_PACKAGE_NAME,
            REBOOT_ERROR_LSKF_NOT_CAPTURED,
            REBOOT_ERROR_SLOT_MISMATCH,
            REBOOT_ERROR_ARM_REBOOT_ESCROW_FAILURE})
    private @interface ResumeOnRebootRebootErrorCode {}

    static class Injector {
    static class Injector {
        protected final Context mContext;
        protected final Context mContext;


@@ -202,6 +226,35 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo
        public void threadSleep(long millis) throws InterruptedException {
        public void threadSleep(long millis) throws InterruptedException {
            Thread.sleep(millis);
            Thread.sleep(millis);
        }
        }

        public int getUidFromPackageName(String packageName) {
            try {
                return mContext.getPackageManager().getPackageUidAsUser(packageName, USER_SYSTEM);
            } catch (PackageManager.NameNotFoundException e) {
                Slog.w(TAG, "Failed to find uid for " + packageName);
            }
            return -1;
        }

        public void reportRebootEscrowPreparationMetrics(int uid,
                @ResumeOnRebootActionsOnRequest int requestResult, int requestedClientCount) {
            FrameworkStatsLog.write(FrameworkStatsLog.REBOOT_ESCROW_PREPARATION_REPORTED, uid,
                    requestResult, requestedClientCount);
        }

        public void reportRebootEscrowLskfCapturedMetrics(int uid, int requestedClientCount,
                int requestedToLskfCapturedDurationInSeconds) {
            FrameworkStatsLog.write(FrameworkStatsLog.REBOOT_ESCROW_LSKF_CAPTURE_REPORTED, uid,
                    requestedClientCount, requestedToLskfCapturedDurationInSeconds);
        }

        public void reportRebootEscrowRebootMetrics(int errorCode, int uid,
                int preparedClientCount, int requestCount, boolean slotSwitch, boolean serverBased,
                int lskfCapturedToRebootDurationInSeconds, int lskfCapturedCounts) {
            FrameworkStatsLog.write(FrameworkStatsLog.REBOOT_ESCROW_REBOOT_REPORTED, errorCode,
                    uid, preparedClientCount, requestCount, slotSwitch, serverBased,
                    lskfCapturedToRebootDurationInSeconds, lskfCapturedCounts);
        }
    }
    }


    /**
    /**
@@ -367,6 +420,16 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo
        }
        }
    }
    }


    private void reportMetricsOnRequestLskf(String packageName, int requestResult) {
        int uid = mInjector.getUidFromPackageName(packageName);
        int pendingRequestCount;
        synchronized (this) {
            pendingRequestCount = mCallerPendingRequest.size();
        }

        mInjector.reportRebootEscrowPreparationMetrics(uid, requestResult, pendingRequestCount);
    }

    @Override // Binder call
    @Override // Binder call
    public boolean requestLskf(String packageName, IntentSender intentSender) {
    public boolean requestLskf(String packageName, IntentSender intentSender) {
        enforcePermissionForResumeOnReboot();
        enforcePermissionForResumeOnReboot();
@@ -378,6 +441,8 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo


        @ResumeOnRebootActionsOnRequest int action = updateRoRPreparationStateOnNewRequest(
        @ResumeOnRebootActionsOnRequest int action = updateRoRPreparationStateOnNewRequest(
                packageName, intentSender);
                packageName, intentSender);
        reportMetricsOnRequestLskf(packageName, action);

        switch (action) {
        switch (action) {
            case ROR_SKIP_PREPARATION_AND_NOTIFY:
            case ROR_SKIP_PREPARATION_AND_NOTIFY:
                // We consider the preparation done if someone else has prepared.
                // We consider the preparation done if someone else has prepared.
@@ -420,12 +485,26 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo
        return needPreparation ? ROR_NEED_PREPARATION : ROR_SKIP_PREPARATION_NOT_NOTIFY;
        return needPreparation ? ROR_NEED_PREPARATION : ROR_SKIP_PREPARATION_NOT_NOTIFY;
    }
    }


    private void reportMetricsOnPreparedForReboot() {
        List<String> preparedClients;
        synchronized (this) {
            preparedClients = new ArrayList<>(mCallerPreparedForReboot);
        }

        for (String packageName : preparedClients) {
            int uid = mInjector.getUidFromPackageName(packageName);
            mInjector.reportRebootEscrowLskfCapturedMetrics(uid, preparedClients.size(),
                    -1 /* duration */);
        }
    }

    @Override
    @Override
    public void onPreparedForReboot(boolean ready) {
    public void onPreparedForReboot(boolean ready) {
        if (!ready) {
        if (!ready) {
            return;
            return;
        }
        }
        updateRoRPreparationStateOnPreparedForReboot();
        updateRoRPreparationStateOnPreparedForReboot();
        reportMetricsOnPreparedForReboot();
    }
    }


    private synchronized void updateRoRPreparationStateOnPreparedForReboot() {
    private synchronized void updateRoRPreparationStateOnPreparedForReboot() {
@@ -548,22 +627,49 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo
        return true;
        return true;
    }
    }


    private boolean rebootWithLskfImpl(String packageName, String reason, boolean slotSwitch) {
    private @ResumeOnRebootRebootErrorCode int armRebootEscrow(String packageName,
            boolean slotSwitch) {
        if (packageName == null) {
        if (packageName == null) {
            Slog.w(TAG, "Missing packageName when rebooting with lskf.");
            Slog.w(TAG, "Missing packageName when rebooting with lskf.");
            return false;
            return REBOOT_ERROR_INVALID_PACKAGE_NAME;
        }
        }
        if (!isLskfCaptured(packageName)) {
        if (!isLskfCaptured(packageName)) {
            return false;
            return REBOOT_ERROR_LSKF_NOT_CAPTURED;
        }
        }


        if (!verifySlotForNextBoot(slotSwitch)) {
        if (!verifySlotForNextBoot(slotSwitch)) {
            return false;
            return REBOOT_ERROR_SLOT_MISMATCH;
        }
        }


        // TODO(xunchang) write the vbmeta digest along with the escrowKey before reboot.
        if (!mInjector.getLockSettingsService().armRebootEscrow()) {
        if (!mInjector.getLockSettingsService().armRebootEscrow()) {
            Slog.w(TAG, "Failure to escrow key for reboot");
            Slog.w(TAG, "Failure to escrow key for reboot");
            return REBOOT_ERROR_ARM_REBOOT_ESCROW_FAILURE;
        }

        return REBOOT_ERROR_NONE;
    }

    private void reportMetricsOnRebootWithLskf(String packageName, boolean slotSwitch,
            @ResumeOnRebootRebootErrorCode int errorCode) {
        int uid = mInjector.getUidFromPackageName(packageName);
        boolean serverBased = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_OTA,
                "server_based_ror_enabled", false);
        int preparedClientCount;
        synchronized (this) {
            preparedClientCount = mCallerPreparedForReboot.size();
        }

        // TODO(b/179105110) report the true value of duration and counts
        mInjector.reportRebootEscrowRebootMetrics(errorCode, uid, preparedClientCount,
                1 /* request count */, slotSwitch, serverBased,
                -1 /* duration */, 1 /* lskf capture count */);
    }

    private boolean rebootWithLskfImpl(String packageName, String reason, boolean slotSwitch) {
        @ResumeOnRebootRebootErrorCode int errorCode = armRebootEscrow(packageName, slotSwitch);
        reportMetricsOnRebootWithLskf(packageName, slotSwitch, errorCode);

        if (errorCode != REBOOT_ERROR_NONE) {
            return false;
            return false;
        }
        }


+42 −1
Original line number Original line Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.server.recoverysystem;


import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertThat;
import static org.mockito.AdditionalMatchers.not;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -70,6 +71,7 @@ public class RecoverySystemServiceTest {
    private FileWriter mUncryptUpdateFileWriter;
    private FileWriter mUncryptUpdateFileWriter;
    private LockSettingsInternal mLockSettingsInternal;
    private LockSettingsInternal mLockSettingsInternal;
    private IBootControl mIBootControl;
    private IBootControl mIBootControl;
    private RecoverySystemServiceTestable.IMetricsReporter mMetricsReporter;


    private static final String FAKE_OTA_PACKAGE_NAME = "fake.ota.package";
    private static final String FAKE_OTA_PACKAGE_NAME = "fake.ota.package";
    private static final String FAKE_OTHER_PACKAGE_NAME = "fake.other.package";
    private static final String FAKE_OTHER_PACKAGE_NAME = "fake.other.package";
@@ -94,9 +96,11 @@ public class RecoverySystemServiceTest {
        when(mIBootControl.getCurrentSlot()).thenReturn(0);
        when(mIBootControl.getCurrentSlot()).thenReturn(0);
        when(mIBootControl.getActiveBootSlot()).thenReturn(1);
        when(mIBootControl.getActiveBootSlot()).thenReturn(1);


        mMetricsReporter = mock(RecoverySystemServiceTestable.IMetricsReporter.class);

        mRecoverySystemService = new RecoverySystemServiceTestable(mContext, mSystemProperties,
        mRecoverySystemService = new RecoverySystemServiceTestable(mContext, mSystemProperties,
                powerManager, mUncryptUpdateFileWriter, mUncryptSocket, mLockSettingsInternal,
                powerManager, mUncryptUpdateFileWriter, mUncryptSocket, mLockSettingsInternal,
                mIBootControl);
                mIBootControl, mMetricsReporter);
    }
    }


    @Test
    @Test
@@ -226,6 +230,16 @@ public class RecoverySystemServiceTest {
        mRecoverySystemService.requestLskf(FAKE_OTA_PACKAGE_NAME, null);
        mRecoverySystemService.requestLskf(FAKE_OTA_PACKAGE_NAME, null);
    }
    }


    @Test
    public void requestLskf_reportMetrics() throws Exception {
        IntentSender intentSender = mock(IntentSender.class);
        assertThat(mRecoverySystemService.requestLskf(FAKE_OTA_PACKAGE_NAME, intentSender),
                is(true));
        verify(mMetricsReporter).reportRebootEscrowPreparationMetrics(
                eq(1000), eq(0) /* need preparation */, eq(1) /* client count */);
    }


    @Test
    @Test
    public void requestLskf_success() throws Exception {
    public void requestLskf_success() throws Exception {
        IntentSender intentSender = mock(IntentSender.class);
        IntentSender intentSender = mock(IntentSender.class);
@@ -233,6 +247,8 @@ public class RecoverySystemServiceTest {
                is(true));
                is(true));
        mRecoverySystemService.onPreparedForReboot(true);
        mRecoverySystemService.onPreparedForReboot(true);
        verify(intentSender).sendIntent(any(), anyInt(), any(), any(), any());
        verify(intentSender).sendIntent(any(), anyInt(), any(), any(), any());
        verify(mMetricsReporter).reportRebootEscrowLskfCapturedMetrics(
                eq(1000), eq(1) /* client count */, anyInt() /* duration */);
    }
    }


    @Test
    @Test
@@ -255,6 +271,8 @@ public class RecoverySystemServiceTest {
        assertThat(mRecoverySystemService.requestLskf(FAKE_OTA_PACKAGE_NAME, intentSender),
        assertThat(mRecoverySystemService.requestLskf(FAKE_OTA_PACKAGE_NAME, intentSender),
                is(true));
                is(true));
        verify(intentSender, never()).sendIntent(any(), anyInt(), any(), any(), any());
        verify(intentSender, never()).sendIntent(any(), anyInt(), any(), any(), any());
        verify(mMetricsReporter, never()).reportRebootEscrowLskfCapturedMetrics(
                anyInt(), anyInt(), anyInt());
    }
    }


    @Test
    @Test
@@ -337,6 +355,9 @@ public class RecoverySystemServiceTest {
        assertThat(mRecoverySystemService.rebootWithLskf(FAKE_OTA_PACKAGE_NAME, "ab-update", true),
        assertThat(mRecoverySystemService.rebootWithLskf(FAKE_OTA_PACKAGE_NAME, "ab-update", true),
                is(true));
                is(true));
        verify(mIPowerManager).reboot(anyBoolean(), eq("ab-update"), anyBoolean());
        verify(mIPowerManager).reboot(anyBoolean(), eq("ab-update"), anyBoolean());
        verify(mMetricsReporter).reportRebootEscrowRebootMetrics(eq(0), eq(1000),
                eq(1) /* client count */, eq(1) /* request count */, eq(true) /* slot switch */,
                anyBoolean(), anyInt(), eq(1) /* lskf capture count */);
    }
    }




@@ -373,6 +394,20 @@ public class RecoverySystemServiceTest {
        verify(mIPowerManager).reboot(anyBoolean(), eq("ab-update"), anyBoolean());
        verify(mIPowerManager).reboot(anyBoolean(), eq("ab-update"), anyBoolean());
    }
    }


    @Test
    public void rebootWithLskf_multiClient_success_reportMetrics() throws Exception {
        assertThat(mRecoverySystemService.requestLskf(FAKE_OTA_PACKAGE_NAME, null), is(true));
        assertThat(mRecoverySystemService.requestLskf(FAKE_OTHER_PACKAGE_NAME, null), is(true));
        mRecoverySystemService.onPreparedForReboot(true);

        // Client B's clear won't affect client A's preparation.
        assertThat(mRecoverySystemService.rebootWithLskf(FAKE_OTA_PACKAGE_NAME, "ab-update", true),
                is(true));
        verify(mIPowerManager).reboot(anyBoolean(), eq("ab-update"), anyBoolean());
        verify(mMetricsReporter).reportRebootEscrowRebootMetrics(eq(0), eq(1000),
                eq(2) /* client count */, eq(1) /* request count */, eq(true) /* slot switch */,
                anyBoolean(), anyInt(), eq(1) /* lskf capture count */);
    }


    @Test
    @Test
    public void rebootWithLskf_multiClient_ClientBSuccess() throws Exception {
    public void rebootWithLskf_multiClient_ClientBSuccess() throws Exception {
@@ -384,12 +419,18 @@ public class RecoverySystemServiceTest {
        assertThat(mRecoverySystemService.rebootWithLskf(FAKE_OTA_PACKAGE_NAME, null, true),
        assertThat(mRecoverySystemService.rebootWithLskf(FAKE_OTA_PACKAGE_NAME, null, true),
                is(false));
                is(false));
        verifyNoMoreInteractions(mIPowerManager);
        verifyNoMoreInteractions(mIPowerManager);
        verify(mMetricsReporter).reportRebootEscrowRebootMetrics(not(eq(0)), eq(1000),
                eq(1) /* client count */, eq(1) /* request count */, eq(true) /* slot switch */,
                anyBoolean(), anyInt(), eq(1) /* lskf capture count */);


        assertThat(mRecoverySystemService.requestLskf(FAKE_OTHER_PACKAGE_NAME, null), is(true));
        assertThat(mRecoverySystemService.requestLskf(FAKE_OTHER_PACKAGE_NAME, null), is(true));
        assertThat(
        assertThat(
                mRecoverySystemService.rebootWithLskf(FAKE_OTHER_PACKAGE_NAME, "ab-update", true),
                mRecoverySystemService.rebootWithLskf(FAKE_OTHER_PACKAGE_NAME, "ab-update", true),
                is(true));
                is(true));
        verify(mIPowerManager).reboot(anyBoolean(), eq("ab-update"), anyBoolean());
        verify(mIPowerManager).reboot(anyBoolean(), eq("ab-update"), anyBoolean());
        verify(mMetricsReporter).reportRebootEscrowRebootMetrics(eq(0), eq(2000),
                eq(1) /* client count */, eq(1) /* request count */, eq(true) /* slot switch */,
                anyBoolean(), anyInt(), eq(1) /* lskf capture count */);
    }
    }


    @Test
    @Test
+49 −3
Original line number Original line Diff line number Diff line
@@ -32,11 +32,12 @@ public class RecoverySystemServiceTestable extends RecoverySystemService {
        private final UncryptSocket mUncryptSocket;
        private final UncryptSocket mUncryptSocket;
        private final LockSettingsInternal mLockSettingsInternal;
        private final LockSettingsInternal mLockSettingsInternal;
        private final IBootControl mIBootControl;
        private final IBootControl mIBootControl;
        private final IMetricsReporter mIMetricsReporter;


        MockInjector(Context context, FakeSystemProperties systemProperties,
        MockInjector(Context context, FakeSystemProperties systemProperties,
                PowerManager powerManager, FileWriter uncryptPackageFileWriter,
                PowerManager powerManager, FileWriter uncryptPackageFileWriter,
                UncryptSocket uncryptSocket, LockSettingsInternal lockSettingsInternal,
                UncryptSocket uncryptSocket, LockSettingsInternal lockSettingsInternal,
                IBootControl bootControl) {
                IBootControl bootControl, IMetricsReporter metricsReporter) {
            super(context);
            super(context);
            mSystemProperties = systemProperties;
            mSystemProperties = systemProperties;
            mPowerManager = powerManager;
            mPowerManager = powerManager;
@@ -44,6 +45,7 @@ public class RecoverySystemServiceTestable extends RecoverySystemService {
            mUncryptSocket = uncryptSocket;
            mUncryptSocket = uncryptSocket;
            mLockSettingsInternal = lockSettingsInternal;
            mLockSettingsInternal = lockSettingsInternal;
            mIBootControl = bootControl;
            mIBootControl = bootControl;
            mIMetricsReporter = metricsReporter;
        }
        }


        @Override
        @Override
@@ -94,14 +96,45 @@ public class RecoverySystemServiceTestable extends RecoverySystemService {
        public IBootControl getBootControl() {
        public IBootControl getBootControl() {
            return mIBootControl;
            return mIBootControl;
        }
        }
        @Override
        public int getUidFromPackageName(String packageName) {
            if ("fake.ota.package".equals(packageName)) {
                return 1000;
            }
            if ("fake.other.package".equals(packageName)) {
                return 2000;
            }
            return 3000;
        }

        @Override
        public void reportRebootEscrowPreparationMetrics(int uid, int requestResult,
                int requestedClientCount) {
            mIMetricsReporter.reportRebootEscrowPreparationMetrics(uid, requestResult,
                    requestedClientCount);
        }

        public void reportRebootEscrowLskfCapturedMetrics(int uid, int requestedClientCount,
                int requestedToLskfCapturedDurationInSeconds) {
            mIMetricsReporter.reportRebootEscrowLskfCapturedMetrics(uid, requestedClientCount,
                    requestedToLskfCapturedDurationInSeconds);
        }

        public void reportRebootEscrowRebootMetrics(int errorCode, int uid, int preparedClientCount,
                int requestCount, boolean slotSwitch, boolean serverBased,
                int lskfCapturedToRebootDurationInSeconds, int lskfCapturedCounts) {
            mIMetricsReporter.reportRebootEscrowRebootMetrics(errorCode, uid, preparedClientCount,
                    requestCount, slotSwitch, serverBased, lskfCapturedToRebootDurationInSeconds,
                    lskfCapturedCounts);
        }
    }
    }


    RecoverySystemServiceTestable(Context context, FakeSystemProperties systemProperties,
    RecoverySystemServiceTestable(Context context, FakeSystemProperties systemProperties,
            PowerManager powerManager, FileWriter uncryptPackageFileWriter,
            PowerManager powerManager, FileWriter uncryptPackageFileWriter,
            UncryptSocket uncryptSocket, LockSettingsInternal lockSettingsInternal,
            UncryptSocket uncryptSocket, LockSettingsInternal lockSettingsInternal,
            IBootControl bootControl) {
            IBootControl bootControl, IMetricsReporter metricsReporter) {
        super(new MockInjector(context, systemProperties, powerManager, uncryptPackageFileWriter,
        super(new MockInjector(context, systemProperties, powerManager, uncryptPackageFileWriter,
                uncryptSocket, lockSettingsInternal, bootControl));
                uncryptSocket, lockSettingsInternal, bootControl, metricsReporter));
    }
    }


    public static class FakeSystemProperties {
    public static class FakeSystemProperties {
@@ -131,4 +164,17 @@ public class RecoverySystemServiceTestable extends RecoverySystemService {
            return mCtlStart;
            return mCtlStart;
        }
        }
    }
    }

    public interface IMetricsReporter {
        void reportRebootEscrowPreparationMetrics(int uid, int requestResult,
                int requestedClientCount);

        void reportRebootEscrowLskfCapturedMetrics(int uid, int requestedClientCount,
                int requestedToLskfCapturedDurationInSeconds);

        void reportRebootEscrowRebootMetrics(int errorCode, int uid, int preparedClientCount,
                int requestCount, boolean slotSwitch, boolean serverBased,
                int lskfCapturedToRebootDurationInSeconds, int lskfCapturedCounts);
    }

}
}