diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 9a019b8..25e9224 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -22,7 +22,6 @@
 import android.app.admin.IDevicePolicyManager;
 import android.app.job.IJobScheduler;
 import android.app.job.JobScheduler;
-import android.app.timezone.RulesManager;
 import android.app.trust.TrustManager;
 import android.app.usage.IStorageStatsManager;
 import android.app.usage.IUsageStatsManager;
@@ -872,13 +871,6 @@
                 return new VrManager(IVrManager.Stub.asInterface(b));
             }
         });
-
-        registerService(Context.TIME_ZONE_RULES_MANAGER_SERVICE, RulesManager.class,
-                new CachedServiceFetcher<RulesManager>() {
-            @Override
-            public RulesManager createService(ContextImpl ctx) {
-                return new RulesManager(ctx.getOuterContext());
-            }});
     }
 
     /**
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index f009434..d1b3fec 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1282,49 +1282,6 @@
     <!-- True if WallpaperService is enabled -->
     <bool name="config_enableWallpaperService">true</bool>
 
-    <!-- Enables the TimeZoneRuleManager service. This is the master switch for the updateable time
-         zone update mechanism. -->
-    <bool name="config_enableUpdateableTimeZoneRules">false</bool>
-
-    <!-- Enables APK-based time zone update triggering. Set this to false when updates are triggered
-         via external events and not by APK updates. For example, if an updater checks with a server
-         on a regular schedule.
-         [This is only used if config_enableUpdateableTimeZoneRules is true.] -->
-    <bool name="config_timeZoneRulesUpdateTrackingEnabled">false</bool>
-
-    <!-- The package of the time zone rules updater application. Expected to be the same
-         for all Android devices that support APK-based time zone rule updates.
-         A package-targeted android.intent.action.timezone.TRIGGER_RULES_UPDATE_CHECK intent
-         will be sent to the updater app if the system server detects an update to the updater or
-         data app packages.
-         The package referenced here must have the android.permission.UPDATE_TIME_ZONE_RULES
-         permission.
-         [This is only used if config_enableUpdateableTimeZoneRules and
-         config_timeZoneRulesUpdateTrackingEnabled are true.] -->
-    <string name="config_timeZoneRulesUpdaterPackage" translateable="false"></string>
-
-    <!-- The package of the time zone rules data application. Expected to be configured
-         by OEMs to reference their own priv-app APK package.
-         A package-targeted android.intent.action.timezone.TRIGGER_RULES_UPDATE_CHECK intent
-         will be sent to the updater app if the system server detects an update to the updater or
-         data app packages.
-         [This is only used if config_enableUpdateableTimeZoneRules and
-         config_timeZoneRulesUpdateTrackingEnabled are true.] -->
-    <string name="config_timeZoneRulesDataPackage" translateable="false"></string>
-
-    <!-- The allowed time in milliseconds between an update check intent being broadcast and the
-         response being considered overdue. Reliability triggers will not fire in this time.
-         [This is only used if config_enableUpdateableTimeZoneRules and
-         config_timeZoneRulesUpdateTrackingEnabled are true.] -->
-    <!-- 5 minutes -->
-    <integer name="config_timeZoneRulesCheckTimeMillisAllowed">300000</integer>
-
-    <!-- The number of times a time zone update check is allowed to fail before the system will stop
-         reacting to reliability triggers.
-         [This is only used if config_enableUpdateableTimeZoneRules and
-         config_timeZoneRulesUpdateTrackingEnabled are true.] -->
-    <integer name="config_timeZoneRulesCheckRetryCount">5</integer>
-
     <!-- Whether to enable network location overlay which allows network
          location provider to be replaced by an app at run-time. When disabled,
          only the config_networkLocationProviderPackageName package will be
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 316e202..975737b 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -284,12 +284,6 @@
   <java-symbol type="bool" name="split_action_bar_is_narrow" />
   <java-symbol type="bool" name="config_useVolumeKeySounds" />
   <java-symbol type="bool" name="config_enableWallpaperService" />
-  <java-symbol type="bool" name="config_enableUpdateableTimeZoneRules" />
-  <java-symbol type="bool" name="config_timeZoneRulesUpdateTrackingEnabled" />
-  <java-symbol type="string" name="config_timeZoneRulesUpdaterPackage" />
-  <java-symbol type="string" name="config_timeZoneRulesDataPackage" />
-  <java-symbol type="integer" name="config_timeZoneRulesCheckTimeMillisAllowed" />
-  <java-symbol type="integer" name="config_timeZoneRulesCheckRetryCount" />
   <java-symbol type="bool" name="config_sendAudioBecomingNoisy" />
   <java-symbol type="bool" name="config_enableScreenshotChord" />
   <java-symbol type="bool" name="config_bluetooth_default_profiles" />
diff --git a/services/core/java/com/android/server/timezone/CheckToken.java b/services/core/java/com/android/server/timezone/CheckToken.java
deleted file mode 100644
index 5128360..0000000
--- a/services/core/java/com/android/server/timezone/CheckToken.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.timezone;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.util.Arrays;
-
-/**
- * A deserialized version of the byte[] sent to the time zone update application to identify a
- * triggered time zone update check. It encodes the optimistic lock ID used to detect
- * concurrent checks and the minimal package versions that will have been checked.
- */
-final class CheckToken {
-
-    final int mOptimisticLockId;
-    final PackageVersions mPackageVersions;
-
-    CheckToken(int optimisticLockId, PackageVersions packageVersions) {
-        this.mOptimisticLockId = optimisticLockId;
-
-        if (packageVersions == null) {
-            throw new NullPointerException("packageVersions == null");
-        }
-        this.mPackageVersions = packageVersions;
-    }
-
-    byte[] toByteArray() {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream(12 /* (3 * sizeof(int)) */);
-        try (DataOutputStream dos = new DataOutputStream(baos)) {
-            dos.writeInt(mOptimisticLockId);
-            dos.writeInt(mPackageVersions.mUpdateAppVersion);
-            dos.writeInt(mPackageVersions.mDataAppVersion);
-        } catch (IOException e) {
-            throw new RuntimeException("Unable to write into a ByteArrayOutputStream", e);
-        }
-        return baos.toByteArray();
-    }
-
-    static CheckToken fromByteArray(byte[] tokenBytes) throws IOException {
-        ByteArrayInputStream bais = new ByteArrayInputStream(tokenBytes);
-        try (DataInputStream dis = new DataInputStream(bais)) {
-            int versionId = dis.readInt();
-            int updateAppVersion = dis.readInt();
-            int dataAppVersion = dis.readInt();
-            return new CheckToken(versionId, new PackageVersions(updateAppVersion, dataAppVersion));
-        }
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (o == null || getClass() != o.getClass()) {
-            return false;
-        }
-
-        CheckToken checkToken = (CheckToken) o;
-
-        if (mOptimisticLockId != checkToken.mOptimisticLockId) {
-            return false;
-        }
-        return mPackageVersions.equals(checkToken.mPackageVersions);
-    }
-
-    @Override
-    public int hashCode() {
-        int result = mOptimisticLockId;
-        result = 31 * result + mPackageVersions.hashCode();
-        return result;
-    }
-
-    @Override
-    public String toString() {
-        return "Token{" +
-                "mOptimisticLockId=" + mOptimisticLockId +
-                ", mPackageVersions=" + mPackageVersions +
-                '}';
-    }
-}
diff --git a/services/core/java/com/android/server/timezone/ClockHelper.java b/services/core/java/com/android/server/timezone/ClockHelper.java
deleted file mode 100644
index 353728a..0000000
--- a/services/core/java/com/android/server/timezone/ClockHelper.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.timezone;
-
-/**
- * An easy-to-mock interface for obtaining a monotonically increasing time value in milliseconds.
- */
-interface ClockHelper {
-
-    long currentTimestamp();
-}
diff --git a/services/core/java/com/android/server/timezone/ConfigHelper.java b/services/core/java/com/android/server/timezone/ConfigHelper.java
deleted file mode 100644
index f9984fa..0000000
--- a/services/core/java/com/android/server/timezone/ConfigHelper.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.timezone;
-
-/**
- * An easy-to-mock interface around device config for use by {@link PackageTracker}; it is not
- * possible to test various states with the real one because config is fixed in the system image.
- */
-interface ConfigHelper {
-
-    boolean isTrackingEnabled();
-
-    String getUpdateAppPackageName();
-
-    String getDataAppPackageName();
-
-    int getCheckTimeAllowedMillis();
-
-    int getFailedCheckRetryCount();
-}
diff --git a/services/core/java/com/android/server/timezone/FileDescriptorHelper.java b/services/core/java/com/android/server/timezone/FileDescriptorHelper.java
deleted file mode 100644
index c3b1101..0000000
--- a/services/core/java/com/android/server/timezone/FileDescriptorHelper.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.timezone;
-
-import android.os.ParcelFileDescriptor;
-
-import java.io.IOException;
-
-/**
- * An easy-to-mock interface around use of {@link ParcelFileDescriptor} for use by
- * {@link RulesManagerService}.
- */
-interface FileDescriptorHelper {
-
-    byte[] readFully(ParcelFileDescriptor parcelFileDescriptor) throws IOException;
-}
diff --git a/services/core/java/com/android/server/timezone/IntentHelper.java b/services/core/java/com/android/server/timezone/IntentHelper.java
deleted file mode 100644
index 0cb9065..0000000
--- a/services/core/java/com/android/server/timezone/IntentHelper.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.timezone;
-
-/**
- * An easy-to-mock interface around intent sending / receiving for use by {@link PackageTracker};
- * it is not possible to test various cases with the real one because of the need to simulate
- * receiving and broadcasting intents.
- */
-interface IntentHelper {
-
-    void initialize(String updateAppPackageName, String dataAppPackageName, Listener listener);
-
-    void sendTriggerUpdateCheck(CheckToken checkToken);
-
-    void enableReliabilityTriggering();
-
-    void disableReliabilityTriggering();
-
-    interface Listener {
-        void triggerUpdateIfNeeded(boolean packageUpdated);
-    }
-}
diff --git a/services/core/java/com/android/server/timezone/IntentHelperImpl.java b/services/core/java/com/android/server/timezone/IntentHelperImpl.java
deleted file mode 100644
index 3ffbb2d..0000000
--- a/services/core/java/com/android/server/timezone/IntentHelperImpl.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.timezone;
-
-import android.app.timezone.RulesUpdaterContract;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.PatternMatcher;
-import android.util.Slog;
-
-import java.util.regex.Pattern;
-
-/**
- * The bona fide implementation of {@link IntentHelper}.
- */
-final class IntentHelperImpl implements IntentHelper {
-
-    private final static String TAG = "timezone.IntentHelperImpl";
-
-    private final Context mContext;
-    private String mUpdaterAppPackageName;
-
-    private boolean mReliabilityReceiverEnabled;
-    private Receiver mReliabilityReceiver;
-
-    IntentHelperImpl(Context context) {
-        mContext = context;
-    }
-
-    @Override
-    public void initialize(
-            String updaterAppPackageName, String dataAppPackageName, Listener listener) {
-        mUpdaterAppPackageName = updaterAppPackageName;
-
-        // Register for events of interest.
-
-        // The intent filter that triggers when package update events happen that indicate there may
-        // be work to do.
-        IntentFilter packageIntentFilter = new IntentFilter();
-        // Either of these mean a downgrade?
-        packageIntentFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
-        packageIntentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED);
-        packageIntentFilter.addDataScheme("package");
-        packageIntentFilter.addDataSchemeSpecificPart(
-                updaterAppPackageName, PatternMatcher.PATTERN_LITERAL);
-        packageIntentFilter.addDataSchemeSpecificPart(
-                dataAppPackageName, PatternMatcher.PATTERN_LITERAL);
-        Receiver packageUpdateReceiver = new Receiver(listener, true /* packageUpdated */);
-        mContext.registerReceiver(packageUpdateReceiver, packageIntentFilter);
-
-        // TODO(nfuller): Add more exotic intents as needed. e.g.
-        // packageIntentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
-        // Also, disabled...?
-        mReliabilityReceiver = new Receiver(listener, false /* packageUpdated */);
-    }
-
-    /** Sends an intent to trigger an update check. */
-    @Override
-    public void sendTriggerUpdateCheck(CheckToken checkToken) {
-        RulesUpdaterContract.sendBroadcast(
-                mContext, mUpdaterAppPackageName, checkToken.toByteArray());
-    }
-
-    @Override
-    public synchronized void enableReliabilityTriggering() {
-        if (!mReliabilityReceiverEnabled) {
-            // The intent filter that exists to make updates reliable in the event of failures /
-            // reboots.
-            IntentFilter reliabilityIntentFilter = new IntentFilter();
-            reliabilityIntentFilter.addAction(Intent.ACTION_IDLE_MAINTENANCE_START);
-            mContext.registerReceiver(mReliabilityReceiver, reliabilityIntentFilter);
-            mReliabilityReceiverEnabled = true;
-        }
-    }
-
-    @Override
-    public synchronized void disableReliabilityTriggering() {
-        if (mReliabilityReceiverEnabled) {
-            mContext.unregisterReceiver(mReliabilityReceiver);
-            mReliabilityReceiverEnabled = false;
-        }
-    }
-
-    private static class Receiver extends BroadcastReceiver {
-        private final Listener mListener;
-        private final boolean mPackageUpdated;
-
-        private Receiver(Listener listener, boolean packageUpdated) {
-            mListener = listener;
-            mPackageUpdated = packageUpdated;
-        }
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            Slog.d(TAG, "Received intent: " + intent.toString());
-            mListener.triggerUpdateIfNeeded(mPackageUpdated);
-        }
-    }
-
-}
diff --git a/services/core/java/com/android/server/timezone/PackageManagerHelper.java b/services/core/java/com/android/server/timezone/PackageManagerHelper.java
deleted file mode 100644
index 804941a..0000000
--- a/services/core/java/com/android/server/timezone/PackageManagerHelper.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.timezone;
-
-import android.content.Intent;
-import android.content.pm.PackageManager;
-
-/**
- * An easy-to-mock facade around PackageManager for use by {@link PackageTracker}; it is not
- * possible to test various cases with the real one because of the need to simulate package versions
- * and manifest configurations.
- */
-interface PackageManagerHelper {
-
-    int getInstalledPackageVersion(String packageName)
-            throws PackageManager.NameNotFoundException;
-
-    boolean isPrivilegedApp(String packageName) throws PackageManager.NameNotFoundException;
-
-    boolean usesPermission(String packageName, String requiredPermissionName)
-                    throws PackageManager.NameNotFoundException;
-
-    boolean contentProviderRegistered(String authority, String requiredPackageName);
-
-    boolean receiverRegistered(Intent intent, String requiredPermissionName)
-                            throws PackageManager.NameNotFoundException;
-}
diff --git a/services/core/java/com/android/server/timezone/PackageStatus.java b/services/core/java/com/android/server/timezone/PackageStatus.java
deleted file mode 100644
index 6379096..0000000
--- a/services/core/java/com/android/server/timezone/PackageStatus.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.timezone;
-
-import android.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Information about the status of the time zone update / data packages that are persisted by the
- * Android system.
- */
-final class PackageStatus {
-
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({ CHECK_STARTED, CHECK_COMPLETED_SUCCESS, CHECK_COMPLETED_FAILURE })
-    @interface CheckStatus {}
-
-    /** A time zone update check has been started but not yet completed. */
-    static final int CHECK_STARTED = 1;
-    /** A time zone update check has been completed and succeeded. */
-    static final int CHECK_COMPLETED_SUCCESS = 2;
-    /** A time zone update check has been completed and failed. */
-    static final int CHECK_COMPLETED_FAILURE = 3;
-
-    @CheckStatus
-    final int mCheckStatus;
-
-    // Non-null
-    final PackageVersions mVersions;
-
-    PackageStatus(@CheckStatus int checkStatus, PackageVersions versions) {
-        this.mCheckStatus = checkStatus;
-        if (checkStatus < 1 || checkStatus > 3) {
-            throw new IllegalArgumentException("Unknown checkStatus " + checkStatus);
-        }
-        if (versions == null) {
-            throw new NullPointerException("versions == null");
-        }
-        this.mVersions = versions;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (o == null || getClass() != o.getClass()) {
-            return false;
-        }
-
-        PackageStatus that = (PackageStatus) o;
-
-        if (mCheckStatus != that.mCheckStatus) {
-            return false;
-        }
-        return mVersions.equals(that.mVersions);
-    }
-
-    @Override
-    public int hashCode() {
-        int result = mCheckStatus;
-        result = 31 * result + mVersions.hashCode();
-        return result;
-    }
-
-    @Override
-    public String toString() {
-        return "PackageStatus{" +
-                "mCheckStatus=" + mCheckStatus +
-                ", mVersions=" + mVersions +
-                '}';
-    }
-}
diff --git a/services/core/java/com/android/server/timezone/PackageStatusStorage.java b/services/core/java/com/android/server/timezone/PackageStatusStorage.java
deleted file mode 100644
index 31f0e31..0000000
--- a/services/core/java/com/android/server/timezone/PackageStatusStorage.java
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.timezone;
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.util.Slog;
-
-import java.io.File;
-
-import static com.android.server.timezone.PackageStatus.CHECK_COMPLETED_FAILURE;
-import static com.android.server.timezone.PackageStatus.CHECK_COMPLETED_SUCCESS;
-import static com.android.server.timezone.PackageStatus.CHECK_STARTED;
-
-/**
- * Storage logic for accessing/mutating the Android system's persistent state related to time zone
- * update checking. There is expected to be a single instance and all methods synchronized on
- * {@code this} for thread safety.
- */
-final class PackageStatusStorage {
-
-    private static final String TAG = "timezone.PackageStatusStorage";
-
-    private static final String DATABASE_NAME = "timezonepackagestatus.db";
-    private static final int DATABASE_VERSION = 1;
-
-    /** The table name. It will have a single row with _id == {@link #SINGLETON_ID} */
-    private static final String TABLE = "status";
-    private static final String COLUMN_ID = "_id";
-
-    /**
-     * Column that stores a monotonically increasing lock ID, used to detect concurrent update
-     * issues without on-line locks. Incremented on every write.
-     */
-    private static final String COLUMN_OPTIMISTIC_LOCK_ID = "optimistic_lock_id";
-
-    /**
-     * Column that stores the current "check status" of the time zone update application packages.
-     */
-    private static final String COLUMN_CHECK_STATUS = "check_status";
-
-    /**
-     * Column that stores the version of the time zone rules update application being checked / last
-     * checked.
-     */
-    private static final String COLUMN_UPDATE_APP_VERSION = "update_app_package_version";
-
-    /**
-     * Column that stores the version of the time zone rules data application being checked / last
-     * checked.
-     */
-    private static final String COLUMN_DATA_APP_VERSION = "data_app_package_version";
-
-    /**
-     * The ID of the one row.
-     */
-    private static final int SINGLETON_ID = 1;
-
-    private static final int UNKNOWN_PACKAGE_VERSION = -1;
-
-    private final DatabaseHelper mDatabaseHelper;
-
-    PackageStatusStorage(Context context) {
-        mDatabaseHelper = new DatabaseHelper(context);
-    }
-
-    void deleteDatabaseForTests() {
-        SQLiteDatabase.deleteDatabase(mDatabaseHelper.getDatabaseFile());
-    }
-
-    /**
-     * Obtain the current check status of the application packages. Returns {@code null} the first
-     * time it is called, or after {@link #resetCheckState()}.
-     */
-    PackageStatus getPackageStatus() {
-        synchronized (this) {
-            try {
-                return getPackageStatusInternal();
-            } catch (IllegalArgumentException e) {
-                // This means that data exists in the table but it was bad.
-                Slog.e(TAG, "Package status invalid, resetting and retrying", e);
-
-                // Reset the storage so it is in a good state again.
-                mDatabaseHelper.recoverFromBadData();
-                return getPackageStatusInternal();
-            }
-        }
-    }
-
-    private PackageStatus getPackageStatusInternal() {
-        String[] columns = {
-                COLUMN_CHECK_STATUS, COLUMN_UPDATE_APP_VERSION, COLUMN_DATA_APP_VERSION
-        };
-        Cursor cursor = mDatabaseHelper.getReadableDatabase()
-                .query(TABLE, columns, COLUMN_ID + " = ?",
-                        new String[] { Integer.toString(SINGLETON_ID) },
-                        null /* groupBy */, null /* having */, null /* orderBy */);
-        if (cursor.getCount() != 1) {
-            Slog.e(TAG, "Unable to find package status from package status row. Rows returned: "
-                    + cursor.getCount());
-            return null;
-        }
-        cursor.moveToFirst();
-
-        // Determine check status.
-        if (cursor.isNull(0)) {
-            // This is normal the first time getPackageStatus() is called, or after
-            // resetCheckState().
-            return null;
-        }
-        int checkStatus = cursor.getInt(0);
-
-        // Determine package version.
-        if (cursor.isNull(1) || cursor.isNull(2)) {
-            Slog.e(TAG, "Package version information unexpectedly null");
-            return null;
-        }
-        PackageVersions packageVersions = new PackageVersions(cursor.getInt(1), cursor.getInt(2));
-
-        return new PackageStatus(checkStatus, packageVersions);
-    }
-
-    /**
-     * Generate a new {@link CheckToken} that can be passed to the time zone rules update
-     * application.
-     */
-    CheckToken generateCheckToken(PackageVersions currentInstalledVersions) {
-        if (currentInstalledVersions == null) {
-            throw new NullPointerException("currentInstalledVersions == null");
-        }
-
-        synchronized (this) {
-            Integer optimisticLockId = getCurrentOptimisticLockId();
-            if (optimisticLockId == null) {
-                Slog.w(TAG, "Unable to find optimistic lock ID from package status row");
-
-                // Recover.
-                optimisticLockId = mDatabaseHelper.recoverFromBadData();
-            }
-
-            int newOptimisticLockId = optimisticLockId + 1;
-            boolean statusRowUpdated = writeStatusRow(
-                    optimisticLockId, newOptimisticLockId, CHECK_STARTED, currentInstalledVersions);
-            if (!statusRowUpdated) {
-                Slog.e(TAG, "Unable to update status to CHECK_STARTED in package status row."
-                        + " synchronization failure?");
-                return null;
-            }
-            return new CheckToken(newOptimisticLockId, currentInstalledVersions);
-        }
-    }
-
-    /**
-     * Reset the current device state to "unknown".
-     */
-    void resetCheckState() {
-        synchronized(this) {
-            Integer optimisticLockId = getCurrentOptimisticLockId();
-            if (optimisticLockId == null) {
-                Slog.w(TAG, "resetCheckState: Unable to find optimistic lock ID from package"
-                        + " status row");
-                // Attempt to recover the storage state.
-                optimisticLockId = mDatabaseHelper.recoverFromBadData();
-            }
-
-            int newOptimisticLockId = optimisticLockId + 1;
-            if (!writeStatusRow(optimisticLockId, newOptimisticLockId,
-                    null /* status */, null /* packageVersions */)) {
-                Slog.e(TAG, "resetCheckState: Unable to reset package status row,"
-                        + " newOptimisticLockId=" + newOptimisticLockId);
-            }
-        }
-    }
-
-    /**
-     * Update the current device state if possible. Returns true if the update was successful.
-     * {@code false} indicates the storage has been changed since the {@link CheckToken} was
-     * generated and the update was discarded.
-     */
-    boolean markChecked(CheckToken checkToken, boolean succeeded) {
-        synchronized (this) {
-            int optimisticLockId = checkToken.mOptimisticLockId;
-            int newOptimisticLockId = optimisticLockId + 1;
-            int status = succeeded ? CHECK_COMPLETED_SUCCESS : CHECK_COMPLETED_FAILURE;
-            return writeStatusRow(optimisticLockId, newOptimisticLockId,
-                    status, checkToken.mPackageVersions);
-        }
-    }
-
-    // Caller should be synchronized(this)
-    private Integer getCurrentOptimisticLockId() {
-        final String[] columns = { COLUMN_OPTIMISTIC_LOCK_ID };
-        final String querySelection = COLUMN_ID + " = ?";
-        final String[] querySelectionArgs = { Integer.toString(SINGLETON_ID) };
-
-        SQLiteDatabase database = mDatabaseHelper.getReadableDatabase();
-        try (Cursor cursor = database.query(TABLE, columns, querySelection, querySelectionArgs,
-                null /* groupBy */, null /* having */, null /* orderBy */)) {
-            if (cursor.getCount() != 1) {
-                Slog.w(TAG, cursor.getCount() + " rows returned, expected exactly one.");
-                return null;
-            }
-            cursor.moveToFirst();
-            return cursor.getInt(0);
-        }
-    }
-
-    // Caller should be synchronized(this)
-    private boolean writeStatusRow(int optimisticLockId, int newOptimisticLockId, Integer status,
-            PackageVersions packageVersions) {
-        if ((status == null) != (packageVersions == null)) {
-            throw new IllegalArgumentException(
-                    "Provide both status and packageVersions, or neither.");
-        }
-
-        SQLiteDatabase database = mDatabaseHelper.getWritableDatabase();
-        ContentValues values = new ContentValues();
-        values.put(COLUMN_OPTIMISTIC_LOCK_ID, newOptimisticLockId);
-        if (status == null) {
-            values.putNull(COLUMN_CHECK_STATUS);
-            values.put(COLUMN_UPDATE_APP_VERSION, UNKNOWN_PACKAGE_VERSION);
-            values.put(COLUMN_DATA_APP_VERSION, UNKNOWN_PACKAGE_VERSION);
-        } else {
-            values.put(COLUMN_CHECK_STATUS, status);
-            values.put(COLUMN_UPDATE_APP_VERSION, packageVersions.mUpdateAppVersion);
-            values.put(COLUMN_DATA_APP_VERSION, packageVersions.mDataAppVersion);
-        }
-
-        String updateSelection = COLUMN_ID + " = ? AND " + COLUMN_OPTIMISTIC_LOCK_ID + " = ?";
-        String[] updateSelectionArgs = {
-                Integer.toString(SINGLETON_ID), Integer.toString(optimisticLockId)
-        };
-        int count = database.update(TABLE, values, updateSelection, updateSelectionArgs);
-        if (count > 1) {
-            // This has to be because of corruption: there should only ever be one row.
-            Slog.w(TAG, "writeStatusRow: " + count + " rows updated, expected exactly one.");
-            // Reset the table.
-            mDatabaseHelper.recoverFromBadData();
-        }
-
-        // 1 is the success case. 0 rows updated means the row is missing or the optimistic lock ID
-        // was not as expected, this could be because of corruption but is most likely due to an
-        // optimistic lock failure. Callers can decide on a case-by-case basis.
-        return count == 1;
-    }
-
-    /** Only used during tests to force an empty table. */
-    void deleteRowForTests() {
-        mDatabaseHelper.getWritableDatabase().delete(TABLE, null, null);
-    }
-
-    /** Only used during tests to force a known table state. */
-    public void forceCheckStateForTests(int checkStatus, PackageVersions packageVersions) {
-        int optimisticLockId = getCurrentOptimisticLockId();
-        writeStatusRow(optimisticLockId, optimisticLockId, checkStatus, packageVersions);
-    }
-
-    static class DatabaseHelper extends SQLiteOpenHelper {
-
-        private final Context mContext;
-
-        public DatabaseHelper(Context context) {
-            super(context, DATABASE_NAME, null, DATABASE_VERSION);
-            mContext = context;
-        }
-
-        @Override
-        public void onCreate(SQLiteDatabase db) {
-            db.execSQL("CREATE TABLE " + TABLE + " (" +
-                    "_id INTEGER PRIMARY KEY," +
-                    COLUMN_OPTIMISTIC_LOCK_ID + " INTEGER NOT NULL," +
-                    COLUMN_CHECK_STATUS + " INTEGER," +
-                    COLUMN_UPDATE_APP_VERSION + " INTEGER NOT NULL," +
-                    COLUMN_DATA_APP_VERSION + " INTEGER NOT NULL" +
-                    ");");
-            insertInitialRowState(db);
-        }
-
-        @Override
-        public void onUpgrade(SQLiteDatabase db, int oldVersion, int currentVersion) {
-            // no-op: nothing to upgrade
-        }
-
-        /** Recover the initial data row state, returning the new current optimistic lock ID */
-        int recoverFromBadData() {
-            // Delete the table content.
-            SQLiteDatabase writableDatabase = getWritableDatabase();
-            writableDatabase.delete(TABLE, null /* whereClause */, null /* whereArgs */);
-
-            // Insert the initial content.
-            return insertInitialRowState(writableDatabase);
-        }
-
-        /** Insert the initial data row, returning the optimistic lock ID */
-        private static int insertInitialRowState(SQLiteDatabase db) {
-            // Doesn't matter what it is, but we avoid the obvious starting value each time the row
-            // is reset to ensure that old tokens are unlikely to work.
-           final int initialOptimisticLockId = (int) System.currentTimeMillis();
-
-            // Insert the one row.
-            ContentValues values = new ContentValues();
-            values.put(COLUMN_ID, SINGLETON_ID);
-            values.put(COLUMN_OPTIMISTIC_LOCK_ID, initialOptimisticLockId);
-            values.putNull(COLUMN_CHECK_STATUS);
-            values.put(COLUMN_UPDATE_APP_VERSION, UNKNOWN_PACKAGE_VERSION);
-            values.put(COLUMN_DATA_APP_VERSION, UNKNOWN_PACKAGE_VERSION);
-            long id = db.insert(TABLE, null, values);
-            if (id == -1) {
-                Slog.w(TAG, "insertInitialRow: could not insert initial row, id=" + id);
-                return -1;
-            }
-            return initialOptimisticLockId;
-        }
-
-        File getDatabaseFile() {
-            return mContext.getDatabasePath(DATABASE_NAME);
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/timezone/PackageTracker.java b/services/core/java/com/android/server/timezone/PackageTracker.java
deleted file mode 100644
index 8abf7df..0000000
--- a/services/core/java/com/android/server/timezone/PackageTracker.java
+++ /dev/null
@@ -1,504 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.timezone;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import android.app.timezone.RulesUpdaterContract;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.provider.TimeZoneRulesDataContract;
-import android.util.Slog;
-
-/**
- * Monitors the installed applications associated with time zone updates. If the app packages are
- * updated it indicates there <em>might</em> be a time zone rules update to apply so a targeted
- * broadcast intent is used to trigger the time zone updater app.
- *
- * <p>The "update triggering" behavior of this component can be disabled via device configuration.
- *
- * <p>The package tracker listens for package updates of the time zone "updater app" and "data app".
- * It also listens for "reliability" triggers. Reliability triggers are there to ensure that the
- * package tracker handles failures reliably and are "idle maintenance" events or something similar.
- * Reliability triggers can cause a time zone update check to take place if the current state is
- * unclear. For example, it can be unclear after boot or after a failure. If there are repeated
- * failures reliability updates are halted until the next boot.
- *
- * <p>This component keeps persistent track of the most recent app packages checked to avoid
- * unnecessary expense from broadcasting intents (which will cause other app processes to spawn).
- * The current status is also stored to detect whether the most recently-generated check is
- * complete successfully. For example, if the device was interrupted while doing a check and never
- * acknowledged a check then a check will be retried the next time a "reliability trigger" event
- * happens.
- */
-// Also made non-final so it can be mocked.
-@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
-public class PackageTracker implements IntentHelper.Listener {
-    private static final String TAG = "timezone.PackageTracker";
-
-    private final PackageManagerHelper mPackageManagerHelper;
-    private final IntentHelper mIntentHelper;
-    private final ConfigHelper mConfigHelper;
-    private final PackageStatusStorage mPackageStatusStorage;
-    private final ClockHelper mClockHelper;
-
-    // False if tracking is disabled.
-    private boolean mTrackingEnabled;
-
-    // These fields may be null if package tracking is disabled.
-    private String mUpdateAppPackageName;
-    private String mDataAppPackageName;
-
-    // The time a triggered check is allowed to take before it is considered overdue.
-    private int mCheckTimeAllowedMillis;
-    // The number of failed checks in a row before reliability checks should stop happening.
-    private long mFailedCheckRetryCount;
-
-    // Reliability check state: If a check was triggered but not acknowledged within
-    // mCheckTimeAllowedMillis then another one can be triggered.
-    private Long mLastTriggerTimestamp = null;
-
-    // Reliability check state: Whether any checks have been triggered at all.
-    private boolean mCheckTriggered;
-
-    // Reliability check state: A count of how many failures have occurred consecutively.
-    private int mCheckFailureCount;
-
-    /** Creates the {@link PackageTracker} for normal use. */
-    static PackageTracker create(Context context) {
-        PackageTrackerHelperImpl helperImpl = new PackageTrackerHelperImpl(context);
-        return new PackageTracker(
-                helperImpl /* clock */,
-                helperImpl /* configHelper */,
-                helperImpl /* packageManagerHelper */,
-                new PackageStatusStorage(context),
-                new IntentHelperImpl(context));
-    }
-
-    // A constructor that can be used by tests to supply mocked / faked dependencies.
-    PackageTracker(ClockHelper clockHelper, ConfigHelper configHelper,
-            PackageManagerHelper packageManagerHelper, PackageStatusStorage packageStatusStorage,
-            IntentHelper intentHelper) {
-        mClockHelper = clockHelper;
-        mConfigHelper = configHelper;
-        mPackageManagerHelper = packageManagerHelper;
-        mPackageStatusStorage = packageStatusStorage;
-        mIntentHelper = intentHelper;
-    }
-
-    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
-    protected synchronized void start() {
-        mTrackingEnabled = mConfigHelper.isTrackingEnabled();
-        if (!mTrackingEnabled) {
-            Slog.i(TAG, "Time zone updater / data package tracking explicitly disabled.");
-            return;
-        }
-
-        mUpdateAppPackageName = mConfigHelper.getUpdateAppPackageName();
-        mDataAppPackageName = mConfigHelper.getDataAppPackageName();
-        mCheckTimeAllowedMillis = mConfigHelper.getCheckTimeAllowedMillis();
-        mFailedCheckRetryCount = mConfigHelper.getFailedCheckRetryCount();
-
-        // Validate the device configuration including the application packages.
-        // The manifest entries in the apps themselves are not validated until use as they can
-        // change and we don't want to prevent the system server starting due to a bad application.
-        throwIfDeviceSettingsOrAppsAreBad();
-
-        // Explicitly start in a reliability state where reliability triggering will do something.
-        mCheckTriggered = false;
-        mCheckFailureCount = 0;
-
-        // Initialize the intent helper.
-        mIntentHelper.initialize(mUpdateAppPackageName, mDataAppPackageName, this);
-
-        // Enable the reliability triggering so we will have at least one reliability trigger if
-        // a package isn't updated.
-        mIntentHelper.enableReliabilityTriggering();
-
-        Slog.i(TAG, "Time zone updater / data package tracking enabled");
-    }
-
-    /**
-     * Performs checks that confirm the system image has correctly configured package
-     * tracking configuration. Only called if package tracking is enabled. Throws an exception if
-     * the device is configured badly which will prevent the device booting.
-     */
-    private void throwIfDeviceSettingsOrAppsAreBad() {
-        // None of the checks below can be based on application manifest settings, otherwise a bad
-        // update could leave the device in an unbootable state. See validateDataAppManifest() and
-        // validateUpdaterAppManifest() for softer errors.
-
-        throwRuntimeExceptionIfNullOrEmpty(
-                mUpdateAppPackageName, "Update app package name missing.");
-        throwRuntimeExceptionIfNullOrEmpty(mDataAppPackageName, "Data app package name missing.");
-        if (mFailedCheckRetryCount < 1) {
-            throw logAndThrowRuntimeException("mFailedRetryCount=" + mFailedCheckRetryCount, null);
-        }
-        if (mCheckTimeAllowedMillis < 1000) {
-            throw logAndThrowRuntimeException(
-                    "mCheckTimeAllowedMillis=" + mCheckTimeAllowedMillis, null);
-        }
-
-        // Validate the updater application package.
-        // TODO(nfuller) Uncomment or remove the code below. Currently an app stops being a priv-app
-        // after it is replaced by one in data so this check fails. http://b/35995024
-        // try {
-        //     if (!mPackageManagerHelper.isPrivilegedApp(mUpdateAppPackageName)) {
-        //         throw failWithException(
-        //                 "Update app " + mUpdateAppPackageName + " must be a priv-app.", null);
-        //     }
-        // } catch (PackageManager.NameNotFoundException e) {
-        //     throw failWithException("Could not determine update app package details for "
-        //             + mUpdateAppPackageName, e);
-        // }
-        // TODO(nfuller) Consider permission checks. While an updated system app retains permissions
-        // obtained by the system version it's not clear how to check them.
-        Slog.d(TAG, "Update app " + mUpdateAppPackageName + " is valid.");
-
-        // Validate the data application package.
-        // TODO(nfuller) Uncomment or remove the code below. Currently an app stops being a priv-app
-        // after it is replaced by one in data. http://b/35995024
-        // try {
-        //     if (!mPackageManagerHelper.isPrivilegedApp(mDataAppPackageName)) {
-        //         throw failWithException(
-        //                 "Data app " + mDataAppPackageName + " must be a priv-app.", null);
-        //     }
-        // } catch (PackageManager.NameNotFoundException e) {
-        //     throw failWithException("Could not determine data app package details for "
-        //             + mDataAppPackageName, e);
-        // }
-        // TODO(nfuller) Consider permission checks. While an updated system app retains permissions
-        // obtained by the system version it's not clear how to check them.
-        Slog.d(TAG, "Data app " + mDataAppPackageName + " is valid.");
-    }
-
-    /**
-     * Inspects the current in-memory state, installed packages and storage state to determine if an
-     * update check is needed and then trigger if it is.
-     *
-     * @param packageChanged true if this method was called because a known packaged definitely
-     *     changed, false if the cause is a reliability trigger
-     */
-    @Override
-    public synchronized void triggerUpdateIfNeeded(boolean packageChanged) {
-        if (!mTrackingEnabled) {
-            throw new IllegalStateException("Unexpected call. Tracking is disabled.");
-        }
-
-        // Validate the applications' current manifest entries: make sure they are configured as
-        // they should be. These are not fatal and just means that no update is triggered: we don't
-        // want to take down the system server if an OEM or Google have pushed a bad update to
-        // an application.
-        boolean updaterAppManifestValid = validateUpdaterAppManifest();
-        boolean dataAppManifestValid = validateDataAppManifest();
-        if (!updaterAppManifestValid || !dataAppManifestValid) {
-            Slog.e(TAG, "No update triggered due to invalid application manifest entries."
-                    + " updaterApp=" + updaterAppManifestValid
-                    + ", dataApp=" + dataAppManifestValid);
-
-            // There's no point in doing reliability checks if the current packages are bad.
-            mIntentHelper.disableReliabilityTriggering();
-            return;
-        }
-
-        if (!packageChanged) {
-            // This call was made because the device is doing a "reliability" check.
-            // 4 possible cases:
-            // 1) No check has previously triggered since restart. We want to trigger in this case.
-            // 2) A check has previously triggered and it is in progress. We want to trigger if
-            //    the response is overdue.
-            // 3) A check has previously triggered and it failed. We want to trigger, but only if
-            //    we're not in a persistent failure state.
-            // 4) A check has previously triggered and it succeeded.
-            //    We don't want to trigger, and want to stop future triggers.
-
-            if (!mCheckTriggered) {
-                // Case 1.
-                Slog.d(TAG, "triggerUpdateIfNeeded: First reliability trigger.");
-            } else if (isCheckInProgress()) {
-                // Case 2.
-                if (!isCheckResponseOverdue()) {
-                    // A check is in progress but hasn't been given time to succeed.
-                    Slog.d(TAG,
-                            "triggerUpdateIfNeeded: checkComplete call is not yet overdue."
-                                    + " Not triggering.");
-                    // Not doing any work, but also not disabling future reliability triggers.
-                    return;
-                }
-            } else if (mCheckFailureCount > mFailedCheckRetryCount) {
-                // Case 3. If the system is in some kind of persistent failure state we don't want
-                // to keep checking, so just stop.
-                Slog.i(TAG, "triggerUpdateIfNeeded: number of allowed consecutive check failures"
-                        + " exceeded. Stopping reliability triggers until next reboot or package"
-                        + " update.");
-                mIntentHelper.disableReliabilityTriggering();
-                return;
-            } else if (mCheckFailureCount == 0) {
-                // Case 4.
-                Slog.i(TAG, "triggerUpdateIfNeeded: No reliability check required. Last check was"
-                        + " successful.");
-                mIntentHelper.disableReliabilityTriggering();
-                return;
-            }
-        }
-
-        // Read the currently installed data / updater package versions.
-        PackageVersions currentInstalledVersions = lookupInstalledPackageVersions();
-        if (currentInstalledVersions == null) {
-            // This should not happen if the device is configured in a valid way.
-            Slog.e(TAG, "triggerUpdateIfNeeded: currentInstalledVersions was null");
-            mIntentHelper.disableReliabilityTriggering();
-            return;
-        }
-
-        // Establish the current state using package manager and stored state. Determine if we have
-        // already successfully checked the installed versions.
-        PackageStatus packageStatus = mPackageStatusStorage.getPackageStatus();
-        if (packageStatus == null) {
-            // This can imply corrupt, uninitialized storage state (e.g. first check ever on a
-            // device) or after some kind of reset.
-            Slog.i(TAG, "triggerUpdateIfNeeded: No package status data found. Data check needed.");
-        } else if (!packageStatus.mVersions.equals(currentInstalledVersions)) {
-            // The stored package version information differs from the installed version.
-            // Trigger the check in all cases.
-            Slog.i(TAG, "triggerUpdateIfNeeded: Stored package versions="
-                    + packageStatus.mVersions + ", do not match current package versions="
-                    + currentInstalledVersions + ". Triggering check.");
-        } else {
-            Slog.i(TAG, "triggerUpdateIfNeeded: Stored package versions match currently"
-                    + " installed versions, currentInstalledVersions=" + currentInstalledVersions
-                    + ", packageStatus.mCheckStatus=" + packageStatus.mCheckStatus);
-            if (packageStatus.mCheckStatus == PackageStatus.CHECK_COMPLETED_SUCCESS) {
-                // The last check succeeded and nothing has changed. Do nothing and disable
-                // reliability checks.
-                Slog.i(TAG, "triggerUpdateIfNeeded: Prior check succeeded. No need to trigger.");
-                mIntentHelper.disableReliabilityTriggering();
-                return;
-            }
-        }
-
-        // Generate a token to send to the updater app.
-        CheckToken checkToken =
-                mPackageStatusStorage.generateCheckToken(currentInstalledVersions);
-        if (checkToken == null) {
-            Slog.w(TAG, "triggerUpdateIfNeeded: Unable to generate check token."
-                    + " Not sending check request.");
-            return;
-        }
-
-        // Trigger the update check.
-        mIntentHelper.sendTriggerUpdateCheck(checkToken);
-        mCheckTriggered = true;
-
-        // Update the reliability check state in case the update fails.
-        setCheckInProgress();
-
-        // Enable reliability triggering in case the check doesn't succeed and there is no
-        // response at all. Enabling reliability triggering is idempotent.
-        mIntentHelper.enableReliabilityTriggering();
-    }
-
-    /**
-     * Used to record the result of a check. Can be called even if active package tracking is
-     * disabled.
-     */
-    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
-    protected synchronized void recordCheckResult(CheckToken checkToken, boolean success) {
-        Slog.i(TAG, "recordOperationResult: checkToken=" + checkToken + " success=" + success);
-
-        // If package tracking is disabled it means no record-keeping is required. However, we do
-        // want to clear out any stored state to make it clear that the current state is unknown and
-        // should tracking become enabled again (perhaps through an OTA) we'd need to perform an
-        // update check.
-        if (!mTrackingEnabled) {
-            // This means an updater has spontaneously modified time zone data without having been
-            // triggered. This can happen if the OEM is handling their own updates, but we don't
-            // need to do any tracking in this case.
-
-            if (checkToken == null) {
-                // This is the expected case if tracking is disabled but an OEM is handling time
-                // zone installs using their own mechanism.
-                Slog.d(TAG, "recordCheckResult: Tracking is disabled and no token has been"
-                        + " provided. Resetting tracking state.");
-            } else {
-                // This is unexpected. If tracking is disabled then no check token should have been
-                // generated by the package tracker. An updater should never create its own token.
-                // This could be a bug in the updater.
-                Slog.w(TAG, "recordCheckResult: Tracking is disabled and a token " + checkToken
-                        + " has been unexpectedly provided. Resetting tracking state.");
-            }
-            mPackageStatusStorage.resetCheckState();
-            return;
-        }
-
-        if (checkToken == null) {
-            /*
-             * If the checkToken is null it suggests an install / uninstall / acknowledgement has
-             * occurred without a prior trigger (or the client didn't return the token it was given
-             * for some reason, perhaps a bug).
-             *
-             * This shouldn't happen under normal circumstances:
-             *
-             * If package tracking is enabled, we assume it is the package tracker responsible for
-             * triggering updates and a token should have been produced and returned.
-             *
-             * If the OEM is handling time zone updates case package tracking should be disabled.
-             *
-             * This could happen in tests. The device should recover back to a known state by
-             * itself rather than be left in an invalid state.
-             *
-             * We treat this as putting the device into an unknown state and make sure that
-             * reliability triggering is enabled so we should recover.
-             */
-            Slog.i(TAG, "recordCheckResult: Unexpectedly missing checkToken, resetting"
-                    + " storage state.");
-            mPackageStatusStorage.resetCheckState();
-
-            // Enable reliability triggering and reset the failure count so we know that the
-            // next reliability trigger will do something.
-            mIntentHelper.enableReliabilityTriggering();
-            mCheckFailureCount = 0;
-        } else {
-            // This is the expected case when tracking is enabled: a check was triggered and it has
-            // completed.
-            boolean recordedCheckCompleteSuccessfully =
-                    mPackageStatusStorage.markChecked(checkToken, success);
-            if (recordedCheckCompleteSuccessfully) {
-                // If we have recorded the result (whatever it was) we know there is no check in
-                // progress.
-                setCheckComplete();
-
-                if (success) {
-                    // Since the check was successful, no more reliability checks are required until
-                    // there is a package change.
-                    mIntentHelper.disableReliabilityTriggering();
-                    mCheckFailureCount = 0;
-                } else {
-                    // Enable reliability triggering to potentially check again in future.
-                    mIntentHelper.enableReliabilityTriggering();
-                    mCheckFailureCount++;
-                }
-            } else {
-                // The failure to record the check means an optimistic lock failure and suggests
-                // that another check was triggered after the token was generated.
-                Slog.i(TAG, "recordCheckResult: could not update token=" + checkToken
-                        + " with success=" + success + ". Optimistic lock failure");
-
-                // Enable reliability triggering to potentially try again in future.
-                mIntentHelper.enableReliabilityTriggering();
-                mCheckFailureCount++;
-            }
-        }
-    }
-
-    /** Access to consecutive failure counts for use in tests. */
-    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
-    protected int getCheckFailureCountForTests() {
-        return mCheckFailureCount;
-    }
-
-    private void setCheckInProgress() {
-        mLastTriggerTimestamp = mClockHelper.currentTimestamp();
-    }
-
-    private void setCheckComplete() {
-        mLastTriggerTimestamp = null;
-    }
-
-    private boolean isCheckInProgress() {
-        return mLastTriggerTimestamp != null;
-    }
-
-    private boolean isCheckResponseOverdue() {
-        if (mLastTriggerTimestamp == null) {
-            return false;
-        }
-        // Risk of overflow, but highly unlikely given the implementation and not problematic.
-        return mClockHelper.currentTimestamp() > mLastTriggerTimestamp + mCheckTimeAllowedMillis;
-    }
-
-    private PackageVersions lookupInstalledPackageVersions() {
-        int updatePackageVersion;
-        int dataPackageVersion;
-        try {
-            updatePackageVersion =
-                    mPackageManagerHelper.getInstalledPackageVersion(mUpdateAppPackageName);
-            dataPackageVersion =
-                    mPackageManagerHelper.getInstalledPackageVersion(mDataAppPackageName);
-        } catch (PackageManager.NameNotFoundException e) {
-            Slog.w(TAG, "lookupInstalledPackageVersions: Unable to resolve installed package"
-                    + " versions", e);
-            return null;
-        }
-        return new PackageVersions(updatePackageVersion, dataPackageVersion);
-    }
-
-    private boolean validateDataAppManifest() {
-        // We only want to talk to a provider that exposed by the known data app package
-        // so we look up the providers exposed by that app and check the well-known authority is
-        // there. This prevents the case where *even if* the data app doesn't expose the provider
-        // required, another app cannot expose one to replace it.
-        if (!mPackageManagerHelper.contentProviderRegistered(
-                TimeZoneRulesDataContract.AUTHORITY, mDataAppPackageName)) {
-            // Error! Found the package but it didn't expose the correct provider.
-            Slog.w(TAG, "validateDataAppManifest: Data app " + mDataAppPackageName
-                    + " does not expose the required provider with authority="
-                    + TimeZoneRulesDataContract.AUTHORITY);
-            return false;
-        }
-        // TODO(nfuller) Add any permissions checks needed.
-        return true;
-    }
-
-    private boolean validateUpdaterAppManifest() {
-        try {
-            // The updater app is expected to have the UPDATE_TIME_ZONE_RULES permission.
-            // The updater app is expected to have a receiver for the intent we are going to trigger
-            // and require the TRIGGER_TIME_ZONE_RULES_CHECK.
-            if (!mPackageManagerHelper.usesPermission(
-                    mUpdateAppPackageName,
-                    RulesUpdaterContract.UPDATE_TIME_ZONE_RULES_PERMISSION)) {
-                Slog.w(TAG, "validateUpdaterAppManifest: Updater app " + mDataAppPackageName
-                        + " does not use permission="
-                        + RulesUpdaterContract.UPDATE_TIME_ZONE_RULES_PERMISSION);
-                return false;
-            }
-            if (!mPackageManagerHelper.receiverRegistered(
-                    RulesUpdaterContract.createUpdaterIntent(mUpdateAppPackageName),
-                    RulesUpdaterContract.TRIGGER_TIME_ZONE_RULES_CHECK_PERMISSION)) {
-                return false;
-            }
-
-            return true;
-        } catch (PackageManager.NameNotFoundException e) {
-            Slog.w(TAG, "validateUpdaterAppManifest: Updater app " + mDataAppPackageName
-                    + " does not expose the required broadcast receiver.", e);
-            return false;
-        }
-    }
-
-    private static void throwRuntimeExceptionIfNullOrEmpty(String value, String message) {
-        if (value == null || value.trim().isEmpty()) {
-            throw logAndThrowRuntimeException(message, null);
-        }
-    }
-
-    private static RuntimeException logAndThrowRuntimeException(String message, Throwable cause) {
-        Slog.wtf(TAG, message, cause);
-        throw new RuntimeException(message, cause);
-    }
-}
diff --git a/services/core/java/com/android/server/timezone/PackageTrackerHelperImpl.java b/services/core/java/com/android/server/timezone/PackageTrackerHelperImpl.java
deleted file mode 100644
index 2e0c21b..0000000
--- a/services/core/java/com/android/server/timezone/PackageTrackerHelperImpl.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.timezone;
-
-import com.android.internal.R;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ProviderInfo;
-import android.content.pm.ResolveInfo;
-import android.content.res.Resources;
-import android.os.SystemClock;
-import android.util.Slog;
-
-import java.util.List;
-
-/**
- * A single class that implements multiple helper interfaces for use by {@link PackageTracker}.
- */
-final class PackageTrackerHelperImpl implements ClockHelper, ConfigHelper, PackageManagerHelper {
-
-    private static final String TAG = "PackageTrackerHelperImpl";
-
-    private final Context mContext;
-    private final PackageManager mPackageManager;
-
-    PackageTrackerHelperImpl(Context context) {
-        mContext = context;
-        mPackageManager = context.getPackageManager();
-    }
-
-    @Override
-    public boolean isTrackingEnabled() {
-        return mContext.getResources().getBoolean(R.bool.config_timeZoneRulesUpdateTrackingEnabled);
-    }
-
-    @Override
-    public String getUpdateAppPackageName() {
-        return mContext.getResources().getString(R.string.config_timeZoneRulesUpdaterPackage);
-    }
-
-    @Override
-    public String getDataAppPackageName() {
-        Resources resources = mContext.getResources();
-        return resources.getString(R.string.config_timeZoneRulesDataPackage);
-    }
-
-    @Override
-    public int getCheckTimeAllowedMillis() {
-        return mContext.getResources().getInteger(
-                R.integer.config_timeZoneRulesCheckTimeMillisAllowed);
-    }
-
-    @Override
-    public int getFailedCheckRetryCount() {
-        return mContext.getResources().getInteger(R.integer.config_timeZoneRulesCheckRetryCount);
-    }
-
-    @Override
-    public long currentTimestamp() {
-        // Use of elapsedRealtime() because this is in-memory state and elapsedRealtime() shouldn't
-        // change if the system clock changes.
-        return SystemClock.elapsedRealtime();
-    }
-
-    @Override
-    public int getInstalledPackageVersion(String packageName)
-            throws PackageManager.NameNotFoundException {
-        int flags = PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS;
-        PackageInfo packageInfo = mPackageManager.getPackageInfo(packageName, flags);
-        return packageInfo.versionCode;
-    }
-
-    @Override
-    public boolean isPrivilegedApp(String packageName) throws PackageManager.NameNotFoundException {
-        int flags = PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS;
-        PackageInfo packageInfo = mPackageManager.getPackageInfo(packageName, flags);
-        return packageInfo.applicationInfo.isPrivilegedApp();
-    }
-
-    @Override
-    public boolean usesPermission(String packageName, String requiredPermissionName)
-            throws PackageManager.NameNotFoundException {
-        int flags = PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
-                | PackageManager.GET_PERMISSIONS;
-        PackageInfo packageInfo = mPackageManager.getPackageInfo(packageName, flags);
-        if (packageInfo.requestedPermissions == null) {
-            return false;
-        }
-        for (String requestedPermission : packageInfo.requestedPermissions) {
-            if (requiredPermissionName.equals(requestedPermission)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public boolean contentProviderRegistered(String authority, String requiredPackageName) {
-        int flags = PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS;
-        ProviderInfo providerInfo =
-                mPackageManager.resolveContentProvider(authority, flags);
-        if (providerInfo == null) {
-            Slog.i(TAG, "contentProviderRegistered: No content provider registered with authority="
-                    + authority);
-            return false;
-        }
-        boolean packageMatches =
-                requiredPackageName.equals(providerInfo.applicationInfo.packageName);
-        if (!packageMatches) {
-            Slog.i(TAG, "contentProviderRegistered: App with packageName=" + requiredPackageName
-                    + " does not expose the a content provider with authority=" + authority);
-            return false;
-        }
-        return true;
-    }
-
-    @Override
-    public boolean receiverRegistered(Intent intent, String requiredPermissionName)
-            throws PackageManager.NameNotFoundException {
-
-        int flags = PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS;
-        List<ResolveInfo> resolveInfo = mPackageManager.queryBroadcastReceivers(intent, flags);
-        if (resolveInfo.size() != 1) {
-            Slog.i(TAG, "receiverRegistered: Zero or multiple broadcast receiver registered for"
-                    + " intent=" + intent + ", found=" + resolveInfo);
-            return false;
-        }
-
-        ResolveInfo matched = resolveInfo.get(0);
-        boolean requiresPermission = requiredPermissionName.equals(matched.activityInfo.permission);
-        if (!requiresPermission) {
-            Slog.i(TAG, "receiverRegistered: Broadcast receiver registered for intent="
-                    + intent + " must require permission " + requiredPermissionName);
-        }
-        return requiresPermission;
-    }
-}
diff --git a/services/core/java/com/android/server/timezone/PackageVersions.java b/services/core/java/com/android/server/timezone/PackageVersions.java
deleted file mode 100644
index fc0d6e1..0000000
--- a/services/core/java/com/android/server/timezone/PackageVersions.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.timezone;
-
-/**
- * Package version information about the time zone updater and time zone data application packages.
- */
-final class PackageVersions {
-
-    final int mUpdateAppVersion;
-    final int mDataAppVersion;
-
-    PackageVersions(int updateAppVersion, int dataAppVersion) {
-        this.mUpdateAppVersion = updateAppVersion;
-        this.mDataAppVersion = dataAppVersion;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (o == null || getClass() != o.getClass()) {
-            return false;
-        }
-
-        PackageVersions that = (PackageVersions) o;
-
-        if (mUpdateAppVersion != that.mUpdateAppVersion) {
-            return false;
-        }
-        return mDataAppVersion == that.mDataAppVersion;
-    }
-
-    @Override
-    public int hashCode() {
-        int result = mUpdateAppVersion;
-        result = 31 * result + mDataAppVersion;
-        return result;
-    }
-
-    @Override
-    public String toString() {
-        return "PackageVersions{" +
-                "mUpdateAppVersion=" + mUpdateAppVersion +
-                ", mDataAppVersion=" + mDataAppVersion +
-                '}';
-    }
-}
diff --git a/services/core/java/com/android/server/timezone/PermissionHelper.java b/services/core/java/com/android/server/timezone/PermissionHelper.java
deleted file mode 100644
index ba91c7f..0000000
--- a/services/core/java/com/android/server/timezone/PermissionHelper.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.timezone;
-
-/**
- * An easy-to-mock interface around permission checks for use by {@link RulesManagerService}.
- */
-public interface PermissionHelper {
-
-    void enforceCallerHasPermission(String requiredPermission) throws SecurityException;
-}
diff --git a/services/core/java/com/android/server/timezone/RulesManagerService.java b/services/core/java/com/android/server/timezone/RulesManagerService.java
deleted file mode 100644
index 82bd356..0000000
--- a/services/core/java/com/android/server/timezone/RulesManagerService.java
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.timezone;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.server.SystemService;
-
-import android.app.timezone.Callback;
-import android.app.timezone.DistroFormatVersion;
-import android.app.timezone.DistroRulesVersion;
-import android.app.timezone.ICallback;
-import android.app.timezone.IRulesManager;
-import android.app.timezone.RulesManager;
-import android.app.timezone.RulesState;
-import android.content.Context;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-import android.util.Slog;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.concurrent.Executor;
-import java.util.concurrent.atomic.AtomicBoolean;
-import libcore.tzdata.shared2.DistroException;
-import libcore.tzdata.shared2.DistroVersion;
-import libcore.tzdata.shared2.StagedDistroOperation;
-import libcore.tzdata.update2.TimeZoneDistroInstaller;
-
-// TODO(nfuller) Add EventLog calls where useful in the system server.
-// TODO(nfuller) Check logging best practices in the system server.
-// TODO(nfuller) Check error handling best practices in the system server.
-public final class RulesManagerService extends IRulesManager.Stub {
-
-    private static final String TAG = "timezone.RulesManagerService";
-
-    /** The distro format supported by this device. */
-    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
-    static final DistroFormatVersion DISTRO_FORMAT_VERSION_SUPPORTED =
-            new DistroFormatVersion(
-                    DistroVersion.CURRENT_FORMAT_MAJOR_VERSION,
-                    DistroVersion.CURRENT_FORMAT_MINOR_VERSION);
-
-    public static class Lifecycle extends SystemService {
-        private RulesManagerService mService;
-
-        public Lifecycle(Context context) {
-            super(context);
-        }
-
-        @Override
-        public void onStart() {
-            mService = RulesManagerService.create(getContext());
-            mService.start();
-
-            publishBinderService(Context.TIME_ZONE_RULES_MANAGER_SERVICE, mService);
-        }
-    }
-
-    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
-    static final String REQUIRED_UPDATER_PERMISSION =
-            android.Manifest.permission.UPDATE_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;
-    private final PackageTracker mPackageTracker;
-    private final Executor mExecutor;
-    private final TimeZoneDistroInstaller mInstaller;
-    private final FileDescriptorHelper mFileDescriptorHelper;
-
-    private static RulesManagerService create(Context context) {
-        RulesManagerServiceHelperImpl helper = new RulesManagerServiceHelperImpl(context);
-        return new RulesManagerService(
-                helper /* permissionHelper */,
-                helper /* executor */,
-                helper /* fileDescriptorHelper */,
-                PackageTracker.create(context),
-                new TimeZoneDistroInstaller(TAG, SYSTEM_TZ_DATA_FILE, TZ_DATA_DIR));
-    }
-
-    // A constructor that can be used by tests to supply mocked / faked dependencies.
-    RulesManagerService(PermissionHelper permissionHelper,
-            Executor executor,
-            FileDescriptorHelper fileDescriptorHelper, PackageTracker packageTracker,
-            TimeZoneDistroInstaller timeZoneDistroInstaller) {
-        mPermissionHelper = permissionHelper;
-        mExecutor = executor;
-        mFileDescriptorHelper = fileDescriptorHelper;
-        mPackageTracker = packageTracker;
-        mInstaller = timeZoneDistroInstaller;
-    }
-
-    public void start() {
-        mPackageTracker.start();
-    }
-
-    @Override // Binder call
-    public RulesState getRulesState() {
-        mPermissionHelper.enforceCallerHasPermission(REQUIRED_UPDATER_PERMISSION);
-
-        synchronized(this) {
-            String systemRulesVersion;
-            try {
-                systemRulesVersion = mInstaller.getSystemRulesVersion();
-            } catch (IOException e) {
-                Slog.w(TAG, "Failed to read system rules", e);
-                return null;
-            }
-
-            boolean operationInProgress = this.mOperationInProgress.get();
-
-            // Determine the staged operation status, if possible.
-            DistroRulesVersion stagedDistroRulesVersion = null;
-            int stagedOperationStatus = RulesState.STAGED_OPERATION_UNKNOWN;
-            if (!operationInProgress) {
-                StagedDistroOperation stagedDistroOperation;
-                try {
-                    stagedDistroOperation = mInstaller.getStagedDistroOperation();
-                    if (stagedDistroOperation == null) {
-                        stagedOperationStatus = RulesState.STAGED_OPERATION_NONE;
-                    } else if (stagedDistroOperation.isUninstall) {
-                        stagedOperationStatus = RulesState.STAGED_OPERATION_UNINSTALL;
-                    } else {
-                        // Must be an install.
-                        stagedOperationStatus = RulesState.STAGED_OPERATION_INSTALL;
-                        DistroVersion stagedDistroVersion = stagedDistroOperation.distroVersion;
-                        stagedDistroRulesVersion = new DistroRulesVersion(
-                                stagedDistroVersion.rulesVersion,
-                                stagedDistroVersion.revision);
-                    }
-                } catch (DistroException | IOException e) {
-                    Slog.w(TAG, "Failed to read staged distro.", e);
-                }
-            }
-
-            // Determine the installed distro state, if possible.
-            DistroVersion installedDistroVersion;
-            int distroStatus = RulesState.DISTRO_STATUS_UNKNOWN;
-            DistroRulesVersion installedDistroRulesVersion = null;
-            if (!operationInProgress) {
-                try {
-                    installedDistroVersion = mInstaller.getInstalledDistroVersion();
-                    if (installedDistroVersion == null) {
-                        distroStatus = RulesState.DISTRO_STATUS_NONE;
-                        installedDistroRulesVersion = null;
-                    } else {
-                        distroStatus = RulesState.DISTRO_STATUS_INSTALLED;
-                        installedDistroRulesVersion = new DistroRulesVersion(
-                                installedDistroVersion.rulesVersion,
-                                installedDistroVersion.revision);
-                    }
-                } catch (DistroException | IOException e) {
-                    Slog.w(TAG, "Failed to read installed distro.", e);
-                }
-            }
-            return new RulesState(systemRulesVersion, DISTRO_FORMAT_VERSION_SUPPORTED,
-                    operationInProgress, stagedOperationStatus, stagedDistroRulesVersion,
-                    distroStatus, installedDistroRulesVersion);
-        }
-    }
-
-    @Override
-    public int requestInstall(
-            ParcelFileDescriptor timeZoneDistro, byte[] checkTokenBytes, ICallback callback) {
-        mPermissionHelper.enforceCallerHasPermission(REQUIRED_UPDATER_PERMISSION);
-
-        CheckToken checkToken = null;
-        if (checkTokenBytes != null) {
-            checkToken = createCheckTokenOrThrow(checkTokenBytes);
-        }
-        synchronized (this) {
-            if (timeZoneDistro == null) {
-                throw new NullPointerException("timeZoneDistro == null");
-            }
-            if (callback == null) {
-                throw new NullPointerException("observer == null");
-            }
-            if (mOperationInProgress.get()) {
-                return RulesManager.ERROR_OPERATION_IN_PROGRESS;
-            }
-            mOperationInProgress.set(true);
-
-            // Execute the install asynchronously.
-            mExecutor.execute(new InstallRunnable(timeZoneDistro, checkToken, callback));
-
-            return RulesManager.SUCCESS;
-        }
-    }
-
-    private class InstallRunnable implements Runnable {
-
-        private final ParcelFileDescriptor mTimeZoneDistro;
-        private final CheckToken mCheckToken;
-        private final ICallback mCallback;
-
-        InstallRunnable(
-                ParcelFileDescriptor timeZoneDistro, CheckToken checkToken, ICallback callback) {
-            mTimeZoneDistro = timeZoneDistro;
-            mCheckToken = checkToken;
-            mCallback = callback;
-        }
-
-        @Override
-        public void run() {
-            // Adopt the ParcelFileDescriptor into this try-with-resources so it is closed
-            // when we are done.
-            boolean success = false;
-            try {
-                byte[] distroBytes =
-                        RulesManagerService.this.mFileDescriptorHelper.readFully(mTimeZoneDistro);
-                int installerResult = mInstaller.stageInstallWithErrorCode(distroBytes);
-                int resultCode = mapInstallerResultToApiCode(installerResult);
-                sendFinishedStatus(mCallback, resultCode);
-
-                // All the installer failure modes are currently non-recoverable and won't be
-                // improved by trying again. Therefore success = true.
-                success = true;
-            } catch (Exception e) {
-                Slog.w(TAG, "Failed to install distro.", e);
-                sendFinishedStatus(mCallback, Callback.ERROR_UNKNOWN_FAILURE);
-            } finally {
-                // Notify the package tracker that the operation is now complete.
-                mPackageTracker.recordCheckResult(mCheckToken, success);
-
-                mOperationInProgress.set(false);
-            }
-        }
-
-        private int mapInstallerResultToApiCode(int installerResult) {
-            switch (installerResult) {
-                case TimeZoneDistroInstaller.INSTALL_SUCCESS:
-                    return Callback.SUCCESS;
-                case TimeZoneDistroInstaller.INSTALL_FAIL_BAD_DISTRO_STRUCTURE:
-                    return Callback.ERROR_INSTALL_BAD_DISTRO_STRUCTURE;
-                case TimeZoneDistroInstaller.INSTALL_FAIL_RULES_TOO_OLD:
-                    return Callback.ERROR_INSTALL_RULES_TOO_OLD;
-                case TimeZoneDistroInstaller.INSTALL_FAIL_BAD_DISTRO_FORMAT_VERSION:
-                    return Callback.ERROR_INSTALL_BAD_DISTRO_FORMAT_VERSION;
-                case TimeZoneDistroInstaller.INSTALL_FAIL_VALIDATION_ERROR:
-                    return Callback.ERROR_INSTALL_VALIDATION_ERROR;
-                default:
-                    return Callback.ERROR_UNKNOWN_FAILURE;
-            }
-        }
-    }
-
-    @Override
-    public int requestUninstall(byte[] checkTokenBytes, ICallback callback) {
-        mPermissionHelper.enforceCallerHasPermission(REQUIRED_UPDATER_PERMISSION);
-
-        CheckToken checkToken = null;
-        if (checkTokenBytes != null) {
-            checkToken = createCheckTokenOrThrow(checkTokenBytes);
-        }
-        synchronized(this) {
-            if (callback == null) {
-                throw new NullPointerException("callback == null");
-            }
-
-            if (mOperationInProgress.get()) {
-                return RulesManager.ERROR_OPERATION_IN_PROGRESS;
-            }
-            mOperationInProgress.set(true);
-
-            // Execute the uninstall asynchronously.
-            mExecutor.execute(new UninstallRunnable(checkToken, callback));
-
-            return RulesManager.SUCCESS;
-        }
-    }
-
-    private class UninstallRunnable implements Runnable {
-
-        private final CheckToken mCheckToken;
-        private final ICallback mCallback;
-
-        public UninstallRunnable(CheckToken checkToken, ICallback callback) {
-            mCheckToken = checkToken;
-            mCallback = callback;
-        }
-
-        @Override
-        public void run() {
-            boolean success = false;
-            try {
-                success = mInstaller.stageUninstall();
-                // Right now we just have success (0) / failure (1). All clients should be checking
-                // against SUCCESS. More granular failures may be added in future.
-                int resultCode = success ? Callback.SUCCESS
-                        : Callback.ERROR_UNKNOWN_FAILURE;
-                sendFinishedStatus(mCallback, resultCode);
-            } catch (Exception e) {
-                Slog.w(TAG, "Failed to uninstall distro.", e);
-                sendFinishedStatus(mCallback, Callback.ERROR_UNKNOWN_FAILURE);
-            } finally {
-                // Notify the package tracker that the operation is now complete.
-                mPackageTracker.recordCheckResult(mCheckToken, success);
-
-                mOperationInProgress.set(false);
-            }
-        }
-    }
-
-    private void sendFinishedStatus(ICallback callback, int resultCode) {
-        try {
-            callback.onFinished(resultCode);
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Unable to notify observer of result", e);
-        }
-    }
-
-    @Override
-    public void requestNothing(byte[] checkTokenBytes, boolean success) {
-        mPermissionHelper.enforceCallerHasPermission(REQUIRED_UPDATER_PERMISSION);
-        CheckToken checkToken = null;
-        if (checkTokenBytes != null) {
-            checkToken = createCheckTokenOrThrow(checkTokenBytes);
-        }
-        mPackageTracker.recordCheckResult(checkToken, success);
-    }
-
-    private static CheckToken createCheckTokenOrThrow(byte[] checkTokenBytes) {
-        CheckToken checkToken;
-        try {
-            checkToken = CheckToken.fromByteArray(checkTokenBytes);
-        } catch (IOException e) {
-            throw new IllegalArgumentException("Unable to read token bytes "
-                    + Arrays.toString(checkTokenBytes), e);
-        }
-        return checkToken;
-    }
-}
diff --git a/services/core/java/com/android/server/timezone/RulesManagerServiceHelperImpl.java b/services/core/java/com/android/server/timezone/RulesManagerServiceHelperImpl.java
deleted file mode 100644
index 15a571d..0000000
--- a/services/core/java/com/android/server/timezone/RulesManagerServiceHelperImpl.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.timezone;
-
-import android.content.Context;
-import android.os.ParcelFileDescriptor;
-
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.concurrent.Executor;
-import libcore.io.Streams;
-
-/**
- * A single class that implements multiple helper interfaces for use by {@link RulesManagerService}.
- */
-final class RulesManagerServiceHelperImpl
-        implements PermissionHelper, Executor, FileDescriptorHelper {
-
-    private final Context mContext;
-
-    RulesManagerServiceHelperImpl(Context context) {
-        mContext = context;
-    }
-
-    @Override
-    public void enforceCallerHasPermission(String requiredPermission) {
-        mContext.enforceCallingPermission(requiredPermission, null /* message */);
-    }
-
-    // TODO Wake lock required?
-    @Override
-    public void execute(Runnable runnable) {
-        // TODO Is there a better way?
-        new Thread(runnable).start();
-    }
-
-    @Override
-    public byte[] readFully(ParcelFileDescriptor parcelFileDescriptor) throws IOException {
-        try (ParcelFileDescriptor pfd = parcelFileDescriptor) {
-            // Read bytes
-            FileInputStream in = new FileInputStream(pfd.getFileDescriptor(), false /* isOwner */);
-            return Streams.readFully(in);
-        }
-    }
-}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 35062c1..4cdd7fe 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -200,8 +200,6 @@
             "com.android.server.wallpaper.WallpaperManagerService$Lifecycle";
     private static final String AUTO_FILL_MANAGER_SERVICE_CLASS =
             "com.android.server.autofill.AutofillManagerService";
-    private static final String TIME_ZONE_RULES_MANAGER_SERVICE_CLASS =
-            "com.android.server.timezone.RulesManagerService$Lifecycle";
 
     private static final String PERSISTENT_DATA_BLOCK_PROP = "ro.frp.pst";
 
@@ -1213,13 +1211,6 @@
                 traceEnd();
             }
 
-            if (!disableNonCoreServices && context.getResources().getBoolean(
-                        R.bool.config_enableUpdateableTimeZoneRules)) {
-                traceBeginAndSlog("StartTimeZoneRulesManagerService");
-                mSystemServiceManager.startService(TIME_ZONE_RULES_MANAGER_SERVICE_CLASS);
-                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
-            }
-
             traceBeginAndSlog("StartAudioService");
             mSystemServiceManager.startService(AudioService.Lifecycle.class);
             traceEnd();
diff --git a/services/tests/servicestests/src/com/android/server/timezone/CheckTokenTest.java b/services/tests/servicestests/src/com/android/server/timezone/CheckTokenTest.java
deleted file mode 100644
index 9603a06..0000000
--- a/services/tests/servicestests/src/com/android/server/timezone/CheckTokenTest.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.timezone;
-
-import org.junit.Test;
-
-import android.support.test.filters.SmallTest;
-
-import java.io.IOException;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.fail;
-
-@SmallTest
-public class CheckTokenTest {
-
-    @Test
-    public void toByteArray() throws Exception {
-        PackageVersions packageVersions =
-                new PackageVersions(1 /* updateAppVersion */, 1 /* dataAppVersion */);
-        CheckToken originalToken = new CheckToken(1 /* optimisticLockId */, packageVersions);
-        assertEquals(originalToken, CheckToken.fromByteArray(originalToken.toByteArray()));
-    }
-
-    @Test
-    public void fromByteArray() {
-        PackageVersions packageVersions =
-                new PackageVersions(1 /* updateAppVersion */, 1 /* dataAppVersion */);
-        CheckToken token = new CheckToken(1, packageVersions);
-        byte[] validTokenBytes = token.toByteArray();
-        byte[] shortTokenBytes = new byte[validTokenBytes.length - 1];
-        System.arraycopy(validTokenBytes, 0, shortTokenBytes, 0, shortTokenBytes.length);
-
-        try {
-            CheckToken.fromByteArray(shortTokenBytes);
-            fail();
-        } catch (IOException expected) {}
-    }
-
-    @Test
-    public void equals() {
-        PackageVersions packageVersions1 =
-                new PackageVersions(1 /* updateAppVersion */, 1 /* dataAppVersion */);
-        PackageVersions packageVersions2 =
-                new PackageVersions(2 /* updateAppVersion */, 2 /* dataAppVersion */);
-        assertFalse(packageVersions1.equals(packageVersions2));
-
-        CheckToken baseline = new CheckToken(1, packageVersions1);
-        assertEquals(baseline, baseline);
-
-        CheckToken deepEqual = new CheckToken(1, packageVersions1);
-        assertEquals(baseline, deepEqual);
-
-        CheckToken differentOptimisticLockId = new CheckToken(2, packageVersions1);
-        assertFalse(differentOptimisticLockId.equals(baseline));
-
-        CheckToken differentPackageVersions = new CheckToken(1, packageVersions2);
-        assertFalse(differentPackageVersions.equals(baseline));
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/timezone/PackageStatusStorageTest.java b/services/tests/servicestests/src/com/android/server/timezone/PackageStatusStorageTest.java
deleted file mode 100644
index e085270..0000000
--- a/services/tests/servicestests/src/com/android/server/timezone/PackageStatusStorageTest.java
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.timezone;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import android.content.Context;
-import android.database.sqlite.SQLiteDatabase;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-
-import static junit.framework.Assert.assertTrue;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-
-@SmallTest
-public class PackageStatusStorageTest {
-    private static final PackageVersions VALID_PACKAGE_VERSIONS = new PackageVersions(1, 2);
-
-    private PackageStatusStorage mPackageStatusStorage;
-
-    @Before
-    public void setUp() throws Exception {
-        Context context = InstrumentationRegistry.getContext();
-
-        // Using the instrumentation context means the database is created in a test app-specific
-        // directory.
-        mPackageStatusStorage = new PackageStatusStorage(context);
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        mPackageStatusStorage.deleteDatabaseForTests();
-    }
-
-    @Test
-    public void getPackageStatus_initialState() {
-        assertNull(mPackageStatusStorage.getPackageStatus());
-    }
-
-    @Test
-    public void resetCheckState() {
-        // Assert initial state.
-        assertNull(mPackageStatusStorage.getPackageStatus());
-
-        CheckToken token1 = mPackageStatusStorage.generateCheckToken(VALID_PACKAGE_VERSIONS);
-
-        // There should now be a state.
-        assertNotNull(mPackageStatusStorage.getPackageStatus());
-
-        // Now clear the state.
-        mPackageStatusStorage.resetCheckState();
-
-        // After reset, there should be no package state again.
-        assertNull(mPackageStatusStorage.getPackageStatus());
-
-        CheckToken token2 = mPackageStatusStorage.generateCheckToken(VALID_PACKAGE_VERSIONS);
-
-        // Token after a reset should still be distinct.
-        assertFalse(token1.equals(token2));
-
-        // Now clear the state again.
-        mPackageStatusStorage.resetCheckState();
-
-        // After reset, there should be no package state again.
-        assertNull(mPackageStatusStorage.getPackageStatus());
-
-        CheckToken token3 = mPackageStatusStorage.generateCheckToken(VALID_PACKAGE_VERSIONS);
-
-        // A CheckToken generated after a reset should still be distinct.
-        assertFalse(token2.equals(token3));
-    }
-
-    @Test
-    public void generateCheckToken_missingRowBehavior() {
-        // Assert initial state.
-        assertNull(mPackageStatusStorage.getPackageStatus());
-
-        CheckToken token1 = mPackageStatusStorage.generateCheckToken(VALID_PACKAGE_VERSIONS);
-        assertNotNull(token1);
-
-        // There should now be state.
-        assertNotNull(mPackageStatusStorage.getPackageStatus());
-
-        // Corrupt the table by removing the one row.
-        mPackageStatusStorage.deleteRowForTests();
-
-        // Check that generateCheckToken recovers.
-        assertNotNull(mPackageStatusStorage.generateCheckToken(VALID_PACKAGE_VERSIONS));
-    }
-
-    @Test
-    public void getPackageStatus_missingRowBehavior() {
-        // Assert initial state.
-        assertNull(mPackageStatusStorage.getPackageStatus());
-
-        CheckToken token1 = mPackageStatusStorage.generateCheckToken(VALID_PACKAGE_VERSIONS);
-        assertNotNull(token1);
-
-        // There should now be a state.
-        assertNotNull(mPackageStatusStorage.getPackageStatus());
-
-        // Corrupt the table by removing the one row.
-        mPackageStatusStorage.deleteRowForTests();
-
-        assertNull(mPackageStatusStorage.getPackageStatus());
-    }
-
-    @Test
-    public void markChecked_missingRowBehavior() {
-        // Assert initial state.
-        CheckToken token1 = mPackageStatusStorage.generateCheckToken(VALID_PACKAGE_VERSIONS);
-        assertNotNull(token1);
-
-        // There should now be a state.
-        assertNotNull(mPackageStatusStorage.getPackageStatus());
-
-        // Corrupt the table by removing the one row.
-        mPackageStatusStorage.deleteRowForTests();
-
-        // The missing row should mean token1 is now considered invalid, so we should get a false.
-        assertFalse(mPackageStatusStorage.markChecked(token1, true /* succeeded */));
-
-        // The storage should have recovered and we should be able to carry on like before.
-        CheckToken token2 = mPackageStatusStorage.generateCheckToken(VALID_PACKAGE_VERSIONS);
-        assertTrue(mPackageStatusStorage.markChecked(token2, true /* succeeded */));
-    }
-
-    @Test
-    public void checkToken_tokenIsUnique() {
-        PackageVersions packageVersions = VALID_PACKAGE_VERSIONS;
-        PackageStatus expectedPackageStatus =
-                new PackageStatus(PackageStatus.CHECK_STARTED, packageVersions);
-
-        CheckToken token1 = mPackageStatusStorage.generateCheckToken(packageVersions);
-        assertEquals(packageVersions, token1.mPackageVersions);
-
-        PackageStatus actualPackageStatus1 = mPackageStatusStorage.getPackageStatus();
-        assertEquals(expectedPackageStatus, actualPackageStatus1);
-
-        CheckToken token2 = mPackageStatusStorage.generateCheckToken(packageVersions);
-        assertEquals(packageVersions, token1.mPackageVersions);
-        assertFalse(token1.mOptimisticLockId == token2.mOptimisticLockId);
-        assertFalse(token1.equals(token2));
-    }
-
-    @Test
-    public void markChecked_checkSucceeded() {
-        PackageVersions packageVersions = VALID_PACKAGE_VERSIONS;
-
-        CheckToken token = mPackageStatusStorage.generateCheckToken(packageVersions);
-        boolean writeOk = mPackageStatusStorage.markChecked(token, true /* succeeded */);
-        assertTrue(writeOk);
-
-        PackageStatus expectedPackageStatus =
-                new PackageStatus(PackageStatus.CHECK_COMPLETED_SUCCESS, packageVersions);
-        assertEquals(expectedPackageStatus, mPackageStatusStorage.getPackageStatus());
-    }
-
-    @Test
-    public void markChecked_checkFailed() {
-        PackageVersions packageVersions = VALID_PACKAGE_VERSIONS;
-
-        CheckToken token = mPackageStatusStorage.generateCheckToken(packageVersions);
-        boolean writeOk = mPackageStatusStorage.markChecked(token, false /* succeeded */);
-        assertTrue(writeOk);
-
-        PackageStatus expectedPackageStatus =
-                new PackageStatus(PackageStatus.CHECK_COMPLETED_FAILURE, packageVersions);
-        assertEquals(expectedPackageStatus, mPackageStatusStorage.getPackageStatus());
-    }
-
-    @Test
-    public void markChecked_optimisticLocking_multipleToken() {
-        PackageVersions packageVersions = VALID_PACKAGE_VERSIONS;
-        CheckToken token1 = mPackageStatusStorage.generateCheckToken(packageVersions);
-        CheckToken token2 = mPackageStatusStorage.generateCheckToken(packageVersions);
-
-        PackageStatus packageStatusBeforeChecked = mPackageStatusStorage.getPackageStatus();
-
-        boolean writeOk1 = mPackageStatusStorage.markChecked(token1, true /* succeeded */);
-        // Generation of token2 should mean that token1 is no longer valid.
-        assertFalse(writeOk1);
-        assertEquals(packageStatusBeforeChecked, mPackageStatusStorage.getPackageStatus());
-
-        boolean writeOk2 = mPackageStatusStorage.markChecked(token2, true /* succeeded */);
-        // token2 should still be valid, and the attempt with token1 should have had no effect.
-        assertTrue(writeOk2);
-        PackageStatus expectedPackageStatus =
-                new PackageStatus(PackageStatus.CHECK_COMPLETED_SUCCESS, packageVersions);
-        assertEquals(expectedPackageStatus, mPackageStatusStorage.getPackageStatus());
-    }
-
-    @Test
-    public void markChecked_optimisticLocking_repeatedTokenUse() {
-        PackageVersions packageVersions = VALID_PACKAGE_VERSIONS;
-        CheckToken token = mPackageStatusStorage.generateCheckToken(packageVersions);
-
-        boolean writeOk1 = mPackageStatusStorage.markChecked(token, true /* succeeded */);
-        assertTrue(writeOk1);
-
-        PackageStatus expectedPackageStatus =
-                new PackageStatus(PackageStatus.CHECK_COMPLETED_SUCCESS, packageVersions);
-        assertEquals(expectedPackageStatus, mPackageStatusStorage.getPackageStatus());
-
-        // token cannot be reused.
-        boolean writeOk2 = mPackageStatusStorage.markChecked(token, true /* succeeded */);
-        assertFalse(writeOk2);
-        assertEquals(expectedPackageStatus, mPackageStatusStorage.getPackageStatus());
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/timezone/PackageStatusTest.java b/services/tests/servicestests/src/com/android/server/timezone/PackageStatusTest.java
deleted file mode 100644
index c0ae81e..0000000
--- a/services/tests/servicestests/src/com/android/server/timezone/PackageStatusTest.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.timezone;
-
-import org.junit.Test;
-
-import android.support.test.filters.SmallTest;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-
-@SmallTest
-public class PackageStatusTest {
-
-    @Test
-    public void equals() {
-        PackageVersions packageVersions1 =
-                new PackageVersions(1 /* updateAppVersion */, 1 /* dataAppVersion */);
-        PackageVersions packageVersions2 =
-                new PackageVersions(2 /* updateAppVersion */, 1 /* dataAppVersion */);
-        assertFalse(packageVersions1.equals(packageVersions2));
-
-        PackageStatus baseline =
-                new PackageStatus(PackageStatus.CHECK_STARTED, packageVersions1);
-        assertEquals(baseline, baseline);
-
-        PackageStatus deepEqual =
-                new PackageStatus(PackageStatus.CHECK_STARTED, packageVersions1);
-        assertEquals(baseline, deepEqual);
-
-        PackageStatus differentStatus =
-                new PackageStatus(PackageStatus.CHECK_COMPLETED_SUCCESS, packageVersions1);
-        assertFalse(differentStatus.equals(baseline));
-
-        PackageStatus differentPackageVersions =
-                new PackageStatus(PackageStatus.CHECK_STARTED, packageVersions2);
-        assertFalse(differentPackageVersions.equals(baseline));
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/timezone/PackageTrackerTest.java b/services/tests/servicestests/src/com/android/server/timezone/PackageTrackerTest.java
deleted file mode 100644
index 45b0af3..0000000
--- a/services/tests/servicestests/src/com/android/server/timezone/PackageTrackerTest.java
+++ /dev/null
@@ -1,1471 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.timezone;
-
-import org.hamcrest.BaseMatcher;
-import org.hamcrest.Description;
-import org.hamcrest.Matcher;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import android.app.timezone.RulesUpdaterContract;
-import android.content.Context;
-import android.content.Intent;
-import android.provider.TimeZoneRulesDataContract;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-import static org.mockito.hamcrest.MockitoHamcrest.argThat;
-
-/**
- * White box interaction / unit testing of the {@link PackageTracker}.
- */
-@SmallTest
-public class PackageTrackerTest {
-    private static final String UPDATE_APP_PACKAGE_NAME = "updateAppPackageName";
-    private static final String DATA_APP_PACKAGE_NAME = "dataAppPackageName";
-    private static final PackageVersions INITIAL_APP_PACKAGE_VERSIONS =
-            new PackageVersions(2 /* updateAppVersion */, 2 /* dataAppVersion */);
-
-    private ConfigHelper mMockConfigHelper;
-    private PackageManagerHelper mMockPackageManagerHelper;
-
-    private FakeClockHelper mFakeClock;
-    private FakeIntentHelper mFakeIntentHelper;
-    private PackageStatusStorage mPackageStatusStorage;
-    private PackageTracker mPackageTracker;
-
-    @Before
-    public void setUp() throws Exception {
-        Context context = InstrumentationRegistry.getContext();
-
-        mFakeClock = new FakeClockHelper();
-
-        // Read-only interfaces so are easy to mock.
-        mMockConfigHelper = mock(ConfigHelper.class);
-        mMockPackageManagerHelper = mock(PackageManagerHelper.class);
-
-        // Using the instrumentation context means the database is created in a test app-specific
-        // directory. We can use the real thing for this test.
-        mPackageStatusStorage = new PackageStatusStorage(context);
-
-        // For other interactions with the Android framework we create a fake object.
-        mFakeIntentHelper = new FakeIntentHelper();
-
-        // Create the PackageTracker to use in tests.
-        mPackageTracker = new PackageTracker(
-                mFakeClock,
-                mMockConfigHelper,
-                mMockPackageManagerHelper,
-                mPackageStatusStorage,
-                mFakeIntentHelper);
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        if (mPackageStatusStorage != null) {
-            mPackageStatusStorage.deleteDatabaseForTests();
-        }
-    }
-
-    @Test
-    public void trackingDisabled_intentHelperNotUsed() {
-        // Set up device configuration.
-        configureTrackingDisabled();
-
-        // Initialize the tracker.
-        mPackageTracker.start();
-
-        // Check the IntentHelper was not initialized.
-        mFakeIntentHelper.assertNotInitialized();
-
-        // Check reliability triggering state.
-        mFakeIntentHelper.assertReliabilityTriggeringDisabled();
-    }
-
-    @Test
-    public void trackingDisabled_triggerUpdateIfNeededNotAllowed() {
-        // Set up device configuration.
-        configureTrackingDisabled();
-
-        // Initialize the tracker.
-        mPackageTracker.start();
-
-        // Check reliability triggering state.
-        mFakeIntentHelper.assertReliabilityTriggeringDisabled();
-
-        try {
-            // This call should also not be allowed and will throw an exception if tracking is
-            // disabled.
-            mPackageTracker.triggerUpdateIfNeeded(true);
-            fail();
-        } catch (IllegalStateException expected) {}
-
-        // Check reliability triggering state.
-        mFakeIntentHelper.assertReliabilityTriggeringDisabled();
-    }
-
-    @Test
-    public void trackingDisabled_unsolicitedResultsIgnored_withoutToken() {
-        // Set up device configuration.
-        configureTrackingDisabled();
-
-        // Initialize the tracker.
-        mPackageTracker.start();
-
-        // Check reliability triggering state.
-        mFakeIntentHelper.assertReliabilityTriggeringDisabled();
-
-        // Receiving a check result when tracking is disabled should cause the storage to be
-        // reset.
-        mPackageTracker.recordCheckResult(null /* checkToken */, true /* success */);
-
-        // Check reliability triggering state.
-        mFakeIntentHelper.assertReliabilityTriggeringDisabled();
-
-        // Assert the storage was reset.
-        checkPackageStorageStatusIsInitialOrReset();
-    }
-
-    @Test
-    public void trackingDisabled_unsolicitedResultsIgnored_withToken() {
-        // Set up device configuration.
-        configureTrackingDisabled();
-
-        // Set the storage into an arbitrary state so we can detect a reset.
-        mPackageStatusStorage.generateCheckToken(INITIAL_APP_PACKAGE_VERSIONS);
-
-        // Initialize the tracker.
-        mPackageTracker.start();
-
-        // Check reliability triggering state.
-        mFakeIntentHelper.assertReliabilityTriggeringDisabled();
-
-        // Receiving a check result when tracking is disabled should cause the storage to be reset.
-        mPackageTracker.recordCheckResult(createArbitraryCheckToken(), true /* success */);
-
-        // Check reliability triggering state.
-        mFakeIntentHelper.assertReliabilityTriggeringDisabled();
-
-        // Assert the storage was reset.
-        checkPackageStorageStatusIsInitialOrReset();
-    }
-
-    @Test
-    public void trackingEnabled_updateAppConfigMissing() throws Exception {
-        // Set up device configuration.
-        configureTrackingEnabled();
-        configureReliabilityConfigSettingsOk();
-        configureUpdateAppPackageNameMissing();
-        configureDataAppPackageOk(DATA_APP_PACKAGE_NAME);
-
-        try {
-            // Initialize the tracker.
-            mPackageTracker.start();
-            fail();
-        } catch (RuntimeException expected) {}
-
-        mFakeIntentHelper.assertNotInitialized();
-
-        // Check reliability triggering state.
-        mFakeIntentHelper.assertReliabilityTriggeringDisabled();
-    }
-
-    // TODO(nfuller): Uncomment or delete when it's clear what will happen with http://b/35995024
-    // @Test
-    // public void trackingEnabled_updateAppNotPrivileged() throws Exception {
-    //     // Set up device configuration.
-    //     configureTrackingEnabled();
-    //     configureReliabilityConfigSettingsOk();
-    //     configureUpdateAppPackageNotPrivileged(UPDATE_APP_PACKAGE_NAME);
-    //     configureDataAppPackageOk(DATA_APP_PACKAGE_NAME);
-    //
-    //     try {
-    //         // Initialize the tracker.
-    //         mPackageTracker.start();
-    //         fail();
-    //     } catch (RuntimeException expected) {}
-    //
-    //     mFakeIntentHelper.assertNotInitialized();
-    //
-    //     // Check reliability triggering state.
-    //     mFakeIntentHelper.assertReliabilityTriggeringDisabled();
-    // }
-
-    @Test
-    public void trackingEnabled_dataAppConfigMissing() throws Exception {
-        // Set up device configuration.
-        configureTrackingEnabled();
-        configureReliabilityConfigSettingsOk();
-        configureUpdateAppPackageOk(UPDATE_APP_PACKAGE_NAME);
-        configureDataAppPackageNameMissing();
-
-        try {
-            // Initialize the tracker.
-            mPackageTracker.start();
-            fail();
-        } catch (RuntimeException expected) {}
-
-        mFakeIntentHelper.assertNotInitialized();
-
-        // Check reliability triggering state.
-        mFakeIntentHelper.assertReliabilityTriggeringDisabled();
-    }
-
-    // TODO(nfuller): Uncomment or delete when it's clear what will happen with http://b/35995024
-    // @Test
-    // public void trackingEnabled_dataAppNotPrivileged() throws Exception {
-    //     // Set up device configuration.
-    //     configureTrackingEnabled();
-    //     configureReliabilityConfigSettingsOk();
-    //     configureUpdateAppPackageOk(UPDATE_APP_PACKAGE_NAME);
-    //     configureDataAppPackageNotPrivileged(DATA_APP_PACKAGE_NAME);
-    //
-    //     try {
-    //         // Initialize the tracker.
-    //         mPackageTracker.start();
-    //         fail();
-    //     } catch (RuntimeException expected) {}
-    //
-    //     mFakeIntentHelper.assertNotInitialized();
-    //
-    //     // Check reliability triggering state.
-    //     mFakeIntentHelper.assertReliabilityTriggeringDisabled();
-    // }
-
-    @Test
-    public void trackingEnabled_packageUpdate_badUpdateAppManifestEntry() throws Exception {
-        // Set up device configuration.
-        configureTrackingEnabled();
-        configureReliabilityConfigSettingsOk();
-        configureValidApplications();
-
-        // Initialize the tracker.
-        mPackageTracker.start();
-
-        // Check the intent helper is properly configured.
-        checkIntentHelperInitializedAndReliabilityTrackingEnabled();
-
-        // Check the initial storage state.
-        checkPackageStorageStatusIsInitialOrReset();
-
-        // Configure a bad manifest for the update app. Should effectively turn off tracking.
-        PackageVersions packageVersions =
-                new PackageVersions(2 /* updateAppPackageVersion */, 3 /* dataAppPackageVersion */);
-        configureUpdateAppManifestBad(UPDATE_APP_PACKAGE_NAME);
-        configureDataAppManifestOk(DATA_APP_PACKAGE_NAME);
-        configureUpdateAppPackageVersion(
-                UPDATE_APP_PACKAGE_NAME, packageVersions.mUpdateAppVersion);
-        configureDataAppPackageVersion(DATA_APP_PACKAGE_NAME, packageVersions.mDataAppVersion);
-        // Simulate a tracked package being updated.
-        mFakeIntentHelper.simulatePackageUpdatedEvent();
-
-        // Assert the PackageTracker did not attempt to trigger an update.
-        mFakeIntentHelper.assertUpdateNotTriggered();
-
-        // Check reliability triggering state.
-        mFakeIntentHelper.assertReliabilityTriggeringDisabled();
-
-        // Assert the storage was not touched.
-        checkPackageStorageStatusIsInitialOrReset();
-    }
-
-    @Test
-    public void trackingEnabled_packageUpdate_badDataAppManifestEntry() throws Exception {
-        // Set up device configuration.
-        configureTrackingEnabled();
-        configureReliabilityConfigSettingsOk();
-        configureValidApplications();
-
-        // Initialize the tracker.
-        mPackageTracker.start();
-
-        // Check the intent helper is properly configured.
-        checkIntentHelperInitializedAndReliabilityTrackingEnabled();
-
-        // Check the initial storage state.
-        checkPackageStorageStatusIsInitialOrReset();
-
-        // Configure a bad manifest for the data app. Should effectively turn off tracking.
-        PackageVersions packageVersions =
-                new PackageVersions(2 /* updateAppPackageVersion */, 3 /* dataAppPackageVersion */);
-        configureUpdateAppManifestOk(UPDATE_APP_PACKAGE_NAME);
-        configureDataAppManifestBad(DATA_APP_PACKAGE_NAME);
-        configureUpdateAppPackageVersion(
-                UPDATE_APP_PACKAGE_NAME, packageVersions.mUpdateAppVersion);
-        configureDataAppPackageVersion(DATA_APP_PACKAGE_NAME, packageVersions.mDataAppVersion);
-        mFakeIntentHelper.simulatePackageUpdatedEvent();
-
-        // Assert the PackageTracker did not attempt to trigger an update.
-        mFakeIntentHelper.assertUpdateNotTriggered();
-
-        // Check reliability triggering state.
-        mFakeIntentHelper.assertReliabilityTriggeringDisabled();
-
-        // Assert the storage was not touched.
-        checkPackageStorageStatusIsInitialOrReset();
-    }
-
-    @Test
-    public void trackingEnabled_packageUpdate_responseWithToken_success() throws Exception {
-        trackingEnabled_packageUpdate_responseWithToken(true);
-    }
-
-    @Test
-    public void trackingEnabled_packageUpdate_responseWithToken_failed() throws Exception {
-        trackingEnabled_packageUpdate_responseWithToken(false);
-    }
-
-    private void trackingEnabled_packageUpdate_responseWithToken(boolean success) throws Exception {
-        // Set up device configuration.
-        configureTrackingEnabled();
-        configureReliabilityConfigSettingsOk();
-        configureValidApplications();
-
-        // Initialize the tracker.
-        mPackageTracker.start();
-
-        // Check the intent helper is properly configured.
-        checkIntentHelperInitializedAndReliabilityTrackingEnabled();
-
-        // Check the initial storage state.
-        checkPackageStorageStatusIsInitialOrReset();
-
-        // Simulate a tracked package being updated.
-        PackageVersions packageVersions =
-                new PackageVersions(2 /* updateAppPackageVersion */, 3 /* dataAppPackageVersion */);
-        simulatePackageInstallation(packageVersions);
-
-        // Confirm an update was triggered.
-        checkUpdateCheckTriggered(packageVersions);
-
-        // Get the token that was passed to the intent helper, and pass it back.
-        CheckToken token = mFakeIntentHelper.captureAndResetLastToken();
-        mPackageTracker.recordCheckResult(token, success);
-
-        // Check storage and reliability triggering state.
-        if (success) {
-            checkUpdateCheckSuccessful(packageVersions);
-        } else {
-            checkUpdateCheckFailed(packageVersions);
-        }
-    }
-
-    @Test
-    public void trackingEnabled_packageUpdate_responseWithoutTokenCausesStorageReset_success()
-            throws Exception {
-        trackingEnabled_packageUpdate_responseWithoutTokenCausesStorageReset(true);
-    }
-
-    @Test
-    public void trackingEnabled_packageUpdate_responseWithoutTokenCausesStorageReset_failed()
-            throws Exception {
-        trackingEnabled_packageUpdate_responseWithoutTokenCausesStorageReset(false);
-    }
-
-    private void trackingEnabled_packageUpdate_responseWithoutTokenCausesStorageReset(
-            boolean success) throws Exception {
-        // Set up device configuration.
-        configureTrackingEnabled();
-        configureReliabilityConfigSettingsOk();
-        configureValidApplications();
-
-        // Initialize the tracker.
-        mPackageTracker.start();
-
-        // Check the intent helper is properly configured.
-        checkIntentHelperInitializedAndReliabilityTrackingEnabled();
-
-        // Check the initial storage state.
-        checkPackageStorageStatusIsInitialOrReset();
-
-        // Set up installed app versions / manifests.
-        PackageVersions packageVersions =
-                new PackageVersions(2 /* updateAppPackageVersion */, 3 /* dataAppPackageVersion */);
-        simulatePackageInstallation(packageVersions);
-
-        // Confirm an update was triggered.
-        checkUpdateCheckTriggered(packageVersions);
-
-        // Ignore the token that was given to the intent helper, just pass null.
-        mPackageTracker.recordCheckResult(null /* checkToken */, success);
-
-        // Check reliability triggering state.
-        mFakeIntentHelper.assertReliabilityTriggeringEnabled();
-
-        // Assert the storage was reset.
-        checkPackageStorageStatusIsInitialOrReset();
-    }
-
-    /**
-     * Two package updates triggered for the same package versions. The second is triggered while
-     * the first is still happening.
-     */
-    @Test
-    public void trackingEnabled_packageUpdate_twoChecksNoPackageChange_secondWhileFirstInProgress()
-            throws Exception {
-        // Set up device configuration.
-        configureTrackingEnabled();
-        configureReliabilityConfigSettingsOk();
-        configureValidApplications();
-
-        // Initialize the tracker.
-        mPackageTracker.start();
-
-        // Check the intent helper is properly configured.
-        checkIntentHelperInitializedAndReliabilityTrackingEnabled();
-
-        // Check the initial storage state.
-        checkPackageStorageStatusIsInitialOrReset();
-
-        // Simulate package installation.
-        PackageVersions packageVersions =
-                new PackageVersions(2 /* updateAppPackageVersion */, 3 /* dataAppPackageVersion */);
-        simulatePackageInstallation(packageVersions);
-
-        // Confirm an update was triggered.
-        checkUpdateCheckTriggered(packageVersions);
-
-        // Get the first token.
-        CheckToken token1 = mFakeIntentHelper.captureAndResetLastToken();
-        assertEquals(packageVersions, token1.mPackageVersions);
-
-        // Now attempt to generate another check while the first is in progress and without having
-        // updated the package versions. The PackageTracker should trigger again for safety.
-        simulatePackageInstallation(packageVersions);
-
-        // Confirm an update was triggered.
-        checkUpdateCheckTriggered(packageVersions);
-
-        CheckToken token2 = mFakeIntentHelper.captureAndResetLastToken();
-        assertEquals(packageVersions, token2.mPackageVersions);
-        assertEquals(token1.mPackageVersions, token2.mPackageVersions);
-        assertTrue(token1.mOptimisticLockId != token2.mOptimisticLockId);
-    }
-
-    /**
-     * Two package updates triggered for the same package versions. The second happens after
-     * the first has succeeded.
-     */
-    @Test
-    public void trackingEnabled_packageUpdate_twoChecksNoPackageChange_sequential()
-            throws Exception {
-        // Set up device configuration.
-        configureTrackingEnabled();
-        configureReliabilityConfigSettingsOk();
-        configureValidApplications();
-
-        // Initialize the tracker.
-        mPackageTracker.start();
-
-        // Check the intent helper is properly configured.
-        checkIntentHelperInitializedAndReliabilityTrackingEnabled();
-
-        // Check the initial storage state.
-        checkPackageStorageStatusIsInitialOrReset();
-
-        // Simulate package installation.
-        PackageVersions packageVersions =
-                new PackageVersions(2 /* updateAppPackageVersion */, 3 /* dataAppPackageVersion */);
-        simulatePackageInstallation(packageVersions);
-
-        // Confirm an update was triggered.
-        checkUpdateCheckTriggered(packageVersions);
-
-        // Get the token.
-        CheckToken token = mFakeIntentHelper.captureAndResetLastToken();
-        assertEquals(packageVersions, token.mPackageVersions);
-
-        // Simulate a successful check.
-        mPackageTracker.recordCheckResult(token, true /* success */);
-
-        // Check storage and reliability triggering state.
-        checkUpdateCheckSuccessful(packageVersions);
-
-        // Now attempt to generate another check, but without having updated the package. The
-        // PackageTracker should be smart enough to recognize there's nothing to do here.
-        simulatePackageInstallation(packageVersions);
-
-        // Assert the PackageTracker did not attempt to trigger an update.
-        mFakeIntentHelper.assertUpdateNotTriggered();
-
-        // Check storage and reliability triggering state.
-        checkUpdateCheckSuccessful(packageVersions);
-    }
-
-    /**
-     * Two package updates triggered for the same package versions. The second is triggered after
-     * the first has failed.
-     */
-    @Test
-    public void trackingEnabled_packageUpdate_afterFailure() throws Exception {
-        // Set up device configuration.
-        configureTrackingEnabled();
-        configureReliabilityConfigSettingsOk();
-        configureValidApplications();
-
-        // Initialize the tracker.
-        mPackageTracker.start();
-
-        // Check the intent helper is properly configured.
-        checkIntentHelperInitializedAndReliabilityTrackingEnabled();
-
-        // Check the initial storage state.
-        checkPackageStorageStatusIsInitialOrReset();
-
-        // Simulate package installation.
-        PackageVersions packageVersions =
-                new PackageVersions(2 /* updateAppPackageVersion */, 3 /* dataAppPackageVersion */);
-        simulatePackageInstallation(packageVersions);
-
-        // Confirm an update was triggered.
-        checkUpdateCheckTriggered(packageVersions);
-
-        // Get the first token.
-        CheckToken token1 = mFakeIntentHelper.captureAndResetLastToken();
-        assertEquals(packageVersions, token1.mPackageVersions);
-
-        // Simulate an *unsuccessful* check.
-        mPackageTracker.recordCheckResult(token1, false /* success */);
-
-        // Check storage and reliability triggering state.
-        checkUpdateCheckFailed(packageVersions);
-
-        // Now generate another check, but without having updated the package. The
-        // PackageTracker should recognize the last check failed and trigger again.
-        simulatePackageInstallation(packageVersions);
-
-        // Confirm an update was triggered.
-        checkUpdateCheckTriggered(packageVersions);
-
-        // Get the second token.
-        CheckToken token2 = mFakeIntentHelper.captureAndResetLastToken();
-
-        // Assert some things about the tokens.
-        assertEquals(packageVersions, token2.mPackageVersions);
-        assertTrue(token1.mOptimisticLockId != token2.mOptimisticLockId);
-
-        // For completeness, now simulate this check was successful.
-        mPackageTracker.recordCheckResult(token2, true /* success */);
-
-        // Check storage and reliability triggering state.
-        checkUpdateCheckSuccessful(packageVersions);
-    }
-
-    /**
-     * Two package updates triggered for different package versions. The second is triggered while
-     * the first is still happening.
-     */
-    @Test
-    public void trackingEnabled_packageUpdate_twoChecksWithPackageChange_firstCheckInProcess()
-            throws Exception {
-        // Set up device configuration.
-        configureTrackingEnabled();
-        configureReliabilityConfigSettingsOk();
-        configureValidApplications();
-
-        // Initialize the package tracker.
-        mPackageTracker.start();
-
-        // Check the intent helper is properly configured.
-        checkIntentHelperInitializedAndReliabilityTrackingEnabled();
-
-        // Check the initial storage state.
-        checkPackageStorageStatusIsInitialOrReset();
-
-        // Simulate package installation.
-        PackageVersions packageVersions1 =
-                new PackageVersions(2 /* updateAppPackageVersion */, 3 /* dataAppPackageVersion */);
-        simulatePackageInstallation(packageVersions1);
-
-        // Confirm an update was triggered.
-        checkUpdateCheckTriggered(packageVersions1);
-
-        // Get the first token.
-        CheckToken token1 = mFakeIntentHelper.captureAndResetLastToken();
-        assertEquals(packageVersions1, token1.mPackageVersions);
-
-        // Simulate a tracked package being updated a second time (before the response for the
-        // first has been received).
-        PackageVersions packageVersions2 =
-                new PackageVersions(3 /* updateAppPackageVersion */, 4 /* dataAppPackageVersion */);
-        simulatePackageInstallation(packageVersions2);
-
-        // Confirm an update was triggered.
-        checkUpdateCheckTriggered(packageVersions2);
-
-        // Get the second token.
-        CheckToken token2 = mFakeIntentHelper.captureAndResetLastToken();
-        assertEquals(packageVersions2, token2.mPackageVersions);
-
-        // token1 should be invalid because the token2 was generated.
-        mPackageTracker.recordCheckResult(token1, true /* success */);
-
-        // Reliability triggering should still be enabled.
-        mFakeIntentHelper.assertReliabilityTriggeringEnabled();
-
-        // Check the expected storage state.
-        checkPackageStorageStatus(PackageStatus.CHECK_STARTED, packageVersions2);
-
-        // token2 should still be accepted.
-        mPackageTracker.recordCheckResult(token2, true /* success */);
-
-        // Check storage and reliability triggering state.
-        checkUpdateCheckSuccessful(packageVersions2);
-    }
-
-    /**
-     * Two package updates triggered for different package versions. The second is triggered after
-     * the first has completed successfully.
-     */
-    @Test
-    public void trackingEnabled_packageUpdate_twoChecksWithPackageChange_sequential()
-            throws Exception {
-        // Set up device configuration.
-        configureTrackingEnabled();
-        configureReliabilityConfigSettingsOk();
-        configureValidApplications();
-
-        // Initialize the package tracker.
-        mPackageTracker.start();
-
-        // Check the intent helper is properly configured.
-        checkIntentHelperInitializedAndReliabilityTrackingEnabled();
-
-        // Check the initial storage state.
-        checkPackageStorageStatusIsInitialOrReset();
-
-        // Simulate package installation.
-        PackageVersions packageVersions1 =
-                new PackageVersions(2 /* updateAppPackageVersion */, 3 /* dataAppPackageVersion */);
-        simulatePackageInstallation(packageVersions1);
-
-        // Confirm an update was triggered.
-        checkUpdateCheckTriggered(packageVersions1);
-
-        // Get the first token.
-        CheckToken token1 = mFakeIntentHelper.captureAndResetLastToken();
-        assertEquals(packageVersions1, token1.mPackageVersions);
-
-        // token1 should be accepted.
-        mPackageTracker.recordCheckResult(token1, true /* success */);
-
-        // Check storage and reliability triggering state.
-        checkUpdateCheckSuccessful(packageVersions1);
-
-        // Simulate a tracked package being updated a second time.
-        PackageVersions packageVersions2 =
-                new PackageVersions(3 /* updateAppPackageVersion */, 4 /* dataAppPackageVersion */);
-        simulatePackageInstallation(packageVersions2);
-
-        // Confirm an update was triggered.
-        checkUpdateCheckTriggered(packageVersions2);
-
-        // Get the second token.
-        CheckToken token2 = mFakeIntentHelper.captureAndResetLastToken();
-        assertEquals(packageVersions2, token2.mPackageVersions);
-
-        // token2 should still be accepted.
-        mPackageTracker.recordCheckResult(token2, true /* success */);
-
-        // Check storage and reliability triggering state.
-        checkUpdateCheckSuccessful(packageVersions2);
-    }
-
-    /**
-     * Replaying the same token twice.
-     */
-    @Test
-    public void trackingEnabled_packageUpdate_sameTokenReplayFails() throws Exception {
-        // Set up device configuration.
-        configureTrackingEnabled();
-        configureReliabilityConfigSettingsOk();
-        configureValidApplications();
-
-        // Initialize the package tracker.
-        mPackageTracker.start();
-
-        // Check the intent helper is properly configured.
-        checkIntentHelperInitializedAndReliabilityTrackingEnabled();
-
-        // Check the initial storage state.
-        checkPackageStorageStatusIsInitialOrReset();
-
-        // Simulate package installation.
-        PackageVersions packageVersions1 =
-                new PackageVersions(2 /* updateAppPackageVersion */, 3 /* dataAppPackageVersion */);
-        simulatePackageInstallation(packageVersions1);
-
-        // Confirm an update was triggered.
-        checkUpdateCheckTriggered(packageVersions1);
-
-        // Get the first token.
-        CheckToken token1 = mFakeIntentHelper.captureAndResetLastToken();
-        assertEquals(packageVersions1, token1.mPackageVersions);
-
-        // token1 should be accepted.
-        mPackageTracker.recordCheckResult(token1, true /* success */);
-
-        // Check storage and reliability triggering state.
-        checkUpdateCheckSuccessful(packageVersions1);
-
-        // Apply token1 again.
-        mPackageTracker.recordCheckResult(token1, true /* success */);
-
-        // Check the expected storage state. No real way to tell if it has been updated, but
-        // we can check the final state is still what it should be.
-        checkPackageStorageStatus(PackageStatus.CHECK_COMPLETED_SUCCESS, packageVersions1);
-
-        // Under the covers we expect it to fail to update because the storage should recognize that
-        // the token is no longer valid.
-        mFakeIntentHelper.assertReliabilityTriggeringEnabled();
-
-        // Peek inside the package tracker to make sure it is tracking failure counts properly.
-        assertEquals(1, mPackageTracker.getCheckFailureCountForTests());
-    }
-
-    @Test
-    public void trackingEnabled_reliabilityTrigger_firstTime_initialStorage() throws Exception {
-        // Set up device configuration.
-        configureTrackingEnabled();
-        configureReliabilityConfigSettingsOk();
-        PackageVersions packageVersions = configureValidApplications();
-
-        // Initialize the package tracker.
-        mPackageTracker.start();
-
-        // Check the intent helper is properly configured.
-        checkIntentHelperInitializedAndReliabilityTrackingEnabled();
-
-        // Check the initial storage state.
-        checkPackageStorageStatusIsInitialOrReset();
-
-        // Simulate a reliability trigger.
-        mFakeIntentHelper.simulateReliabilityTrigger();
-
-        // Assert the PackageTracker did trigger an update.
-        checkUpdateCheckTriggered(packageVersions);
-
-        // Confirm the token was correct.
-        CheckToken token1 = mFakeIntentHelper.captureAndResetLastToken();
-        assertEquals(packageVersions, token1.mPackageVersions);
-
-        // token1 should be accepted.
-        mPackageTracker.recordCheckResult(token1, true /* success */);
-
-        // Check storage and reliability triggering state.
-        checkUpdateCheckSuccessful(packageVersions);
-    }
-
-    @Test
-    public void trackingEnabled_reliabilityTrigger_afterRebootNoTriggerNeeded() throws Exception {
-        // Set up device configuration.
-        configureTrackingEnabled();
-        configureReliabilityConfigSettingsOk();
-        PackageVersions packageVersions = configureValidApplications();
-
-        // Force the storage into a state we want.
-        mPackageStatusStorage.forceCheckStateForTests(
-                PackageStatus.CHECK_COMPLETED_SUCCESS, packageVersions);
-
-        // Initialize the package tracker.
-        mPackageTracker.start();
-
-        // Check the intent helper is properly configured.
-        checkIntentHelperInitializedAndReliabilityTrackingEnabled();
-
-        // Check the initial storage state.
-        checkPackageStorageStatus(PackageStatus.CHECK_COMPLETED_SUCCESS, packageVersions);
-
-        // Simulate a reliability trigger.
-        mFakeIntentHelper.simulateReliabilityTrigger();
-
-        // Assert the PackageTracker did not attempt to trigger an update.
-        mFakeIntentHelper.assertUpdateNotTriggered();
-
-        // Check storage and reliability triggering state.
-        checkUpdateCheckSuccessful(packageVersions);
-    }
-
-    /**
-     * Simulates the device starting where the storage records do not match the installed app
-     * versions. The reliability trigger should cause the package tracker to perform a check.
-     */
-    @Test
-    public void trackingEnabled_reliabilityTrigger_afterRebootTriggerNeededBecausePreviousFailed()
-            throws Exception {
-        // Set up device configuration.
-        configureTrackingEnabled();
-        configureReliabilityConfigSettingsOk();
-
-        PackageVersions oldPackageVersions = new PackageVersions(1, 1);
-        PackageVersions currentPackageVersions = new PackageVersions(2, 2);
-
-        // Simulate there being a newer version installed than the one recorded in storage.
-        configureValidApplications(currentPackageVersions);
-
-        // Force the storage into a state we want.
-        mPackageStatusStorage.forceCheckStateForTests(
-                PackageStatus.CHECK_COMPLETED_FAILURE, oldPackageVersions);
-
-        // Initialize the package tracker.
-        mPackageTracker.start();
-
-        // Check the intent helper is properly configured.
-        checkIntentHelperInitializedAndReliabilityTrackingEnabled();
-
-        // Check the initial storage state.
-        checkPackageStorageStatus(PackageStatus.CHECK_COMPLETED_FAILURE, oldPackageVersions);
-
-        // Simulate a reliability trigger.
-        mFakeIntentHelper.simulateReliabilityTrigger();
-
-        // Assert the PackageTracker did trigger an update.
-        checkUpdateCheckTriggered(currentPackageVersions);
-
-        // Simulate the update check completing successfully.
-        CheckToken checkToken = mFakeIntentHelper.captureAndResetLastToken();
-        mPackageTracker.recordCheckResult(checkToken, true /* success */);
-
-        // Check storage and reliability triggering state.
-        checkUpdateCheckSuccessful(currentPackageVersions);
-    }
-
-    /**
-     * Simulates persistent failures of the reliability check. It should stop after the configured
-     * number of checks.
-     */
-    @Test
-    public void trackingEnabled_reliabilityTrigger_repeatedFailures() throws Exception {
-        // Set up device configuration.
-        configureTrackingEnabled();
-
-        int retriesAllowed = 3;
-        int checkDelayMillis = 5 * 60 * 1000;
-        configureReliabilityConfigSettings(retriesAllowed, checkDelayMillis);
-
-        PackageVersions oldPackageVersions = new PackageVersions(1, 1);
-        PackageVersions currentPackageVersions = new PackageVersions(2, 2);
-
-        // Simulate there being a newer version installed than the one recorded in storage.
-        configureValidApplications(currentPackageVersions);
-
-        // Force the storage into a state we want.
-        mPackageStatusStorage.forceCheckStateForTests(
-                PackageStatus.CHECK_COMPLETED_FAILURE, oldPackageVersions);
-
-        // Initialize the package tracker.
-        mPackageTracker.start();
-
-        // Check the intent helper is properly configured.
-        checkIntentHelperInitializedAndReliabilityTrackingEnabled();
-
-        // Check the initial storage state.
-        checkPackageStorageStatus(PackageStatus.CHECK_COMPLETED_FAILURE, oldPackageVersions);
-
-        for (int i = 0; i < retriesAllowed + 1; i++) {
-            // Simulate a reliability trigger.
-            mFakeIntentHelper.simulateReliabilityTrigger();
-
-            // Assert the PackageTracker did trigger an update.
-            checkUpdateCheckTriggered(currentPackageVersions);
-
-            // Check the PackageTracker failure count before calling recordCheckResult.
-            assertEquals(i, mPackageTracker.getCheckFailureCountForTests());
-
-            // Simulate a check failure.
-            CheckToken checkToken = mFakeIntentHelper.captureAndResetLastToken();
-            mPackageTracker.recordCheckResult(checkToken, false /* success */);
-
-            // Peek inside the package tracker to make sure it is tracking failure counts properly.
-            assertEquals(i + 1, mPackageTracker.getCheckFailureCountForTests());
-
-            // Confirm nothing has changed.
-            mFakeIntentHelper.assertUpdateNotTriggered();
-            checkPackageStorageStatus(PackageStatus.CHECK_COMPLETED_FAILURE,
-                    currentPackageVersions);
-
-            // Check reliability triggering is in the correct state.
-            if (i <= retriesAllowed) {
-                mFakeIntentHelper.assertReliabilityTriggeringEnabled();
-            } else {
-                mFakeIntentHelper.assertReliabilityTriggeringDisabled();
-            }
-        }
-    }
-
-    @Test
-    public void trackingEnabled_reliabilityTrigger_failureCountIsReset() throws Exception {
-        // Set up device configuration.
-        configureTrackingEnabled();
-
-        int retriesAllowed = 3;
-        int checkDelayMillis = 5 * 60 * 1000;
-        configureReliabilityConfigSettings(retriesAllowed, checkDelayMillis);
-
-        PackageVersions oldPackageVersions = new PackageVersions(1, 1);
-        PackageVersions currentPackageVersions = new PackageVersions(2, 2);
-
-        // Simulate there being a newer version installed than the one recorded in storage.
-        configureValidApplications(currentPackageVersions);
-
-        // Force the storage into a state we want.
-        mPackageStatusStorage.forceCheckStateForTests(
-                PackageStatus.CHECK_COMPLETED_FAILURE, oldPackageVersions);
-
-        // Initialize the package tracker.
-        mPackageTracker.start();
-
-        // Check the intent helper is properly configured.
-        checkIntentHelperInitializedAndReliabilityTrackingEnabled();
-
-        // Check the initial storage state.
-        checkPackageStorageStatus(PackageStatus.CHECK_COMPLETED_FAILURE, oldPackageVersions);
-
-        // Fail (retries - 1) times.
-        for (int i = 0; i < retriesAllowed - 1; i++) {
-            // Simulate a reliability trigger.
-            mFakeIntentHelper.simulateReliabilityTrigger();
-
-            // Assert the PackageTracker did trigger an update.
-            checkUpdateCheckTriggered(currentPackageVersions);
-
-            // Check the PackageTracker failure count before calling recordCheckResult.
-            assertEquals(i, mPackageTracker.getCheckFailureCountForTests());
-
-            // Simulate a check failure.
-            CheckToken checkToken = mFakeIntentHelper.captureAndResetLastToken();
-            mPackageTracker.recordCheckResult(checkToken, false /* success */);
-
-            // Peek inside the package tracker to make sure it is tracking failure counts properly.
-            assertEquals(i + 1, mPackageTracker.getCheckFailureCountForTests());
-
-            // Confirm nothing has changed.
-            mFakeIntentHelper.assertUpdateNotTriggered();
-            checkPackageStorageStatus(PackageStatus.CHECK_COMPLETED_FAILURE,
-                    currentPackageVersions);
-
-            // Check reliability triggering is still enabled.
-            mFakeIntentHelper.assertReliabilityTriggeringEnabled();
-        }
-
-        // Simulate a reliability trigger.
-        mFakeIntentHelper.simulateReliabilityTrigger();
-
-        // Assert the PackageTracker did trigger an update.
-        checkUpdateCheckTriggered(currentPackageVersions);
-
-        // Check the PackageTracker failure count before calling recordCheckResult.
-        assertEquals(retriesAllowed - 1, mPackageTracker.getCheckFailureCountForTests());
-
-        // On the last possible try, succeed.
-        CheckToken checkToken = mFakeIntentHelper.captureAndResetLastToken();
-        mPackageTracker.recordCheckResult(checkToken, true /* success */);
-
-        checkUpdateCheckSuccessful(currentPackageVersions);
-    }
-
-    /**
-     * Simulates reliability triggers happening too close together. Package tracker should ignore
-     * the ones it doesn't need.
-     */
-    @Test
-    public void trackingEnabled_reliabilityTrigger_tooSoon() throws Exception {
-        // Set up device configuration.
-        configureTrackingEnabled();
-
-        int retriesAllowed = 5;
-        int checkDelayMillis = 5 * 60 * 1000;
-        configureReliabilityConfigSettings(retriesAllowed, checkDelayMillis);
-
-        PackageVersions oldPackageVersions = new PackageVersions(1, 1);
-        PackageVersions currentPackageVersions = new PackageVersions(2, 2);
-
-        // Simulate there being a newer version installed than the one recorded in storage.
-        configureValidApplications(currentPackageVersions);
-
-        // Force the storage into a state we want.
-        mPackageStatusStorage.forceCheckStateForTests(
-                PackageStatus.CHECK_COMPLETED_FAILURE, oldPackageVersions);
-
-        // Initialize the package tracker.
-        mPackageTracker.start();
-
-        // Check the intent helper is properly configured.
-        checkIntentHelperInitializedAndReliabilityTrackingEnabled();
-
-        // Check the initial storage state.
-        checkPackageStorageStatus(PackageStatus.CHECK_COMPLETED_FAILURE, oldPackageVersions);
-
-        // Simulate a reliability trigger.
-        mFakeIntentHelper.simulateReliabilityTrigger();
-
-        // Assert the PackageTracker did trigger an update.
-        checkUpdateCheckTriggered(currentPackageVersions);
-        CheckToken token1 = mFakeIntentHelper.captureAndResetLastToken();
-
-        // Increment the clock, but not enough.
-        mFakeClock.incrementClock(checkDelayMillis - 1);
-
-        // Simulate a reliability trigger.
-        mFakeIntentHelper.simulateReliabilityTrigger();
-
-        // Assert the PackageTracker did not trigger an update.
-        mFakeIntentHelper.assertUpdateNotTriggered();
-        checkPackageStorageStatus(PackageStatus.CHECK_STARTED, currentPackageVersions);
-        mFakeIntentHelper.assertReliabilityTriggeringEnabled();
-
-        // Increment the clock slightly more. Should now consider the response overdue.
-        mFakeClock.incrementClock(2);
-
-        // Simulate a reliability trigger.
-        mFakeIntentHelper.simulateReliabilityTrigger();
-
-        // Triggering should have happened.
-        checkUpdateCheckTriggered(currentPackageVersions);
-        CheckToken token2 = mFakeIntentHelper.captureAndResetLastToken();
-
-        // Check a new token was generated.
-        assertFalse(token1.equals(token2));
-    }
-
-    /**
-     * Tests what happens when a package update doesn't complete and a reliability trigger cleans
-     * up for it.
-     */
-    @Test
-    public void trackingEnabled_reliabilityTrigger_afterPackageUpdateDidNotComplete()
-            throws Exception {
-
-        // Set up device configuration.
-        configureTrackingEnabled();
-
-        int retriesAllowed = 5;
-        int checkDelayMillis = 5 * 60 * 1000;
-        configureReliabilityConfigSettings(retriesAllowed, checkDelayMillis);
-
-        PackageVersions currentPackageVersions = new PackageVersions(1, 1);
-        PackageVersions newPackageVersions = new PackageVersions(2, 2);
-
-        // Simulate there being a newer version installed than the one recorded in storage.
-        configureValidApplications(currentPackageVersions);
-
-        // Force the storage into a state we want.
-        mPackageStatusStorage.forceCheckStateForTests(
-                PackageStatus.CHECK_COMPLETED_SUCCESS, currentPackageVersions);
-
-        // Initialize the package tracker.
-        mPackageTracker.start();
-
-        // Check the intent helper is properly configured.
-        checkIntentHelperInitializedAndReliabilityTrackingEnabled();
-
-        // Simulate a reliability trigger.
-        simulatePackageInstallation(newPackageVersions);
-
-        // Assert the PackageTracker did trigger an update.
-        checkUpdateCheckTriggered(newPackageVersions);
-        CheckToken token1 = mFakeIntentHelper.captureAndResetLastToken();
-
-        // Increment the clock, but not enough.
-        mFakeClock.incrementClock(checkDelayMillis + 1);
-
-        // Simulate a reliability trigger.
-        mFakeIntentHelper.simulateReliabilityTrigger();
-
-        // Assert the PackageTracker triggered an update.
-        checkUpdateCheckTriggered(newPackageVersions);
-        CheckToken token2 = mFakeIntentHelper.captureAndResetLastToken();
-
-        // Check a new token was generated.
-        assertFalse(token1.equals(token2));
-
-        // Simulate the reliability check completing.
-        mPackageTracker.recordCheckResult(token2, true /* success */);
-
-        // Check everything is now as it should be.
-        checkUpdateCheckSuccessful(newPackageVersions);
-    }
-
-    /**
-     * Simulates a reliability trigger happening too soon after a package update trigger occurred.
-     */
-    @Test
-    public void trackingEnabled_reliabilityTriggerAfterUpdate_tooSoon() throws Exception {
-        // Set up device configuration.
-        configureTrackingEnabled();
-
-        int retriesAllowed = 5;
-        int checkDelayMillis = 5 * 60 * 1000;
-        configureReliabilityConfigSettings(retriesAllowed, checkDelayMillis);
-
-        PackageVersions currentPackageVersions = new PackageVersions(1, 1);
-        PackageVersions newPackageVersions = new PackageVersions(2, 2);
-
-        // Simulate there being a newer version installed than the one recorded in storage.
-        configureValidApplications(currentPackageVersions);
-
-        // Force the storage into a state we want.
-        mPackageStatusStorage.forceCheckStateForTests(
-                PackageStatus.CHECK_COMPLETED_SUCCESS, currentPackageVersions);
-
-        // Initialize the package tracker.
-        mPackageTracker.start();
-
-        // Check the intent helper is properly configured.
-        checkIntentHelperInitializedAndReliabilityTrackingEnabled();
-
-        // Check the initial storage state.
-        checkPackageStorageStatus(PackageStatus.CHECK_COMPLETED_SUCCESS, currentPackageVersions);
-
-        // Simulate a package update trigger.
-        simulatePackageInstallation(newPackageVersions);
-
-        // Assert the PackageTracker did trigger an update.
-        checkUpdateCheckTriggered(newPackageVersions);
-        CheckToken token1 = mFakeIntentHelper.captureAndResetLastToken();
-
-        // Increment the clock, but not enough.
-        mFakeClock.incrementClock(checkDelayMillis - 1);
-
-        // Simulate a reliability trigger.
-        mFakeIntentHelper.simulateReliabilityTrigger();
-
-        // Assert the PackageTracker did not trigger an update.
-        mFakeIntentHelper.assertUpdateNotTriggered();
-        checkPackageStorageStatus(PackageStatus.CHECK_STARTED, newPackageVersions);
-        mFakeIntentHelper.assertReliabilityTriggeringEnabled();
-
-        // Increment the clock slightly more. Should now consider the response overdue.
-        mFakeClock.incrementClock(2);
-
-        // Simulate a reliability trigger.
-        mFakeIntentHelper.simulateReliabilityTrigger();
-
-        // Triggering should have happened.
-        checkUpdateCheckTriggered(newPackageVersions);
-        CheckToken token2 = mFakeIntentHelper.captureAndResetLastToken();
-
-        // Check a new token was generated.
-        assertFalse(token1.equals(token2));
-    }
-
-    private void simulatePackageInstallation(PackageVersions packageVersions) throws Exception {
-        configureApplicationsValidManifests(packageVersions);
-
-        // Simulate a tracked package being updated.
-        mFakeIntentHelper.simulatePackageUpdatedEvent();
-    }
-
-    /**
-     * Checks an update check was triggered, reliability triggering is therefore enabled and the
-     * storage state reflects that there is a check in progress.
-     */
-    private void checkUpdateCheckTriggered(PackageVersions packageVersions) {
-        // Assert the PackageTracker attempted to trigger an update.
-        mFakeIntentHelper.assertUpdateTriggered();
-
-        // If an update check was triggered reliability triggering should always be enabled to
-        // ensure that it can be completed if it fails.
-        mFakeIntentHelper.assertReliabilityTriggeringEnabled();
-
-        // Check the expected storage state.
-        checkPackageStorageStatus(PackageStatus.CHECK_STARTED, packageVersions);
-    }
-
-    private void checkUpdateCheckFailed(PackageVersions packageVersions) {
-        // Check reliability triggering state.
-        mFakeIntentHelper.assertReliabilityTriggeringEnabled();
-
-        // Assert the storage was updated.
-        checkPackageStorageStatus(PackageStatus.CHECK_COMPLETED_FAILURE, packageVersions);
-    }
-
-    private void checkUpdateCheckSuccessful(PackageVersions packageVersions) {
-        // Check reliability triggering state.
-        mFakeIntentHelper.assertReliabilityTriggeringDisabled();
-
-        // Assert the storage was updated.
-        checkPackageStorageStatus(PackageStatus.CHECK_COMPLETED_SUCCESS, packageVersions);
-
-        // Peek inside the package tracker to make sure it is tracking failure counts properly.
-        assertEquals(0, mPackageTracker.getCheckFailureCountForTests());
-    }
-
-    private PackageVersions configureValidApplications() throws Exception {
-        configureValidApplications(INITIAL_APP_PACKAGE_VERSIONS);
-        return INITIAL_APP_PACKAGE_VERSIONS;
-    }
-
-    private void configureValidApplications(PackageVersions versions) throws Exception {
-        configureUpdateAppPackageOk(UPDATE_APP_PACKAGE_NAME);
-        configureDataAppPackageOk(DATA_APP_PACKAGE_NAME);
-        configureApplicationsValidManifests(versions);
-    }
-
-    private void configureApplicationsValidManifests(PackageVersions versions) throws Exception {
-        configureUpdateAppManifestOk(UPDATE_APP_PACKAGE_NAME);
-        configureDataAppManifestOk(DATA_APP_PACKAGE_NAME);
-        configureUpdateAppPackageVersion(UPDATE_APP_PACKAGE_NAME, versions.mUpdateAppVersion);
-        configureDataAppPackageVersion(DATA_APP_PACKAGE_NAME, versions.mDataAppVersion);
-    }
-
-    private void configureUpdateAppPackageVersion(String updateAppPackageName,
-            int updataAppPackageVersion) throws Exception {
-        when(mMockPackageManagerHelper.getInstalledPackageVersion(updateAppPackageName))
-                .thenReturn(updataAppPackageVersion);
-    }
-
-    private void configureDataAppPackageVersion(String dataAppPackageName,
-            int dataAppPackageVersion) throws Exception {
-        when(mMockPackageManagerHelper.getInstalledPackageVersion(dataAppPackageName))
-                .thenReturn(dataAppPackageVersion);
-    }
-
-    private void configureUpdateAppManifestOk(String updateAppPackageName) throws Exception {
-        Intent expectedIntent = RulesUpdaterContract.createUpdaterIntent(updateAppPackageName);
-        when(mMockPackageManagerHelper.receiverRegistered(
-                filterEquals(expectedIntent),
-                eq(RulesUpdaterContract.TRIGGER_TIME_ZONE_RULES_CHECK_PERMISSION)))
-                .thenReturn(true);
-        when(mMockPackageManagerHelper.usesPermission(
-                updateAppPackageName, RulesUpdaterContract.UPDATE_TIME_ZONE_RULES_PERMISSION))
-                .thenReturn(true);
-    }
-
-    private void configureUpdateAppManifestBad(String updateAppPackageName) throws Exception {
-        Intent expectedIntent = RulesUpdaterContract.createUpdaterIntent(updateAppPackageName);
-        when(mMockPackageManagerHelper.receiverRegistered(
-                filterEquals(expectedIntent),
-                eq(RulesUpdaterContract.TRIGGER_TIME_ZONE_RULES_CHECK_PERMISSION)))
-                .thenReturn(false);
-        // Has permission, but that shouldn't matter if the check above is false.
-        when(mMockPackageManagerHelper.usesPermission(
-                updateAppPackageName, RulesUpdaterContract.UPDATE_TIME_ZONE_RULES_PERMISSION))
-                .thenReturn(true);
-    }
-
-    private void configureDataAppManifestOk(String dataAppPackageName) throws Exception {
-        when(mMockPackageManagerHelper.contentProviderRegistered(
-                TimeZoneRulesDataContract.AUTHORITY, dataAppPackageName))
-                .thenReturn(true);
-    }
-
-    private void configureDataAppManifestBad(String dataAppPackageName) throws Exception {
-        // Simulate the data app not exposing the content provider we require.
-        when(mMockPackageManagerHelper.contentProviderRegistered(
-                TimeZoneRulesDataContract.AUTHORITY, dataAppPackageName))
-                .thenReturn(false);
-    }
-
-    private void configureTrackingEnabled() {
-        when(mMockConfigHelper.isTrackingEnabled()).thenReturn(true);
-    }
-
-    private void configureTrackingDisabled() {
-        when(mMockConfigHelper.isTrackingEnabled()).thenReturn(false);
-    }
-
-    private void configureReliabilityConfigSettings(int retriesAllowed, int checkDelayMillis) {
-        when(mMockConfigHelper.getFailedCheckRetryCount()).thenReturn(retriesAllowed);
-        when(mMockConfigHelper.getCheckTimeAllowedMillis()).thenReturn(checkDelayMillis);
-    }
-
-    private void configureReliabilityConfigSettingsOk() {
-        configureReliabilityConfigSettings(5, 5 * 60 * 1000);
-    }
-
-    private void configureUpdateAppPackageOk(String updateAppPackageName) throws Exception {
-        when(mMockConfigHelper.getUpdateAppPackageName()).thenReturn(updateAppPackageName);
-        when(mMockPackageManagerHelper.isPrivilegedApp(updateAppPackageName)).thenReturn(true);
-    }
-
-    private void configureUpdateAppPackageNotPrivileged(String updateAppPackageName)
-            throws Exception {
-        when(mMockConfigHelper.getUpdateAppPackageName()).thenReturn(updateAppPackageName);
-        when(mMockPackageManagerHelper.isPrivilegedApp(updateAppPackageName)).thenReturn(false);
-    }
-
-    private void configureUpdateAppPackageNameMissing() {
-        when(mMockConfigHelper.getUpdateAppPackageName()).thenReturn(null);
-    }
-
-    private void configureDataAppPackageOk(String dataAppPackageName) throws Exception {
-        when(mMockConfigHelper.getDataAppPackageName()).thenReturn(dataAppPackageName);
-        when(mMockPackageManagerHelper.isPrivilegedApp(dataAppPackageName)).thenReturn(true);
-    }
-
-    private void configureDataAppPackageNotPrivileged(String dataAppPackageName)
-            throws Exception {
-        when(mMockConfigHelper.getUpdateAppPackageName()).thenReturn(dataAppPackageName);
-        when(mMockPackageManagerHelper.isPrivilegedApp(dataAppPackageName)).thenReturn(false);
-    }
-
-    private void configureDataAppPackageNameMissing() {
-        when(mMockConfigHelper.getDataAppPackageName()).thenThrow(new RuntimeException());
-    }
-
-    private void checkIntentHelperInitializedAndReliabilityTrackingEnabled() {
-        // Verify that calling start initialized the IntentHelper as well.
-        mFakeIntentHelper.assertInitialized(UPDATE_APP_PACKAGE_NAME, DATA_APP_PACKAGE_NAME);
-
-        // Assert that reliability tracking is always enabled after initialization.
-        mFakeIntentHelper.assertReliabilityTriggeringEnabled();
-    }
-
-    private void checkPackageStorageStatus(
-            int expectedCheckStatus, PackageVersions expectedPackageVersions) {
-        PackageStatus packageStatus = mPackageStatusStorage.getPackageStatus();
-        assertEquals(expectedCheckStatus, packageStatus.mCheckStatus);
-        assertEquals(expectedPackageVersions, packageStatus.mVersions);
-    }
-
-    private void checkPackageStorageStatusIsInitialOrReset() {
-        assertNull(mPackageStatusStorage.getPackageStatus());
-    }
-
-    private static CheckToken createArbitraryCheckToken() {
-        return new CheckToken(1, INITIAL_APP_PACKAGE_VERSIONS);
-    }
-
-    /**
-     * A fake IntentHelper implementation for use in tests.
-     */
-    private static class FakeIntentHelper implements IntentHelper {
-
-        private Listener mListener;
-        private String mUpdateAppPackageName;
-        private String mDataAppPackageName;
-
-        private CheckToken mLastToken;
-
-        private boolean mReliabilityTriggeringEnabled;
-
-        @Override
-        public void initialize(String updateAppPackageName, String dataAppPackageName,
-                Listener listener) {
-            assertNotNull(updateAppPackageName);
-            assertNotNull(dataAppPackageName);
-            assertNotNull(listener);
-            mListener = listener;
-            mUpdateAppPackageName = updateAppPackageName;
-            mDataAppPackageName = dataAppPackageName;
-        }
-
-        public void assertInitialized(
-                String expectedUpdateAppPackageName, String expectedDataAppPackageName) {
-            assertNotNull(mListener);
-            assertEquals(expectedUpdateAppPackageName, mUpdateAppPackageName);
-            assertEquals(expectedDataAppPackageName, mDataAppPackageName);
-        }
-
-        public void assertNotInitialized() {
-            assertNull(mListener);
-        }
-
-        @Override
-        public void sendTriggerUpdateCheck(CheckToken checkToken) {
-            if (mLastToken != null) {
-                fail("lastToken already set");
-            }
-            mLastToken = checkToken;
-        }
-
-        @Override
-        public void enableReliabilityTriggering() {
-            mReliabilityTriggeringEnabled = true;
-        }
-
-        @Override
-        public void disableReliabilityTriggering() {
-            mReliabilityTriggeringEnabled = false;
-        }
-
-        public void assertReliabilityTriggeringEnabled() {
-            assertTrue(mReliabilityTriggeringEnabled);
-        }
-
-        public void assertReliabilityTriggeringDisabled() {
-            assertFalse(mReliabilityTriggeringEnabled);
-        }
-
-        public void assertUpdateTriggered() {
-            assertNotNull(mLastToken);
-        }
-
-        public void assertUpdateNotTriggered() {
-            assertNull(mLastToken);
-        }
-
-        public CheckToken captureAndResetLastToken() {
-            CheckToken toReturn = mLastToken;
-            assertNotNull("No update triggered", toReturn);
-            mLastToken = null;
-            return toReturn;
-        }
-
-        public void simulatePackageUpdatedEvent() {
-            mListener.triggerUpdateIfNeeded(true);
-        }
-
-        public void simulateReliabilityTrigger() {
-            mListener.triggerUpdateIfNeeded(false);
-        }
-    }
-
-    private static class FakeClockHelper implements ClockHelper {
-
-        private long currentTime = 1000;
-
-        @Override
-        public long currentTimestamp() {
-            return currentTime;
-        }
-
-        public void incrementClock(long millis) {
-            currentTime += millis;
-        }
-    }
-
-    /**
-     * Registers a mockito parameter matcher that uses {@link Intent#filterEquals(Intent)}. to
-     * check the parameter against the intent supplied.
-     */
-    private static Intent filterEquals(final Intent expected) {
-        final Matcher<Intent> m = new BaseMatcher<Intent>() {
-            @Override
-            public boolean matches(Object actual) {
-                return actual != null && expected.filterEquals((Intent) actual);
-            }
-            @Override
-            public void describeTo(Description description) {
-                description.appendText(expected.toString());
-            }
-        };
-        return argThat(m);
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/timezone/PackageVersionsTest.java b/services/tests/servicestests/src/com/android/server/timezone/PackageVersionsTest.java
deleted file mode 100644
index a470f8f..0000000
--- a/services/tests/servicestests/src/com/android/server/timezone/PackageVersionsTest.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.timezone;
-
-import org.junit.Test;
-
-import android.support.test.filters.SmallTest;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-
-@SmallTest
-public class PackageVersionsTest {
-
-    @Test
-    public void equals() {
-        PackageVersions baseline =
-                new PackageVersions(1 /* updateAppVersion */, 1 /* dataAppVersion */);
-        assertEquals(baseline, baseline);
-
-        PackageVersions deepEqual =
-                new PackageVersions(1 /* updateAppVersion */, 1 /* dataAppVersion */);
-        assertEquals(baseline, deepEqual);
-
-        PackageVersions differentUpdateAppVersion =
-                new PackageVersions(2 /* updateAppVersion */, 1 /* dataAppVersion */);
-        assertFalse(baseline.equals(differentUpdateAppVersion));
-
-        PackageVersions differentDataAppVersion =
-                new PackageVersions(1 /* updateAppVersion */, 2 /* dataAppVersion */);
-        assertFalse(baseline.equals(differentDataAppVersion));
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/timezone/RulesManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/timezone/RulesManagerServiceTest.java
deleted file mode 100644
index a7f4c99..0000000
--- a/services/tests/servicestests/src/com/android/server/timezone/RulesManagerServiceTest.java
+++ /dev/null
@@ -1,924 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.timezone;
-
-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.IOException;
-import java.util.concurrent.Executor;
-import javax.annotation.Nullable;
-import libcore.tzdata.shared2.DistroVersion;
-import libcore.tzdata.shared2.StagedDistroOperation;
-import libcore.tzdata.update2.TimeZoneDistroInstaller;
-
-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;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-/**
- * White box interaction / unit testing of the {@link RulesManagerService}.
- */
-public class RulesManagerServiceTest {
-
-    private RulesManagerService mRulesManagerService;
-
-    private FakeExecutor mFakeExecutor;
-    private PermissionHelper mMockPermissionHelper;
-    private FileDescriptorHelper mMockFileDescriptorHelper;
-    private PackageTracker mMockPackageTracker;
-    private TimeZoneDistroInstaller mMockTimeZoneDistroInstaller;
-
-    @Before
-    public void setUp() {
-        mFakeExecutor = new FakeExecutor();
-
-        mMockFileDescriptorHelper = mock(FileDescriptorHelper.class);
-        mMockPackageTracker = mock(PackageTracker.class);
-        mMockPermissionHelper = mock(PermissionHelper.class);
-        mMockTimeZoneDistroInstaller = mock(TimeZoneDistroInstaller.class);
-
-        mRulesManagerService = new RulesManagerService(
-                mMockPermissionHelper,
-                mFakeExecutor,
-                mMockFileDescriptorHelper,
-                mMockPackageTracker,
-                mMockTimeZoneDistroInstaller);
-    }
-
-    @Test(expected = SecurityException.class)
-    public void getRulesState_noCallerPermission() throws Exception {
-        configureCallerDoesNotHavePermission();
-        mRulesManagerService.getRulesState();
-    }
-
-    @Test(expected = SecurityException.class)
-    public void requestInstall_noCallerPermission() throws Exception {
-        configureCallerDoesNotHavePermission();
-        mRulesManagerService.requestInstall(null, null, null);
-    }
-
-    @Test(expected = SecurityException.class)
-    public void requestUninstall_noCallerPermission() throws Exception {
-        configureCallerDoesNotHavePermission();
-        mRulesManagerService.requestUninstall(null, null);
-    }
-
-    @Test(expected = SecurityException.class)
-    public void requestNothing_noCallerPermission() throws Exception {
-        configureCallerDoesNotHavePermission();
-        mRulesManagerService.requestNothing(null, true);
-    }
-
-    @Test
-    public void getRulesState_systemRulesError() throws Exception {
-        configureDeviceCannotReadSystemRulesVersion();
-
-        assertNull(mRulesManagerService.getRulesState());
-    }
-
-    @Test
-    public void getRulesState_stagedInstall() throws Exception {
-        configureCallerHasPermission();
-
-        configureDeviceSystemRulesVersion("2016a");
-
-        DistroVersion stagedDistroVersion = new DistroVersion(
-                DistroVersion.CURRENT_FORMAT_MAJOR_VERSION,
-                DistroVersion.CURRENT_FORMAT_MINOR_VERSION - 1,
-                "2016c",
-                3);
-        configureStagedInstall(stagedDistroVersion);
-
-        DistroVersion installedDistroVersion = new DistroVersion(
-                DistroVersion.CURRENT_FORMAT_MAJOR_VERSION,
-                DistroVersion.CURRENT_FORMAT_MINOR_VERSION - 1,
-                "2016b",
-                4);
-        configureInstalledDistroVersion(installedDistroVersion);
-
-        DistroRulesVersion stagedDistroRulesVersion = new DistroRulesVersion(
-                stagedDistroVersion.rulesVersion, stagedDistroVersion.revision);
-        DistroRulesVersion installedDistroRulesVersion = new DistroRulesVersion(
-                installedDistroVersion.rulesVersion, installedDistroVersion.revision);
-        RulesState expectedRuleState = new RulesState(
-                "2016a", RulesManagerService.DISTRO_FORMAT_VERSION_SUPPORTED,
-                false /* operationInProgress */,
-                RulesState.STAGED_OPERATION_INSTALL, stagedDistroRulesVersion,
-                RulesState.DISTRO_STATUS_INSTALLED, installedDistroRulesVersion);
-        assertEquals(expectedRuleState, mRulesManagerService.getRulesState());
-    }
-
-    @Test
-    public void getRulesState_nothingStaged() throws Exception {
-        configureCallerHasPermission();
-
-        configureDeviceSystemRulesVersion("2016a");
-
-        configureNoStagedOperation();
-
-        DistroVersion installedDistroVersion = new DistroVersion(
-                DistroVersion.CURRENT_FORMAT_MAJOR_VERSION,
-                DistroVersion.CURRENT_FORMAT_MINOR_VERSION - 1,
-                "2016b",
-                4);
-        configureInstalledDistroVersion(installedDistroVersion);
-
-        DistroRulesVersion installedDistroRulesVersion = new DistroRulesVersion(
-                installedDistroVersion.rulesVersion, installedDistroVersion.revision);
-        RulesState expectedRuleState = new RulesState(
-                "2016a", RulesManagerService.DISTRO_FORMAT_VERSION_SUPPORTED,
-                false /* operationInProgress */,
-                RulesState.STAGED_OPERATION_NONE, null /* stagedDistroRulesVersion */,
-                RulesState.DISTRO_STATUS_INSTALLED, installedDistroRulesVersion);
-        assertEquals(expectedRuleState, mRulesManagerService.getRulesState());
-    }
-
-    @Test
-    public void getRulesState_uninstallStaged() throws Exception {
-        configureCallerHasPermission();
-
-        configureDeviceSystemRulesVersion("2016a");
-
-        configureStagedUninstall();
-
-        DistroVersion installedDistroVersion = new DistroVersion(
-                DistroVersion.CURRENT_FORMAT_MAJOR_VERSION,
-                DistroVersion.CURRENT_FORMAT_MINOR_VERSION - 1,
-                "2016b",
-                4);
-        configureInstalledDistroVersion(installedDistroVersion);
-
-        DistroRulesVersion installedDistroRulesVersion = new DistroRulesVersion(
-                installedDistroVersion.rulesVersion, installedDistroVersion.revision);
-        RulesState expectedRuleState = new RulesState(
-                "2016a", RulesManagerService.DISTRO_FORMAT_VERSION_SUPPORTED,
-                false /* operationInProgress */,
-                RulesState.STAGED_OPERATION_UNINSTALL, null /* stagedDistroRulesVersion */,
-                RulesState.DISTRO_STATUS_INSTALLED, installedDistroRulesVersion);
-        assertEquals(expectedRuleState, mRulesManagerService.getRulesState());
-    }
-
-    @Test
-    public void getRulesState_installedRulesError() throws Exception {
-        configureCallerHasPermission();
-
-        String systemRulesVersion = "2016a";
-        configureDeviceSystemRulesVersion(systemRulesVersion);
-
-        configureStagedUninstall();
-        configureDeviceCannotReadInstalledDistroVersion();
-
-        RulesState expectedRuleState = new RulesState(
-                "2016a", RulesManagerService.DISTRO_FORMAT_VERSION_SUPPORTED,
-                false /* operationInProgress */,
-                RulesState.STAGED_OPERATION_UNINSTALL, null /* stagedDistroRulesVersion */,
-                RulesState.DISTRO_STATUS_UNKNOWN, null /* installedDistroRulesVersion */);
-        assertEquals(expectedRuleState, mRulesManagerService.getRulesState());
-    }
-
-    @Test
-    public void getRulesState_stagedRulesError() throws Exception {
-        configureCallerHasPermission();
-
-        String systemRulesVersion = "2016a";
-        configureDeviceSystemRulesVersion(systemRulesVersion);
-
-        configureDeviceCannotReadStagedDistroOperation();
-
-        DistroVersion installedDistroVersion = new DistroVersion(
-                DistroVersion.CURRENT_FORMAT_MAJOR_VERSION,
-                DistroVersion.CURRENT_FORMAT_MINOR_VERSION - 1,
-                "2016b",
-                4);
-        configureInstalledDistroVersion(installedDistroVersion);
-
-        DistroRulesVersion installedDistroRulesVersion = new DistroRulesVersion(
-                installedDistroVersion.rulesVersion, installedDistroVersion.revision);
-        RulesState expectedRuleState = new RulesState(
-                "2016a", RulesManagerService.DISTRO_FORMAT_VERSION_SUPPORTED,
-                false /* operationInProgress */,
-                RulesState.STAGED_OPERATION_UNKNOWN, null /* stagedDistroRulesVersion */,
-                RulesState.DISTRO_STATUS_INSTALLED, installedDistroRulesVersion);
-        assertEquals(expectedRuleState, mRulesManagerService.getRulesState());
-    }
-
-    @Test
-    public void getRulesState_noInstalledRules() throws Exception {
-        configureCallerHasPermission();
-
-        String systemRulesVersion = "2016a";
-        configureDeviceSystemRulesVersion(systemRulesVersion);
-        configureNoStagedOperation();
-        configureInstalledDistroVersion(null);
-
-        RulesState expectedRuleState = new RulesState(
-                systemRulesVersion, RulesManagerService.DISTRO_FORMAT_VERSION_SUPPORTED,
-                false /* operationInProgress */,
-                RulesState.STAGED_OPERATION_NONE, null /* stagedDistroRulesVersion */,
-                RulesState.DISTRO_STATUS_NONE, null /* installedDistroRulesVersion */);
-        assertEquals(expectedRuleState, mRulesManagerService.getRulesState());
-    }
-
-    @Test
-    public void getRulesState_operationInProgress() throws Exception {
-        configureCallerHasPermission();
-
-        String systemRulesVersion = "2016a";
-        String installedRulesVersion = "2016b";
-        int revision = 3;
-
-        configureDeviceSystemRulesVersion(systemRulesVersion);
-
-        DistroVersion installedDistroVersion = new DistroVersion(
-                DistroVersion.CURRENT_FORMAT_MAJOR_VERSION,
-                DistroVersion.CURRENT_FORMAT_MINOR_VERSION - 1,
-                installedRulesVersion,
-                revision);
-        configureInstalledDistroVersion(installedDistroVersion);
-
-        byte[] expectedContent = createArbitraryBytes(1000);
-        ParcelFileDescriptor parcelFileDescriptor = createFakeParcelFileDescriptor();
-        configureParcelFileDescriptorReadSuccess(parcelFileDescriptor, expectedContent);
-
-        // Start an async operation so there is one in progress. The mFakeExecutor won't actually
-        // execute it.
-        byte[] tokenBytes = createArbitraryTokenBytes();
-        ICallback callback = new StubbedCallback();
-
-        mRulesManagerService.requestInstall(parcelFileDescriptor, tokenBytes, callback);
-
-        RulesState expectedRuleState = new RulesState(
-                systemRulesVersion, RulesManagerService.DISTRO_FORMAT_VERSION_SUPPORTED,
-                true /* operationInProgress */,
-                RulesState.STAGED_OPERATION_UNKNOWN, null /* stagedDistroRulesVersion */,
-                RulesState.DISTRO_STATUS_UNKNOWN, null /* installedDistroRulesVersion */);
-        assertEquals(expectedRuleState, mRulesManagerService.getRulesState());
-    }
-
-    @Test
-    public void requestInstall_operationInProgress() throws Exception {
-        configureCallerHasPermission();
-
-        byte[] expectedContent = createArbitraryBytes(1000);
-        ParcelFileDescriptor parcelFileDescriptor = createFakeParcelFileDescriptor();
-        configureParcelFileDescriptorReadSuccess(parcelFileDescriptor, expectedContent);
-
-        byte[] tokenBytes = createArbitraryTokenBytes();
-        ICallback callback = new StubbedCallback();
-
-        // First request should succeed.
-        assertEquals(RulesManager.SUCCESS,
-                mRulesManagerService.requestInstall(parcelFileDescriptor, tokenBytes, callback));
-
-        // Something async should be enqueued. Clear it but do not execute it so we can detect the
-        // second request does nothing.
-        mFakeExecutor.getAndResetLastCommand();
-
-        // Second request should fail.
-        assertEquals(RulesManager.ERROR_OPERATION_IN_PROGRESS,
-                mRulesManagerService.requestInstall(parcelFileDescriptor, tokenBytes, callback));
-
-        // Assert nothing async was enqueued.
-        mFakeExecutor.assertNothingQueued();
-        verifyNoInstallerCallsMade();
-        verifyNoPackageTrackerCallsMade();
-    }
-
-    @Test
-    public void requestInstall_badToken() throws Exception {
-        configureCallerHasPermission();
-
-        byte[] expectedContent = createArbitraryBytes(1000);
-        ParcelFileDescriptor parcelFileDescriptor = createFakeParcelFileDescriptor();
-        configureParcelFileDescriptorReadSuccess(parcelFileDescriptor, expectedContent);
-
-        byte[] badTokenBytes = new byte[2];
-        ICallback callback = new StubbedCallback();
-
-        try {
-            mRulesManagerService.requestInstall(parcelFileDescriptor, badTokenBytes, callback);
-            fail();
-        } catch (IllegalArgumentException expected) {
-        }
-
-        // Assert nothing async was enqueued.
-        mFakeExecutor.assertNothingQueued();
-        verifyNoInstallerCallsMade();
-        verifyNoPackageTrackerCallsMade();
-    }
-
-    @Test
-    public void requestInstall_nullParcelFileDescriptor() throws Exception {
-        configureCallerHasPermission();
-
-        ParcelFileDescriptor parcelFileDescriptor = null;
-        byte[] tokenBytes = createArbitraryTokenBytes();
-        ICallback callback = new StubbedCallback();
-
-        try {
-            mRulesManagerService.requestInstall(parcelFileDescriptor, tokenBytes, callback);
-            fail();
-        } catch (NullPointerException expected) {}
-
-        // Assert nothing async was enqueued.
-        mFakeExecutor.assertNothingQueued();
-        verifyNoInstallerCallsMade();
-        verifyNoPackageTrackerCallsMade();
-    }
-
-    @Test
-    public void requestInstall_nullCallback() throws Exception {
-        configureCallerHasPermission();
-
-        ParcelFileDescriptor parcelFileDescriptor = createFakeParcelFileDescriptor();
-        byte[] tokenBytes = createArbitraryTokenBytes();
-        ICallback callback = null;
-
-        try {
-            mRulesManagerService.requestInstall(parcelFileDescriptor, tokenBytes, callback);
-            fail();
-        } catch (NullPointerException expected) {}
-
-        // Assert nothing async was enqueued.
-        mFakeExecutor.assertNothingQueued();
-        verifyNoInstallerCallsMade();
-        verifyNoPackageTrackerCallsMade();
-    }
-
-    @Test
-    public void requestInstall_asyncSuccess() throws Exception {
-        configureCallerHasPermission();
-
-        ParcelFileDescriptor parcelFileDescriptor = createFakeParcelFileDescriptor();
-        byte[] expectedContent = createArbitraryBytes(1000);
-        configureParcelFileDescriptorReadSuccess(parcelFileDescriptor, expectedContent);
-
-        CheckToken token = createArbitraryToken();
-        byte[] tokenBytes = token.toByteArray();
-
-        TestCallback callback = new TestCallback();
-
-        // Request the install.
-        assertEquals(RulesManager.SUCCESS,
-                mRulesManagerService.requestInstall(parcelFileDescriptor, tokenBytes, callback));
-
-        // Assert nothing has happened yet.
-        callback.assertNoResultReceived();
-        verifyNoInstallerCallsMade();
-        verifyNoPackageTrackerCallsMade();
-
-        // Set up the installer.
-        configureStageInstallExpectation(expectedContent, TimeZoneDistroInstaller.INSTALL_SUCCESS);
-
-        // Simulate the async execution.
-        mFakeExecutor.simulateAsyncExecutionOfLastCommand();
-
-        // Verify the expected calls were made to other components.
-        verifyStageInstallCalled(expectedContent);
-        verifyPackageTrackerCalled(token, true /* success */);
-
-        // Check the callback was called.
-        callback.assertResultReceived(Callback.SUCCESS);
-    }
-
-    @Test
-    public void requestInstall_nullTokenBytes() throws Exception {
-        configureCallerHasPermission();
-
-        ParcelFileDescriptor parcelFileDescriptor = createFakeParcelFileDescriptor();
-        byte[] expectedContent = createArbitraryBytes(1000);
-        configureParcelFileDescriptorReadSuccess(parcelFileDescriptor, expectedContent);
-
-        TestCallback callback = new TestCallback();
-
-        // Request the install.
-        assertEquals(RulesManager.SUCCESS,
-                mRulesManagerService.requestInstall(
-                        parcelFileDescriptor, null /* tokenBytes */, callback));
-
-        // Assert nothing has happened yet.
-        verifyNoInstallerCallsMade();
-        callback.assertNoResultReceived();
-
-        // Set up the installer.
-        configureStageInstallExpectation(expectedContent, TimeZoneDistroInstaller.INSTALL_SUCCESS);
-
-        // Simulate the async execution.
-        mFakeExecutor.simulateAsyncExecutionOfLastCommand();
-
-        // Verify the expected calls were made to other components.
-        verifyStageInstallCalled(expectedContent);
-        verifyPackageTrackerCalled(null /* expectedToken */, true /* success */);
-
-        // Check the callback was received.
-        callback.assertResultReceived(Callback.SUCCESS);
-    }
-
-    @Test
-    public void requestInstall_asyncInstallFail() throws Exception {
-        configureCallerHasPermission();
-
-        byte[] expectedContent = createArbitraryBytes(1000);
-        ParcelFileDescriptor parcelFileDescriptor = createFakeParcelFileDescriptor();
-        configureParcelFileDescriptorReadSuccess(parcelFileDescriptor, expectedContent);
-
-        CheckToken token = createArbitraryToken();
-        byte[] tokenBytes = token.toByteArray();
-
-        TestCallback callback = new TestCallback();
-
-        // Request the install.
-        assertEquals(RulesManager.SUCCESS,
-                mRulesManagerService.requestInstall(parcelFileDescriptor, tokenBytes, callback));
-
-        // Assert nothing has happened yet.
-        verifyNoInstallerCallsMade();
-        callback.assertNoResultReceived();
-
-        // Set up the installer.
-        configureStageInstallExpectation(
-                expectedContent, TimeZoneDistroInstaller.INSTALL_FAIL_VALIDATION_ERROR);
-
-        // Simulate the async execution.
-        mFakeExecutor.simulateAsyncExecutionOfLastCommand();
-
-        // Verify the expected calls were made to other components.
-        verifyStageInstallCalled(expectedContent);
-
-        // Validation failure is treated like a successful check: repeating it won't improve things.
-        boolean expectedSuccess = true;
-        verifyPackageTrackerCalled(token, expectedSuccess);
-
-        // Check the callback was received.
-        callback.assertResultReceived(Callback.ERROR_INSTALL_VALIDATION_ERROR);
-    }
-
-    @Test
-    public void requestInstall_asyncParcelFileDescriptorReadFail() throws Exception {
-        configureCallerHasPermission();
-
-        ParcelFileDescriptor parcelFileDescriptor = createFakeParcelFileDescriptor();
-        configureParcelFileDescriptorReadFailure(parcelFileDescriptor);
-
-        CheckToken token = createArbitraryToken();
-        byte[] tokenBytes = token.toByteArray();
-
-        TestCallback callback = new TestCallback();
-
-        // Request the install.
-        assertEquals(RulesManager.SUCCESS,
-                mRulesManagerService.requestInstall(parcelFileDescriptor, tokenBytes, callback));
-
-        // Simulate the async execution.
-        mFakeExecutor.simulateAsyncExecutionOfLastCommand();
-
-        // Verify nothing else happened.
-        verifyNoInstallerCallsMade();
-
-        // A failure to read the ParcelFileDescriptor is treated as a failure. It might be the
-        // result of a file system error. This is a fairly arbitrary choice.
-        verifyPackageTrackerCalled(token, false /* success */);
-
-        verifyNoPackageTrackerCallsMade();
-
-        // Check the callback was received.
-        callback.assertResultReceived(Callback.ERROR_UNKNOWN_FAILURE);
-    }
-
-    @Test
-    public void requestUninstall_operationInProgress() throws Exception {
-        configureCallerHasPermission();
-
-        byte[] tokenBytes = createArbitraryTokenBytes();
-        ICallback callback = new StubbedCallback();
-
-        // First request should succeed.
-        assertEquals(RulesManager.SUCCESS,
-                mRulesManagerService.requestUninstall(tokenBytes, callback));
-
-        // Something async should be enqueued. Clear it but do not execute it so we can detect the
-        // second request does nothing.
-        mFakeExecutor.getAndResetLastCommand();
-
-        // Second request should fail.
-        assertEquals(RulesManager.ERROR_OPERATION_IN_PROGRESS,
-                mRulesManagerService.requestUninstall(tokenBytes, callback));
-
-        // Assert nothing async was enqueued.
-        mFakeExecutor.assertNothingQueued();
-        verifyNoInstallerCallsMade();
-        verifyNoPackageTrackerCallsMade();
-    }
-
-    @Test
-    public void requestUninstall_badToken() throws Exception {
-        configureCallerHasPermission();
-
-        byte[] badTokenBytes = new byte[2];
-        ICallback callback = new StubbedCallback();
-
-        try {
-            mRulesManagerService.requestUninstall(badTokenBytes, callback);
-            fail();
-        } catch (IllegalArgumentException expected) {
-        }
-
-        // Assert nothing async was enqueued.
-        mFakeExecutor.assertNothingQueued();
-        verifyNoInstallerCallsMade();
-        verifyNoPackageTrackerCallsMade();
-    }
-
-    @Test
-    public void requestUninstall_nullCallback() throws Exception {
-        configureCallerHasPermission();
-
-        byte[] tokenBytes = createArbitraryTokenBytes();
-        ICallback callback = null;
-
-        try {
-            mRulesManagerService.requestUninstall(tokenBytes, callback);
-            fail();
-        } catch (NullPointerException expected) {}
-
-        // Assert nothing async was enqueued.
-        mFakeExecutor.assertNothingQueued();
-        verifyNoInstallerCallsMade();
-        verifyNoPackageTrackerCallsMade();
-    }
-
-    @Test
-    public void requestUninstall_asyncSuccess() throws Exception {
-        configureCallerHasPermission();
-
-        CheckToken token = createArbitraryToken();
-        byte[] tokenBytes = token.toByteArray();
-
-        TestCallback callback = new TestCallback();
-
-        // Request the uninstall.
-        assertEquals(RulesManager.SUCCESS,
-                mRulesManagerService.requestUninstall(tokenBytes, callback));
-
-        // Assert nothing has happened yet.
-        callback.assertNoResultReceived();
-        verifyNoInstallerCallsMade();
-        verifyNoPackageTrackerCallsMade();
-
-        // Set up the installer.
-        configureStageUninstallExpectation(true /* success */);
-
-        // Simulate the async execution.
-        mFakeExecutor.simulateAsyncExecutionOfLastCommand();
-
-        // Verify the expected calls were made to other components.
-        verifyStageUninstallCalled();
-        verifyPackageTrackerCalled(token, true /* success */);
-
-        // Check the callback was called.
-        callback.assertResultReceived(Callback.SUCCESS);
-    }
-
-    @Test
-    public void requestUninstall_nullTokenBytes() throws Exception {
-        configureCallerHasPermission();
-
-        TestCallback callback = new TestCallback();
-
-        // Request the uninstall.
-        assertEquals(RulesManager.SUCCESS,
-                mRulesManagerService.requestUninstall(null /* tokenBytes */, callback));
-
-        // Assert nothing has happened yet.
-        verifyNoInstallerCallsMade();
-        callback.assertNoResultReceived();
-
-        // Set up the installer.
-        configureStageUninstallExpectation(true /* success */);
-
-        // Simulate the async execution.
-        mFakeExecutor.simulateAsyncExecutionOfLastCommand();
-
-        // Verify the expected calls were made to other components.
-        verifyStageUninstallCalled();
-        verifyPackageTrackerCalled(null /* expectedToken */, true /* success */);
-
-        // Check the callback was received.
-        callback.assertResultReceived(Callback.SUCCESS);
-    }
-
-    @Test
-    public void requestUninstall_asyncUninstallFail() throws Exception {
-        configureCallerHasPermission();
-
-        CheckToken token = createArbitraryToken();
-        byte[] tokenBytes = token.toByteArray();
-
-        TestCallback callback = new TestCallback();
-
-        // Request the uninstall.
-        assertEquals(RulesManager.SUCCESS,
-                mRulesManagerService.requestUninstall(tokenBytes, callback));
-
-        // Assert nothing has happened yet.
-        verifyNoInstallerCallsMade();
-        callback.assertNoResultReceived();
-
-        // Set up the installer.
-        configureStageUninstallExpectation(false /* success */);
-
-        // Simulate the async execution.
-        mFakeExecutor.simulateAsyncExecutionOfLastCommand();
-
-        // Verify the expected calls were made to other components.
-        verifyStageUninstallCalled();
-        verifyPackageTrackerCalled(token, false /* success */);
-
-        // Check the callback was received.
-        callback.assertResultReceived(Callback.ERROR_UNKNOWN_FAILURE);
-    }
-
-    @Test
-    public void requestNothing_operationInProgressOk() throws Exception {
-        configureCallerHasPermission();
-
-        // Set up a parallel operation.
-        assertEquals(RulesManager.SUCCESS,
-                mRulesManagerService.requestUninstall(null, new StubbedCallback()));
-        // Something async should be enqueued. Clear it but do not execute it to simulate it still
-        // being in progress.
-        mFakeExecutor.getAndResetLastCommand();
-
-        CheckToken token = createArbitraryToken();
-        byte[] tokenBytes = token.toByteArray();
-
-        // Make the call.
-        mRulesManagerService.requestNothing(tokenBytes, true /* success */);
-
-        // Assert nothing async was enqueued.
-        mFakeExecutor.assertNothingQueued();
-
-        // Verify the expected calls were made to other components.
-        verifyPackageTrackerCalled(token, true /* success */);
-        verifyNoInstallerCallsMade();
-    }
-
-    @Test
-    public void requestNothing_badToken() throws Exception {
-        configureCallerHasPermission();
-
-        byte[] badTokenBytes = new byte[2];
-
-        try {
-            mRulesManagerService.requestNothing(badTokenBytes, true /* success */);
-            fail();
-        } catch (IllegalArgumentException expected) {
-        }
-
-        // Assert nothing async was enqueued.
-        mFakeExecutor.assertNothingQueued();
-
-        // Assert no other calls were made.
-        verifyNoInstallerCallsMade();
-        verifyNoPackageTrackerCallsMade();
-    }
-
-    @Test
-    public void requestNothing() throws Exception {
-        configureCallerHasPermission();
-
-        CheckToken token = createArbitraryToken();
-        byte[] tokenBytes = token.toByteArray();
-
-        // Make the call.
-        mRulesManagerService.requestNothing(tokenBytes, false /* success */);
-
-        // Assert everything required was done.
-        verifyNoInstallerCallsMade();
-        verifyPackageTrackerCalled(token, false /* success */);
-    }
-
-    @Test
-    public void requestNothing_nullTokenBytes() throws Exception {
-        configureCallerHasPermission();
-
-        // Make the call.
-        mRulesManagerService.requestNothing(null /* tokenBytes */, true /* success */);
-
-        // Assert everything required was done.
-        verifyNoInstallerCallsMade();
-        verifyPackageTrackerCalled(null /* token */, true /* success */);
-    }
-
-    private void verifyNoPackageTrackerCallsMade() {
-        verifyNoMoreInteractions(mMockPackageTracker);
-        reset(mMockPackageTracker);
-    }
-
-    private void verifyPackageTrackerCalled(
-            CheckToken expectedCheckToken, boolean expectedSuccess) {
-        verify(mMockPackageTracker).recordCheckResult(expectedCheckToken, expectedSuccess);
-        reset(mMockPackageTracker);
-    }
-
-    private void configureCallerHasPermission() throws Exception {
-        doNothing()
-                .when(mMockPermissionHelper)
-                .enforceCallerHasPermission(REQUIRED_UPDATER_PERMISSION);
-    }
-
-    private void configureCallerDoesNotHavePermission() {
-        doThrow(new SecurityException("Simulated permission failure"))
-                .when(mMockPermissionHelper)
-                .enforceCallerHasPermission(REQUIRED_UPDATER_PERMISSION);
-    }
-
-    private void configureParcelFileDescriptorReadSuccess(ParcelFileDescriptor parcelFileDescriptor,
-            byte[] content) throws Exception {
-        when(mMockFileDescriptorHelper.readFully(parcelFileDescriptor)).thenReturn(content);
-    }
-
-    private void configureParcelFileDescriptorReadFailure(ParcelFileDescriptor parcelFileDescriptor)
-            throws Exception {
-        when(mMockFileDescriptorHelper.readFully(parcelFileDescriptor))
-                .thenThrow(new IOException("Simulated failure"));
-    }
-
-    private void configureStageInstallExpectation(byte[] expectedContent, int resultCode)
-            throws Exception {
-        when(mMockTimeZoneDistroInstaller.stageInstallWithErrorCode(eq(expectedContent)))
-                .thenReturn(resultCode);
-    }
-
-    private void configureStageUninstallExpectation(boolean success) throws Exception {
-        doReturn(success).when(mMockTimeZoneDistroInstaller).stageUninstall();
-    }
-
-    private void verifyStageInstallCalled(byte[] expectedContent) throws Exception {
-        verify(mMockTimeZoneDistroInstaller).stageInstallWithErrorCode(eq(expectedContent));
-        verifyNoMoreInteractions(mMockTimeZoneDistroInstaller);
-        reset(mMockTimeZoneDistroInstaller);
-    }
-
-    private void verifyStageUninstallCalled() throws Exception {
-        verify(mMockTimeZoneDistroInstaller).stageUninstall();
-        verifyNoMoreInteractions(mMockTimeZoneDistroInstaller);
-        reset(mMockTimeZoneDistroInstaller);
-    }
-
-    private void verifyNoInstallerCallsMade() {
-        verifyNoMoreInteractions(mMockTimeZoneDistroInstaller);
-        reset(mMockTimeZoneDistroInstaller);
-    }
-
-    private static byte[] createArbitraryBytes(int length) {
-        byte[] bytes = new byte[length];
-        for (int i = 0; i < length; i++) {
-            bytes[i] = (byte) i;
-        }
-        return bytes;
-    }
-
-    private byte[] createArbitraryTokenBytes() {
-        return createArbitraryToken().toByteArray();
-    }
-
-    private CheckToken createArbitraryToken() {
-        return new CheckToken(1, new PackageVersions(1, 1));
-    }
-
-    private ParcelFileDescriptor createFakeParcelFileDescriptor() {
-        return new ParcelFileDescriptor((ParcelFileDescriptor) null);
-    }
-
-    private void configureDeviceSystemRulesVersion(String systemRulesVersion) throws Exception {
-        when(mMockTimeZoneDistroInstaller.getSystemRulesVersion()).thenReturn(systemRulesVersion);
-    }
-
-    private void configureInstalledDistroVersion(@Nullable DistroVersion installedDistroVersion)
-            throws Exception {
-        when(mMockTimeZoneDistroInstaller.getInstalledDistroVersion())
-                .thenReturn(installedDistroVersion);
-    }
-
-    private void configureStagedInstall(DistroVersion stagedDistroVersion) throws Exception {
-        when(mMockTimeZoneDistroInstaller.getStagedDistroOperation())
-                .thenReturn(StagedDistroOperation.install(stagedDistroVersion));
-    }
-
-    private void configureStagedUninstall() throws Exception {
-        when(mMockTimeZoneDistroInstaller.getStagedDistroOperation())
-                .thenReturn(StagedDistroOperation.uninstall());
-    }
-
-    private void configureNoStagedOperation() throws Exception {
-        when(mMockTimeZoneDistroInstaller.getStagedDistroOperation()).thenReturn(null);
-    }
-
-    private void configureDeviceCannotReadStagedDistroOperation() throws Exception {
-        when(mMockTimeZoneDistroInstaller.getStagedDistroOperation())
-                .thenThrow(new IOException("Simulated failure"));
-    }
-
-    private void configureDeviceCannotReadSystemRulesVersion() throws Exception {
-        when(mMockTimeZoneDistroInstaller.getSystemRulesVersion())
-                .thenThrow(new IOException("Simulated failure"));
-    }
-
-    private void configureDeviceCannotReadInstalledDistroVersion() throws Exception {
-        when(mMockTimeZoneDistroInstaller.getInstalledDistroVersion())
-                .thenThrow(new IOException("Simulated failure"));
-    }
-
-    private static class FakeExecutor implements Executor {
-
-        private Runnable mLastCommand;
-
-        @Override
-        public void execute(Runnable command) {
-            assertNull(mLastCommand);
-            assertNotNull(command);
-            mLastCommand = command;
-        }
-
-        public Runnable getAndResetLastCommand() {
-            assertNotNull(mLastCommand);
-            Runnable toReturn = mLastCommand;
-            mLastCommand = null;
-            return toReturn;
-        }
-
-        public void simulateAsyncExecutionOfLastCommand() {
-            Runnable toRun = getAndResetLastCommand();
-            toRun.run();
-        }
-
-        public void assertNothingQueued() {
-            assertNull(mLastCommand);
-        }
-    }
-
-    private static class TestCallback extends ICallback.Stub {
-
-        private boolean mOnFinishedCalled;
-        private int mLastError;
-
-        @Override
-        public void onFinished(int error) {
-            assertFalse(mOnFinishedCalled);
-            mOnFinishedCalled = true;
-            mLastError = error;
-        }
-
-        public void assertResultReceived(int expectedResult) {
-            assertTrue(mOnFinishedCalled);
-            assertEquals(expectedResult, mLastError);
-        }
-
-        public void assertNoResultReceived() {
-            assertFalse(mOnFinishedCalled);
-        }
-    }
-
-    private static class StubbedCallback extends ICallback.Stub {
-        @Override
-        public void onFinished(int error) {
-            fail("Unexpected call");
-        }
-    }
-}
