diff --git a/Android.mk b/Android.mk
index 59aa699..3fcfea9 100644
--- a/Android.mk
+++ b/Android.mk
@@ -114,8 +114,6 @@
 	core/java/android/app/backup/IRestoreObserver.aidl \
 	core/java/android/app/backup/IRestoreSession.aidl \
 	core/java/android/app/backup/ISelectBackupTransportCallback.aidl \
-	core/java/android/app/timezone/ICallback.aidl \
-	core/java/android/app/timezone/IRulesManager.aidl \
 	core/java/android/app/usage/ICacheQuotaService.aidl \
 	core/java/android/app/usage/IStorageStatsManager.aidl \
 	core/java/android/app/usage/IUsageStatsManager.aidl \
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/java/android/app/timezone/Callback.java b/core/java/android/app/timezone/Callback.java
deleted file mode 100644
index b51e5ba..0000000
--- a/core/java/android/app/timezone/Callback.java
+++ /dev/null
@@ -1,76 +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 android.app.timezone;
-
-import android.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Callback interface for receiving information about an async time zone operation.
- * The methods will be called on your application's main thread.
- *
- * @hide
- */
-// TODO(nfuller): Expose necessary APIs for OEMs with @SystemApi. http://b/31008728
-public abstract class Callback {
-
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({SUCCESS, ERROR_UNKNOWN_FAILURE, ERROR_INSTALL_BAD_DISTRO_STRUCTURE,
-        ERROR_INSTALL_BAD_DISTRO_FORMAT_VERSION, ERROR_INSTALL_RULES_TOO_OLD,
-        ERROR_INSTALL_VALIDATION_ERROR})
-    public @interface AsyncResultCode {}
-
-    /**
-     * Indicates that an operation succeeded.
-     */
-    public static final int SUCCESS = 0;
-
-    /**
-     * Indicates an install / uninstall did not fully succeed for an unknown reason.
-     */
-    public static final int ERROR_UNKNOWN_FAILURE = 1;
-
-    /**
-     * Indicates an install failed because of a structural issue with the provided distro,
-     * e.g. it wasn't in the right format or the contents were structured incorrectly.
-     */
-    public static final int ERROR_INSTALL_BAD_DISTRO_STRUCTURE = 2;
-
-    /**
-     * Indicates an install failed because of a versioning issue with the provided distro,
-     * e.g. it was created for a different version of Android.
-     */
-    public static final int ERROR_INSTALL_BAD_DISTRO_FORMAT_VERSION = 3;
-
-    /**
-     * Indicates an install failed because the rules provided are too old for the device,
-     * e.g. the Android device shipped with a newer rules version.
-     */
-    public static final int ERROR_INSTALL_RULES_TOO_OLD = 4;
-
-    /**
-     * Indicates an install failed because the distro contents failed validation.
-     */
-    public static final int ERROR_INSTALL_VALIDATION_ERROR = 5;
-
-    /**
-     * Reports the result of an async time zone operation.
-     */
-    public abstract void onFinished(@AsyncResultCode int status);
-}
diff --git a/core/java/android/app/timezone/DistroFormatVersion.java b/core/java/android/app/timezone/DistroFormatVersion.java
deleted file mode 100644
index e879e8f..0000000
--- a/core/java/android/app/timezone/DistroFormatVersion.java
+++ /dev/null
@@ -1,120 +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 android.app.timezone;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Versioning information about a distro's format or a device's supported format.
- *
- * <p>The following properties are included:
- * <dl>
- *     <dt>majorVersion</dt>
- *     <dd>the major distro format version. Major versions differences are not compatible - e.g.
- *     2 is not compatible with 1 or 3.</dd>
- *     <dt>minorVersion</dt>
- *     <dd>the minor distro format version. Minor versions should be backwards compatible iff the
- *     major versions match exactly, i.e. version 2.2 will be compatible with 2.1 devices but not
- *     2.3 devices.</dd>
- * </dl>
- *
- * @hide
- */
-// TODO(nfuller): Expose necessary APIs for OEMs with @SystemApi. http://b/31008728
-public final class DistroFormatVersion implements Parcelable {
-
-    private final int mMajorVersion;
-    private final int mMinorVersion;
-
-    public DistroFormatVersion(int majorVersion, int minorVersion) {
-        mMajorVersion = Utils.validateVersion("major", majorVersion);
-        mMinorVersion = Utils.validateVersion("minor", minorVersion);
-    }
-
-    public static final Creator<DistroFormatVersion> CREATOR = new Creator<DistroFormatVersion>() {
-        public DistroFormatVersion createFromParcel(Parcel in) {
-            int majorVersion = in.readInt();
-            int minorVersion = in.readInt();
-            return new DistroFormatVersion(majorVersion, minorVersion);
-        }
-
-        public DistroFormatVersion[] newArray(int size) {
-            return new DistroFormatVersion[size];
-        }
-    };
-
-    public int getMajorVersion() {
-        return mMajorVersion;
-    }
-
-    public int getMinorVersion() {
-        return mMinorVersion;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(mMajorVersion);
-        out.writeInt(mMinorVersion);
-    }
-
-    /**
-     * If this object describes a device's supported version and the parameter describes a distro's
-     * version, this method returns whether the device would accept the distro.
-     */
-    public boolean supports(DistroFormatVersion distroFormatVersion) {
-        return mMajorVersion == distroFormatVersion.mMajorVersion
-                && mMinorVersion <= distroFormatVersion.mMinorVersion;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (o == null || getClass() != o.getClass()) {
-            return false;
-        }
-
-        DistroFormatVersion that = (DistroFormatVersion) o;
-
-        if (mMajorVersion != that.mMajorVersion) {
-            return false;
-        }
-        return mMinorVersion == that.mMinorVersion;
-    }
-
-    @Override
-    public int hashCode() {
-        int result = mMajorVersion;
-        result = 31 * result + mMinorVersion;
-        return result;
-    }
-
-    @Override
-    public String toString() {
-        return "DistroFormatVersion{"
-                + "mMajorVersion=" + mMajorVersion
-                + ", mMinorVersion=" + mMinorVersion
-                + '}';
-    }
-}
diff --git a/core/java/android/app/timezone/DistroRulesVersion.java b/core/java/android/app/timezone/DistroRulesVersion.java
deleted file mode 100644
index 5503ce1..0000000
--- a/core/java/android/app/timezone/DistroRulesVersion.java
+++ /dev/null
@@ -1,128 +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 android.app.timezone;
-
-import static android.app.timezone.Utils.validateRulesVersion;
-import static android.app.timezone.Utils.validateVersion;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Versioning information about a set of time zone rules.
- *
- * <p>The following properties are included:
- * <dl>
- *     <dt>rulesVersion</dt>
- *     <dd>the IANA rules version. e.g. "2017a"</dd>
- *     <dt>revision</dt>
- *     <dd>the revision for the rules. Allows there to be several revisions for a given IANA rules
- *     release. Numerically higher is newer.</dd>
- * </dl>
- *
- * @hide
- */
-// TODO(nfuller): Expose necessary APIs for OEMs with @SystemApi. http://b/31008728
-public final class DistroRulesVersion implements Parcelable {
-
-    private final String mRulesVersion;
-    private final int mRevision;
-
-    public DistroRulesVersion(String rulesVersion, int revision) {
-        mRulesVersion = validateRulesVersion("rulesVersion", rulesVersion);
-        mRevision = validateVersion("revision", revision);
-    }
-
-    public static final Creator<DistroRulesVersion> CREATOR = new Creator<DistroRulesVersion>() {
-        public DistroRulesVersion createFromParcel(Parcel in) {
-            String rulesVersion = in.readString();
-            int revision = in.readInt();
-            return new DistroRulesVersion(rulesVersion, revision);
-        }
-
-        public DistroRulesVersion[] newArray(int size) {
-            return new DistroRulesVersion[size];
-        }
-    };
-
-    public String getRulesVersion() {
-        return mRulesVersion;
-    }
-
-    public int getRevision() {
-        return mRevision;
-    }
-
-    /**
-     * Returns true if this DistroRulesVersion is older than the one supplied. It returns false if
-     * it is the same or newer. This method compares the {@code rulesVersion} and the
-     * {@code revision}.
-     */
-    public boolean isOlderThan(DistroRulesVersion distroRulesVersion) {
-        int rulesComparison = mRulesVersion.compareTo(distroRulesVersion.mRulesVersion);
-        if (rulesComparison < 0) {
-            return true;
-        }
-        if (rulesComparison > 0) {
-            return false;
-        }
-        return mRevision < distroRulesVersion.mRevision;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeString(mRulesVersion);
-        out.writeInt(mRevision);
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (o == null || getClass() != o.getClass()) {
-            return false;
-        }
-
-        DistroRulesVersion that = (DistroRulesVersion) o;
-
-        if (mRevision != that.mRevision) {
-            return false;
-        }
-        return mRulesVersion.equals(that.mRulesVersion);
-    }
-
-    @Override
-    public int hashCode() {
-        int result = mRulesVersion.hashCode();
-        result = 31 * result + mRevision;
-        return result;
-    }
-
-    @Override
-    public String toString() {
-        return "DistroRulesVersion{"
-                + "mRulesVersion='" + mRulesVersion + '\''
-                + ", mRevision='" + mRevision + '\''
-                + '}';
-    }
-}
diff --git a/core/java/android/app/timezone/ICallback.aidl b/core/java/android/app/timezone/ICallback.aidl
deleted file mode 100644
index 519ef1a..0000000
--- a/core/java/android/app/timezone/ICallback.aidl
+++ /dev/null
@@ -1,27 +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 android.app.timezone;
-
-/**
- * Callback interface for a timezone updater to receive information about the success or failure of
- * an installation/uninstallation attempt.
- *
- * {@hide}
- */
-oneway interface ICallback {
-    void onFinished(int error);
-}
\ No newline at end of file
diff --git a/core/java/android/app/timezone/IRulesManager.aidl b/core/java/android/app/timezone/IRulesManager.aidl
deleted file mode 100644
index 40f3fd2..0000000
--- a/core/java/android/app/timezone/IRulesManager.aidl
+++ /dev/null
@@ -1,84 +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 android.app.timezone;
-
-import android.app.timezone.ICallback;
-import android.app.timezone.RulesState;
-import android.os.ParcelFileDescriptor;
-
- /**
-  * Interface to the TimeZone Rules Manager Service.
-  *
-  * <p>This interface is only intended for system apps to call. They should use the
-  * {@link android.app.timezone.RulesManager} class rather than going through this
-  * Binder interface directly. See {@link android.app.timezone.RulesManager} for more complete
-  * documentation.
-  *
-  * {@hide}
-  */
-interface IRulesManager {
-
-    /**
-     * Returns information about the current time zone rules state such as the IANA version of
-     * the system and any currently installed distro. This method is intended to allow clients to
-     * determine if the current state can be improved; for example by passing the information to a
-     * server that may provide a new distro for download.
-     */
-    RulesState getRulesState();
-
-    /**
-     * Requests installation of the supplied distro. The distro must have been checked for integrity
-     * by the caller or have been received via a trusted mechanism.
-     *
-     * @param distroFileDescriptor the file descriptor for the distro
-     * @param checkToken an optional token provided if the install was triggered in response to a
-     *     {@link RulesUpdaterContract#ACTION_TRIGGER_RULES_UPDATE_CHECK} intent
-     * @param callback the {@link ICallback} to receive callbacks related to the
-     *     installation
-     * @return zero if the installation will be attempted; nonzero on error
-     */
-    int requestInstall(in ParcelFileDescriptor distroFileDescriptor, in byte[] checkToken,
-            ICallback callback);
-
-    /**
-     * Requests uninstallation of the currently installed distro (leaving the device with no
-     * distro installed).
-     *
-     * @param checkToken an optional token provided if the uninstall was triggered in response to a
-     *     {@link RulesUpdaterContract#ACTION_TRIGGER_RULES_UPDATE_CHECK} intent
-     * @param callback the {@link ICallback} to receive callbacks related to the
-     *     uninstall
-     * @return zero if the uninstallation will be attempted; nonzero on error
-     */
-    int requestUninstall(in byte[] checkToken, ICallback callback);
-
-    /**
-     * Requests the system does not modify the currently installed time zone distro, if any. This
-     * method records the fact that a time zone check operation triggered by the system is now
-     * complete and there was nothing to do. The token passed should be the one presented when the
-     * check was triggered.
-     *
-     * <p>Note: Passing {@code success == false} may result in more checks being triggered. Clients
-     * should be careful not to pass false if the failure is unlikely to resolve by itself.
-     *
-     * @param checkToken an optional token provided if the install was triggered in response to a
-     *     {@link RulesUpdaterContract#ACTION_TRIGGER_RULES_UPDATE_CHECK} intent
-     * @param success true if the check was successful, false if it was not successful but may
-     *     succeed if it is retried
-     */
-    void requestNothing(in byte[] token, boolean success);
-}
diff --git a/core/java/android/app/timezone/RulesManager.java b/core/java/android/app/timezone/RulesManager.java
deleted file mode 100644
index 649d894..0000000
--- a/core/java/android/app/timezone/RulesManager.java
+++ /dev/null
@@ -1,212 +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 android.app.timezone;
-
-import android.annotation.IntDef;
-import android.content.Context;
-import android.os.Handler;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.util.Log;
-
-import java.io.IOException;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Arrays;
-
-/**
- * The interface through which a time zone update application interacts with the Android system
- * to handle time zone rule updates.
- *
- * <p>This interface is intended for use with the default APK-based time zone rules update
- * application but it can also be used by OEMs if that mechanism is turned off using configuration.
- * All callers must possess the {@link android.Manifest.permission#UPDATE_TIME_ZONE_RULES} system
- * permission.
- *
- * <p>When using the default mechanism, when properly configured the Android system will send a
- * {@link RulesUpdaterContract#ACTION_TRIGGER_RULES_UPDATE_CHECK} intent with a
- * {@link RulesUpdaterContract#EXTRA_CHECK_TOKEN} extra to the time zone rules updater application
- * when it detects that it or the OEM's APK containing time zone rules data has been modified. The
- * updater application is then responsible for calling one of
- * {@link #requestInstall(ParcelFileDescriptor, byte[], Callback)},
- * {@link #requestUninstall(byte[], Callback)} or
- * {@link #requestNothing(byte[], boolean)}, indicating, respectively, whether a new time zone rules
- * distro should be installed, the current distro should be uninstalled, or there is nothing to do
- * (or that the correct operation could not be determined due to an error). In each case the updater
- * must pass the {@link RulesUpdaterContract#EXTRA_CHECK_TOKEN} value it received from the intent
- * back so the system in the {@code checkToken} parameter.
- *
- * <p>If OEMs want to handle their own time zone rules updates, perhaps via a server-side component
- * rather than an APK, then they should disable the default triggering mechanism in config and are
- * responsible for triggering their own update checks / installs / uninstalls. In this case the
- * "check token" parameter can be left null and there is never any need to call
- * {@link #requestNothing(byte[], boolean)}.
- *
- * <p>OEMs should not mix the default mechanism and their own as this could lead to conflicts and
- * unnecessary checks being triggered.
- *
- * <p>Applications obtain this using {@link android.app.Activity#getSystemService(String)} with
- * {@link Context#TIME_ZONE_RULES_MANAGER_SERVICE}.
- * @hide
- */
-// TODO(nfuller): Expose necessary APIs for OEMs with @SystemApi. http://b/31008728
-public final class RulesManager {
-    private static final String TAG = "timezone.RulesManager";
-    private static final boolean DEBUG = false;
-
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({SUCCESS, ERROR_UNKNOWN_FAILURE, ERROR_OPERATION_IN_PROGRESS})
-    public @interface ResultCode {}
-
-    /**
-     * Indicates that an operation succeeded.
-     */
-    public static final int SUCCESS = 0;
-
-    /**
-     * Indicates that an install/uninstall cannot be initiated because there is one already in
-     * progress.
-     */
-    public static final int ERROR_OPERATION_IN_PROGRESS = 1;
-
-    /**
-     * Indicates an install / uninstall did not fully succeed for an unknown reason.
-     */
-    public static final int ERROR_UNKNOWN_FAILURE = 2;
-
-    private final Context mContext;
-    private final IRulesManager mIRulesManager;
-
-    public RulesManager(Context context) {
-        mContext = context;
-        mIRulesManager = IRulesManager.Stub.asInterface(
-                ServiceManager.getService(Context.TIME_ZONE_RULES_MANAGER_SERVICE));
-    }
-
-    /**
-     * Returns information about the current time zone rules state such as the IANA version of
-     * the system and any currently installed distro. This method is intended to allow clients to
-     * determine if the current state can be improved; for example by passing the information to a
-     * server that may provide a new distro for download.
-     */
-    public RulesState getRulesState() {
-        try {
-            logDebug("sIRulesManager.getRulesState()");
-            RulesState rulesState = mIRulesManager.getRulesState();
-            logDebug("sIRulesManager.getRulesState() returned " + rulesState);
-            return rulesState;
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Requests installation of the supplied distro. The distro must have been checked for integrity
-     * by the caller or have been received via a trusted mechanism.
-     *
-     * @param distroFileDescriptor the file descriptor for the distro
-     * @param checkToken an optional token provided if the install was triggered in response to a
-     *     {@link RulesUpdaterContract#ACTION_TRIGGER_RULES_UPDATE_CHECK} intent
-     * @param callback the {@link Callback} to receive callbacks related to the installation
-     * @return {@link #SUCCESS} if the installation will be attempted
-     */
-    @ResultCode
-    public int requestInstall(
-            ParcelFileDescriptor distroFileDescriptor, byte[] checkToken, Callback callback)
-            throws IOException {
-
-        ICallback iCallback = new CallbackWrapper(mContext, callback);
-        try {
-            logDebug("sIRulesManager.requestInstall()");
-            return mIRulesManager.requestInstall(distroFileDescriptor, checkToken, iCallback);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Requests uninstallation of the currently installed distro (leaving the device with no
-     * distro installed).
-     *
-     * @param checkToken an optional token provided if the uninstall was triggered in response to a
-     *     {@link RulesUpdaterContract#ACTION_TRIGGER_RULES_UPDATE_CHECK} intent
-     * @param callback the {@link Callback} to receive callbacks related to the uninstall
-     * @return {@link #SUCCESS} if the uninstallation will be attempted
-     */
-    @ResultCode
-    public int requestUninstall(byte[] checkToken, Callback callback) {
-        ICallback iCallback = new CallbackWrapper(mContext, callback);
-        try {
-            logDebug("sIRulesManager.requestUninstall()");
-            return mIRulesManager.requestUninstall(checkToken, iCallback);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /*
-     * We wrap incoming binder calls with a private class implementation that
-     * redirects them into main-thread actions.  This serializes the backup
-     * progress callbacks nicely within the usual main-thread lifecycle pattern.
-     */
-    private class CallbackWrapper extends ICallback.Stub {
-        final Handler mHandler;
-        final Callback mCallback;
-
-        CallbackWrapper(Context context, Callback callback) {
-            mCallback = callback;
-            mHandler = new Handler(context.getMainLooper());
-        }
-
-        // Binder calls into this object just enqueue on the main-thread handler
-        @Override
-        public void onFinished(int status) {
-            logDebug("mCallback.onFinished(status), status=" + status);
-            mHandler.post(() -> mCallback.onFinished(status));
-        }
-    }
-
-    /**
-     * Requests the system does not modify the currently installed time zone distro, if any. This
-     * method records the fact that a time zone check operation triggered by the system is now
-     * complete and there was nothing to do. The token passed should be the one presented when the
-     * check was triggered.
-     *
-     * <p>Note: Passing {@code success == false} may result in more checks being triggered. Clients
-     * should be careful not to pass false if the failure is unlikely to resolve by itself.
-     *
-     * @param checkToken an optional token provided if the install was triggered in response to a
-     *     {@link RulesUpdaterContract#ACTION_TRIGGER_RULES_UPDATE_CHECK} intent
-     * @param succeeded true if the check was successful, false if it was not successful but may
-     *     succeed if it is retried
-     */
-    public void requestNothing(byte[] checkToken, boolean succeeded) {
-        try {
-            logDebug("sIRulesManager.requestNothing() with token=" + Arrays.toString(checkToken));
-            mIRulesManager.requestNothing(checkToken, succeeded);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    static void logDebug(String msg) {
-        if (DEBUG) {
-            Log.v(TAG, msg);
-        }
-    }
-}
diff --git a/core/java/android/app/timezone/RulesState.aidl b/core/java/android/app/timezone/RulesState.aidl
deleted file mode 100644
index f789120..0000000
--- a/core/java/android/app/timezone/RulesState.aidl
+++ /dev/null
@@ -1,17 +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.
- */
-
-parcelable RulesState;
\ No newline at end of file
diff --git a/core/java/android/app/timezone/RulesState.java b/core/java/android/app/timezone/RulesState.java
deleted file mode 100644
index 33f4e80..0000000
--- a/core/java/android/app/timezone/RulesState.java
+++ /dev/null
@@ -1,319 +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 android.app.timezone;
-
-import static android.app.timezone.Utils.validateConditionalNull;
-import static android.app.timezone.Utils.validateNotNull;
-import static android.app.timezone.Utils.validateRulesVersion;
-
-import android.annotation.IntDef;
-import android.annotation.Nullable;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Description of the state of time zone rules on a device.
- *
- * <p>The following properties are included:
- * <dl>
- *     <dt>systemRulesVersion</dt>
- *     <dd>the IANA rules version that shipped with the OS. Always present. e.g. "2017a".</dd>
- *     <dt>distroFormatVersionSupported</dt>
- *     <dd>the distro format version supported by this device. Always present.</dd>
- *     <dt>operationInProgress</dt>
- *     <dd>{@code true} if there is an install / uninstall operation currently happening.</dd>
- *     <dt>stagedOperationType</dt>
- *     <dd>one of {@link #STAGED_OPERATION_UNKNOWN}, {@link #STAGED_OPERATION_NONE},
- *     {@link #STAGED_OPERATION_UNINSTALL} and {@link #STAGED_OPERATION_INSTALL} indicating whether
- *     there is a currently staged time zone distro operation. {@link #STAGED_OPERATION_UNKNOWN} is
- *     used when {@link #isOperationInProgress()} is {@code true}. Staged operations currently
- *     require a reboot to become active.</dd>
- *     <dt>stagedDistroRulesVersion</dt>
- *     <dd>[present if distroStagedState == STAGED_STATE_INSTALL], the rules version of the distro
- *     currently staged for installation.</dd>
- *     <dt>distroStatus</dt>
- *     <dd>{@link #DISTRO_STATUS_INSTALLED} if there is a time zone distro installed and active,
- *     {@link #DISTRO_STATUS_NONE} if there is no active installed distro.
- *     {@link #DISTRO_STATUS_UNKNOWN} is used when {@link #isOperationInProgress()} is {@code true}.
- *     </dd>
- *     <dt>installedDistroRulesVersion</dt>
- *     <dd>[present if distroStatus == {@link #DISTRO_STATUS_INSTALLED}], the rules version of the
- *     installed and active distro.</dd>
- * </dl>
- *
- * @hide
- */
-// TODO(nfuller): Expose necessary APIs for OEMs with @SystemApi. http://b/31008728
-public final class RulesState implements Parcelable {
-
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({
-            STAGED_OPERATION_UNKNOWN,
-            STAGED_OPERATION_NONE,
-            STAGED_OPERATION_UNINSTALL,
-            STAGED_OPERATION_INSTALL })
-    private @interface StagedOperationType {}
-
-    /** Staged state could not be determined. */
-    public static final int STAGED_OPERATION_UNKNOWN = 0;
-    /** Nothing is staged. */
-    public static final int STAGED_OPERATION_NONE = 1;
-    /** An uninstall is staged. */
-    public static final int STAGED_OPERATION_UNINSTALL = 2;
-    /** An install is staged. */
-    public static final int STAGED_OPERATION_INSTALL = 3;
-
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({
-            DISTRO_STATUS_UNKNOWN,
-            DISTRO_STATUS_NONE,
-            DISTRO_STATUS_INSTALLED })
-    private @interface DistroStatus {}
-
-    /** The current distro status could not be determined. */
-    public static final int DISTRO_STATUS_UNKNOWN = 0;
-    /** There is no active installed time zone distro. */
-    public static final int DISTRO_STATUS_NONE = 1;
-    /** The is an active, installed time zone distro. */
-    public static final int DISTRO_STATUS_INSTALLED = 2;
-
-    private static final byte BYTE_FALSE = 0;
-    private static final byte BYTE_TRUE = 1;
-
-    private final String mSystemRulesVersion;
-    private final DistroFormatVersion mDistroFormatVersionSupported;
-    private final boolean mOperationInProgress;
-    @StagedOperationType private final int mStagedOperationType;
-    @Nullable private final DistroRulesVersion mStagedDistroRulesVersion;
-    @DistroStatus private final int mDistroStatus;
-    @Nullable private final DistroRulesVersion mInstalledDistroRulesVersion;
-
-    public RulesState(String systemRulesVersion, DistroFormatVersion distroFormatVersionSupported,
-            boolean operationInProgress,
-            @StagedOperationType int stagedOperationType,
-            @Nullable DistroRulesVersion stagedDistroRulesVersion,
-            @DistroStatus int distroStatus,
-            @Nullable DistroRulesVersion installedDistroRulesVersion) {
-        this.mSystemRulesVersion = validateRulesVersion("systemRulesVersion", systemRulesVersion);
-        this.mDistroFormatVersionSupported =
-                validateNotNull("distroFormatVersionSupported", distroFormatVersionSupported);
-        this.mOperationInProgress = operationInProgress;
-
-        if (operationInProgress && stagedOperationType != STAGED_OPERATION_UNKNOWN) {
-            throw new IllegalArgumentException(
-                    "stagedOperationType != STAGED_OPERATION_UNKNOWN");
-        }
-        this.mStagedOperationType = validateStagedOperation(stagedOperationType);
-        this.mStagedDistroRulesVersion = validateConditionalNull(
-                mStagedOperationType == STAGED_OPERATION_INSTALL /* requireNotNull */,
-                "stagedDistroRulesVersion", stagedDistroRulesVersion);
-
-        if (operationInProgress && distroStatus != DISTRO_STATUS_UNKNOWN) {
-            throw new IllegalArgumentException("distroInstalled != DISTRO_STATUS_UNKNOWN");
-        }
-        this.mDistroStatus = validateDistroStatus(distroStatus);
-        this.mInstalledDistroRulesVersion = validateConditionalNull(
-                mDistroStatus == DISTRO_STATUS_INSTALLED/* requireNotNull */,
-                "installedDistroRulesVersion", installedDistroRulesVersion);
-    }
-
-    public String getSystemRulesVersion() {
-        return mSystemRulesVersion;
-    }
-
-    public boolean isOperationInProgress() {
-        return mOperationInProgress;
-    }
-
-    public @StagedOperationType int getStagedOperationType() {
-        return mStagedOperationType;
-    }
-
-    /**
-     * Returns the staged rules version when {@link #getStagedOperationType()} is
-     * {@link #STAGED_OPERATION_INSTALL}.
-     */
-    public @Nullable DistroRulesVersion getStagedDistroRulesVersion() {
-        return mStagedDistroRulesVersion;
-    }
-
-    public @DistroStatus int getDistroStatus() {
-        return mDistroStatus;
-    }
-
-    /**
-     * Returns the installed rules version when {@link #getDistroStatus()} is
-     * {@link #DISTRO_STATUS_INSTALLED}.
-     */
-    public @Nullable DistroRulesVersion getInstalledDistroRulesVersion() {
-        return mInstalledDistroRulesVersion;
-    }
-
-    /**
-     * Returns true if a distro in the specified format is supported on this device.
-     */
-    public boolean isDistroFormatVersionSupported(DistroFormatVersion distroFormatVersion) {
-        return mDistroFormatVersionSupported.supports(distroFormatVersion);
-    }
-
-    /**
-     * Returns true if the distro IANA rules version supplied is newer or the same as the version in
-     * the system image data files.
-     */
-    public boolean isSystemVersionOlderThan(DistroRulesVersion distroRulesVersion) {
-        return mSystemRulesVersion.compareTo(distroRulesVersion.getRulesVersion()) < 0;
-    }
-
-    public boolean isDistroInstalled() {
-        return mDistroStatus == DISTRO_STATUS_INSTALLED;
-    }
-
-    /**
-     * Returns true if the rules version supplied is newer than the one currently installed. If
-     * there is no installed distro this method throws IllegalStateException.
-     */
-    public boolean isInstalledDistroOlderThan(DistroRulesVersion distroRulesVersion) {
-        if (mOperationInProgress) {
-            throw new IllegalStateException("Distro state not known: operation in progress.");
-        }
-        if (!isDistroInstalled()) {
-            throw new IllegalStateException("No distro installed.");
-        }
-        return mInstalledDistroRulesVersion.isOlderThan(distroRulesVersion);
-    }
-
-    public static final Parcelable.Creator<RulesState> CREATOR =
-            new Parcelable.Creator<RulesState>() {
-        public RulesState createFromParcel(Parcel in) {
-            return RulesState.createFromParcel(in);
-        }
-
-        public RulesState[] newArray(int size) {
-            return new RulesState[size];
-        }
-    };
-
-    private static RulesState createFromParcel(Parcel in) {
-        String systemRulesVersion = in.readString();
-        DistroFormatVersion distroFormatVersionSupported = in.readParcelable(null);
-        boolean operationInProgress = in.readByte() == BYTE_TRUE;
-        int distroStagedState = in.readByte();
-        DistroRulesVersion stagedDistroRulesVersion = in.readParcelable(null);
-        int installedDistroStatus = in.readByte();
-        DistroRulesVersion installedDistroRulesVersion = in.readParcelable(null);
-        return new RulesState(systemRulesVersion, distroFormatVersionSupported, operationInProgress,
-                distroStagedState, stagedDistroRulesVersion,
-                installedDistroStatus, installedDistroRulesVersion);
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeString(mSystemRulesVersion);
-        out.writeParcelable(mDistroFormatVersionSupported, 0);
-        out.writeByte(mOperationInProgress ? BYTE_TRUE : BYTE_FALSE);
-        out.writeByte((byte) mStagedOperationType);
-        out.writeParcelable(mStagedDistroRulesVersion, 0);
-        out.writeByte((byte) mDistroStatus);
-        out.writeParcelable(mInstalledDistroRulesVersion, 0);
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (o == null || getClass() != o.getClass()) {
-            return false;
-        }
-
-        RulesState that = (RulesState) o;
-
-        if (mOperationInProgress != that.mOperationInProgress) {
-            return false;
-        }
-        if (mStagedOperationType != that.mStagedOperationType) {
-            return false;
-        }
-        if (mDistroStatus != that.mDistroStatus) {
-            return false;
-        }
-        if (!mSystemRulesVersion.equals(that.mSystemRulesVersion)) {
-            return false;
-        }
-        if (!mDistroFormatVersionSupported.equals(that.mDistroFormatVersionSupported)) {
-            return false;
-        }
-        if (mStagedDistroRulesVersion != null ? !mStagedDistroRulesVersion
-                .equals(that.mStagedDistroRulesVersion) : that.mStagedDistroRulesVersion != null) {
-            return false;
-        }
-        return mInstalledDistroRulesVersion != null ? mInstalledDistroRulesVersion
-                .equals(that.mInstalledDistroRulesVersion)
-                : that.mInstalledDistroRulesVersion == null;
-    }
-
-    @Override
-    public int hashCode() {
-        int result = mSystemRulesVersion.hashCode();
-        result = 31 * result + mDistroFormatVersionSupported.hashCode();
-        result = 31 * result + (mOperationInProgress ? 1 : 0);
-        result = 31 * result + mStagedOperationType;
-        result = 31 * result + (mStagedDistroRulesVersion != null ? mStagedDistroRulesVersion
-                .hashCode()
-                : 0);
-        result = 31 * result + mDistroStatus;
-        result = 31 * result + (mInstalledDistroRulesVersion != null ? mInstalledDistroRulesVersion
-                .hashCode() : 0);
-        return result;
-    }
-
-    @Override
-    public String toString() {
-        return "RulesState{"
-                + "mSystemRulesVersion='" + mSystemRulesVersion + '\''
-                + ", mDistroFormatVersionSupported=" + mDistroFormatVersionSupported
-                + ", mOperationInProgress=" + mOperationInProgress
-                + ", mStagedOperationType=" + mStagedOperationType
-                + ", mStagedDistroRulesVersion=" + mStagedDistroRulesVersion
-                + ", mDistroStatus=" + mDistroStatus
-                + ", mInstalledDistroRulesVersion=" + mInstalledDistroRulesVersion
-                + '}';
-    }
-
-    private static int validateStagedOperation(int stagedOperationType) {
-        if (stagedOperationType < STAGED_OPERATION_UNKNOWN
-                || stagedOperationType > STAGED_OPERATION_INSTALL) {
-            throw new IllegalArgumentException("Unknown operation type=" + stagedOperationType);
-        }
-        return stagedOperationType;
-    }
-
-    private static int validateDistroStatus(int distroStatus) {
-        if (distroStatus < DISTRO_STATUS_UNKNOWN || distroStatus > DISTRO_STATUS_INSTALLED) {
-            throw new IllegalArgumentException("Unknown distro status=" + distroStatus);
-        }
-        return distroStatus;
-    }
-}
diff --git a/core/java/android/app/timezone/RulesUpdaterContract.java b/core/java/android/app/timezone/RulesUpdaterContract.java
deleted file mode 100644
index 4e77818..0000000
--- a/core/java/android/app/timezone/RulesUpdaterContract.java
+++ /dev/null
@@ -1,87 +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 android.app.timezone;
-
-import android.content.Context;
-import android.content.Intent;
-import android.os.ParcelFileDescriptor;
-
-/**
- * Constants related to the contract between the Android system and the privileged time zone updater
- * application.
- *
- * @hide
- */
-// TODO(nfuller): Expose necessary APIs for OEMs with @SystemApi. http://b/31008728
-public final class RulesUpdaterContract {
-
-    /**
-     * The system permission possessed by the Android system that allows it to trigger time zone
-     * update checks. The updater should be configured to require this permission when registering
-     * for {@link #ACTION_TRIGGER_RULES_UPDATE_CHECK} intents.
-     */
-    public static final String TRIGGER_TIME_ZONE_RULES_CHECK_PERMISSION =
-            android.Manifest.permission.TRIGGER_TIME_ZONE_RULES_CHECK;
-
-    /**
-     * The system permission possessed by the time zone rules updater app that allows it to update
-     * device time zone rules. The Android system requires this permission for calls made to
-     * {@link RulesManager}.
-     */
-    public static final String UPDATE_TIME_ZONE_RULES_PERMISSION =
-            android.Manifest.permission.UPDATE_TIME_ZONE_RULES;
-
-    /**
-     * The action of the intent that the Android system will broadcast. The intent will be targeted
-     * at the configured updater application's package meaning the term "broadcast" only loosely
-     * applies.
-     */
-    public static final String ACTION_TRIGGER_RULES_UPDATE_CHECK =
-            "android.intent.action.timezone.TRIGGER_RULES_UPDATE_CHECK";
-
-    /**
-     * The extra containing the {@code byte[]} that should be passed to
-     * {@link RulesManager#requestInstall(ParcelFileDescriptor, byte[], Callback)},
-     * {@link RulesManager#requestUninstall(byte[], Callback)} and
-     * {@link RulesManager#requestNothing(byte[], boolean)} methods when the
-     * {@link #ACTION_TRIGGER_RULES_UPDATE_CHECK} intent has been processed.
-     */
-    public static final String EXTRA_CHECK_TOKEN =
-            "android.intent.extra.timezone.CHECK_TOKEN";
-
-    /**
-     * Creates an intent that would trigger a time zone rules update check.
-     */
-    public static Intent createUpdaterIntent(String updaterPackageName) {
-        Intent intent = new Intent(RulesUpdaterContract.ACTION_TRIGGER_RULES_UPDATE_CHECK);
-        intent.setPackage(updaterPackageName);
-        intent.setFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
-        return intent;
-    }
-
-    /**
-     * Broadcasts an {@link #ACTION_TRIGGER_RULES_UPDATE_CHECK} intent with the
-     * {@link #EXTRA_CHECK_TOKEN} that triggers an update check, including the required receiver
-     * permission.
-     */
-    public static void sendBroadcast(Context context, String updaterAppPackageName,
-            byte[] checkTokenBytes) {
-        Intent intent = createUpdaterIntent(updaterAppPackageName);
-        intent.putExtra(EXTRA_CHECK_TOKEN, checkTokenBytes);
-        context.sendBroadcast(intent, RulesUpdaterContract.UPDATE_TIME_ZONE_RULES_PERMISSION);
-    }
-}
diff --git a/core/java/android/app/timezone/Utils.java b/core/java/android/app/timezone/Utils.java
deleted file mode 100644
index 8dd3fb7..0000000
--- a/core/java/android/app/timezone/Utils.java
+++ /dev/null
@@ -1,67 +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 android.app.timezone;
-
-/**
- * Shared code for android.app.timezone classes.
- */
-final class Utils {
-    private Utils() {}
-
-    static int validateVersion(String type, int version) {
-        if (version < 0 || version > 999) {
-            throw new IllegalArgumentException("Invalid " + type + " version=" + version);
-        }
-        return version;
-    }
-
-    static String validateRulesVersion(String type, String rulesVersion) {
-        validateNotNull(type, rulesVersion);
-
-        if (rulesVersion.isEmpty()) {
-            throw new IllegalArgumentException(type + " must not be empty");
-        }
-        return rulesVersion;
-    }
-
-    /** Validates that {@code object} is not null. Always returns {@code object}. */
-    static <T> T validateNotNull(String type, T object) {
-        if (object == null) {
-            throw new NullPointerException(type + " == null");
-        }
-        return object;
-    }
-
-    /**
-     * If {@code requireNotNull} is {@code true} calls {@link #validateNotNull(String, Object)},
-     * and {@link #validateNull(String, Object)} otherwise. Returns {@code object}.
-     */
-    static <T> T validateConditionalNull(boolean requireNotNull, String type, T object) {
-        if (requireNotNull) {
-            return validateNotNull(type, object);
-        } else {
-            return validateNull(type, object);
-        }
-    }
-
-    /** Validates that {@code object} is null. Always returns null. */
-    static <T> T validateNull(String type, T object) {
-        if (object != null) {
-            throw new IllegalArgumentException(type + " != null");
-        }
-        return null;
-    }
-}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 7d2f8d1..916fb7c 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -34,6 +34,7 @@
 import android.annotation.UserIdInt;
 import android.app.IApplicationThread;
 import android.app.IServiceConnection;
+import android.app.Notification;
 import android.app.VrManager;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
@@ -2711,8 +2712,8 @@
 
     /**
      * Similar to {@link #startService(Intent)}, but with an implicit promise that the
-     * Service will call {@link android.app.Service#startForeground(int, android.app.Notification)
-     * startForeground(int, android.app.Notification)} once it begins running.  The service is given
+     * Service will call {@link android.app.Service#startForeground(int, Notification)
+     * startForeground(int, Notification)} once it begins running.  The service is given
      * an amount of time comparable to the ANR interval to do this, otherwise the system
      * will automatically stop the service and declare the app ANR.
      *
@@ -2733,7 +2734,7 @@
      * or the service can not be found.
      *
      * @see #stopService
-     * @see android.app.Service#startForeground(int, android.app.Notification)
+     * @see android.app.Service#startForeground(int, Notification)
      */
     @Nullable
     public abstract ComponentName startForegroundService(Intent service);
@@ -2921,7 +2922,6 @@
             STORAGE_SERVICE,
             STORAGE_STATS_SERVICE,
             WALLPAPER_SERVICE,
-            TIME_ZONE_RULES_MANAGER_SERVICE,
             VIBRATOR_SERVICE,
             //@hide: STATUS_BAR_SERVICE,
             CONNECTIVITY_SERVICE,
@@ -4026,15 +4026,6 @@
     public static final String VR_SERVICE = "vrmanager";
 
     /**
-     * Use with {@link #getSystemService} to retrieve an
-     * {@link android.app.timezone.ITimeZoneRulesManager}.
-     * @hide
-     *
-     * @see #getSystemService
-     */
-    public static final String TIME_ZONE_RULES_MANAGER_SERVICE = "timezone";
-
-    /**
      * Determine whether the given permission is allowed for a particular
      * process and user ID running in the system.
      *
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index fb14c64..7c2f233 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2219,22 +2219,6 @@
     <permission android:name="android.permission.UPDATE_CONFIG"
         android:protectionLevel="signature|privileged" />
 
-    <!-- Allows a time zone rule updater application to request
-         the system installs / uninstalls timezone rules.
-         <p>An application requesting this permission is responsible for
-         verifying the source and integrity of the update before passing
-         it off to the installer components.
-         @hide -->
-    <permission android:name="android.permission.UPDATE_TIME_ZONE_RULES"
-        android:protectionLevel="signature|privileged" />
-
-    <!-- Must be required by a time zone rule updater application,
-         to ensure that only the system can trigger it.
-         @hide -->
-    <permission android:name="android.permission.TRIGGER_TIME_ZONE_RULES_CHECK"
-        android:protectionLevel="signature" />
-    <uses-permission android:name="android.permission.TRIGGER_TIME_ZONE_RULES_CHECK"/>
-
     <!-- Allows the system to reset throttling in shortcut manager.
          @hide -->
     <permission android:name="android.permission.RESET_SHORTCUT_MANAGER_THROTTLING"
@@ -2773,7 +2757,7 @@
          Could be used to prevent unwanted touch events
          on a touchscreen, for example during swimming or rain.
          @hide -->
-    <permission android:name="android.permission.DISABLE_INPUT_DEVICE"
+    <permission android:name="com.android.permission.DISABLE_INPUT_DEVICE"
         android:protectionLevel="signature" />
 
     <!-- Allows an application to configure and connect to Wifi displays
@@ -3169,7 +3153,7 @@
 
     <!-- Allows notifications to be colorized
          <p>Not for use by third-party applications. @hide -->
-    <permission android:name="android.permission.USE_COLORIZED_NOTIFICATIONS"
+    <permission android:name="com.android.permission.USE_COLORIZED_NOTIFICATIONS"
                 android:protectionLevel="signature|setup" />
 
     <!-- Allows access to keyguard secure storage.  Only allowed for system processes.
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/core/tests/coretests/src/android/app/timezone/DistroFormatVersionTest.java b/core/tests/coretests/src/android/app/timezone/DistroFormatVersionTest.java
deleted file mode 100644
index 9bbcd3d..0000000
--- a/core/tests/coretests/src/android/app/timezone/DistroFormatVersionTest.java
+++ /dev/null
@@ -1,83 +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 android.app.timezone;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.os.Parcel;
-
-import org.junit.Test;
-
-/**
- * Tests for {@link DistroFormatVersion}.
- */
-// TODO(nfuller) Move to CTS once this class is part of the SystemApi. http://b/31008728
-public class DistroFormatVersionTest {
-
-    @Test
-    public void equalsAndHashCode() {
-        DistroFormatVersion one = new DistroFormatVersion(1, 2);
-        assertEqualsContract(one, one);
-
-        DistroFormatVersion two = new DistroFormatVersion(1, 2);
-        assertEqualsContract(one, two);
-
-        DistroFormatVersion three = new DistroFormatVersion(2, 1);
-        assertFalse(one.equals(three));
-    }
-
-    @Test
-    public void parcelable() {
-        DistroFormatVersion version = new DistroFormatVersion(2, 3);
-
-        Parcel parcel = Parcel.obtain();
-        version.writeToParcel(parcel, 0 /* flags */);
-        parcel.setDataPosition(0);
-
-        DistroFormatVersion newVersion = DistroFormatVersion.CREATOR.createFromParcel(parcel);
-
-        assertEquals(version, newVersion);
-    }
-
-    @Test
-    public void supportsVersion() {
-        DistroFormatVersion deviceVersion = new DistroFormatVersion(2, 2);
-        assertTrue(deviceVersion.supports(deviceVersion));
-
-        DistroFormatVersion sameVersion = new DistroFormatVersion(2, 2);
-        assertTrue(deviceVersion.supports(sameVersion));
-
-        // Minor versions are backwards compatible.
-        DistroFormatVersion sameMajorNewerMinor = new DistroFormatVersion(2, 3);
-        assertTrue(deviceVersion.supports(sameMajorNewerMinor));
-        DistroFormatVersion sameMajorOlderMinor = new DistroFormatVersion(2, 1);
-        assertFalse(deviceVersion.supports(sameMajorOlderMinor));
-
-        // Major versions are not backwards compatible.
-        DistroFormatVersion newerMajor = new DistroFormatVersion(1, 2);
-        assertFalse(deviceVersion.supports(newerMajor));
-        DistroFormatVersion olderMajor = new DistroFormatVersion(3, 2);
-        assertFalse(deviceVersion.supports(olderMajor));
-    }
-
-    private static void assertEqualsContract(DistroFormatVersion one, DistroFormatVersion two) {
-        assertEquals(one, two);
-        assertEquals(one.hashCode(), two.hashCode());
-    }
-}
diff --git a/core/tests/coretests/src/android/app/timezone/DistroRulesVersionTest.java b/core/tests/coretests/src/android/app/timezone/DistroRulesVersionTest.java
deleted file mode 100644
index 2fbc9a1..0000000
--- a/core/tests/coretests/src/android/app/timezone/DistroRulesVersionTest.java
+++ /dev/null
@@ -1,83 +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 android.app.timezone;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.os.Parcel;
-
-import org.junit.Test;
-
-/**
- * Tests for {@link DistroRulesVersion}.
- */
-// TODO(nfuller) Move to CTS once this class is part of the SystemApi. http://b/31008728
-public class DistroRulesVersionTest {
-
-    @Test
-    public void equalsAndHashCode() {
-        DistroRulesVersion one = new DistroRulesVersion("2016a", 2);
-        assertEqualsContract(one, one);
-
-        DistroRulesVersion two = new DistroRulesVersion("2016a", 2);
-        assertEqualsContract(one, two);
-
-        DistroRulesVersion three = new DistroRulesVersion("2016b", 1);
-        assertFalse(one.equals(three));
-    }
-
-    @Test
-    public void parcelable() {
-        DistroRulesVersion version = new DistroRulesVersion("2016a", 2);
-
-        Parcel parcel = Parcel.obtain();
-        version.writeToParcel(parcel, 0 /* flags */);
-        parcel.setDataPosition(0);
-
-        DistroRulesVersion newVersion = DistroRulesVersion.CREATOR.createFromParcel(parcel);
-
-        assertEquals(version, newVersion);
-    }
-
-    @Test
-    public void isOlderThan() {
-        DistroRulesVersion deviceVersion = new DistroRulesVersion("2016b", 2);
-        assertFalse(deviceVersion.isOlderThan(deviceVersion));
-
-        DistroRulesVersion sameVersion = new DistroRulesVersion("2016b", 2);
-        assertFalse(deviceVersion.isOlderThan(sameVersion));
-
-        DistroRulesVersion sameRulesNewerRevision = new DistroRulesVersion("2016b", 3);
-        assertTrue(deviceVersion.isOlderThan(sameRulesNewerRevision));
-
-        DistroRulesVersion sameRulesOlderRevision = new DistroRulesVersion("2016b", 1);
-        assertFalse(deviceVersion.isOlderThan(sameRulesOlderRevision));
-
-        DistroRulesVersion newerRules = new DistroRulesVersion("2016c", 2);
-        assertTrue(deviceVersion.isOlderThan(newerRules));
-
-        DistroRulesVersion olderRules = new DistroRulesVersion("2016a", 2);
-        assertFalse(deviceVersion.isOlderThan(olderRules));
-    }
-
-    private static void assertEqualsContract(DistroRulesVersion one, DistroRulesVersion two) {
-        assertEquals(one, two);
-        assertEquals(one.hashCode(), two.hashCode());
-    }
-}
diff --git a/core/tests/coretests/src/android/app/timezone/RulesStateTest.java b/core/tests/coretests/src/android/app/timezone/RulesStateTest.java
deleted file mode 100644
index a9357c9..0000000
--- a/core/tests/coretests/src/android/app/timezone/RulesStateTest.java
+++ /dev/null
@@ -1,187 +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 android.app.timezone;
-
-import static junit.framework.Assert.fail;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.os.Parcel;
-
-import org.junit.Test;
-
-/**
- * Tests for {@link RulesState}.
- */
-// TODO(nfuller) Move to CTS once this class is part of the SystemApi. http://b/31008728
-public class RulesStateTest {
-
-    @Test
-    public void equalsAndHashCode() {
-        RulesState one = new RulesState(
-                "2016a", formatVersion(1, 2), false /* operationInProgress */,
-                RulesState.STAGED_OPERATION_INSTALL, rulesVersion("2016a", 3),
-                RulesState.DISTRO_STATUS_INSTALLED, rulesVersion("2016b", 2));
-        assertEqualsContract(one, one);
-
-        RulesState two = new RulesState(
-                "2016a", formatVersion(1, 2), false /* operationInProgress */,
-                RulesState.STAGED_OPERATION_INSTALL, rulesVersion("2016a", 3),
-                RulesState.DISTRO_STATUS_INSTALLED, rulesVersion("2016b", 2));
-        assertEqualsContract(one, two);
-
-        RulesState differentSystemRules = new RulesState(
-                "2016b", formatVersion(1, 2), false /* operationInProgress */,
-                RulesState.STAGED_OPERATION_INSTALL, rulesVersion("2016a", 3),
-                RulesState.DISTRO_STATUS_INSTALLED, rulesVersion("2016b", 2));
-        assertFalse(one.equals(differentSystemRules));
-
-        RulesState differentFormatVersion = new RulesState(
-                "2016a", formatVersion(1, 1), false /* operationInProgress */,
-                RulesState.STAGED_OPERATION_INSTALL, rulesVersion("2016a", 3),
-                RulesState.DISTRO_STATUS_INSTALLED, rulesVersion("2016b", 2));
-        assertFalse(one.equals(differentFormatVersion));
-
-        RulesState differentOperationInProgress = new RulesState(
-                "2016a", formatVersion(1, 1), true /* operationInProgress */,
-                RulesState.STAGED_OPERATION_UNKNOWN, null /* stagedDistroRulesVersion */,
-                RulesState.DISTRO_STATUS_UNKNOWN, null /* installedDistroRulesVersion */);
-        assertFalse(one.equals(differentOperationInProgress));
-
-        RulesState differentStagedOperation = new RulesState(
-                "2016a", formatVersion(1, 1), false /* operationInProgress */,
-                RulesState.STAGED_OPERATION_UNINSTALL, null /* stagedDistroRulesVersion */,
-                RulesState.DISTRO_STATUS_INSTALLED, rulesVersion("2016b", 2));
-        assertFalse(one.equals(differentStagedOperation));
-
-        RulesState differentStagedInstallVersion = new RulesState(
-                "2016a", formatVersion(1, 1), false /* operationInProgress */,
-                RulesState.STAGED_OPERATION_INSTALL, rulesVersion("2016a", 4),
-                RulesState.DISTRO_STATUS_INSTALLED, rulesVersion("2016b", 2));
-        assertFalse(one.equals(differentStagedInstallVersion));
-
-        RulesState differentInstalled = new RulesState(
-                "2016a", formatVersion(1, 1), false /* operationInProgress */,
-                RulesState.STAGED_OPERATION_INSTALL, rulesVersion("2016a", 3),
-                RulesState.DISTRO_STATUS_NONE, null /* installedDistroRulesVersion */);
-        assertFalse(one.equals(differentInstalled));
-
-        RulesState differentInstalledVersion = new RulesState(
-                "2016a", formatVersion(1, 1), false /* operationInProgress */,
-                RulesState.STAGED_OPERATION_INSTALL, rulesVersion("2016a", 3),
-                RulesState.DISTRO_STATUS_INSTALLED, rulesVersion("2016b", 3));
-        assertFalse(one.equals(differentInstalledVersion));
-    }
-
-    @Test
-    public void parcelable() {
-        RulesState rulesState1 = new RulesState(
-                "2016a", formatVersion(1, 1), false /* operationInProgress */,
-                RulesState.STAGED_OPERATION_INSTALL, rulesVersion("2016b", 2),
-                RulesState.DISTRO_STATUS_INSTALLED, rulesVersion("2016b", 3));
-        checkParcelableRoundTrip(rulesState1);
-
-        RulesState rulesStateWithNulls = new RulesState(
-                "2016a", formatVersion(1, 1), false /* operationInProgress */,
-                RulesState.STAGED_OPERATION_NONE, null /* stagedDistroRulesVersion */,
-                RulesState.DISTRO_STATUS_NONE, null /* installedDistroRulesVersion */);
-        checkParcelableRoundTrip(rulesStateWithNulls);
-
-        RulesState rulesStateWithUnknowns = new RulesState(
-                "2016a", formatVersion(1, 1), true /* operationInProgress */,
-                RulesState.STAGED_OPERATION_UNKNOWN, null /* stagedDistroRulesVersion */,
-                RulesState.DISTRO_STATUS_UNKNOWN, null /* installedDistroRulesVersion */);
-        checkParcelableRoundTrip(rulesStateWithNulls);
-    }
-
-    private static void checkParcelableRoundTrip(RulesState rulesState) {
-        Parcel parcel = Parcel.obtain();
-        rulesState.writeToParcel(parcel, 0 /* flags */);
-        parcel.setDataPosition(0);
-
-        RulesState newVersion = RulesState.CREATOR.createFromParcel(parcel);
-
-        assertEquals(rulesState, newVersion);
-    }
-
-    @Test
-    public void isSystemVersionOlderThan() {
-        RulesState rulesState = new RulesState(
-                "2016b", formatVersion(1, 1), false /* operationInProgress */,
-                RulesState.STAGED_OPERATION_NONE, null /* stagedDistroRulesVersion */,
-                RulesState.DISTRO_STATUS_INSTALLED, rulesVersion("2016b", 3));
-        assertFalse(rulesState.isSystemVersionOlderThan(rulesVersion("2016a", 1)));
-        assertFalse(rulesState.isSystemVersionOlderThan(rulesVersion("2016b", 1)));
-        assertTrue(rulesState.isSystemVersionOlderThan(rulesVersion("2016c", 1)));
-    }
-
-    @Test
-    public void isInstalledDistroOlderThan() {
-        RulesState operationInProgress = new RulesState(
-                "2016b", formatVersion(1, 1), true /* operationInProgress */,
-                RulesState.STAGED_OPERATION_UNKNOWN, null /* stagedDistroRulesVersion */,
-                RulesState.STAGED_OPERATION_UNKNOWN, null /* installedDistroRulesVersion */);
-        try {
-            operationInProgress.isInstalledDistroOlderThan(rulesVersion("2016b", 1));
-            fail();
-        } catch (IllegalStateException expected) {
-        }
-
-        RulesState nothingInstalled = new RulesState(
-                "2016b", formatVersion(1, 1), false /* operationInProgress */,
-                RulesState.STAGED_OPERATION_NONE, null /* stagedDistroRulesVersion */,
-                RulesState.DISTRO_STATUS_NONE, null /* installedDistroRulesVersion */);
-        try {
-            nothingInstalled.isInstalledDistroOlderThan(rulesVersion("2016b", 1));
-            fail();
-        } catch (IllegalStateException expected) {
-        }
-
-        DistroRulesVersion installedVersion = rulesVersion("2016b", 3);
-        RulesState rulesStateWithInstalledVersion = new RulesState(
-                "2016b", formatVersion(1, 1), false /* operationInProgress */,
-                RulesState.STAGED_OPERATION_NONE, null /* stagedDistroRulesVersion */,
-                RulesState.DISTRO_STATUS_INSTALLED, installedVersion);
-
-        DistroRulesVersion olderRules = rulesVersion("2016a", 1);
-        assertEquals(installedVersion.isOlderThan(olderRules),
-                rulesStateWithInstalledVersion.isInstalledDistroOlderThan(olderRules));
-
-        DistroRulesVersion sameRules = rulesVersion("2016b", 1);
-        assertEquals(installedVersion.isOlderThan(sameRules),
-                rulesStateWithInstalledVersion.isInstalledDistroOlderThan(sameRules));
-
-        DistroRulesVersion newerRules = rulesVersion("2016c", 1);
-        assertEquals(installedVersion.isOlderThan(newerRules),
-                rulesStateWithInstalledVersion.isInstalledDistroOlderThan(newerRules));
-    }
-
-    private static void assertEqualsContract(RulesState one, RulesState two) {
-        assertEquals(one, two);
-        assertEquals(one.hashCode(), two.hashCode());
-    }
-
-    private static DistroRulesVersion rulesVersion(String rulesVersion, int revision) {
-        return new DistroRulesVersion(rulesVersion, revision);
-    }
-
-    private static DistroFormatVersion formatVersion(int majorVersion, int minorVersion) {
-        return new DistroFormatVersion(majorVersion, minorVersion);
-    }
-}
diff --git a/core/tests/coretests/src/android/app/timezone/RulesUpdaterContractTest.java b/core/tests/coretests/src/android/app/timezone/RulesUpdaterContractTest.java
deleted file mode 100644
index e7a839c..0000000
--- a/core/tests/coretests/src/android/app/timezone/RulesUpdaterContractTest.java
+++ /dev/null
@@ -1,83 +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 android.app.timezone;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.hamcrest.MockitoHamcrest.argThat;
-
-import android.content.Context;
-import android.content.Intent;
-
-import org.hamcrest.BaseMatcher;
-import org.hamcrest.Description;
-import org.hamcrest.Matcher;
-import org.junit.Test;
-
-/**
- * Tests for {@link RulesUpdaterContract}.
- */
-// TODO(nfuller) Move to CTS once this class is part of the SystemApi. http://b/31008728
-public class RulesUpdaterContractTest {
-
-    @Test
-    public void createUpdaterIntent() throws Exception {
-        String packageName = "foobar";
-        Intent intent = RulesUpdaterContract.createUpdaterIntent(packageName);
-
-        assertEquals(RulesUpdaterContract.ACTION_TRIGGER_RULES_UPDATE_CHECK, intent.getAction());
-        assertEquals(packageName, intent.getPackage());
-        assertEquals(Intent.FLAG_INCLUDE_STOPPED_PACKAGES, intent.getFlags());
-    }
-
-    @Test
-    public void sendBroadcast() throws Exception {
-        String packageName = "foobar";
-        byte[] tokenBytes = new byte[] { 1, 2, 3, 4, 5 };
-
-        Intent expectedIntent = RulesUpdaterContract.createUpdaterIntent(packageName);
-        expectedIntent.putExtra(RulesUpdaterContract.EXTRA_CHECK_TOKEN, tokenBytes);
-
-        Context mockContext = mock(Context.class);
-
-        RulesUpdaterContract.sendBroadcast(mockContext, packageName, tokenBytes);
-
-        verify(mockContext).sendBroadcast(
-                filterEquals(expectedIntent),
-                eq(RulesUpdaterContract.UPDATE_TIME_ZONE_RULES_PERMISSION));
-    }
-
-    /**
-     * 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/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 90b3853..ea9597e 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -3203,9 +3203,9 @@
                     (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
             Notification.addFieldsFromContext(ai, notification);
 
-            int canColorize = mPackageManagerClient.checkPermission(
-                    android.Manifest.permission.USE_COLORIZED_NOTIFICATIONS, pkg);
-            if (canColorize == PERMISSION_GRANTED) {
+            boolean canColorize = PERMISSION_GRANTED == mPackageManagerClient.checkPermission(
+                    "com.android.permission.USE_COLORIZED_NOTIFICATIONS", pkg);
+            if (canColorize) {
                 notification.flags |= Notification.FLAG_CAN_COLORIZE;
             } else {
                 notification.flags &= ~Notification.FLAG_CAN_COLORIZE;
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");
-        }
-    }
-}
