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

Commit ee150671 authored by Neil Fuller's avatar Neil Fuller Committed by Gerrit Code Review
Browse files

Merge "Update RulesManagerService after APEX files"

parents e8eb9673 a1ae0251
Loading
Loading
Loading
Loading
+17 −17
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@ import java.lang.annotation.RetentionPolicy;
 *
 * <p>The following properties are included:
 * <dl>
 *     <dt>systemRulesVersion</dt>
 *     <dt>baseRulesVersion</dt>
 *     <dd>the IANA rules version that shipped with the OS. Always present. e.g. "2017a".</dd>
 *     <dt>distroFormatVersionSupported</dt>
 *     <dd>the distro format version supported by this device. Always present.</dd>
@@ -98,7 +98,7 @@ public final class RulesState implements Parcelable {
    private static final byte BYTE_FALSE = 0;
    private static final byte BYTE_TRUE = 1;

    private final String mSystemRulesVersion;
    private final String mBaseRulesVersion;
    private final DistroFormatVersion mDistroFormatVersionSupported;
    private final boolean mOperationInProgress;
    @StagedOperationType private final int mStagedOperationType;
@@ -106,13 +106,13 @@ public final class RulesState implements Parcelable {
    @DistroStatus private final int mDistroStatus;
    @Nullable private final DistroRulesVersion mInstalledDistroRulesVersion;

    public RulesState(String systemRulesVersion, DistroFormatVersion distroFormatVersionSupported,
    public RulesState(String baseRulesVersion, DistroFormatVersion distroFormatVersionSupported,
            boolean operationInProgress,
            @StagedOperationType int stagedOperationType,
            @Nullable DistroRulesVersion stagedDistroRulesVersion,
            @DistroStatus int distroStatus,
            @Nullable DistroRulesVersion installedDistroRulesVersion) {
        this.mSystemRulesVersion = validateRulesVersion("systemRulesVersion", systemRulesVersion);
        this.mBaseRulesVersion = validateRulesVersion("baseRulesVersion", baseRulesVersion);
        this.mDistroFormatVersionSupported =
                validateNotNull("distroFormatVersionSupported", distroFormatVersionSupported);
        this.mOperationInProgress = operationInProgress;
@@ -132,8 +132,8 @@ public final class RulesState implements Parcelable {
                "installedDistroRulesVersion", installedDistroRulesVersion);
    }

    public String getSystemRulesVersion() {
        return mSystemRulesVersion;
    public String getBaseRulesVersion() {
        return mBaseRulesVersion;
    }

    public boolean isOperationInProgress() {
@@ -172,14 +172,14 @@ public final class RulesState implements Parcelable {
    }

    /**
     * Returns true if the system image data files contain IANA rules data that are newer than the
     * Returns true if the base data files contain IANA rules data that are newer than the
     * distro IANA rules version supplied, i.e. true when the version specified would be "worse"
     * than the one that is in the system image. Returns false if the system image version is the
     * than the one that is in the base data. Returns false if the base version is the
     * same or older, i.e. false when the version specified would be "better" than the one that is
     * in the system image.
     * in the base set.
     */
    public boolean isSystemVersionNewerThan(DistroRulesVersion distroRulesVersion) {
        return mSystemRulesVersion.compareTo(distroRulesVersion.getRulesVersion()) > 0;
    public boolean isBaseVersionNewerThan(DistroRulesVersion distroRulesVersion) {
        return mBaseRulesVersion.compareTo(distroRulesVersion.getRulesVersion()) > 0;
    }

    public static final Parcelable.Creator<RulesState> CREATOR =
@@ -194,14 +194,14 @@ public final class RulesState implements Parcelable {
    };

    private static RulesState createFromParcel(Parcel in) {
        String systemRulesVersion = in.readString();
        String baseRulesVersion = in.readString();
        DistroFormatVersion distroFormatVersionSupported = in.readParcelable(null);
        boolean operationInProgress = in.readByte() == BYTE_TRUE;
        int distroStagedState = in.readByte();
        DistroRulesVersion stagedDistroRulesVersion = in.readParcelable(null);
        int installedDistroStatus = in.readByte();
        DistroRulesVersion installedDistroRulesVersion = in.readParcelable(null);
        return new RulesState(systemRulesVersion, distroFormatVersionSupported, operationInProgress,
        return new RulesState(baseRulesVersion, distroFormatVersionSupported, operationInProgress,
                distroStagedState, stagedDistroRulesVersion,
                installedDistroStatus, installedDistroRulesVersion);
    }
@@ -213,7 +213,7 @@ public final class RulesState implements Parcelable {

    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeString(mSystemRulesVersion);
        out.writeString(mBaseRulesVersion);
        out.writeParcelable(mDistroFormatVersionSupported, 0);
        out.writeByte(mOperationInProgress ? BYTE_TRUE : BYTE_FALSE);
        out.writeByte((byte) mStagedOperationType);
@@ -242,7 +242,7 @@ public final class RulesState implements Parcelable {
        if (mDistroStatus != that.mDistroStatus) {
            return false;
        }
        if (!mSystemRulesVersion.equals(that.mSystemRulesVersion)) {
        if (!mBaseRulesVersion.equals(that.mBaseRulesVersion)) {
            return false;
        }
        if (!mDistroFormatVersionSupported.equals(that.mDistroFormatVersionSupported)) {
@@ -259,7 +259,7 @@ public final class RulesState implements Parcelable {

    @Override
    public int hashCode() {
        int result = mSystemRulesVersion.hashCode();
        int result = mBaseRulesVersion.hashCode();
        result = 31 * result + mDistroFormatVersionSupported.hashCode();
        result = 31 * result + (mOperationInProgress ? 1 : 0);
        result = 31 * result + mStagedOperationType;
@@ -275,7 +275,7 @@ public final class RulesState implements Parcelable {
    @Override
    public String toString() {
        return "RulesState{"
                + "mSystemRulesVersion='" + mSystemRulesVersion + '\''
                + "mBaseRulesVersion='" + mBaseRulesVersion + '\''
                + ", mDistroFormatVersionSupported=" + mDistroFormatVersionSupported
                + ", mOperationInProgress=" + mOperationInProgress
                + ", mStagedOperationType=" + mStagedOperationType
+6 −8
Original line number Diff line number Diff line
@@ -16,8 +16,6 @@

package android.app.timezone;

import static junit.framework.Assert.fail;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -47,11 +45,11 @@ public class RulesStateTest {
                RulesState.DISTRO_STATUS_INSTALLED, rulesVersion("2016b", 2));
        assertEqualsContract(one, two);

        RulesState differentSystemRules = new RulesState(
        RulesState differentBaseRules = new RulesState(
                "2016b", formatVersion(1, 2), false /* operationInProgress */,
                RulesState.STAGED_OPERATION_INSTALL, rulesVersion("2016a", 3),
                RulesState.DISTRO_STATUS_INSTALLED, rulesVersion("2016b", 2));
        assertFalse(one.equals(differentSystemRules));
        assertFalse(one.equals(differentBaseRules));

        RulesState differentFormatVersion = new RulesState(
                "2016a", formatVersion(1, 1), false /* operationInProgress */,
@@ -122,14 +120,14 @@ public class RulesStateTest {
    }

    @Test
    public void isSystemVersionNewerThan() {
    public void isBaseVersionNewerThan() {
        RulesState rulesState = new RulesState(
                "2016b", formatVersion(1, 1), false /* operationInProgress */,
                RulesState.STAGED_OPERATION_NONE, null /* stagedDistroRulesVersion */,
                RulesState.DISTRO_STATUS_INSTALLED, rulesVersion("2016b", 3));
        assertTrue(rulesState.isSystemVersionNewerThan(rulesVersion("2016a", 1)));
        assertFalse(rulesState.isSystemVersionNewerThan(rulesVersion("2016b", 1)));
        assertFalse(rulesState.isSystemVersionNewerThan(rulesVersion("2016c", 1)));
        assertTrue(rulesState.isBaseVersionNewerThan(rulesVersion("2016a", 1)));
        assertFalse(rulesState.isBaseVersionNewerThan(rulesVersion("2016b", 1)));
        assertFalse(rulesState.isBaseVersionNewerThan(rulesVersion("2016c", 1)));
    }

    private static void assertEqualsContract(RulesState one, RulesState two) {
+33 −31
Original line number Diff line number Diff line
@@ -16,14 +16,13 @@

package com.android.server.timezone;

import com.android.internal.annotations.VisibleForTesting;
import com.android.server.EventLogTags;
import com.android.server.SystemService;
import com.android.timezone.distro.DistroException;
import com.android.timezone.distro.DistroVersion;
import com.android.timezone.distro.StagedDistroOperation;
import com.android.timezone.distro.TimeZoneDistro;
import com.android.timezone.distro.installer.TimeZoneDistroInstaller;
import static android.app.timezone.RulesState.DISTRO_STATUS_INSTALLED;
import static android.app.timezone.RulesState.DISTRO_STATUS_NONE;
import static android.app.timezone.RulesState.DISTRO_STATUS_UNKNOWN;
import static android.app.timezone.RulesState.STAGED_OPERATION_INSTALL;
import static android.app.timezone.RulesState.STAGED_OPERATION_NONE;
import static android.app.timezone.RulesState.STAGED_OPERATION_UNINSTALL;
import static android.app.timezone.RulesState.STAGED_OPERATION_UNKNOWN;

import android.app.timezone.Callback;
import android.app.timezone.DistroFormatVersion;
@@ -37,6 +36,21 @@ import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.util.Slog;

import com.android.internal.annotations.VisibleForTesting;
import com.android.server.EventLogTags;
import com.android.server.SystemService;
import com.android.timezone.distro.DistroException;
import com.android.timezone.distro.DistroVersion;
import com.android.timezone.distro.StagedDistroOperation;
import com.android.timezone.distro.TimeZoneDistro;
import com.android.timezone.distro.installer.TimeZoneDistroInstaller;

import libcore.icu.ICU;
import libcore.timezone.TimeZoneDataFiles;
import libcore.timezone.TimeZoneFinder;
import libcore.timezone.TzDataSetVersion;
import libcore.timezone.ZoneInfoDB;

import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
@@ -46,18 +60,6 @@ import java.io.PrintWriter;
import java.util.Arrays;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicBoolean;
import libcore.icu.ICU;
import libcore.timezone.TzDataSetVersion;
import libcore.timezone.TimeZoneFinder;
import libcore.timezone.ZoneInfoDB;

import static android.app.timezone.RulesState.DISTRO_STATUS_INSTALLED;
import static android.app.timezone.RulesState.DISTRO_STATUS_NONE;
import static android.app.timezone.RulesState.DISTRO_STATUS_UNKNOWN;
import static android.app.timezone.RulesState.STAGED_OPERATION_INSTALL;
import static android.app.timezone.RulesState.STAGED_OPERATION_NONE;
import static android.app.timezone.RulesState.STAGED_OPERATION_UNINSTALL;
import static android.app.timezone.RulesState.STAGED_OPERATION_UNKNOWN;

public final class RulesManagerService extends IRulesManager.Stub {

@@ -96,8 +98,6 @@ public final class RulesManagerService extends IRulesManager.Stub {
    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
    static final String REQUIRED_QUERY_PERMISSION =
            android.Manifest.permission.QUERY_TIME_ZONE_RULES;
    private static final File SYSTEM_TZ_DATA_FILE = new File("/system/usr/share/zoneinfo/tzdata");
    private static final File TZ_DATA_DIR = new File("/data/misc/zoneinfo");

    private final AtomicBoolean mOperationInProgress = new AtomicBoolean(false);
    private final PermissionHelper mPermissionHelper;
@@ -108,12 +108,14 @@ public final class RulesManagerService extends IRulesManager.Stub {

    private static RulesManagerService create(Context context) {
        RulesManagerServiceHelperImpl helper = new RulesManagerServiceHelperImpl(context);
        File baseVersionFile = new File(TimeZoneDataFiles.getRuntimeModuleTzVersionFile());
        File tzDataDir = new File(TimeZoneDataFiles.getDataTimeZoneRootDir());
        return new RulesManagerService(
                helper /* permissionHelper */,
                helper /* executor */,
                helper /* intentHelper */,
                PackageTracker.create(context),
                new TimeZoneDistroInstaller(TAG, SYSTEM_TZ_DATA_FILE, TZ_DATA_DIR));
                new TimeZoneDistroInstaller(TAG, baseVersionFile, tzDataDir));
    }

    // A constructor that can be used by tests to supply mocked / faked dependencies.
@@ -143,11 +145,11 @@ public final class RulesManagerService extends IRulesManager.Stub {
    /** Like {@link #getRulesState()} without the permission check. */
    private RulesState getRulesStateInternal() {
        synchronized(this) {
            String systemRulesVersion;
            TzDataSetVersion baseVersion;
            try {
                systemRulesVersion = mInstaller.getSystemRulesVersion();
                baseVersion = mInstaller.readBaseVersion();
            } catch (IOException e) {
                Slog.w(TAG, "Failed to read system rules", e);
                Slog.w(TAG, "Failed to read base rules version", e);
                return null;
            }

@@ -196,7 +198,7 @@ public final class RulesManagerService extends IRulesManager.Stub {
                    Slog.w(TAG, "Failed to read staged distro.", e);
                }
            }
            return new RulesState(systemRulesVersion, DISTRO_FORMAT_VERSION_SUPPORTED,
            return new RulesState(baseVersion.rulesVersion, DISTRO_FORMAT_VERSION_SUPPORTED,
                    operationInProgress, stagedOperationStatus, stagedDistroRulesVersion,
                    distroStatus, installedDistroRulesVersion);
        }
@@ -454,13 +456,13 @@ public final class RulesManagerService extends IRulesManager.Stub {
                            pw.println("Operation in progress: " + value);
                            break;
                        }
                        case 's': {
                            // Report system image rules version
                        case 'b': {
                            // Report base rules version
                            String value = "Unknown";
                            if (rulesState != null) {
                                value = rulesState.getSystemRulesVersion();
                                value = rulesState.getBaseRulesVersion();
                            }
                            pw.println("System rules version: " + value);
                            pw.println("Base rules version: " + value);
                            break;
                        }
                        case 'c': {
+81 −62
Original line number Diff line number Diff line
@@ -16,34 +16,9 @@

package com.android.server.timezone;

import com.android.timezone.distro.DistroVersion;
import com.android.timezone.distro.StagedDistroOperation;
import com.android.timezone.distro.TimeZoneDistro;
import com.android.timezone.distro.installer.TimeZoneDistroInstaller;

import org.junit.Before;
import org.junit.Test;

import android.app.timezone.Callback;
import android.app.timezone.DistroRulesVersion;
import android.app.timezone.ICallback;
import android.app.timezone.RulesManager;
import android.app.timezone.RulesState;
import android.os.ParcelFileDescriptor;

import java.io.File;
import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.concurrent.Executor;
import javax.annotation.Nullable;

import libcore.io.IoUtils;
import libcore.timezone.TzDataSetVersion;

import static com.android.server.timezone.RulesManagerService.REQUIRED_QUERY_PERMISSION;
import static com.android.server.timezone.RulesManagerService.REQUIRED_UPDATER_PERMISSION;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@ -61,11 +36,43 @@ import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;

import android.app.timezone.Callback;
import android.app.timezone.DistroRulesVersion;
import android.app.timezone.ICallback;
import android.app.timezone.RulesManager;
import android.app.timezone.RulesState;
import android.os.ParcelFileDescriptor;

import com.android.timezone.distro.DistroVersion;
import com.android.timezone.distro.StagedDistroOperation;
import com.android.timezone.distro.TimeZoneDistro;
import com.android.timezone.distro.installer.TimeZoneDistroInstaller;

import libcore.io.IoUtils;
import libcore.timezone.TzDataSetVersion;

import org.junit.Before;
import org.junit.Test;

import java.io.File;
import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.concurrent.Executor;

import javax.annotation.Nullable;

/**
 * White box interaction / unit testing of the {@link RulesManagerService}.
 */
public class RulesManagerServiceTest {

    private static final int CURRENT_FORMAT_MAJOR_VERSION =
            TzDataSetVersion.currentFormatMajorVersion();
    private static final int CURRENT_FORMAT_MINOR_VERSION =
            TzDataSetVersion.currentFormatMinorVersion();

    private RulesManagerService mRulesManagerService;

    private FakeExecutor mFakeExecutor;
@@ -116,8 +123,8 @@ public class RulesManagerServiceTest {
    }

    @Test
    public void getRulesState_systemRulesError() throws Exception {
        configureDeviceCannotReadSystemRulesVersion();
    public void getRulesState_baseVersionError() throws Exception {
        configureDeviceCannotReadBaseVersion();

        assertNull(mRulesManagerService.getRulesState());
    }
@@ -126,18 +133,18 @@ public class RulesManagerServiceTest {
    public void getRulesState_stagedInstall() throws Exception {
        configureCallerHasPermission();

        configureDeviceSystemRulesVersion("2016a");
        configureDeviceBaseVersion("2016a");

        DistroVersion stagedDistroVersion = new DistroVersion(
                TzDataSetVersion.currentFormatMajorVersion(),
                TzDataSetVersion.currentFormatMinorVersion() - 1,
                CURRENT_FORMAT_MAJOR_VERSION,
                CURRENT_FORMAT_MINOR_VERSION - 1,
                "2016c",
                3);
                3 /* revision */);
        configureStagedInstall(stagedDistroVersion);

        DistroVersion installedDistroVersion = new DistroVersion(
                TzDataSetVersion.currentFormatMajorVersion(),
                TzDataSetVersion.currentFormatMinorVersion() - 1,
                CURRENT_FORMAT_MAJOR_VERSION,
                CURRENT_FORMAT_MINOR_VERSION - 1,
                "2016b",
                4);
        configureInstalledDistroVersion(installedDistroVersion);
@@ -158,13 +165,13 @@ public class RulesManagerServiceTest {
    public void getRulesState_nothingStaged() throws Exception {
        configureCallerHasPermission();

        configureDeviceSystemRulesVersion("2016a");
        configureDeviceBaseVersion("2016a");

        configureNoStagedOperation();

        DistroVersion installedDistroVersion = new DistroVersion(
                TzDataSetVersion.currentFormatMajorVersion(),
                TzDataSetVersion.currentFormatMinorVersion() - 1,
                CURRENT_FORMAT_MAJOR_VERSION,
                CURRENT_FORMAT_MINOR_VERSION - 1,
                "2016b",
                4);
        configureInstalledDistroVersion(installedDistroVersion);
@@ -183,13 +190,13 @@ public class RulesManagerServiceTest {
    public void getRulesState_uninstallStaged() throws Exception {
        configureCallerHasPermission();

        configureDeviceSystemRulesVersion("2016a");
        configureDeviceBaseVersion("2016a");

        configureStagedUninstall();

        DistroVersion installedDistroVersion = new DistroVersion(
                TzDataSetVersion.currentFormatMajorVersion(),
                TzDataSetVersion.currentFormatMinorVersion() - 1,
                CURRENT_FORMAT_MAJOR_VERSION,
                CURRENT_FORMAT_MINOR_VERSION - 1,
                "2016b",
                4);
        configureInstalledDistroVersion(installedDistroVersion);
@@ -208,8 +215,8 @@ public class RulesManagerServiceTest {
    public void getRulesState_installedRulesError() throws Exception {
        configureCallerHasPermission();

        String systemRulesVersion = "2016a";
        configureDeviceSystemRulesVersion(systemRulesVersion);
        String baseRulesVersion = "2016a";
        configureDeviceBaseVersion(baseRulesVersion);

        configureStagedUninstall();
        configureDeviceCannotReadInstalledDistroVersion();
@@ -226,14 +233,14 @@ public class RulesManagerServiceTest {
    public void getRulesState_stagedRulesError() throws Exception {
        configureCallerHasPermission();

        String systemRulesVersion = "2016a";
        configureDeviceSystemRulesVersion(systemRulesVersion);
        String baseRulesVersion = "2016a";
        configureDeviceBaseVersion(baseRulesVersion);

        configureDeviceCannotReadStagedDistroOperation();

        DistroVersion installedDistroVersion = new DistroVersion(
                TzDataSetVersion.currentFormatMajorVersion(),
                TzDataSetVersion.currentFormatMinorVersion() - 1,
                CURRENT_FORMAT_MAJOR_VERSION,
                CURRENT_FORMAT_MINOR_VERSION - 1,
                "2016b",
                4);
        configureInstalledDistroVersion(installedDistroVersion);
@@ -252,13 +259,13 @@ public class RulesManagerServiceTest {
    public void getRulesState_noInstalledRules() throws Exception {
        configureCallerHasPermission();

        String systemRulesVersion = "2016a";
        configureDeviceSystemRulesVersion(systemRulesVersion);
        String baseRulesVersion = "2016a";
        configureDeviceBaseVersion(baseRulesVersion);
        configureNoStagedOperation();
        configureInstalledDistroVersion(null);

        RulesState expectedRuleState = new RulesState(
                systemRulesVersion, RulesManagerService.DISTRO_FORMAT_VERSION_SUPPORTED,
                baseRulesVersion, RulesManagerService.DISTRO_FORMAT_VERSION_SUPPORTED,
                false /* operationInProgress */,
                RulesState.STAGED_OPERATION_NONE, null /* stagedDistroRulesVersion */,
                RulesState.DISTRO_STATUS_NONE, null /* installedDistroRulesVersion */);
@@ -269,15 +276,15 @@ public class RulesManagerServiceTest {
    public void getRulesState_operationInProgress() throws Exception {
        configureCallerHasPermission();

        String systemRulesVersion = "2016a";
        String baseRulesVersion = "2016a";
        String installedRulesVersion = "2016b";
        int revision = 3;

        configureDeviceSystemRulesVersion(systemRulesVersion);
        configureDeviceBaseVersion(baseRulesVersion);

        DistroVersion installedDistroVersion = new DistroVersion(
                TzDataSetVersion.currentFormatMajorVersion(),
                TzDataSetVersion.currentFormatMinorVersion() - 1,
                CURRENT_FORMAT_MAJOR_VERSION,
                CURRENT_FORMAT_MINOR_VERSION - 1,
                installedRulesVersion,
                revision);
        configureInstalledDistroVersion(installedDistroVersion);
@@ -297,7 +304,7 @@ public class RulesManagerServiceTest {
        DistroRulesVersion expectedInstalledDistroRulesVersion =
                new DistroRulesVersion(installedRulesVersion, revision);
        RulesState expectedRuleState = new RulesState(
                systemRulesVersion, RulesManagerService.DISTRO_FORMAT_VERSION_SUPPORTED,
                baseRulesVersion, RulesManagerService.DISTRO_FORMAT_VERSION_SUPPORTED,
                true /* operationInProgress */,
                RulesState.STAGED_OPERATION_UNKNOWN, null /* stagedDistroRulesVersion */,
                RulesState.DISTRO_STATUS_INSTALLED, expectedInstalledDistroRulesVersion);
@@ -858,11 +865,20 @@ public class RulesManagerServiceTest {
                .thenReturn(true);

        // Set up the mocks to return (arbitrary) information about the current device state.
        when(mMockTimeZoneDistroInstaller.getSystemRulesVersion()).thenReturn("2017a");
        when(mMockTimeZoneDistroInstaller.getInstalledDistroVersion()).thenReturn(
                new DistroVersion(2, 3, "2017b", 4));
        TzDataSetVersion baseVersion = new TzDataSetVersion(
                CURRENT_FORMAT_MAJOR_VERSION, CURRENT_FORMAT_MINOR_VERSION, "2017a",
                1 /* revision */);
        when(mMockTimeZoneDistroInstaller.readBaseVersion()).thenReturn(baseVersion);
        DistroVersion installedDistroVersion = new DistroVersion(
                CURRENT_FORMAT_MAJOR_VERSION, CURRENT_FORMAT_MINOR_VERSION, "2017b",
                4 /* revision */);
        when(mMockTimeZoneDistroInstaller.getInstalledDistroVersion())
                .thenReturn(installedDistroVersion);
        DistroVersion stagedDistroVersion = new DistroVersion(
                CURRENT_FORMAT_MAJOR_VERSION, CURRENT_FORMAT_MINOR_VERSION, "2017c",
                7 /* revision */);
        when(mMockTimeZoneDistroInstaller.getStagedDistroOperation()).thenReturn(
                StagedDistroOperation.install(new DistroVersion(5, 6, "2017c", 7)));
                StagedDistroOperation.install(stagedDistroVersion));

        // Do the dump call.
        String dumpedOutput = doDumpCallAndCapture(rulesManagerService, args);
@@ -973,8 +989,11 @@ public class RulesManagerServiceTest {
        return new CheckToken(1, new PackageVersions(1, 1));
    }

    private void configureDeviceSystemRulesVersion(String systemRulesVersion) throws Exception {
        when(mMockTimeZoneDistroInstaller.getSystemRulesVersion()).thenReturn(systemRulesVersion);
    private void configureDeviceBaseVersion(String baseRulesVersion) throws Exception {
        TzDataSetVersion tzDataSetVersion = new TzDataSetVersion(
                CURRENT_FORMAT_MAJOR_VERSION, CURRENT_FORMAT_MINOR_VERSION, baseRulesVersion,
                1 /* revision */);
        when(mMockTimeZoneDistroInstaller.readBaseVersion()).thenReturn(tzDataSetVersion);
    }

    private void configureInstalledDistroVersion(@Nullable DistroVersion installedDistroVersion)
@@ -1002,8 +1021,8 @@ public class RulesManagerServiceTest {
                .thenThrow(new IOException("Simulated failure"));
    }

    private void configureDeviceCannotReadSystemRulesVersion() throws Exception {
        when(mMockTimeZoneDistroInstaller.getSystemRulesVersion())
    private void configureDeviceCannotReadBaseVersion() throws Exception {
        when(mMockTimeZoneDistroInstaller.readBaseVersion())
                .thenThrow(new IOException("Simulated failure"));
    }