Delete backup encryption code

Previously there was a plan to move the backup encryption logic to the
framework. However this plan was abandoned and encryption logic lives in
GMS now. This code is unused and out of date.

I'm removing this now because it blocks ag/19967045.

Test: m
  atest BackupFrameworksServicesRoboTests
  atest CtsBackupHostTestCases
Bug: 210083465

Change-Id: Ib5dc37898fde5c8ef9ea792931404a1915eda8aa
diff --git a/packages/BackupEncryption/Android.bp b/packages/BackupEncryption/Android.bp
deleted file mode 100644
index 0244f28..0000000
--- a/packages/BackupEncryption/Android.bp
+++ /dev/null
@@ -1,41 +0,0 @@
-//
-// Copyright (C) 2019 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 {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "frameworks_base_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["frameworks_base_license"],
-}
-
-android_app {
-    name: "BackupEncryption",
-    defaults: ["platform_app_defaults"],
-    srcs: ["src/**/*.java"],
-    static_libs: ["backup-encryption-protos", "backuplib"],
-    optimize: { enabled: false },
-    platform_apis: true,
-    certificate: "platform",
-    privileged: true,
-}
-
-java_library {
-    name: "backup-encryption-protos",
-    proto: { type: "nano" },
-    srcs: ["proto/**/*.proto"],
-}
diff --git a/packages/BackupEncryption/AndroidManifest.xml b/packages/BackupEncryption/AndroidManifest.xml
deleted file mode 100644
index 4d174e3..0000000
--- a/packages/BackupEncryption/AndroidManifest.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
- * Copyright (c) 2016 Google Inc.
- *
- * 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.
- */
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.server.backup.encryption"
-    android:sharedUserId="android.uid.system" >
-
-    <application android:allowBackup="false" >
-        <!-- This service does not need to be exported because it shares uid with the system server
-        which is the only client. -->
-        <service android:name=".BackupEncryptionService"
-                 android:exported="false">
-            <intent-filter>
-                <action android:name="android.encryption.BACKUP_ENCRYPTION" />
-            </intent-filter>
-        </service>
-    </application>
-</manifest>
diff --git a/packages/BackupEncryption/OWNERS b/packages/BackupEncryption/OWNERS
deleted file mode 100644
index d99779e..0000000
--- a/packages/BackupEncryption/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-include /services/backup/OWNERS
diff --git a/packages/BackupEncryption/proguard.flags b/packages/BackupEncryption/proguard.flags
deleted file mode 100644
index 851ce8c..0000000
--- a/packages/BackupEncryption/proguard.flags
+++ /dev/null
@@ -1 +0,0 @@
--keep class com.android.server.backup.encryption
diff --git a/packages/BackupEncryption/proto/backup_chunks_metadata.proto b/packages/BackupEncryption/proto/backup_chunks_metadata.proto
deleted file mode 100644
index 2fdedbf..0000000
--- a/packages/BackupEncryption/proto/backup_chunks_metadata.proto
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2018 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
- */
-
-syntax = "proto2";
-
-package android_backup_crypto;
-
-option java_package = "com.android.server.backup.encryption.protos";
-option java_outer_classname = "ChunksMetadataProto";
-
-// Cipher type with which the chunks are encrypted. For now we only support AES/GCM/NoPadding, but
-// this is for backwards-compatibility in case we need to change the default Cipher in the future.
-enum CipherType {
-    UNKNOWN_CIPHER_TYPE = 0;
-    // Chunk is prefixed with a 12-byte nonce. The tag length is 16 bytes.
-    AES_256_GCM = 1;
-}
-
-// Checksum type with which the plaintext is verified.
-enum ChecksumType {
-    UNKNOWN_CHECKSUM_TYPE = 0;
-    SHA_256 = 1;
-}
-
-enum ChunkOrderingType {
-    CHUNK_ORDERING_TYPE_UNSPECIFIED = 0;
-    // The chunk ordering contains a list of the start position of each chunk in the encrypted file,
-    // ordered as in the plaintext file. This allows us to recreate the original plaintext file
-    // during decryption. We use this mode for full backups where the order of the data in the file
-    // is important.
-    EXPLICIT_STARTS = 1;
-    // The chunk ordering does not contain any start positions, and instead each encrypted chunk in
-    // the backup file is prefixed with its length. This allows us to decrypt each chunk but does
-    // not give any information about the order. However, we use this mode for key value backups
-    // where the order does not matter.
-    INLINE_LENGTHS = 2;
-}
-
-// Chunk entry (for local state)
-message Chunk {
-    // SHA-256 MAC of the plaintext of the chunk
-    optional bytes hash = 1;
-    // Number of bytes in encrypted chunk
-    optional int32 length = 2;
-}
-
-// List of the chunks in the blob, along with the length of each chunk. From this is it possible to
-// extract individual chunks. (i.e., start position is equal to the sum of the lengths of all
-// preceding chunks.)
-//
-// This is local state stored on the device. It is never sent to the backup server. See
-// ChunkOrdering for how the device restores the chunks in the correct order.
-// Next tag : 6
-message ChunkListing {
-    repeated Chunk chunks = 1;
-
-    // Cipher algorithm with which the chunks are encrypted.
-    optional CipherType cipher_type = 2;
-
-    // Defines the type of chunk order used to encode the backup file on the server, so that we can
-    // consistently use the same type between backups. If unspecified this backup file was created
-    // before INLINE_LENGTHS was supported, thus assume it is EXPLICIT_STARTS.
-    optional ChunkOrderingType chunk_ordering_type = 5;
-
-    // The document ID returned from Scotty server after uploading the blob associated with this
-    // listing. This needs to be sent when uploading new diff scripts.
-    optional string document_id = 3;
-
-    // Fingerprint mixer salt used for content defined chunking. This is randomly generated for each
-    // package during the initial non-incremental backup and reused for incremental backups.
-    optional bytes fingerprint_mixer_salt = 4;
-}
-
-// Ordering information about plaintext and checksum. This is used on restore to reconstruct the
-// blob in its correct order. (The chunk order is randomized so as to give the server less
-// information about which parts of the backup are changing over time.) This proto is encrypted
-// before being uploaded to the server, with a key unknown to the server.
-message ChunkOrdering {
-    // For backups where ChunksMetadata#chunk_ordering_type = EXPLICIT STARTS:
-    // Ordered start positions of chunks. i.e., the file is the chunk starting at this position,
-    // followed by the chunk starting at this position, followed by ... etc. You can compute the
-    // lengths of the chunks by sorting this list then looking at the start position of the next
-    // chunk after the chunk you care about. This is guaranteed to work as all chunks are
-    // represented in this list.
-    //
-    // For backups where ChunksMetadata#chunk_ordering_type = INLINE_LENGTHS:
-    // This field is unused. See ChunkOrderingType#INLINE_LENGTHS.
-    repeated int32 starts = 1 [packed = true];
-
-    // Checksum of plaintext content. (i.e., in correct order.)
-    //
-    // Each chunk also has a MAC, as generated by GCM, so this is NOT Mac-then-Encrypt, which has
-    // security implications. This is an additional checksum to verify that once the chunks have
-    // been reordered, that the file matches the expected plaintext. This prevents the device
-    // restoring garbage data in case of a mismatch between the ChunkOrdering and the backup blob.
-    optional bytes checksum = 2;
-}
-
-// Additional metadata about a backup blob that needs to be synced to the server. This is used on
-// restore to reconstruct the blob in its correct order. (The chunk order is randomized so as to
-// give the server less information about which parts of the backup are changing over time.) This
-// data structure is only ever uploaded to the server encrypted with a key unknown to the server.
-// Next tag : 6
-message ChunksMetadata {
-    // Cipher algorithm with which the chunk listing and chunks are encrypted.
-    optional CipherType cipher_type = 1;
-
-    // Defines the type of chunk order this metadata contains. If unspecified this backup file was
-    // created before INLINE_LENGTHS was supported, thus assume it is EXPLICIT_STARTS.
-    optional ChunkOrderingType chunk_ordering_type = 5
-    [default = CHUNK_ORDERING_TYPE_UNSPECIFIED];
-
-    // Encrypted bytes of ChunkOrdering
-    optional bytes chunk_ordering = 2;
-
-    // The type of algorithm used for the checksum of the plaintext. (See ChunkOrdering.) This is
-    // for forwards compatibility in case we change the algorithm in the future. For now, always
-    // SHA-256.
-    optional ChecksumType checksum_type = 3;
-
-    // This used to be the plaintext tertiary key. No longer used.
-    reserved 4;
-}
\ No newline at end of file
diff --git a/packages/BackupEncryption/proto/key_value_listing.proto b/packages/BackupEncryption/proto/key_value_listing.proto
deleted file mode 100644
index 001e697..0000000
--- a/packages/BackupEncryption/proto/key_value_listing.proto
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2019 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
- */
-
-syntax = "proto2";
-
-package android_backup_crypto;
-
-option java_package = "com.android.server.backup.encryption.protos";
-option java_outer_classname = "KeyValueListingProto";
-
-// An entry of a key-value pair.
-message KeyValueEntry {
-  // Plaintext key of the key-value pair.
-  optional string key = 1;
-  // SHA-256 MAC of the plaintext of the chunk containing the pair
-  optional bytes hash = 2;
-}
-
-// Describes the key/value pairs currently in the backup blob, mapping from the
-// plaintext key to the hash of the chunk containing the pair.
-//
-// This is local state stored on the device. It is never sent to the
-// backup server. See ChunkOrdering for how the device restores the
-// key-value pairs in the correct order.
-message KeyValueListing {
-  repeated KeyValueEntry entries = 1;
-}
diff --git a/packages/BackupEncryption/proto/key_value_pair.proto b/packages/BackupEncryption/proto/key_value_pair.proto
deleted file mode 100644
index 177fa30..0000000
--- a/packages/BackupEncryption/proto/key_value_pair.proto
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2019 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
- */
-
-syntax = "proto2";
-
-package android_backup_crypto;
-
-option java_package = "com.android.server.backup.encryption.protos";
-option java_outer_classname = "KeyValuePairProto";
-
-// Serialized form of a key-value pair, when it is to be encrypted in a blob.
-// The backup blob for a key-value database consists of repeated encrypted
-// key-value pairs like this, in a randomized order. See ChunkOrdering for how
-// these are then reconstructed during a restore.
-message KeyValuePair {
-  optional string key = 1;
-  optional bytes value = 2;
-}
diff --git a/packages/BackupEncryption/proto/wrapped_key.proto b/packages/BackupEncryption/proto/wrapped_key.proto
deleted file mode 100644
index 817b7b40..0000000
--- a/packages/BackupEncryption/proto/wrapped_key.proto
+++ /dev/null
@@ -1,52 +0,0 @@
-syntax = "proto2";
-
-package android_backup_crypto;
-
-option java_package = "com.android.server.backup.encryption.protos";
-option java_outer_classname = "WrappedKeyProto";
-
-// Metadata associated with a tertiary key.
-message KeyMetadata {
-  // Type of Cipher algorithm the key is used for.
-  enum Type {
-    UNKNOWN = 0;
-    // No padding. Uses 12-byte nonce. Tag length 16 bytes.
-    AES_256_GCM = 1;
-  }
-
-  // What kind of Cipher algorithm the key is used for. We assume at the moment
-  // that this will always be AES_256_GCM and throw if this is not the case.
-  // Provided here for forwards compatibility in case at some point we need to
-  // change Cipher algorithm.
-  optional Type type = 1;
-}
-
-// An encrypted tertiary key.
-message WrappedKey {
-  // The Cipher with which the key was encrypted.
-  enum WrapAlgorithm {
-    UNKNOWN = 0;
-    // No padding. Uses 16-byte nonce (see nonce field). Tag length 16 bytes.
-    // The nonce is 16-bytes as this is wrapped with a key in AndroidKeyStore.
-    // AndroidKeyStore requires that it generates the IV, and it generates a
-    // 16-byte IV for you. You CANNOT provide your own IV.
-    AES_256_GCM = 1;
-  }
-
-  // Cipher algorithm used to wrap the key. We assume at the moment that this
-  // is always AES_256_GC and throw if this is not the case. Provided here for
-  // forwards compatibility if at some point we need to change Cipher algorithm.
-  optional WrapAlgorithm wrap_algorithm = 1;
-
-  // The nonce used to initialize the Cipher in AES/256/GCM mode.
-  optional bytes nonce = 2;
-
-  // The encrypted bytes of the key material.
-  optional bytes key = 3;
-
-  // Associated key metadata.
-  optional KeyMetadata metadata = 4;
-
-  // Deprecated field; Do not use
-  reserved 5;
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/CryptoSettings.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/CryptoSettings.java
deleted file mode 100644
index bb1336f..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/CryptoSettings.java
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption;
-
-import static com.android.internal.util.Preconditions.checkState;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.Editor;
-import android.security.keystore.recovery.InternalRecoveryServiceException;
-import android.security.keystore.recovery.RecoveryController;
-import android.util.Slog;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.security.KeyStoreException;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.concurrent.TimeUnit;
-
-/**
- * State about encrypted backups that needs to be remembered.
- */
-public class CryptoSettings {
-
-    private static final String TAG = "CryptoSettings";
-
-    private static final String SHARED_PREFERENCES_NAME = "crypto_settings";
-
-    private static final String KEY_IS_INITIALIZED = "isInitialized";
-    private static final String KEY_ACTIVE_SECONDARY_ALIAS = "activeSecondary";
-    private static final String KEY_NEXT_SECONDARY_ALIAS = "nextSecondary";
-    private static final String SECONDARY_KEY_LAST_ROTATED_AT = "secondaryKeyLastRotatedAt";
-    private static final String[] SETTINGS_FOR_BACKUP = {
-        KEY_IS_INITIALIZED,
-        KEY_ACTIVE_SECONDARY_ALIAS,
-        KEY_NEXT_SECONDARY_ALIAS,
-        SECONDARY_KEY_LAST_ROTATED_AT
-    };
-
-    private static final long DEFAULT_SECONDARY_KEY_ROTATION_PERIOD =
-            TimeUnit.MILLISECONDS.convert(31, TimeUnit.DAYS);
-
-    private static final String KEY_ANCESTRAL_SECONDARY_KEY_VERSION =
-            "ancestral_secondary_key_version";
-
-    private final SharedPreferences mSharedPreferences;
-    private final Context mContext;
-
-    /**
-     * A new instance.
-     *
-     * @param context For looking up the {@link SharedPreferences}, for storing state.
-     * @return The instance.
-     */
-    public static CryptoSettings getInstance(Context context) {
-        // We need single process mode because CryptoSettings may be used from several processes
-        // simultaneously.
-        SharedPreferences sharedPreferences =
-                context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
-        return new CryptoSettings(sharedPreferences, context);
-    }
-
-    /**
-     * A new instance using {@link SharedPreferences} in the default mode.
-     *
-     * <p>This will not work across multiple processes but will work in tests.
-     */
-    @VisibleForTesting
-    public static CryptoSettings getInstanceForTesting(Context context) {
-        SharedPreferences sharedPreferences =
-                context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
-        return new CryptoSettings(sharedPreferences, context);
-    }
-
-    private CryptoSettings(SharedPreferences sharedPreferences, Context context) {
-        mSharedPreferences = Objects.requireNonNull(sharedPreferences);
-        mContext = Objects.requireNonNull(context);
-    }
-
-    /**
-     * The alias of the current active secondary key. This should be used to retrieve the key from
-     * AndroidKeyStore.
-     */
-    public Optional<String> getActiveSecondaryKeyAlias() {
-        return getStringInSharedPrefs(KEY_ACTIVE_SECONDARY_ALIAS);
-    }
-
-    /**
-     * The alias of the secondary key to which the client is rotating. The rotation is not
-     * immediate, which is why this setting is needed. Once the next key is created, it can take up
-     * to 72 hours potentially (or longer if the user has no network) for the next key to be synced
-     * with the keystore. Only after that has happened does the client attempt to re-wrap all
-     * tertiary keys and commit the rotation.
-     */
-    public Optional<String> getNextSecondaryKeyAlias() {
-        return getStringInSharedPrefs(KEY_NEXT_SECONDARY_ALIAS);
-    }
-
-    /**
-     * If the settings have been initialized.
-     */
-    public boolean getIsInitialized() {
-        return mSharedPreferences.getBoolean(KEY_IS_INITIALIZED, false);
-    }
-
-    /**
-     * Sets the alias of the currently active secondary key.
-     *
-     * @param activeAlias The alias, as in AndroidKeyStore.
-     * @throws IllegalArgumentException if the alias is not in the user's keystore.
-     */
-    public void setActiveSecondaryKeyAlias(String activeAlias) throws IllegalArgumentException {
-        assertIsValidAlias(activeAlias);
-        mSharedPreferences.edit().putString(KEY_ACTIVE_SECONDARY_ALIAS, activeAlias).apply();
-    }
-
-    /**
-     * Sets the alias of the secondary key to which the client is rotating.
-     *
-     * @param nextAlias The alias, as in AndroidKeyStore.
-     * @throws KeyStoreException if unable to check whether alias is valid in the keystore.
-     * @throws IllegalArgumentException if the alias is not in the user's keystore.
-     */
-    public void setNextSecondaryAlias(String nextAlias) throws IllegalArgumentException {
-        assertIsValidAlias(nextAlias);
-        mSharedPreferences.edit().putString(KEY_NEXT_SECONDARY_ALIAS, nextAlias).apply();
-    }
-
-    /**
-     * Unsets the alias of the key to which the client is rotating. This is generally performed once
-     * a rotation is complete.
-     */
-    public void removeNextSecondaryKeyAlias() {
-        mSharedPreferences.edit().remove(KEY_NEXT_SECONDARY_ALIAS).apply();
-    }
-
-    /**
-     * Sets the timestamp of when the secondary key was last rotated.
-     *
-     * @param timestamp The timestamp to set.
-     */
-    public void setSecondaryLastRotated(long timestamp) {
-        mSharedPreferences.edit().putLong(SECONDARY_KEY_LAST_ROTATED_AT, timestamp).apply();
-    }
-
-    /**
-     * Returns a timestamp of when the secondary key was last rotated.
-     *
-     * @return The timestamp.
-     */
-    public Optional<Long> getSecondaryLastRotated() {
-        if (!mSharedPreferences.contains(SECONDARY_KEY_LAST_ROTATED_AT)) {
-            return Optional.empty();
-        }
-        return Optional.of(mSharedPreferences.getLong(SECONDARY_KEY_LAST_ROTATED_AT, -1));
-    }
-
-    /**
-     * Sets the settings to have been initialized. (Otherwise loading should try to initialize
-     * again.)
-     */
-    private void setIsInitialized() {
-        mSharedPreferences.edit().putBoolean(KEY_IS_INITIALIZED, true).apply();
-    }
-
-    /**
-     * Initializes with the given key alias.
-     *
-     * @param alias The secondary key alias to be set as active.
-     * @throws IllegalArgumentException if the alias does not reference a valid key.
-     * @throws IllegalStateException if attempting to initialize an already initialized settings.
-     */
-    public void initializeWithKeyAlias(String alias) throws IllegalArgumentException {
-        checkState(
-                !getIsInitialized(), "Attempting to initialize an already initialized settings.");
-        setActiveSecondaryKeyAlias(alias);
-        setIsInitialized();
-    }
-
-    /** Returns the secondary key version of the encrypted backup set to restore from (if set). */
-    public Optional<String> getAncestralSecondaryKeyVersion() {
-        return Optional.ofNullable(
-                mSharedPreferences.getString(KEY_ANCESTRAL_SECONDARY_KEY_VERSION, null));
-    }
-
-    /** Sets the secondary key version of the encrypted backup set to restore from. */
-    public void setAncestralSecondaryKeyVersion(String ancestralSecondaryKeyVersion) {
-        mSharedPreferences
-                .edit()
-                .putString(KEY_ANCESTRAL_SECONDARY_KEY_VERSION, ancestralSecondaryKeyVersion)
-                .apply();
-    }
-
-    /** The number of milliseconds between secondary key rotation */
-    public long backupSecondaryKeyRotationIntervalMs() {
-        return DEFAULT_SECONDARY_KEY_ROTATION_PERIOD;
-    }
-
-    /** Deletes all crypto settings related to backup (as opposed to restore). */
-    public void clearAllSettingsForBackup() {
-        Editor sharedPrefsEditor = mSharedPreferences.edit();
-        for (String backupSettingKey : SETTINGS_FOR_BACKUP) {
-            sharedPrefsEditor.remove(backupSettingKey);
-        }
-        sharedPrefsEditor.apply();
-
-        Slog.d(TAG, "Cleared crypto settings for backup");
-    }
-
-    /**
-     * Throws {@link IllegalArgumentException} if the alias does not refer to a key that is in
-     * the {@link RecoveryController}.
-     */
-    private void assertIsValidAlias(String alias) throws IllegalArgumentException {
-        try {
-            if (!RecoveryController.getInstance(mContext).getAliases().contains(alias)) {
-                throw new IllegalArgumentException(alias + " is not in RecoveryController");
-            }
-        } catch (InternalRecoveryServiceException e) {
-            throw new IllegalArgumentException("Problem accessing recovery service", e);
-        }
-    }
-
-    private Optional<String> getStringInSharedPrefs(String key) {
-        return Optional.ofNullable(mSharedPreferences.getString(key, null));
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/EncryptionKeyHelper.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/EncryptionKeyHelper.java
deleted file mode 100644
index 2035b66..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/EncryptionKeyHelper.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption;
-
-import android.content.Context;
-import android.security.keystore.recovery.InternalRecoveryServiceException;
-import android.security.keystore.recovery.RecoveryController;
-
-import com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKey;
-import com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKeyManager;
-import com.android.server.backup.encryption.keys.TertiaryKeyManager;
-import com.android.server.backup.encryption.keys.TertiaryKeyRotationScheduler;
-
-import java.io.IOException;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.security.UnrecoverableKeyException;
-
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.SecretKey;
-
-class EncryptionKeyHelper {
-    private static SecureRandom sSecureRandom = new  SecureRandom();
-
-    private final Context mContext;
-    private final RecoverableKeyStoreSecondaryKeyManager
-            .RecoverableKeyStoreSecondaryKeyManagerProvider
-            mSecondaryKeyManagerProvider;
-
-    EncryptionKeyHelper(Context context) {
-        mContext = context;
-        mSecondaryKeyManagerProvider =
-                () ->
-                        new RecoverableKeyStoreSecondaryKeyManager(
-                                RecoveryController.getInstance(mContext), sSecureRandom);
-    }
-
-    RecoverableKeyStoreSecondaryKeyManager
-            .RecoverableKeyStoreSecondaryKeyManagerProvider getKeyManagerProvider() {
-        return mSecondaryKeyManagerProvider;
-    }
-
-    RecoverableKeyStoreSecondaryKey getActiveSecondaryKey()
-            throws UnrecoverableKeyException, InternalRecoveryServiceException {
-        String keyAlias = CryptoSettings.getInstance(mContext).getActiveSecondaryKeyAlias().get();
-        return mSecondaryKeyManagerProvider.get().get(keyAlias).get();
-    }
-
-    SecretKey getTertiaryKey(
-            String packageName,
-            RecoverableKeyStoreSecondaryKey secondaryKey)
-            throws IllegalBlockSizeException, InvalidAlgorithmParameterException,
-            NoSuchAlgorithmException, IOException, NoSuchPaddingException,
-            InvalidKeyException {
-        TertiaryKeyManager tertiaryKeyManager =
-                new TertiaryKeyManager(
-                        mContext,
-                        sSecureRandom,
-                        TertiaryKeyRotationScheduler.getInstance(mContext),
-                        secondaryKey,
-                        packageName);
-        return tertiaryKeyManager.getKey();
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/FullBackupDataProcessor.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/FullBackupDataProcessor.java
deleted file mode 100644
index f3ab2bde..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/FullBackupDataProcessor.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption;
-
-import android.app.backup.BackupTransport;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-/** Accepts the full backup data stream and sends it to the server. */
-public interface FullBackupDataProcessor {
-    /**
-     * Prepares the upload.
-     *
-     * <p>After this, call {@link #start()} to establish the connection.
-     *
-     * @param inputStream to read the backup data from, calling {@link #finish} or {@link #cancel}
-     *     will close the stream
-     * @return {@code true} if the connection was set up successfully, otherwise {@code false}
-     */
-    boolean initiate(InputStream inputStream) throws IOException;
-
-    /**
-     * Starts the upload, establishing the connection to the server.
-     *
-     * <p>After this, call {@link #pushData(int)} to request that the processor reads data from the
-     * socket, and uploads it to the server.
-     *
-     * <p>After this you must call one of {@link #cancel()}, {@link #finish()}, {@link
-     * #handleCheckSizeRejectionZeroBytes()}, {@link #handleCheckSizeRejectionQuotaExceeded()} or
-     * {@link #handleSendBytesQuotaExceeded()} to close the upload.
-     */
-    void start();
-
-    /**
-     * Requests that the processor read {@code numBytes} from the input stream passed in {@link
-     * #initiate(InputStream)} and upload them to the server.
-     *
-     * @return {@link BackupTransport#TRANSPORT_OK} if the upload succeeds, or {@link
-     *     BackupTransport#TRANSPORT_QUOTA_EXCEEDED} if the upload exceeded the server-side app size
-     *     quota, or {@link BackupTransport#TRANSPORT_PACKAGE_REJECTED} for other errors.
-     */
-    int pushData(int numBytes);
-
-    /** Cancels the upload and tears down the connection. */
-    void cancel();
-
-    /**
-     * Finish the upload and tear down the connection.
-     *
-     * <p>Call this after there is no more data to push with {@link #pushData(int)}.
-     *
-     * @return One of {@link BackupTransport#TRANSPORT_OK} if the app upload succeeds, {@link
-     *     BackupTransport#TRANSPORT_QUOTA_EXCEEDED} if the upload exceeded the server-side app size
-     *     quota, {@link BackupTransport#TRANSPORT_ERROR} for server 500s, or {@link
-     *     BackupTransport#TRANSPORT_PACKAGE_REJECTED} for other errors.
-     */
-    int finish();
-
-    /**
-     * Notifies the processor that the current upload should be terminated because the estimated
-     * size is zero.
-     */
-    void handleCheckSizeRejectionZeroBytes();
-
-    /**
-     * Notifies the processor that the current upload should be terminated because the estimated
-     * size exceeds the quota.
-     */
-    void handleCheckSizeRejectionQuotaExceeded();
-
-    /**
-     * Notifies this class that the current upload should be terminated because the quota was
-     * exceeded during upload.
-     */
-    void handleSendBytesQuotaExceeded();
-
-    /**
-     * Attaches {@link FullBackupCallbacks} which the processor will notify when the backup
-     * succeeds.
-     */
-    void attachCallbacks(FullBackupCallbacks fullBackupCallbacks);
-
-    /**
-     * Implemented by the caller of the processor to receive notification of when the backup
-     * succeeds.
-     */
-    interface FullBackupCallbacks {
-        /** The processor calls this to indicate that the current backup has succeeded. */
-        void onSuccess();
-
-        /** The processor calls this if the upload failed for a non-transient reason. */
-        void onTransferFailed();
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/FullRestoreDataProcessor.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/FullRestoreDataProcessor.java
deleted file mode 100644
index e4c4049..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/FullRestoreDataProcessor.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption;
-
-import java.io.IOException;
-
-/**
- * Retrieves the data during a full restore, decrypting it if necessary.
- *
- * <p>Use {@link FullRestoreDataProcessorFactory} to construct the encrypted or unencrypted
- * processor as appropriate during restore.
- */
-public interface FullRestoreDataProcessor {
-    /** Return value of {@link #readNextChunk} when there is no more data to download. */
-    int END_OF_STREAM = -1;
-
-    /**
-     * Reads the next chunk of restore data and writes it to the given buffer.
-     *
-     * <p>Where necessary, will open the connection to the server and/or decrypt the backup file.
-     *
-     * <p>The implementation may retry various errors. If the retries fail it will throw the
-     * relevant exception.
-     *
-     * @return the number of bytes read, or {@link #END_OF_STREAM} if there is no more data
-     * @throws IOException when downloading from the network or writing to disk
-     */
-    int readNextChunk(byte[] buffer) throws IOException;
-
-    /**
-     * Closes the connection to the server, deletes any temporary files and optionally sends a log
-     * with the given finish type.
-     *
-     * @param finishType one of {@link FullRestoreDownloader.FinishType}
-     */
-    void finish(FullRestoreDownloader.FinishType finishType);
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/FullRestoreDownloader.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/FullRestoreDownloader.java
deleted file mode 100644
index afcca79..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/FullRestoreDownloader.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption;
-
-import java.io.IOException;
-
-/** Interface for classes which will provide backup data */
-public abstract class FullRestoreDownloader {
-    /** Enum to provide information on why a download finished */
-    public enum FinishType {
-        UNKNOWN_FINISH(0),
-        // Finish the downloading and successfully write data to Android OS.
-        FINISHED(1),
-        // Download failed with any kind of exception.
-        TRANSFER_FAILURE(2),
-        // Download failed due to auth failure on the device.
-        AUTH_FAILURE(3),
-        // Aborted by Android Framework.
-        FRAMEWORK_ABORTED(4);
-
-        private int mValue;
-
-        FinishType(int value) {
-            mValue = value;
-        }
-    }
-
-    /** Get the next data chunk from the backing store */
-    public abstract int readNextChunk(byte[] buffer) throws IOException;
-
-    /** Called when we've finished restoring the data */
-    public abstract void finish(FinishType finishType);
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/KeyValueEncrypter.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/KeyValueEncrypter.java
deleted file mode 100644
index db2dd2f..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/KeyValueEncrypter.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption;
-
-import android.content.Context;
-import android.os.ParcelFileDescriptor;
-import android.util.Log;
-
-import com.android.server.backup.encryption.client.CryptoBackupServer;
-import com.android.server.backup.encryption.keys.KeyWrapUtils;
-import com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKey;
-import com.android.server.backup.encryption.protos.nano.WrappedKeyProto;
-import com.android.server.backup.encryption.tasks.EncryptedKvBackupTask;
-import com.android.server.backup.encryption.tasks.EncryptedKvRestoreTask;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.security.SecureRandom;
-import java.util.Map;
-
-public class KeyValueEncrypter {
-    private static final String TAG = "KeyValueEncrypter";
-
-    private final Context mContext;
-    private final EncryptionKeyHelper mKeyHelper;
-
-    public KeyValueEncrypter(Context context) {
-        mContext = context;
-        mKeyHelper = new EncryptionKeyHelper(mContext);
-    }
-
-    public void encryptKeyValueData(
-            String packageName, ParcelFileDescriptor inputFd, OutputStream outputStream)
-            throws Exception {
-        EncryptedKvBackupTask.EncryptedKvBackupTaskFactory backupTaskFactory =
-                new EncryptedKvBackupTask.EncryptedKvBackupTaskFactory();
-        EncryptedKvBackupTask backupTask =
-                backupTaskFactory.newInstance(
-                        mContext,
-                        new SecureRandom(),
-                        new FileBackupServer(outputStream),
-                        CryptoSettings.getInstance(mContext),
-                        mKeyHelper.getKeyManagerProvider(),
-                        inputFd,
-                        packageName);
-        backupTask.performBackup(/* incremental */ false);
-    }
-
-    public void decryptKeyValueData(String packageName,
-            InputStream encryptedInputStream, ParcelFileDescriptor outputFd) throws Exception {
-        RecoverableKeyStoreSecondaryKey secondaryKey = mKeyHelper.getActiveSecondaryKey();
-
-        EncryptedKvRestoreTask.EncryptedKvRestoreTaskFactory restoreTaskFactory =
-                new EncryptedKvRestoreTask.EncryptedKvRestoreTaskFactory();
-        EncryptedKvRestoreTask restoreTask =
-                restoreTaskFactory.newInstance(
-                        mContext,
-                        mKeyHelper.getKeyManagerProvider(),
-                        new InputStreamFullRestoreDownloader(encryptedInputStream),
-                        secondaryKey.getAlias(),
-                        KeyWrapUtils.wrap(
-                                secondaryKey.getSecretKey(),
-                                mKeyHelper.getTertiaryKey(packageName, secondaryKey)));
-
-        restoreTask.getRestoreData(outputFd);
-    }
-
-    // TODO(b/142455725): Extract into a commong class.
-    private static class FileBackupServer implements CryptoBackupServer {
-        private static final String EMPTY_DOC_ID = "";
-
-        private final OutputStream mOutputStream;
-
-        FileBackupServer(OutputStream outputStream) {
-            mOutputStream = outputStream;
-        }
-
-        @Override
-        public String uploadIncrementalBackup(
-                String packageName,
-                String oldDocId,
-                byte[] diffScript,
-                WrappedKeyProto.WrappedKey tertiaryKey) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public String uploadNonIncrementalBackup(
-                String packageName, byte[] data, WrappedKeyProto.WrappedKey tertiaryKey) {
-            try {
-                mOutputStream.write(data);
-            } catch (IOException e) {
-                Log.w(TAG, "Failed to write encrypted data to file: ", e);
-            }
-
-            return EMPTY_DOC_ID;
-        }
-
-        @Override
-        public void setActiveSecondaryKeyAlias(
-                String keyAlias, Map<String, WrappedKeyProto.WrappedKey> tertiaryKeys) {
-            // Do nothing.
-        }
-    }
-
-    // TODO(b/142455725): Extract into a commong class.
-    private static class InputStreamFullRestoreDownloader extends FullRestoreDownloader {
-        private final InputStream mInputStream;
-
-        InputStreamFullRestoreDownloader(InputStream inputStream) {
-            mInputStream = inputStream;
-        }
-
-        @Override
-        public int readNextChunk(byte[] buffer) throws IOException {
-            return mInputStream.read(buffer);
-        }
-
-        @Override
-        public void finish(FinishType finishType) {
-            try {
-                mInputStream.close();
-            } catch (IOException e) {
-                Log.w(TAG, "Error while reading restore data");
-            }
-        }
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/StreamUtils.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/StreamUtils.java
deleted file mode 100644
index 66be25b..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/StreamUtils.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-/** Utility methods for dealing with Streams */
-public class StreamUtils {
-    private static final int MAX_COPY_BUFFER_SIZE = 1024; // 1k copy buffer size.
-
-    /**
-     * Close a Closeable and silently ignore any IOExceptions.
-     *
-     * @param closeable The closeable to close
-     */
-    public static void closeQuietly(Closeable closeable) {
-        try {
-            closeable.close();
-        } catch (IOException ioe) {
-            // Silently ignore
-        }
-    }
-
-    /**
-     * Copy data from an InputStream to an OutputStream upto a given number of bytes.
-     *
-     * @param in The source InputStream
-     * @param out The destination OutputStream
-     * @param limit The maximum number of bytes to copy
-     * @throws IOException Thrown if there is a problem performing the copy.
-     */
-    public static void copyStream(InputStream in, OutputStream out, int limit) throws IOException {
-        int bufferSize = Math.min(MAX_COPY_BUFFER_SIZE, limit);
-        byte[] buffer = new byte[bufferSize];
-
-        int copied = 0;
-        while (copied < limit) {
-            int maxReadSize = Math.min(bufferSize, limit - copied);
-            int read = in.read(buffer, 0, maxReadSize);
-            if (read < 0) {
-                return; // Reached the stream end before the limit
-            }
-            out.write(buffer, 0, read);
-            copied += read;
-        }
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunk/ChunkHash.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunk/ChunkHash.java
deleted file mode 100644
index 1630eb8..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunk/ChunkHash.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.chunk;
-
-import com.android.internal.util.Preconditions;
-
-import java.util.Arrays;
-import java.util.Base64;
-
-/**
- * Represents the SHA-256 hash of the plaintext of a chunk, which is frequently used as a key.
- *
- * <p>This class is {@link Comparable} and implements {@link #equals(Object)} and {@link
- * #hashCode()}.
- */
-public class ChunkHash implements Comparable<ChunkHash> {
-    /** The length of the hash in bytes. The hash is a SHA-256, so this is 256 bits. */
-    public static final int HASH_LENGTH_BYTES = 256 / 8;
-
-    private static final int UNSIGNED_MASK = 0xFF;
-
-    private final byte[] mHash;
-
-    /** Constructs a new instance which wraps the given SHA-256 hash bytes. */
-    public ChunkHash(byte[] hash) {
-        Preconditions.checkArgument(hash.length == HASH_LENGTH_BYTES, "Hash must have 256 bits");
-        mHash = hash;
-    }
-
-    public byte[] getHash() {
-        return mHash;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (!(o instanceof ChunkHash)) {
-            return false;
-        }
-
-        ChunkHash chunkHash = (ChunkHash) o;
-        return Arrays.equals(mHash, chunkHash.mHash);
-    }
-
-    @Override
-    public int hashCode() {
-        return Arrays.hashCode(mHash);
-    }
-
-    @Override
-    public int compareTo(ChunkHash other) {
-        return lexicographicalCompareUnsignedBytes(getHash(), other.getHash());
-    }
-
-    @Override
-    public String toString() {
-        return Base64.getEncoder().encodeToString(mHash);
-    }
-
-    private static int lexicographicalCompareUnsignedBytes(byte[] left, byte[] right) {
-        int minLength = Math.min(left.length, right.length);
-        for (int i = 0; i < minLength; i++) {
-            int result = toInt(left[i]) - toInt(right[i]);
-            if (result != 0) {
-                return result;
-            }
-        }
-        return left.length - right.length;
-    }
-
-    private static int toInt(byte value) {
-        return value & UNSIGNED_MASK;
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunk/ChunkListingMap.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunk/ChunkListingMap.java
deleted file mode 100644
index 51d7d53..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunk/ChunkListingMap.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.chunk;
-
-import android.annotation.Nullable;
-
-import com.android.server.backup.encryption.protos.nano.ChunksMetadataProto;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Chunk listing in a format optimized for quick look up of chunks via their hash keys. This is
- * useful when building an incremental backup. After a chunk has been produced, the algorithm can
- * quickly look up whether the chunk existed in the previous backup by checking this chunk listing.
- * It can then tell the server to use that chunk, through telling it the position and length of the
- * chunk in the previous backup's blob.
- */
-public class ChunkListingMap {
-
-    private final Map<ChunkHash, Entry> mChunksByHash;
-
-    /** Construct a map from a {@link ChunksMetadataProto.ChunkListing} protobuf */
-    public static ChunkListingMap fromProto(ChunksMetadataProto.ChunkListing chunkListingProto) {
-        Map<ChunkHash, Entry> entries = new HashMap<>();
-
-        long start = 0;
-
-        for (ChunksMetadataProto.Chunk chunk : chunkListingProto.chunks) {
-            entries.put(new ChunkHash(chunk.hash), new Entry(start, chunk.length));
-            start += chunk.length;
-        }
-
-        return new ChunkListingMap(entries);
-    }
-
-    private ChunkListingMap(Map<ChunkHash, Entry> chunksByHash) {
-        // This is only called from the {@link #fromProto} method, so we don't
-        // need to take a copy.
-        this.mChunksByHash = chunksByHash;
-    }
-
-    /** Returns {@code true} if there is a chunk with the given SHA-256 MAC key in the listing. */
-    public boolean hasChunk(ChunkHash hash) {
-        return mChunksByHash.containsKey(hash);
-    }
-
-    /**
-     * Returns the entry for the chunk with the given hash.
-     *
-     * @param hash The SHA-256 MAC of the plaintext of the chunk.
-     * @return The entry, containing position and length of the chunk in the backup blob, or null if
-     *     it does not exist.
-     */
-    @Nullable
-    public Entry getChunkEntry(ChunkHash hash) {
-        return mChunksByHash.get(hash);
-    }
-
-    /** Information about a chunk entry in a backup blob - i.e., its position and length. */
-    public static final class Entry {
-        private final int mLength;
-        private final long mStart;
-
-        private Entry(long start, int length) {
-            mLength = length;
-            mStart = start;
-        }
-
-        /** Returns the length of the chunk in bytes. */
-        public int getLength() {
-            return mLength;
-        }
-
-        /** Returns the start position of the chunk in the backup blob, in bytes. */
-        public long getStart() {
-            return mStart;
-        }
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunk/ChunkOrderingType.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunk/ChunkOrderingType.java
deleted file mode 100644
index 9cda339..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunk/ChunkOrderingType.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.chunk;
-
-import static com.android.server.backup.encryption.protos.nano.ChunksMetadataProto.CHUNK_ORDERING_TYPE_UNSPECIFIED;
-import static com.android.server.backup.encryption.protos.nano.ChunksMetadataProto.EXPLICIT_STARTS;
-import static com.android.server.backup.encryption.protos.nano.ChunksMetadataProto.INLINE_LENGTHS;
-
-import android.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/** IntDef corresponding to the ChunkOrderingType enum in the ChunksMetadataProto protobuf. */
-@IntDef({CHUNK_ORDERING_TYPE_UNSPECIFIED, EXPLICIT_STARTS, INLINE_LENGTHS})
-@Retention(RetentionPolicy.SOURCE)
-public @interface ChunkOrderingType {}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunk/EncryptedChunkOrdering.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunk/EncryptedChunkOrdering.java
deleted file mode 100644
index edf1b9a..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunk/EncryptedChunkOrdering.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.chunk;
-
-import java.util.Arrays;
-
-/**
- * Holds the bytes of an encrypted {@link ChunksMetadataProto.ChunkOrdering}.
- *
- * <p>TODO(b/116575321): After all code is ported, remove the factory method and rename
- * encryptedChunkOrdering() to getBytes().
- */
-public class EncryptedChunkOrdering {
-    /**
-     * Constructs a new object holding the given bytes of an encrypted {@link
-     * ChunksMetadataProto.ChunkOrdering}.
-     *
-     * <p>Note that this just holds an ordering which is already encrypted, it does not encrypt the
-     * ordering.
-     */
-    public static EncryptedChunkOrdering create(byte[] encryptedChunkOrdering) {
-        return new EncryptedChunkOrdering(encryptedChunkOrdering);
-    }
-
-    private final byte[] mEncryptedChunkOrdering;
-
-    /** Get the encrypted chunk ordering */
-    public byte[] encryptedChunkOrdering() {
-        return mEncryptedChunkOrdering;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (!(o instanceof EncryptedChunkOrdering)) {
-            return false;
-        }
-
-        EncryptedChunkOrdering encryptedChunkOrdering = (EncryptedChunkOrdering) o;
-        return Arrays.equals(
-                mEncryptedChunkOrdering, encryptedChunkOrdering.mEncryptedChunkOrdering);
-    }
-
-    @Override
-    public int hashCode() {
-        return Arrays.hashCode(mEncryptedChunkOrdering);
-    }
-
-    private EncryptedChunkOrdering(byte[] encryptedChunkOrdering) {
-        mEncryptedChunkOrdering = encryptedChunkOrdering;
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/BackupFileBuilder.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/BackupFileBuilder.java
deleted file mode 100644
index 4010bfd..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/BackupFileBuilder.java
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.chunking;
-
-import static com.android.internal.util.Preconditions.checkArgument;
-import static com.android.internal.util.Preconditions.checkState;
-
-import android.annotation.Nullable;
-import android.util.Slog;
-
-import com.android.server.backup.encryption.chunk.ChunkHash;
-import com.android.server.backup.encryption.chunk.ChunkListingMap;
-import com.android.server.backup.encryption.protos.nano.ChunksMetadataProto;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * Writes batches of {@link EncryptedChunk} to a diff script, and generates the associated {@link
- * ChunksMetadataProto.ChunkListing} and {@link ChunksMetadataProto.ChunkOrdering}.
- */
-public class BackupFileBuilder {
-    private static final String TAG = "BackupFileBuilder";
-
-    private static final int BYTES_PER_KILOBYTE = 1024;
-
-    private final BackupWriter mBackupWriter;
-    private final EncryptedChunkEncoder mEncryptedChunkEncoder;
-    private final ChunkListingMap mOldChunkListing;
-    private final ChunksMetadataProto.ChunkListing mNewChunkListing;
-    private final ChunksMetadataProto.ChunkOrdering mChunkOrdering;
-    private final List<ChunksMetadataProto.Chunk> mKnownChunks = new ArrayList<>();
-    private final List<Integer> mKnownStarts = new ArrayList<>();
-    private final Map<ChunkHash, Long> mChunkStartPositions;
-
-    private long mNewChunksSizeBytes;
-    private boolean mFinished;
-
-    /**
-     * Constructs a new instance which writes raw data to the given {@link OutputStream}, without
-     * generating a diff.
-     *
-     * <p>This class never closes the output stream.
-     */
-    public static BackupFileBuilder createForNonIncremental(OutputStream outputStream) {
-        return new BackupFileBuilder(
-                new RawBackupWriter(outputStream), new ChunksMetadataProto.ChunkListing());
-    }
-
-    /**
-     * Constructs a new instance which writes a diff script to the given {@link OutputStream} using
-     * a {@link SingleStreamDiffScriptWriter}.
-     *
-     * <p>This class never closes the output stream.
-     *
-     * @param oldChunkListing against which the diff will be generated.
-     */
-    public static BackupFileBuilder createForIncremental(
-            OutputStream outputStream, ChunksMetadataProto.ChunkListing oldChunkListing) {
-        return new BackupFileBuilder(
-                DiffScriptBackupWriter.newInstance(outputStream), oldChunkListing);
-    }
-
-    private BackupFileBuilder(
-            BackupWriter backupWriter, ChunksMetadataProto.ChunkListing oldChunkListing) {
-        this.mBackupWriter = backupWriter;
-        // TODO(b/77188289): Use InlineLengthsEncryptedChunkEncoder for key-value backups
-        this.mEncryptedChunkEncoder = new LengthlessEncryptedChunkEncoder();
-        this.mOldChunkListing = ChunkListingMap.fromProto(oldChunkListing);
-
-        mNewChunkListing = new ChunksMetadataProto.ChunkListing();
-        mNewChunkListing.cipherType = ChunksMetadataProto.AES_256_GCM;
-        mNewChunkListing.chunkOrderingType = ChunksMetadataProto.CHUNK_ORDERING_TYPE_UNSPECIFIED;
-
-        mChunkOrdering = new ChunksMetadataProto.ChunkOrdering();
-        mChunkStartPositions = new HashMap<>();
-    }
-
-    /**
-     * Writes the given chunks to the output stream, and adds them to the new chunk listing and
-     * chunk ordering.
-     *
-     * <p>Sorts the chunks in lexicographical order before writing.
-     *
-     * @param allChunks The hashes of all the chunks, in the order they appear in the plaintext.
-     * @param newChunks A map from hash to {@link EncryptedChunk} containing the new chunks not
-     *     present in the previous backup.
-     */
-    public void writeChunks(List<ChunkHash> allChunks, Map<ChunkHash, EncryptedChunk> newChunks)
-            throws IOException {
-        checkState(!mFinished, "Cannot write chunks after flushing.");
-
-        List<ChunkHash> sortedChunks = new ArrayList<>(allChunks);
-        Collections.sort(sortedChunks);
-        for (ChunkHash chunkHash : sortedChunks) {
-            // As we have already included this chunk in the backup file, don't add it again to
-            // deduplicate identical chunks.
-            if (!mChunkStartPositions.containsKey(chunkHash)) {
-                // getBytesWritten() gives us the start of the chunk.
-                mChunkStartPositions.put(chunkHash, mBackupWriter.getBytesWritten());
-
-                writeChunkToFileAndListing(chunkHash, newChunks);
-            }
-        }
-
-        long totalSizeKb = mBackupWriter.getBytesWritten() / BYTES_PER_KILOBYTE;
-        long newChunksSizeKb = mNewChunksSizeBytes / BYTES_PER_KILOBYTE;
-        Slog.d(
-                TAG,
-                "Total backup size: "
-                        + totalSizeKb
-                        + " kb, new chunks size: "
-                        + newChunksSizeKb
-                        + " kb");
-
-        for (ChunkHash chunkHash : allChunks) {
-            mKnownStarts.add(mChunkStartPositions.get(chunkHash).intValue());
-        }
-    }
-
-    /**
-     * Returns a new listing for all of the chunks written so far, setting the given fingerprint
-     * mixer salt (this overrides the {@link ChunksMetadataProto.ChunkListing#fingerprintMixerSalt}
-     * in the old {@link ChunksMetadataProto.ChunkListing} passed into the
-     * {@link #BackupFileBuilder).
-     */
-    public ChunksMetadataProto.ChunkListing getNewChunkListing(
-            @Nullable byte[] fingerprintMixerSalt) {
-        // TODO: b/141537803 Add check to ensure this is called only once per instance
-        mNewChunkListing.fingerprintMixerSalt =
-                fingerprintMixerSalt != null
-                        ? Arrays.copyOf(fingerprintMixerSalt, fingerprintMixerSalt.length)
-                        : new byte[0];
-        mNewChunkListing.chunks = mKnownChunks.toArray(new ChunksMetadataProto.Chunk[0]);
-        return mNewChunkListing;
-    }
-
-    /** Returns a new ordering for all of the chunks written so far, setting the given checksum. */
-    public ChunksMetadataProto.ChunkOrdering getNewChunkOrdering(byte[] checksum) {
-        // TODO: b/141537803 Add check to ensure this is called only once per instance
-        mChunkOrdering.starts = new int[mKnownStarts.size()];
-        for (int i = 0; i < mKnownStarts.size(); i++) {
-            mChunkOrdering.starts[i] = mKnownStarts.get(i).intValue();
-        }
-        mChunkOrdering.checksum = Arrays.copyOf(checksum, checksum.length);
-        return mChunkOrdering;
-    }
-
-    /**
-     * Finishes the backup file by writing the chunk metadata and metadata position.
-     *
-     * <p>Once this is called, calling {@link #writeChunks(List, Map)} will throw {@link
-     * IllegalStateException}.
-     */
-    public void finish(ChunksMetadataProto.ChunksMetadata metadata) throws IOException {
-        Objects.requireNonNull(metadata, "Metadata cannot be null");
-
-        long startOfMetadata = mBackupWriter.getBytesWritten();
-        mBackupWriter.writeBytes(ChunksMetadataProto.ChunksMetadata.toByteArray(metadata));
-        mBackupWriter.writeBytes(toByteArray(startOfMetadata));
-
-        mBackupWriter.flush();
-        mFinished = true;
-    }
-
-    /**
-     * Checks if the given chunk hash references an existing chunk or a new chunk, and adds this
-     * chunk to the backup file and new chunk listing.
-     */
-    private void writeChunkToFileAndListing(
-            ChunkHash chunkHash, Map<ChunkHash, EncryptedChunk> newChunks) throws IOException {
-        Objects.requireNonNull(chunkHash, "Hash cannot be null");
-
-        if (mOldChunkListing.hasChunk(chunkHash)) {
-            ChunkListingMap.Entry oldChunk = mOldChunkListing.getChunkEntry(chunkHash);
-            mBackupWriter.writeChunk(oldChunk.getStart(), oldChunk.getLength());
-
-            checkArgument(oldChunk.getLength() >= 0, "Chunk must have zero or positive length");
-            addChunk(chunkHash.getHash(), oldChunk.getLength());
-        } else if (newChunks.containsKey(chunkHash)) {
-            EncryptedChunk newChunk = newChunks.get(chunkHash);
-            mEncryptedChunkEncoder.writeChunkToWriter(mBackupWriter, newChunk);
-            int length = mEncryptedChunkEncoder.getEncodedLengthOfChunk(newChunk);
-            mNewChunksSizeBytes += length;
-
-            checkArgument(length >= 0, "Chunk must have zero or positive length");
-            addChunk(chunkHash.getHash(), length);
-        } else {
-            throw new IllegalArgumentException(
-                    "Chunk did not exist in old chunks or new chunks: " + chunkHash);
-        }
-    }
-
-    private void addChunk(byte[] chunkHash, int length) {
-        ChunksMetadataProto.Chunk chunk = new ChunksMetadataProto.Chunk();
-        chunk.hash = Arrays.copyOf(chunkHash, chunkHash.length);
-        chunk.length = length;
-        mKnownChunks.add(chunk);
-    }
-
-    private static byte[] toByteArray(long value) {
-        // Note that this code needs to stay compatible with GWT, which has known
-        // bugs when narrowing byte casts of long values occur.
-        byte[] result = new byte[8];
-        for (int i = 7; i >= 0; i--) {
-            result[i] = (byte) (value & 0xffL);
-            value >>= 8;
-        }
-        return result;
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/BackupWriter.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/BackupWriter.java
deleted file mode 100644
index baa820c..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/BackupWriter.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.chunking;
-
-import java.io.IOException;
-
-/** Writes backup data either as a diff script or as raw data, determined by the implementation. */
-public interface BackupWriter {
-    /** Writes the given bytes to the output. */
-    void writeBytes(byte[] bytes) throws IOException;
-
-    /**
-     * Writes an existing chunk from the previous backup to the output.
-     *
-     * <p>Note: not all implementations support this method.
-     */
-    void writeChunk(long start, int length) throws IOException;
-
-    /** Returns the number of bytes written, included bytes copied from the old file. */
-    long getBytesWritten();
-
-    /**
-     * Indicates that no more bytes or chunks will be written.
-     *
-     * <p>After calling this, you may not call {@link #writeBytes(byte[])} or {@link
-     * #writeChunk(long, int)}
-     */
-    void flush() throws IOException;
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/ByteRange.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/ByteRange.java
deleted file mode 100644
index 004d9e3..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/ByteRange.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.chunking;
-
-import com.android.internal.util.Preconditions;
-
-/** Representation of a range of bytes to be downloaded. */
-final class ByteRange {
-    private final long mStart;
-    private final long mEnd;
-
-    /** Creates a range of bytes which includes {@code mStart} and {@code mEnd}. */
-    ByteRange(long start, long end) {
-        Preconditions.checkArgument(start >= 0);
-        Preconditions.checkArgument(end >= start);
-        mStart = start;
-        mEnd = end;
-    }
-
-    /** Returns the start of the {@code ByteRange}. The start is included in the range. */
-    long getStart() {
-        return mStart;
-    }
-
-    /** Returns the end of the {@code ByteRange}. The end is included in the range. */
-    long getEnd() {
-        return mEnd;
-    }
-
-    /** Returns the number of bytes included in the {@code ByteRange}. */
-    int getLength() {
-        return (int) (mEnd - mStart + 1);
-    }
-
-    /** Creates a new {@link ByteRange} from {@code mStart} to {@code mEnd + length}. */
-    ByteRange extend(long length) {
-        Preconditions.checkArgument(length > 0);
-        return new ByteRange(mStart, mEnd + length);
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (!(o instanceof ByteRange)) {
-            return false;
-        }
-
-        ByteRange byteRange = (ByteRange) o;
-        return (mEnd == byteRange.mEnd && mStart == byteRange.mStart);
-    }
-
-    @Override
-    public int hashCode() {
-        int result = 17;
-        result = 31 * result + (int) (mStart ^ (mStart >>> 32));
-        result = 31 * result + (int) (mEnd ^ (mEnd >>> 32));
-        return result;
-    }
-
-    @Override
-    public String toString() {
-        return String.format("ByteRange{mStart=%d, mEnd=%d}", mStart, mEnd);
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/ChunkEncryptor.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/ChunkEncryptor.java
deleted file mode 100644
index 48abc8c..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/ChunkEncryptor.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.chunking;
-
-import com.android.server.backup.encryption.chunk.ChunkHash;
-
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.SecretKey;
-import javax.crypto.spec.GCMParameterSpec;
-
-/** Encrypts chunks of a file using AES/GCM. */
-public class ChunkEncryptor {
-    private static final String CIPHER_ALGORITHM = "AES/GCM/NoPadding";
-    private static final int GCM_NONCE_LENGTH_BYTES = 12;
-    private static final int GCM_TAG_LENGTH_BYTES = 16;
-
-    private final SecretKey mSecretKey;
-    private final SecureRandom mSecureRandom;
-
-    /**
-     * A new instance using {@code mSecretKey} to encrypt chunks and {@code mSecureRandom} to
-     * generate nonces.
-     */
-    public ChunkEncryptor(SecretKey secretKey, SecureRandom secureRandom) {
-        this.mSecretKey = secretKey;
-        this.mSecureRandom = secureRandom;
-    }
-
-    /**
-     * Transforms {@code plaintext} into an {@link EncryptedChunk}.
-     *
-     * @param plaintextHash The hash of the plaintext to encrypt, to attach as the key of the chunk.
-     * @param plaintext Bytes to encrypt.
-     * @throws InvalidKeyException If the given secret key is not a valid AES key for decryption.
-     * @throws IllegalBlockSizeException If the input data cannot be encrypted using
-     *     AES/GCM/NoPadding. This should never be the case.
-     */
-    public EncryptedChunk encrypt(ChunkHash plaintextHash, byte[] plaintext)
-            throws InvalidKeyException, IllegalBlockSizeException {
-        byte[] nonce = generateNonce();
-        Cipher cipher;
-        try {
-            cipher = Cipher.getInstance(CIPHER_ALGORITHM);
-            cipher.init(
-                    Cipher.ENCRYPT_MODE,
-                    mSecretKey,
-                    new GCMParameterSpec(GCM_TAG_LENGTH_BYTES * 8, nonce));
-        } catch (NoSuchAlgorithmException
-                | NoSuchPaddingException
-                | InvalidAlgorithmParameterException e) {
-            // This can not happen - AES/GCM/NoPadding is supported.
-            throw new AssertionError(e);
-        }
-        byte[] encryptedBytes;
-        try {
-            encryptedBytes = cipher.doFinal(plaintext);
-        } catch (BadPaddingException e) {
-            // This can not happen - BadPaddingException can only be thrown in decrypt mode.
-            throw new AssertionError("Impossible: threw BadPaddingException in encrypt mode.");
-        }
-
-        return EncryptedChunk.create(/*key=*/ plaintextHash, nonce, encryptedBytes);
-    }
-
-    private byte[] generateNonce() {
-        byte[] nonce = new byte[GCM_NONCE_LENGTH_BYTES];
-        mSecureRandom.nextBytes(nonce);
-        return nonce;
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/ChunkHasher.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/ChunkHasher.java
deleted file mode 100644
index 02d498c..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/ChunkHasher.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.chunking;
-
-import com.android.server.backup.encryption.chunk.ChunkHash;
-
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-
-import javax.crypto.Mac;
-import javax.crypto.SecretKey;
-
-/** Computes the SHA-256 HMAC of a chunk of bytes. */
-public class ChunkHasher {
-    private static final String MAC_ALGORITHM = "HmacSHA256";
-
-    private final SecretKey mSecretKey;
-
-    /** Constructs a new hasher which computes the HMAC using the given secret key. */
-    public ChunkHasher(SecretKey secretKey) {
-        this.mSecretKey = secretKey;
-    }
-
-    /** Returns the SHA-256 over the given bytes. */
-    public ChunkHash computeHash(byte[] plaintext) throws InvalidKeyException {
-        try {
-            Mac mac = Mac.getInstance(MAC_ALGORITHM);
-            mac.init(mSecretKey);
-            return new ChunkHash(mac.doFinal(plaintext));
-        } catch (NoSuchAlgorithmException e) {
-            // This can not happen - AES/GCM/NoPadding is available as part of the framework.
-            throw new AssertionError(e);
-        }
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/Chunker.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/Chunker.java
deleted file mode 100644
index c9a6293..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/Chunker.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.chunking;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.GeneralSecurityException;
-
-/** Splits an input stream into chunks, which are to be encrypted separately. */
-public interface Chunker {
-    /**
-     * Splits the input stream into chunks.
-     *
-     * @param inputStream The input stream.
-     * @param chunkConsumer A function that processes each chunk as it is produced.
-     * @throws IOException If there is a problem reading the input stream.
-     * @throws GeneralSecurityException if the consumer function throws an error.
-     */
-    void chunkify(InputStream inputStream, ChunkConsumer chunkConsumer)
-            throws IOException, GeneralSecurityException;
-
-    /** Function that consumes chunks. */
-    interface ChunkConsumer {
-        /**
-         * Invoked for each chunk.
-         *
-         * @param chunk Plaintext bytes of chunk.
-         * @throws GeneralSecurityException if there is an issue encrypting the chunk.
-         */
-        void accept(byte[] chunk) throws GeneralSecurityException;
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/DecryptedChunkFileOutput.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/DecryptedChunkFileOutput.java
deleted file mode 100644
index ae2e150..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/DecryptedChunkFileOutput.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.chunking;
-
-import static com.android.internal.util.Preconditions.checkState;
-
-import android.annotation.Nullable;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.server.backup.encryption.tasks.DecryptedChunkOutput;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-
-/** Writes plaintext chunks to a file, building a digest of the plaintext of the resulting file. */
-public class DecryptedChunkFileOutput implements DecryptedChunkOutput {
-    @VisibleForTesting static final String DIGEST_ALGORITHM = "SHA-256";
-
-    private final File mOutputFile;
-    private final MessageDigest mMessageDigest;
-    @Nullable private FileOutputStream mFileOutputStream;
-    private boolean mClosed;
-    @Nullable private byte[] mDigest;
-
-    /**
-     * Constructs a new instance which writes chunks to the given file and uses the default message
-     * digest algorithm.
-     */
-    public DecryptedChunkFileOutput(File outputFile) {
-        mOutputFile = outputFile;
-        try {
-            mMessageDigest = MessageDigest.getInstance(DIGEST_ALGORITHM);
-        } catch (NoSuchAlgorithmException e) {
-            throw new AssertionError(
-                    "Impossible condition: JCE thinks it does not support AES.", e);
-        }
-    }
-
-    @Override
-    public DecryptedChunkOutput open() throws IOException {
-        checkState(mFileOutputStream == null, "Cannot open twice");
-        mFileOutputStream = new FileOutputStream(mOutputFile);
-        return this;
-    }
-
-    @Override
-    public void processChunk(byte[] plaintextBuffer, int length) throws IOException {
-        checkState(mFileOutputStream != null, "Must open before processing chunks");
-        mFileOutputStream.write(plaintextBuffer, /*off=*/ 0, length);
-        mMessageDigest.update(plaintextBuffer, /*offset=*/ 0, length);
-    }
-
-    @Override
-    public byte[] getDigest() {
-        checkState(mClosed, "Must close before getting mDigest");
-
-        // After the first call to mDigest() the MessageDigest is reset, thus we must store the
-        // result.
-        if (mDigest == null) {
-            mDigest = mMessageDigest.digest();
-        }
-        return mDigest;
-    }
-
-    @Override
-    public void close() throws IOException {
-        mFileOutputStream.close();
-        mClosed = true;
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/DiffScriptBackupWriter.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/DiffScriptBackupWriter.java
deleted file mode 100644
index 69fb5cb..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/DiffScriptBackupWriter.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.chunking;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-/** Writes backup data to a diff script, using a {@link SingleStreamDiffScriptWriter}. */
-public class DiffScriptBackupWriter implements BackupWriter {
-    /**
-     * The maximum size of a chunk in the diff script. The diff script writer {@code mWriter} will
-     * buffer this many bytes in memory.
-     */
-    private static final int ENCRYPTION_DIFF_SCRIPT_MAX_CHUNK_SIZE_BYTES = 1024 * 1024;
-
-    private final SingleStreamDiffScriptWriter mWriter;
-    private long mBytesWritten;
-
-    /**
-     * Constructs a new writer which writes the diff script to the given output stream, using the
-     * maximum new chunk size {@code ENCRYPTION_DIFF_SCRIPT_MAX_CHUNK_SIZE_BYTES}.
-     */
-    public static DiffScriptBackupWriter newInstance(OutputStream outputStream) {
-        SingleStreamDiffScriptWriter writer =
-                new SingleStreamDiffScriptWriter(
-                        outputStream, ENCRYPTION_DIFF_SCRIPT_MAX_CHUNK_SIZE_BYTES);
-        return new DiffScriptBackupWriter(writer);
-    }
-
-    @VisibleForTesting
-    DiffScriptBackupWriter(SingleStreamDiffScriptWriter writer) {
-        mWriter = writer;
-    }
-
-    @Override
-    public void writeBytes(byte[] bytes) throws IOException {
-        for (byte b : bytes) {
-            mWriter.writeByte(b);
-        }
-
-        mBytesWritten += bytes.length;
-    }
-
-    @Override
-    public void writeChunk(long start, int length) throws IOException {
-        mWriter.writeChunk(start, length);
-        mBytesWritten += length;
-    }
-
-    @Override
-    public long getBytesWritten() {
-        return mBytesWritten;
-    }
-
-    @Override
-    public void flush() throws IOException {
-        mWriter.flush();
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/DiffScriptWriter.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/DiffScriptWriter.java
deleted file mode 100644
index 49d1571..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/DiffScriptWriter.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.chunking;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-/** Writer that formats a Diff Script and writes it to an output source. */
-interface DiffScriptWriter {
-    /** Adds a new byte to the diff script. */
-    void writeByte(byte b) throws IOException;
-
-    /** Adds a known chunk to the diff script. */
-    void writeChunk(long chunkStart, int chunkLength) throws IOException;
-
-    /** Indicates that no more bytes or chunks will be added to the diff script. */
-    void flush() throws IOException;
-
-    interface Factory {
-        DiffScriptWriter create(OutputStream outputStream);
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/EncryptedChunk.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/EncryptedChunk.java
deleted file mode 100644
index cde59fa..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/EncryptedChunk.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.chunking;
-
-import com.android.internal.util.Preconditions;
-import com.android.server.backup.encryption.chunk.ChunkHash;
-
-import java.util.Arrays;
-import java.util.Objects;
-
-/**
- * A chunk of a file encrypted using AES/GCM.
- *
- * <p>TODO(b/116575321): After all code is ported, remove the factory method and rename
- * encryptedBytes(), key() and nonce().
- */
-public class EncryptedChunk {
-    public static final int KEY_LENGTH_BYTES = ChunkHash.HASH_LENGTH_BYTES;
-    public static final int NONCE_LENGTH_BYTES = 12;
-
-    /**
-     * Constructs a new instance with the given key, nonce, and encrypted bytes.
-     *
-     * @param key SHA-256 Hmac of the chunk plaintext.
-     * @param nonce Nonce with which the bytes of the chunk were encrypted.
-     * @param encryptedBytes Encrypted bytes of the chunk.
-     */
-    public static EncryptedChunk create(ChunkHash key, byte[] nonce, byte[] encryptedBytes) {
-        Preconditions.checkArgument(
-                nonce.length == NONCE_LENGTH_BYTES, "Nonce does not have the correct length.");
-        return new EncryptedChunk(key, nonce, encryptedBytes);
-    }
-
-    private ChunkHash mKey;
-    private byte[] mNonce;
-    private byte[] mEncryptedBytes;
-
-    private EncryptedChunk(ChunkHash key, byte[] nonce, byte[] encryptedBytes) {
-        mKey = key;
-        mNonce = nonce;
-        mEncryptedBytes = encryptedBytes;
-    }
-
-    /** The SHA-256 Hmac of the plaintext bytes of the chunk. */
-    public ChunkHash key() {
-        return mKey;
-    }
-
-    /** The nonce with which the chunk was encrypted. */
-    public byte[] nonce() {
-        return mNonce;
-    }
-
-    /** The encrypted bytes of the chunk. */
-    public byte[] encryptedBytes() {
-        return mEncryptedBytes;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (!(o instanceof EncryptedChunk)) {
-            return false;
-        }
-
-        EncryptedChunk encryptedChunkOrdering = (EncryptedChunk) o;
-        return Arrays.equals(mEncryptedBytes, encryptedChunkOrdering.mEncryptedBytes)
-                && Arrays.equals(mNonce, encryptedChunkOrdering.mNonce)
-                && mKey.equals(encryptedChunkOrdering.mKey);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mKey, Arrays.hashCode(mNonce), Arrays.hashCode(mEncryptedBytes));
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/EncryptedChunkEncoder.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/EncryptedChunkEncoder.java
deleted file mode 100644
index 16beda3..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/EncryptedChunkEncoder.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.chunking;
-
-import com.android.server.backup.encryption.chunk.ChunkOrderingType;
-
-import java.io.IOException;
-
-/** Encodes an {@link EncryptedChunk} as bytes to write to the encrypted backup file. */
-public interface EncryptedChunkEncoder {
-    /**
-     * Encodes the given chunk and asks the writer to write it.
-     *
-     * <p>The chunk will be encoded in the format [nonce]+[encrypted data].
-     *
-     * <p>TODO(b/116575321): Choose a more descriptive method name after the code move is done.
-     */
-    void writeChunkToWriter(BackupWriter writer, EncryptedChunk chunk) throws IOException;
-
-    /**
-     * Returns the length in bytes that this chunk would be if encoded with {@link
-     * #writeChunkToWriter}.
-     */
-    int getEncodedLengthOfChunk(EncryptedChunk chunk);
-
-    /**
-     * Returns the {@link ChunkOrderingType} that must be included in the backup file, when using
-     * this decoder, so that the file may be correctly decoded.
-     */
-    @ChunkOrderingType
-    int getChunkOrderingType();
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/InlineLengthsEncryptedChunkEncoder.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/InlineLengthsEncryptedChunkEncoder.java
deleted file mode 100644
index 6b9be9f..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/InlineLengthsEncryptedChunkEncoder.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.chunking;
-
-import com.android.server.backup.encryption.chunk.ChunkOrderingType;
-import com.android.server.backup.encryption.protos.nano.ChunksMetadataProto;
-
-import java.io.IOException;
-
-/**
- * Encodes an {@link EncryptedChunk} as bytes, prepending the length of the chunk.
- *
- * <p>This allows us to decode the backup file during restore without any extra information about
- * the boundaries of the chunks. The backup file should contain a chunk ordering in mode {@link
- * ChunksMetadataProto#INLINE_LENGTHS}.
- *
- * <p>We use this implementation during key value backup.
- */
-public class InlineLengthsEncryptedChunkEncoder implements EncryptedChunkEncoder {
-    public static final int BYTES_LENGTH = Integer.SIZE / Byte.SIZE;
-
-    private final LengthlessEncryptedChunkEncoder mLengthlessEncryptedChunkEncoder =
-            new LengthlessEncryptedChunkEncoder();
-
-    @Override
-    public void writeChunkToWriter(BackupWriter writer, EncryptedChunk chunk) throws IOException {
-        int length = mLengthlessEncryptedChunkEncoder.getEncodedLengthOfChunk(chunk);
-        writer.writeBytes(toByteArray(length));
-        mLengthlessEncryptedChunkEncoder.writeChunkToWriter(writer, chunk);
-    }
-
-    @Override
-    public int getEncodedLengthOfChunk(EncryptedChunk chunk) {
-        return BYTES_LENGTH + mLengthlessEncryptedChunkEncoder.getEncodedLengthOfChunk(chunk);
-    }
-
-    @Override
-    @ChunkOrderingType
-    public int getChunkOrderingType() {
-        return ChunksMetadataProto.INLINE_LENGTHS;
-    }
-
-    /**
-     * Returns a big-endian representation of {@code value} in a 4-element byte array; equivalent to
-     * {@code ByteBuffer.allocate(4).putInt(value).array()}. For example, the input value {@code
-     * 0x12131415} would yield the byte array {@code {0x12, 0x13, 0x14, 0x15}}.
-     *
-     * <p>Equivalent to guava's Ints.toByteArray.
-     */
-    static byte[] toByteArray(int value) {
-        return new byte[] {
-            (byte) (value >> 24), (byte) (value >> 16), (byte) (value >> 8), (byte) value
-        };
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/LengthlessEncryptedChunkEncoder.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/LengthlessEncryptedChunkEncoder.java
deleted file mode 100644
index e707350..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/LengthlessEncryptedChunkEncoder.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.chunking;
-
-import com.android.server.backup.encryption.chunk.ChunkOrderingType;
-import com.android.server.backup.encryption.protos.nano.ChunksMetadataProto;
-
-import java.io.IOException;
-
-/**
- * Encodes an {@link EncryptedChunk} as bytes without including any information about the length of
- * the chunk.
- *
- * <p>In order for us to decode the backup file during restore it must include a chunk ordering in
- * mode {@link ChunksMetadataProto#EXPLICIT_STARTS}, which contains the boundaries of the chunks in
- * the encrypted file. This information allows us to decode the backup file and divide it into
- * chunks without including the length of each chunk inline.
- *
- * <p>We use this implementation during full backup.
- */
-public class LengthlessEncryptedChunkEncoder implements EncryptedChunkEncoder {
-    @Override
-    public void writeChunkToWriter(BackupWriter writer, EncryptedChunk chunk) throws IOException {
-        writer.writeBytes(chunk.nonce());
-        writer.writeBytes(chunk.encryptedBytes());
-    }
-
-    @Override
-    public int getEncodedLengthOfChunk(EncryptedChunk chunk) {
-        return chunk.nonce().length + chunk.encryptedBytes().length;
-    }
-
-    @Override
-    @ChunkOrderingType
-    public int getChunkOrderingType() {
-        return ChunksMetadataProto.EXPLICIT_STARTS;
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/OutputStreamWrapper.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/OutputStreamWrapper.java
deleted file mode 100644
index 4aea601..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/OutputStreamWrapper.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.chunking;
-
-import java.io.OutputStream;
-
-/** An interface that wraps one {@link OutputStream} with another for filtration purposes. */
-public interface OutputStreamWrapper {
-    /** Wraps a given {@link OutputStream}. */
-    OutputStream wrap(OutputStream outputStream);
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/ProtoStore.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/ProtoStore.java
deleted file mode 100644
index b0a562c..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/ProtoStore.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.chunking;
-
-import android.content.Context;
-import android.text.TextUtils;
-import android.util.AtomicFile;
-import android.util.Slog;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.server.backup.encryption.protos.nano.ChunksMetadataProto;
-import com.android.server.backup.encryption.protos.nano.KeyValueListingProto;
-
-import com.google.protobuf.nano.MessageNano;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.util.Objects;
-import java.util.Optional;
-
-/**
- * Stores a nano proto for each package, persisting the proto to disk.
- *
- * <p>This is used to store {@link ChunksMetadataProto.ChunkListing}.
- *
- * @param <T> the type of nano proto to store.
- */
-public class ProtoStore<T extends MessageNano> {
-    private static final String CHUNK_LISTING_FOLDER = "backup_chunk_listings";
-    private static final String KEY_VALUE_LISTING_FOLDER = "backup_kv_listings";
-
-    private static final String TAG = "BupEncProtoStore";
-
-    private final File mStoreFolder;
-    private final Class<T> mClazz;
-
-    /** Creates a new instance which stores chunk listings at the default location. */
-    public static ProtoStore<ChunksMetadataProto.ChunkListing> createChunkListingStore(
-            Context context) throws IOException {
-        return new ProtoStore<>(
-                ChunksMetadataProto.ChunkListing.class,
-                new File(context.getFilesDir().getAbsoluteFile(), CHUNK_LISTING_FOLDER));
-    }
-
-    /** Creates a new instance which stores key value listings in the default location. */
-    public static ProtoStore<KeyValueListingProto.KeyValueListing> createKeyValueListingStore(
-            Context context) throws IOException {
-        return new ProtoStore<>(
-                KeyValueListingProto.KeyValueListing.class,
-                new File(context.getFilesDir().getAbsoluteFile(), KEY_VALUE_LISTING_FOLDER));
-    }
-
-    /**
-     * Creates a new instance which stores protos in the given folder.
-     *
-     * @param storeFolder The location where the serialized form is stored.
-     */
-    @VisibleForTesting
-    ProtoStore(Class<T> clazz, File storeFolder) throws IOException {
-        mClazz = Objects.requireNonNull(clazz);
-        mStoreFolder = ensureDirectoryExistsOrThrow(storeFolder);
-    }
-
-    private static File ensureDirectoryExistsOrThrow(File directory) throws IOException {
-        if (directory.exists() && !directory.isDirectory()) {
-            throw new IOException("Store folder already exists, but isn't a directory.");
-        }
-
-        if (!directory.exists() && !directory.mkdir()) {
-            throw new IOException("Unable to create store folder.");
-        }
-
-        return directory;
-    }
-
-    /**
-     * Returns the chunk listing for the given package, or {@link Optional#empty()} if no listing
-     * exists.
-     */
-    public Optional<T> loadProto(String packageName)
-            throws IOException, IllegalAccessException, InstantiationException,
-            NoSuchMethodException, InvocationTargetException {
-        File file = getFileForPackage(packageName);
-
-        if (!file.exists()) {
-            Slog.d(
-                    TAG,
-                    "No chunk listing existed for " + packageName + ", returning empty listing.");
-            return Optional.empty();
-        }
-
-        AtomicFile protoStore = new AtomicFile(file);
-        byte[] data = protoStore.readFully();
-
-        Constructor<T> constructor = mClazz.getDeclaredConstructor();
-        T proto = constructor.newInstance();
-        MessageNano.mergeFrom(proto, data);
-        return Optional.of(proto);
-    }
-
-    /** Saves a proto to disk, associating it with the given package. */
-    public void saveProto(String packageName, T proto) throws IOException {
-        Objects.requireNonNull(proto);
-        File file = getFileForPackage(packageName);
-
-        try (FileOutputStream os = new FileOutputStream(file)) {
-            os.write(MessageNano.toByteArray(proto));
-        } catch (IOException e) {
-            Slog.e(
-                    TAG,
-                    "Exception occurred when saving the listing for "
-                            + packageName
-                            + ", deleting saved listing.",
-                    e);
-
-            // If a problem occurred when writing the listing then it might be corrupt, so delete
-            // it.
-            file.delete();
-
-            throw e;
-        }
-    }
-
-    /** Deletes the proto for the given package, or does nothing if the package has no proto. */
-    public void deleteProto(String packageName) {
-        File file = getFileForPackage(packageName);
-        file.delete();
-    }
-
-    /** Deletes every proto of this type, for all package names. */
-    public void deleteAllProtos() {
-        File[] files = mStoreFolder.listFiles();
-
-        // We ensure that the storeFolder exists in the constructor, but check just in case it has
-        // mysteriously disappeared.
-        if (files == null) {
-            return;
-        }
-
-        for (File file : files) {
-            file.delete();
-        }
-    }
-
-    private File getFileForPackage(String packageName) {
-        checkPackageName(packageName);
-        return new File(mStoreFolder, packageName);
-    }
-
-    private static void checkPackageName(String packageName) {
-        if (TextUtils.isEmpty(packageName) || packageName.contains("/")) {
-            throw new IllegalArgumentException(
-                    "Package name must not contain '/' or be empty: " + packageName);
-        }
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/RawBackupWriter.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/RawBackupWriter.java
deleted file mode 100644
index b211b0f..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/RawBackupWriter.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.chunking;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-/** Writes data straight to an output stream. */
-public class RawBackupWriter implements BackupWriter {
-    private final OutputStream mOutputStream;
-    private long mBytesWritten;
-
-    /** Constructs a new writer which writes bytes to the given output stream. */
-    public RawBackupWriter(OutputStream outputStream) {
-        this.mOutputStream = outputStream;
-    }
-
-    @Override
-    public void writeBytes(byte[] bytes) throws IOException {
-        mOutputStream.write(bytes);
-        mBytesWritten += bytes.length;
-    }
-
-    @Override
-    public void writeChunk(long start, int length) throws IOException {
-        throw new UnsupportedOperationException("RawBackupWriter cannot write existing chunks");
-    }
-
-    @Override
-    public long getBytesWritten() {
-        return mBytesWritten;
-    }
-
-    @Override
-    public void flush() throws IOException {
-        mOutputStream.flush();
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/SingleStreamDiffScriptWriter.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/SingleStreamDiffScriptWriter.java
deleted file mode 100644
index 0e4bd58..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/SingleStreamDiffScriptWriter.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.chunking;
-
-import android.annotation.Nullable;
-
-import com.android.internal.util.Preconditions;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.nio.charset.Charset;
-import java.util.Locale;
-
-/**
- * A {@link DiffScriptWriter} that writes an entire diff script to a single {@link OutputStream}.
- */
-public class SingleStreamDiffScriptWriter implements DiffScriptWriter {
-    static final byte LINE_SEPARATOR = 0xA;
-    private static final Charset UTF_8 = Charset.forName("UTF-8");
-
-    private final int mMaxNewByteChunkSize;
-    private final OutputStream mOutputStream;
-    private final byte[] mByteBuffer;
-    private int mBufferSize = 0;
-    // Each chunk could be written immediately to the output stream. However,
-    // it is possible that chunks may overlap. We therefore cache the most recent
-    // reusable chunk and try to merge it with future chunks.
-    private ByteRange mReusableChunk;
-
-    public SingleStreamDiffScriptWriter(OutputStream outputStream, int maxNewByteChunkSize) {
-        mOutputStream = outputStream;
-        mMaxNewByteChunkSize = maxNewByteChunkSize;
-        mByteBuffer = new byte[maxNewByteChunkSize];
-    }
-
-    @Override
-    public void writeByte(byte b) throws IOException {
-        if (mReusableChunk != null) {
-            writeReusableChunk();
-        }
-        mByteBuffer[mBufferSize++] = b;
-        if (mBufferSize == mMaxNewByteChunkSize) {
-            writeByteBuffer();
-        }
-    }
-
-    @Override
-    public void writeChunk(long chunkStart, int chunkLength) throws IOException {
-        Preconditions.checkArgument(chunkStart >= 0);
-        Preconditions.checkArgument(chunkLength > 0);
-        if (mBufferSize != 0) {
-            writeByteBuffer();
-        }
-
-        if (mReusableChunk != null && mReusableChunk.getEnd() + 1 == chunkStart) {
-            // The new chunk overlaps the old, so combine them into a single byte range.
-            mReusableChunk = mReusableChunk.extend(chunkLength);
-        } else {
-            writeReusableChunk();
-            mReusableChunk = new ByteRange(chunkStart, chunkStart + chunkLength - 1);
-        }
-    }
-
-    @Override
-    public void flush() throws IOException {
-        Preconditions.checkState(!(mBufferSize != 0 && mReusableChunk != null));
-        if (mBufferSize != 0) {
-            writeByteBuffer();
-        }
-        if (mReusableChunk != null) {
-            writeReusableChunk();
-        }
-        mOutputStream.flush();
-    }
-
-    private void writeByteBuffer() throws IOException {
-        mOutputStream.write(Integer.toString(mBufferSize).getBytes(UTF_8));
-        mOutputStream.write(LINE_SEPARATOR);
-        mOutputStream.write(mByteBuffer, 0, mBufferSize);
-        mOutputStream.write(LINE_SEPARATOR);
-        mBufferSize = 0;
-    }
-
-    private void writeReusableChunk() throws IOException {
-        if (mReusableChunk != null) {
-            mOutputStream.write(
-                    String.format(
-                                    Locale.US,
-                                    "%d-%d",
-                                    mReusableChunk.getStart(),
-                                    mReusableChunk.getEnd())
-                            .getBytes(UTF_8));
-            mOutputStream.write(LINE_SEPARATOR);
-            mReusableChunk = null;
-        }
-    }
-
-    /** A factory that creates {@link SingleStreamDiffScriptWriter}s. */
-    public static class Factory implements DiffScriptWriter.Factory {
-        private final int mMaxNewByteChunkSize;
-        private final OutputStreamWrapper mOutputStreamWrapper;
-
-        public Factory(int maxNewByteChunkSize, @Nullable OutputStreamWrapper outputStreamWrapper) {
-            mMaxNewByteChunkSize = maxNewByteChunkSize;
-            mOutputStreamWrapper = outputStreamWrapper;
-        }
-
-        @Override
-        public SingleStreamDiffScriptWriter create(OutputStream outputStream) {
-            if (mOutputStreamWrapper != null) {
-                outputStream = mOutputStreamWrapper.wrap(outputStream);
-            }
-            return new SingleStreamDiffScriptWriter(outputStream, mMaxNewByteChunkSize);
-        }
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/cdc/ContentDefinedChunker.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/cdc/ContentDefinedChunker.java
deleted file mode 100644
index 18011f6..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/cdc/ContentDefinedChunker.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.chunking.cdc;
-
-import static com.android.internal.util.Preconditions.checkArgument;
-
-import com.android.server.backup.encryption.chunking.Chunker;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.GeneralSecurityException;
-import java.util.Arrays;
-
-/** Splits a stream of bytes into variable-sized chunks, using content-defined chunking. */
-public class ContentDefinedChunker implements Chunker {
-    private static final int WINDOW_SIZE = 31;
-    private static final byte DEFAULT_OUT_BYTE = (byte) 0;
-
-    private final byte[] mChunkBuffer;
-    private final RabinFingerprint64 mRabinFingerprint64;
-    private final FingerprintMixer mFingerprintMixer;
-    private final BreakpointPredicate mBreakpointPredicate;
-    private final int mMinChunkSize;
-    private final int mMaxChunkSize;
-
-    /**
-     * Constructor.
-     *
-     * @param minChunkSize The minimum size of a chunk. No chunk will be produced of a size smaller
-     *     than this except possibly at the very end of the stream.
-     * @param maxChunkSize The maximum size of a chunk. No chunk will be produced of a larger size.
-     * @param rabinFingerprint64 Calculates fingerprints, with which to determine breakpoints.
-     * @param breakpointPredicate Given a Rabin fingerprint, returns whether this ought to be a
-     *     breakpoint.
-     */
-    public ContentDefinedChunker(
-            int minChunkSize,
-            int maxChunkSize,
-            RabinFingerprint64 rabinFingerprint64,
-            FingerprintMixer fingerprintMixer,
-            BreakpointPredicate breakpointPredicate) {
-        checkArgument(
-                minChunkSize >= WINDOW_SIZE,
-                "Minimum chunk size must be greater than window size.");
-        checkArgument(
-                maxChunkSize >= minChunkSize,
-                "Maximum chunk size cannot be smaller than minimum chunk size.");
-        mChunkBuffer = new byte[maxChunkSize];
-        mRabinFingerprint64 = rabinFingerprint64;
-        mBreakpointPredicate = breakpointPredicate;
-        mFingerprintMixer = fingerprintMixer;
-        mMinChunkSize = minChunkSize;
-        mMaxChunkSize = maxChunkSize;
-    }
-
-    /**
-     * Breaks the input stream into variable-sized chunks.
-     *
-     * @param inputStream The input bytes to break into chunks.
-     * @param chunkConsumer A function to process each chunk as it's generated.
-     * @throws IOException Thrown if there is an issue reading from the input stream.
-     * @throws GeneralSecurityException Thrown if the {@link ChunkConsumer} throws it.
-     */
-    @Override
-    public void chunkify(InputStream inputStream, ChunkConsumer chunkConsumer)
-            throws IOException, GeneralSecurityException {
-        int chunkLength;
-        int initialReadLength = mMinChunkSize - WINDOW_SIZE;
-
-        // Performance optimization - there is no reason to calculate fingerprints for windows
-        // ending before the minimum chunk size.
-        while ((chunkLength =
-                        inputStream.read(mChunkBuffer, /*off=*/ 0, /*len=*/ initialReadLength))
-                != -1) {
-            int b;
-            long fingerprint = 0L;
-
-            while ((b = inputStream.read()) != -1) {
-                byte inByte = (byte) b;
-                byte outByte = getCurrentWindowStartByte(chunkLength);
-                mChunkBuffer[chunkLength++] = inByte;
-
-                fingerprint =
-                        mRabinFingerprint64.computeFingerprint64(inByte, outByte, fingerprint);
-
-                if (chunkLength >= mMaxChunkSize
-                        || (chunkLength >= mMinChunkSize
-                                && mBreakpointPredicate.isBreakpoint(
-                                        mFingerprintMixer.mix(fingerprint)))) {
-                    chunkConsumer.accept(Arrays.copyOf(mChunkBuffer, chunkLength));
-                    chunkLength = 0;
-                    break;
-                }
-            }
-
-            if (chunkLength > 0) {
-                chunkConsumer.accept(Arrays.copyOf(mChunkBuffer, chunkLength));
-            }
-        }
-    }
-
-    private byte getCurrentWindowStartByte(int chunkLength) {
-        if (chunkLength < mMinChunkSize) {
-            return DEFAULT_OUT_BYTE;
-        } else {
-            return mChunkBuffer[chunkLength - WINDOW_SIZE];
-        }
-    }
-
-    /** Whether the current fingerprint indicates the end of a chunk. */
-    public interface BreakpointPredicate {
-
-        /**
-         * Returns {@code true} if the fingerprint of the last {@code WINDOW_SIZE} bytes indicates
-         * the chunk ought to end at this position.
-         *
-         * @param fingerprint Fingerprint of the last {@code WINDOW_SIZE} bytes.
-         * @return Whether this ought to be a chunk breakpoint.
-         */
-        boolean isBreakpoint(long fingerprint);
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/cdc/FingerprintMixer.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/cdc/FingerprintMixer.java
deleted file mode 100644
index e9f3050..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/cdc/FingerprintMixer.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.chunking.cdc;
-
-import static com.android.internal.util.Preconditions.checkArgument;
-
-import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
-import java.security.InvalidKeyException;
-
-import javax.crypto.SecretKey;
-
-/**
- * Helper for mixing fingerprint with key material.
- *
- * <p>We do this as otherwise the Rabin fingerprint leaks information about the plaintext. i.e., if
- * two users have the same file, it will be partitioned by Rabin in the same way, allowing us to
- * infer that it is the same as another user's file.
- *
- * <p>By mixing the fingerprint with the user's secret key, the chunking method is different on a
- * per key basis. Each application has its own {@link SecretKey}, so we cannot infer that a file is
- * the same even across multiple applications owned by the same user, never mind across multiple
- * users.
- *
- * <p>Instead of directly mixing the fingerprint with the user's secret, we first securely and
- * deterministically derive a secondary chunking key. As Rabin is not a cryptographically secure
- * hash, it might otherwise leak information about the user's secret. This prevents that from
- * happening.
- */
-public class FingerprintMixer {
-    public static final int SALT_LENGTH_BYTES = 256 / Byte.SIZE;
-    private static final String DERIVED_KEY_NAME = "RabinFingerprint64Mixer";
-
-    private final long mAddend;
-    private final long mMultiplicand;
-
-    /**
-     * A new instance from a given secret key and salt. Salt must be the same across incremental
-     * backups, or a different chunking strategy will be used each time, defeating the dedup.
-     *
-     * @param secretKey The application-specific secret.
-     * @param salt The salt.
-     * @throws InvalidKeyException If the encoded form of {@code secretKey} is inaccessible.
-     */
-    public FingerprintMixer(SecretKey secretKey, byte[] salt) throws InvalidKeyException {
-        checkArgument(salt.length == SALT_LENGTH_BYTES, "Requires a 256-bit salt.");
-        byte[] keyBytes = secretKey.getEncoded();
-        if (keyBytes == null) {
-            throw new InvalidKeyException("SecretKey must support encoding for FingerprintMixer.");
-        }
-        byte[] derivedKey =
-                Hkdf.hkdf(keyBytes, salt, DERIVED_KEY_NAME.getBytes(StandardCharsets.UTF_8));
-        ByteBuffer buffer = ByteBuffer.wrap(derivedKey);
-        mAddend = buffer.getLong();
-        // Multiplicand must be odd - otherwise we lose some bits of the Rabin fingerprint when
-        // mixing
-        mMultiplicand = buffer.getLong() | 1;
-    }
-
-    /**
-     * Mixes the fingerprint with the derived key material. This is performed by adding part of the
-     * derived key and multiplying by another part of the derived key (which is forced to be odd, so
-     * that the operation is reversible).
-     *
-     * @param fingerprint A 64-bit Rabin fingerprint.
-     * @return The mixed fingerprint.
-     */
-    long mix(long fingerprint) {
-        return ((fingerprint + mAddend) * mMultiplicand);
-    }
-
-    /** The addend part of the derived key. */
-    long getAddend() {
-        return mAddend;
-    }
-
-    /** The multiplicand part of the derived key. */
-    long getMultiplicand() {
-        return mMultiplicand;
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/cdc/Hkdf.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/cdc/Hkdf.java
deleted file mode 100644
index d0776ae..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/cdc/Hkdf.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.chunking.cdc;
-
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.util.Objects;
-
-import javax.crypto.Mac;
-import javax.crypto.spec.SecretKeySpec;
-
-/**
- * Secure HKDF utils. Allows client to deterministically derive additional key material from a base
- * secret. If the derived key material is compromised, this does not in of itself compromise the
- * root secret.
- *
- * <p>TODO(b/116575321): After all code is ported, rename this class to HkdfUtils.
- */
-public final class Hkdf {
-    private static final byte[] CONSTANT_01 = {0x01};
-    private static final String HmacSHA256 = "HmacSHA256";
-    private static final String AES = "AES";
-
-    /**
-     * Implements HKDF (RFC 5869) with the SHA-256 hash and a 256-bit output key length.
-     *
-     * <p>IMPORTANT: The use or edit of this method requires a security review.
-     *
-     * @param mainKey Main key from which to derive sub-keys.
-     * @param salt A randomly generated 256-bit byte string.
-     * @param data Arbitrary information that is bound to the derived key (i.e., used in its
-     *     creation).
-     * @return Raw derived key bytes = HKDF-SHA256(mainKey, salt, data).
-     * @throws InvalidKeyException If the salt can not be used as a valid key.
-     */
-    static byte[] hkdf(byte[] mainKey, byte[] salt, byte[] data) throws InvalidKeyException {
-        Objects.requireNonNull(mainKey, "HKDF requires main key to be set.");
-        Objects.requireNonNull(salt, "HKDF requires a salt.");
-        Objects.requireNonNull(data, "No data provided to HKDF.");
-        return hkdfSha256Expand(hkdfSha256Extract(mainKey, salt), data);
-    }
-
-    private Hkdf() {}
-
-    /**
-     * The HKDF (RFC 5869) extraction function, using the SHA-256 hash function. This function is
-     * used to pre-process the {@code inputKeyMaterial} and mix it with the {@code salt}, producing
-     * output suitable for use with HKDF expansion function (which produces the actual derived key).
-     *
-     * <p>IMPORTANT: The use or edit of this method requires a security review.
-     *
-     * @see #hkdfSha256Expand(byte[], byte[])
-     * @return HMAC-SHA256(salt, inputKeyMaterial) (salt is the "key" for the HMAC)
-     * @throws InvalidKeyException If the salt can not be used as a valid key.
-     */
-    private static byte[] hkdfSha256Extract(byte[] inputKeyMaterial, byte[] salt)
-            throws InvalidKeyException {
-        // Note that the SecretKey encoding format is defined to be RAW, so the encoded form should
-        // be consistent across implementations.
-        Mac sha256;
-        try {
-            sha256 = Mac.getInstance(HmacSHA256);
-        } catch (NoSuchAlgorithmException e) {
-            // This can not happen - HmacSHA256 is supported by the platform.
-            throw new AssertionError(e);
-        }
-        sha256.init(new SecretKeySpec(salt, AES));
-
-        return sha256.doFinal(inputKeyMaterial);
-    }
-
-    /**
-     * Special case of HKDF (RFC 5869) expansion function, using the SHA-256 hash function and
-     * allowing for a maximum output length of 256 bits.
-     *
-     * <p>IMPORTANT: The use or edit of this method requires a security review.
-     *
-     * @param pseudoRandomKey Generated by {@link #hkdfSha256Extract(byte[], byte[])}.
-     * @param info Arbitrary information the derived key should be bound to.
-     * @return Raw derived key bytes = HMAC-SHA256(pseudoRandomKey, info | 0x01).
-     * @throws InvalidKeyException If the salt can not be used as a valid key.
-     */
-    private static byte[] hkdfSha256Expand(byte[] pseudoRandomKey, byte[] info)
-            throws InvalidKeyException {
-        // Note that RFC 5869 computes number of blocks N = ceil(hash length / output length), but
-        // here we only deal with a 256 bit hash up to a 256 bit output, yielding N=1.
-        Mac sha256;
-        try {
-            sha256 = Mac.getInstance(HmacSHA256);
-        } catch (NoSuchAlgorithmException e) {
-            // This can not happen - HmacSHA256 is supported by the platform.
-            throw new AssertionError(e);
-        }
-        sha256.init(new SecretKeySpec(pseudoRandomKey, AES));
-
-        sha256.update(info);
-        sha256.update(CONSTANT_01);
-        return sha256.doFinal();
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/cdc/IsChunkBreakpoint.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/cdc/IsChunkBreakpoint.java
deleted file mode 100644
index e867e7c..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/cdc/IsChunkBreakpoint.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.chunking.cdc;
-
-import static com.android.internal.util.Preconditions.checkArgument;
-
-import com.android.server.backup.encryption.chunking.cdc.ContentDefinedChunker.BreakpointPredicate;
-
-/**
- * Function to determine whether a 64-bit fingerprint ought to be a chunk breakpoint.
- *
- * <p>This works by checking whether there are at least n leading zeros in the fingerprint. n is
- * calculated to on average cause a breakpoint after a given number of trials (provided in the
- * constructor). This allows us to choose a number of trials that gives a desired average chunk
- * size. This works because the fingerprint is pseudo-randomly distributed.
- */
-public class IsChunkBreakpoint implements BreakpointPredicate {
-    private final int mLeadingZeros;
-    private final long mBitmask;
-
-    /**
-     * A new instance that causes a breakpoint after a given number of trials on average.
-     *
-     * @param averageNumberOfTrialsUntilBreakpoint The number of trials after which on average to
-     *     create a new chunk. If this is not a power of 2, some precision is sacrificed (i.e., on
-     *     average, breaks will actually happen after the nearest power of 2 to the average number
-     *     of trials passed in).
-     */
-    public IsChunkBreakpoint(long averageNumberOfTrialsUntilBreakpoint) {
-        checkArgument(
-                averageNumberOfTrialsUntilBreakpoint >= 0,
-                "Average number of trials must be non-negative");
-
-        // Want n leading zeros after t trials.
-        // P(leading zeros = n) = 1/2^n
-        // Expected num trials to get n leading zeros = 1/2^-n
-        // t = 1/2^-n
-        // n = log2(t)
-        mLeadingZeros = (int) Math.round(log2(averageNumberOfTrialsUntilBreakpoint));
-        mBitmask = ~(~0L >>> mLeadingZeros);
-    }
-
-    /**
-     * Returns {@code true} if {@code fingerprint} indicates that there should be a chunk
-     * breakpoint.
-     */
-    @Override
-    public boolean isBreakpoint(long fingerprint) {
-        return (fingerprint & mBitmask) == 0;
-    }
-
-    /** Returns the number of leading zeros in the fingerprint that causes a breakpoint. */
-    public int getLeadingZeros() {
-        return mLeadingZeros;
-    }
-
-    /**
-     * Calculates log base 2 of x. Not the most efficient possible implementation, but it's simple,
-     * obviously correct, and is only invoked on object construction.
-     */
-    private static double log2(double x) {
-        return Math.log(x) / Math.log(2);
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/cdc/RabinFingerprint64.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/cdc/RabinFingerprint64.java
deleted file mode 100644
index 1e14ffa..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/chunking/cdc/RabinFingerprint64.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.chunking.cdc;
-
-/** Helper to calculate a 64-bit Rabin fingerprint over a 31-byte window. */
-public class RabinFingerprint64 {
-    private static final long DEFAULT_IRREDUCIBLE_POLYNOMIAL_64 = 0x000000000000001BL;
-    private static final int POLYNOMIAL_DEGREE = 64;
-    private static final int SLIDING_WINDOW_SIZE_BYTES = 31;
-
-    private final long mPoly64;
-    // Auxiliary tables to speed up the computation of Rabin fingerprints.
-    private final long[] mTableFP64 = new long[256];
-    private final long[] mTableOutByte = new long[256];
-
-    /**
-     * Constructs a new instance over the given irreducible 64-degree polynomial. It is up to the
-     * caller to determine that the polynomial is irreducible. If it is not the fingerprinting will
-     * not behave as expected.
-     *
-     * @param poly64 The polynomial.
-     */
-    public RabinFingerprint64(long poly64) {
-        mPoly64 = poly64;
-    }
-
-    /** Constructs a new instance using {@code x^64 + x^4 + x + 1} as the irreducible polynomial. */
-    public RabinFingerprint64() {
-        this(DEFAULT_IRREDUCIBLE_POLYNOMIAL_64);
-        computeFingerprintTables64();
-        computeFingerprintTables64Windowed();
-    }
-
-    /**
-     * Computes the fingerprint for the new sliding window given the fingerprint of the previous
-     * sliding window, the byte sliding in, and the byte sliding out.
-     *
-     * @param inChar The new char coming into the sliding window.
-     * @param outChar The left most char sliding out of the window.
-     * @param fingerPrint Fingerprint for previous window.
-     * @return New fingerprint for the new sliding window.
-     */
-    public long computeFingerprint64(byte inChar, byte outChar, long fingerPrint) {
-        return (fingerPrint << 8)
-                ^ (inChar & 0xFF)
-                ^ mTableFP64[(int) (fingerPrint >>> 56)]
-                ^ mTableOutByte[outChar & 0xFF];
-    }
-
-    /** Compute auxiliary tables to speed up the fingerprint computation. */
-    private void computeFingerprintTables64() {
-        long[] degreesRes64 = new long[POLYNOMIAL_DEGREE];
-        degreesRes64[0] = mPoly64;
-        for (int i = 1; i < POLYNOMIAL_DEGREE; i++) {
-            if ((degreesRes64[i - 1] & (1L << 63)) == 0) {
-                degreesRes64[i] = degreesRes64[i - 1] << 1;
-            } else {
-                degreesRes64[i] = (degreesRes64[i - 1] << 1) ^ mPoly64;
-            }
-        }
-        for (int i = 0; i < 256; i++) {
-            int currIndex = i;
-            for (int j = 0; (currIndex > 0) && (j < 8); j++) {
-                if ((currIndex & 0x1) == 1) {
-                    mTableFP64[i] ^= degreesRes64[j];
-                }
-                currIndex >>>= 1;
-            }
-        }
-    }
-
-    /**
-     * Compute auxiliary table {@code mTableOutByte} to facilitate the computing of fingerprints for
-     * sliding windows. This table is to take care of the effect on the fingerprint when the
-     * leftmost byte in the window slides out.
-     */
-    private void computeFingerprintTables64Windowed() {
-        // Auxiliary array degsRes64[8] defined by: <code>degsRes64[i] = x^(8 *
-        // SLIDING_WINDOW_SIZE_BYTES + i) mod this.mPoly64.</code>
-        long[] degsRes64 = new long[8];
-        degsRes64[0] = mPoly64;
-        for (int i = 65; i < 8 * (SLIDING_WINDOW_SIZE_BYTES + 1); i++) {
-            if ((degsRes64[(i - 1) % 8] & (1L << 63)) == 0) {
-                degsRes64[i % 8] = degsRes64[(i - 1) % 8] << 1;
-            } else {
-                degsRes64[i % 8] = (degsRes64[(i - 1) % 8] << 1) ^ mPoly64;
-            }
-        }
-        for (int i = 0; i < 256; i++) {
-            int currIndex = i;
-            for (int j = 0; (currIndex > 0) && (j < 8); j++) {
-                if ((currIndex & 0x1) == 1) {
-                    mTableOutByte[i] ^= degsRes64[j];
-                }
-                currIndex >>>= 1;
-            }
-        }
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/client/CryptoBackupServer.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/client/CryptoBackupServer.java
deleted file mode 100644
index d7f7dc7..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/client/CryptoBackupServer.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.client;
-
-import com.android.server.backup.encryption.protos.nano.WrappedKeyProto;
-
-import java.util.Map;
-
-/**
- * Contains methods for communicating with the parts of the backup server relevant to encryption.
- */
-public interface CryptoBackupServer {
-    /**
-     * Uploads an incremental backup to the server.
-     *
-     * <p>Handles setting up and tearing down the connection.
-     *
-     * @param packageName the package to associate the data with
-     * @param oldDocId the id of the previous backup doc in Drive
-     * @param diffScript containing the actual backup data
-     * @param tertiaryKey the wrapped key used to encrypt this backup
-     * @return the id of the new backup doc in Drive.
-     */
-    String uploadIncrementalBackup(
-            String packageName,
-            String oldDocId,
-            byte[] diffScript,
-            WrappedKeyProto.WrappedKey tertiaryKey);
-
-    /**
-     * Uploads non-incremental backup to the server.
-     *
-     * <p>Handles setting up and tearing down the connection.
-     *
-     * @param packageName the package to associate the data with
-     * @param data the actual backup data
-     * @param tertiaryKey the wrapped key used to encrypt this backup
-     * @return the id of the new backup doc in Drive.
-     */
-    String uploadNonIncrementalBackup(
-            String packageName, byte[] data, WrappedKeyProto.WrappedKey tertiaryKey);
-
-    /**
-     * Sets the alias of the active secondary key. This is the alias used to refer to the key in the
-     * {@link java.security.KeyStore}. It is also used to key storage for tertiary keys on the
-     * backup server. Also has to upload all existing tertiary keys, wrapped with the new key.
-     *
-     * @param keyAlias The ID of the secondary key.
-     * @param tertiaryKeys The tertiary keys, wrapped with the new secondary key.
-     */
-    void setActiveSecondaryKeyAlias(
-            String keyAlias, Map<String, WrappedKeyProto.WrappedKey> tertiaryKeys);
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/client/UnexpectedActiveSecondaryOnServerException.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/client/UnexpectedActiveSecondaryOnServerException.java
deleted file mode 100644
index 9e31385..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/client/UnexpectedActiveSecondaryOnServerException.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.client;
-
-/**
- * Error thrown when the user attempts to retrieve a key set from the server, but is asking for keys
- * from an inactive secondary.
- *
- * <p>Although we could just return old keys, there is no good reason to do this. It almost
- * certainly indicates a logic error on the client.
- */
-public class UnexpectedActiveSecondaryOnServerException extends Exception {
-    public UnexpectedActiveSecondaryOnServerException(String message) {
-        super(message);
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/KeyWrapUtils.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/KeyWrapUtils.java
deleted file mode 100644
index a043c1f..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/KeyWrapUtils.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.keys;
-
-import com.android.server.backup.encryption.protos.nano.WrappedKeyProto;
-
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.util.Locale;
-
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.SecretKey;
-import javax.crypto.spec.GCMParameterSpec;
-
-/** Utility functions for wrapping and unwrapping tertiary keys. */
-public class KeyWrapUtils {
-    private static final String AES_GCM_MODE = "AES/GCM/NoPadding";
-    private static final int GCM_TAG_LENGTH_BYTES = 16;
-    private static final int BITS_PER_BYTE = 8;
-    private static final int GCM_TAG_LENGTH_BITS = GCM_TAG_LENGTH_BYTES * BITS_PER_BYTE;
-    private static final String KEY_ALGORITHM = "AES";
-
-    /**
-     * Uses the secondary key to unwrap the wrapped tertiary key.
-     *
-     * @param secondaryKey The secondary key used to wrap the tertiary key.
-     * @param wrappedKey The wrapped tertiary key.
-     * @return The unwrapped tertiary key.
-     * @throws InvalidKeyException if the provided secondary key cannot unwrap the tertiary key.
-     */
-    public static SecretKey unwrap(SecretKey secondaryKey, WrappedKeyProto.WrappedKey wrappedKey)
-            throws InvalidKeyException, NoSuchAlgorithmException,
-                    InvalidAlgorithmParameterException, NoSuchPaddingException {
-        if (wrappedKey.wrapAlgorithm != WrappedKeyProto.WrappedKey.AES_256_GCM) {
-            throw new InvalidKeyException(
-                    String.format(
-                            Locale.US,
-                            "Could not unwrap key wrapped with %s algorithm",
-                            wrappedKey.wrapAlgorithm));
-        }
-
-        if (wrappedKey.metadata == null) {
-            throw new InvalidKeyException("Metadata missing from wrapped tertiary key.");
-        }
-
-        if (wrappedKey.metadata.type != WrappedKeyProto.KeyMetadata.AES_256_GCM) {
-            throw new InvalidKeyException(
-                    String.format(
-                            Locale.US,
-                            "Wrapped key was unexpected %s algorithm. Only support"
-                                + " AES/GCM/NoPadding.",
-                            wrappedKey.metadata.type));
-        }
-
-        Cipher cipher = getCipher();
-
-        cipher.init(
-                Cipher.UNWRAP_MODE,
-                secondaryKey,
-                new GCMParameterSpec(GCM_TAG_LENGTH_BITS, wrappedKey.nonce));
-
-        return (SecretKey) cipher.unwrap(wrappedKey.key, KEY_ALGORITHM, Cipher.SECRET_KEY);
-    }
-
-    /**
-     * Wraps the tertiary key with the secondary key.
-     *
-     * @param secondaryKey The secondary key to use for wrapping.
-     * @param tertiaryKey The key to wrap.
-     * @return The wrapped key.
-     * @throws InvalidKeyException if the key is not good for wrapping.
-     * @throws IllegalBlockSizeException if there is an issue wrapping.
-     */
-    public static WrappedKeyProto.WrappedKey wrap(SecretKey secondaryKey, SecretKey tertiaryKey)
-            throws InvalidKeyException, IllegalBlockSizeException, NoSuchAlgorithmException,
-                    NoSuchPaddingException {
-        Cipher cipher = getCipher();
-        cipher.init(Cipher.WRAP_MODE, secondaryKey);
-
-        WrappedKeyProto.WrappedKey wrappedKey = new WrappedKeyProto.WrappedKey();
-        wrappedKey.key = cipher.wrap(tertiaryKey);
-        wrappedKey.nonce = cipher.getIV();
-        wrappedKey.wrapAlgorithm = WrappedKeyProto.WrappedKey.AES_256_GCM;
-        wrappedKey.metadata = new WrappedKeyProto.KeyMetadata();
-        wrappedKey.metadata.type = WrappedKeyProto.KeyMetadata.AES_256_GCM;
-        return wrappedKey;
-    }
-
-    /**
-     * Rewraps a tertiary key with a new secondary key.
-     *
-     * @param oldSecondaryKey The old secondary key, used to unwrap the tertiary key.
-     * @param newSecondaryKey The new secondary key, used to rewrap the tertiary key.
-     * @param tertiaryKey The tertiary key, wrapped by {@code oldSecondaryKey}.
-     * @return The tertiary key, wrapped by {@code newSecondaryKey}.
-     * @throws InvalidKeyException if the key is not good for wrapping or unwrapping.
-     * @throws IllegalBlockSizeException if there is an issue wrapping.
-     */
-    public static WrappedKeyProto.WrappedKey rewrap(
-            SecretKey oldSecondaryKey,
-            SecretKey newSecondaryKey,
-            WrappedKeyProto.WrappedKey tertiaryKey)
-            throws InvalidKeyException, IllegalBlockSizeException,
-                    InvalidAlgorithmParameterException, NoSuchAlgorithmException,
-                    NoSuchPaddingException {
-        return wrap(newSecondaryKey, unwrap(oldSecondaryKey, tertiaryKey));
-    }
-
-    private static Cipher getCipher() throws NoSuchPaddingException, NoSuchAlgorithmException {
-        return Cipher.getInstance(AES_GCM_MODE);
-    }
-
-    // Statics only
-    private KeyWrapUtils() {}
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKey.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKey.java
deleted file mode 100644
index 436c6de8..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKey.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.keys;
-
-import android.annotation.IntDef;
-import android.content.Context;
-import android.security.keystore.recovery.InternalRecoveryServiceException;
-import android.security.keystore.recovery.RecoveryController;
-import android.util.Slog;
-
-import java.util.Objects;
-
-import javax.crypto.SecretKey;
-
-/**
- * Wraps a {@link RecoveryController}'s {@link SecretKey}. These are kept in "AndroidKeyStore" (a
- * provider for {@link java.security.KeyStore} and {@link javax.crypto.KeyGenerator}. They are also
- * synced with the recoverable key store, wrapped by the primary key. This allows them to be
- * recovered on a user's subsequent device through providing their lock screen secret.
- */
-public class RecoverableKeyStoreSecondaryKey {
-    private static final String TAG = "RecoverableKeyStoreSecondaryKey";
-
-    private final String mAlias;
-    private final SecretKey mSecretKey;
-
-    /**
-     * A new instance.
-     *
-     * @param alias The alias. It is keyed with this in AndroidKeyStore and the recoverable key
-     *     store.
-     * @param secretKey The key.
-     */
-    public RecoverableKeyStoreSecondaryKey(String alias, SecretKey secretKey) {
-        mAlias = Objects.requireNonNull(alias);
-        mSecretKey = Objects.requireNonNull(secretKey);
-    }
-
-    /**
-     * The ID, as stored in the recoverable {@link java.security.KeyStore}, and as used to identify
-     * wrapped tertiary keys on the backup server.
-     */
-    public String getAlias() {
-        return mAlias;
-    }
-
-    /** The secret key, to be used to wrap tertiary keys. */
-    public SecretKey getSecretKey() {
-        return mSecretKey;
-    }
-
-    /**
-     * The status of the key. i.e., whether it's been synced to remote trusted hardware.
-     *
-     * @param context The application context.
-     * @return One of {@link Status#SYNCED}, {@link Status#NOT_SYNCED} or {@link Status#DESTROYED}.
-     */
-    public @Status int getStatus(Context context) {
-        try {
-            return getStatusInternal(context);
-        } catch (InternalRecoveryServiceException e) {
-            Slog.wtf(TAG, "Internal error getting recovery status", e);
-            // Return NOT_SYNCED by default, as we do not want the backups to fail or to repeatedly
-            // attempt to reinitialize.
-            return Status.NOT_SYNCED;
-        }
-    }
-
-    private @Status int getStatusInternal(Context context) throws InternalRecoveryServiceException {
-        int status = RecoveryController.getInstance(context).getRecoveryStatus(mAlias);
-        switch (status) {
-            case RecoveryController.RECOVERY_STATUS_PERMANENT_FAILURE:
-                return Status.DESTROYED;
-            case RecoveryController.RECOVERY_STATUS_SYNCED:
-                return Status.SYNCED;
-            case RecoveryController.RECOVERY_STATUS_SYNC_IN_PROGRESS:
-                return Status.NOT_SYNCED;
-            default:
-                // Throw an exception if we encounter a status that doesn't match any of the above.
-                throw new InternalRecoveryServiceException(
-                        "Unexpected status from getRecoveryStatus: " + status);
-        }
-    }
-
-    /** Status of a key in the recoverable key store. */
-    @IntDef({Status.NOT_SYNCED, Status.SYNCED, Status.DESTROYED})
-    public @interface Status {
-        /**
-         * The key has not yet been synced to remote trusted hardware. This may be because the user
-         * has not yet unlocked their device.
-         */
-        int NOT_SYNCED = 1;
-
-        /**
-         * The key has been synced with remote trusted hardware. It should now be recoverable on
-         * another device.
-         */
-        int SYNCED = 2;
-
-        /** The key has been lost forever. This can occur if the user disables their lock screen. */
-        int DESTROYED = 3;
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyManager.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyManager.java
deleted file mode 100644
index c89076b..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyManager.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.keys;
-
-import android.content.Context;
-import android.security.keystore.recovery.InternalRecoveryServiceException;
-import android.security.keystore.recovery.LockScreenRequiredException;
-import android.security.keystore.recovery.RecoveryController;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import libcore.util.HexEncoding;
-
-import java.security.SecureRandom;
-import java.security.UnrecoverableKeyException;
-import java.util.Optional;
-
-import javax.crypto.SecretKey;
-
-/**
- * Manages generating, deleting, and retrieving secondary keys through {@link RecoveryController}.
- *
- * <p>The recoverable key store will be synced remotely via the {@link RecoveryController}, allowing
- * recovery of keys on other devices owned by the user.
- */
-public class RecoverableKeyStoreSecondaryKeyManager {
-    private static final String BACKUP_KEY_ALIAS_PREFIX =
-            "com.android.server.backup/recoverablekeystore/";
-    private static final int BACKUP_KEY_SUFFIX_LENGTH_BITS = 128;
-    private static final int BITS_PER_BYTE = 8;
-
-    /** A new instance. */
-    public static RecoverableKeyStoreSecondaryKeyManager getInstance(Context context) {
-        return new RecoverableKeyStoreSecondaryKeyManager(
-                RecoveryController.getInstance(context), new SecureRandom());
-    }
-
-    private final RecoveryController mRecoveryController;
-    private final SecureRandom mSecureRandom;
-
-    @VisibleForTesting
-    public RecoverableKeyStoreSecondaryKeyManager(
-            RecoveryController recoveryController, SecureRandom secureRandom) {
-        mRecoveryController = recoveryController;
-        mSecureRandom = secureRandom;
-    }
-
-    /**
-     * Generates a new recoverable key using the {@link RecoveryController}.
-     *
-     * @throws InternalRecoveryServiceException if an unexpected error occurred generating the key.
-     * @throws LockScreenRequiredException if the user does not have a lock screen. A lock screen is
-     *     required to generate a recoverable key.
-     */
-    public RecoverableKeyStoreSecondaryKey generate()
-            throws InternalRecoveryServiceException, LockScreenRequiredException,
-                    UnrecoverableKeyException {
-        String alias = generateId();
-        mRecoveryController.generateKey(alias);
-        SecretKey key = (SecretKey) mRecoveryController.getKey(alias);
-        if (key == null) {
-            throw new InternalRecoveryServiceException(
-                    String.format(
-                            "Generated key %s but could not get it back immediately afterwards.",
-                            alias));
-        }
-        return new RecoverableKeyStoreSecondaryKey(alias, key);
-    }
-
-    /**
-     * Removes the secondary key. This means the key will no longer be recoverable.
-     *
-     * @param alias The alias of the key.
-     * @throws InternalRecoveryServiceException if there was a {@link RecoveryController} error.
-     */
-    public void remove(String alias) throws InternalRecoveryServiceException {
-        mRecoveryController.removeKey(alias);
-    }
-
-    /**
-     * Returns the {@link RecoverableKeyStoreSecondaryKey} with {@code alias} if it is in the {@link
-     * RecoveryController}. Otherwise, {@link Optional#empty()}.
-     */
-    public Optional<RecoverableKeyStoreSecondaryKey> get(String alias)
-            throws InternalRecoveryServiceException, UnrecoverableKeyException {
-        SecretKey secretKey = (SecretKey) mRecoveryController.getKey(alias);
-        return Optional.ofNullable(secretKey)
-                .map(key -> new RecoverableKeyStoreSecondaryKey(alias, key));
-    }
-
-    /**
-     * Generates a new key alias. This has more entropy than a UUID - it can be considered
-     * universally unique.
-     */
-    private String generateId() {
-        byte[] id = new byte[BACKUP_KEY_SUFFIX_LENGTH_BITS / BITS_PER_BYTE];
-        mSecureRandom.nextBytes(id);
-        return BACKUP_KEY_ALIAS_PREFIX + HexEncoding.encodeToString(id);
-    }
-
-    /** Constructs a {@link RecoverableKeyStoreSecondaryKeyManager}. */
-    public interface RecoverableKeyStoreSecondaryKeyManagerProvider {
-        /** Returns a newly constructed {@link RecoverableKeyStoreSecondaryKeyManager}. */
-        RecoverableKeyStoreSecondaryKeyManager get();
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/RestoreKeyFetcher.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/RestoreKeyFetcher.java
deleted file mode 100644
index 6fb958b..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/RestoreKeyFetcher.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.keys;
-
-import android.security.keystore.recovery.InternalRecoveryServiceException;
-
-import com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKeyManager.RecoverableKeyStoreSecondaryKeyManagerProvider;
-import com.android.server.backup.encryption.protos.nano.WrappedKeyProto;
-
-import java.security.InvalidAlgorithmParameterException;
-import java.security.KeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.UnrecoverableKeyException;
-import java.util.Optional;
-
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.SecretKey;
-
-/** Fetches the secondary key and uses it to unwrap the tertiary key during restore. */
-public class RestoreKeyFetcher {
-
-    /**
-     * Retrieves the secondary key with the given alias and uses it to unwrap the given wrapped
-     * tertiary key.
-     *
-     * @param secondaryKeyManagerProvider Provider which creates {@link
-     *     RecoverableKeyStoreSecondaryKeyManager}
-     * @param secondaryKeyAlias Alias of the secondary key used to wrap the tertiary key
-     * @param wrappedTertiaryKey Tertiary key wrapped with the secondary key above
-     * @return The unwrapped tertiary key
-     */
-    public static SecretKey unwrapTertiaryKey(
-            RecoverableKeyStoreSecondaryKeyManagerProvider secondaryKeyManagerProvider,
-            String secondaryKeyAlias,
-            WrappedKeyProto.WrappedKey wrappedTertiaryKey)
-            throws KeyException, InvalidAlgorithmParameterException, NoSuchAlgorithmException,
-                    NoSuchPaddingException {
-        Optional<RecoverableKeyStoreSecondaryKey> secondaryKey =
-                getSecondaryKey(secondaryKeyManagerProvider, secondaryKeyAlias);
-        if (!secondaryKey.isPresent()) {
-            throw new KeyException("No key:" + secondaryKeyAlias);
-        }
-
-        return KeyWrapUtils.unwrap(secondaryKey.get().getSecretKey(), wrappedTertiaryKey);
-    }
-
-    private static Optional<RecoverableKeyStoreSecondaryKey> getSecondaryKey(
-            RecoverableKeyStoreSecondaryKeyManagerProvider secondaryKeyManagerProvider,
-            String secondaryKeyAlias)
-            throws KeyException {
-        try {
-            return secondaryKeyManagerProvider.get().get(secondaryKeyAlias);
-        } catch (InternalRecoveryServiceException | UnrecoverableKeyException e) {
-            throw new KeyException("Could not retrieve key:" + secondaryKeyAlias, e);
-        }
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/SecondaryKeyRotationScheduler.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/SecondaryKeyRotationScheduler.java
deleted file mode 100644
index 91b57cf..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/SecondaryKeyRotationScheduler.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.keys;
-
-import android.content.Context;
-import android.util.Slog;
-
-import com.android.server.backup.encryption.CryptoSettings;
-import com.android.server.backup.encryption.tasks.StartSecondaryKeyRotationTask;
-
-import java.io.File;
-import java.time.Clock;
-import java.util.Optional;
-
-/**
- * Helps schedule rotations of secondary keys.
- *
- * <p>TODO(b/72028016) Replace with a job.
- */
-public class SecondaryKeyRotationScheduler {
-
-    private static final String TAG = "SecondaryKeyRotationScheduler";
-    private static final String SENTINEL_FILE_PATH = "force_secondary_key_rotation";
-
-    private final Context mContext;
-    private final RecoverableKeyStoreSecondaryKeyManager mSecondaryKeyManager;
-    private final CryptoSettings mCryptoSettings;
-    private final Clock mClock;
-
-    public SecondaryKeyRotationScheduler(
-            Context context,
-            RecoverableKeyStoreSecondaryKeyManager secondaryKeyManager,
-            CryptoSettings cryptoSettings,
-            Clock clock) {
-        mContext = context;
-        mCryptoSettings = cryptoSettings;
-        mClock = clock;
-        mSecondaryKeyManager = secondaryKeyManager;
-    }
-
-    /**
-     * Returns {@code true} if a sentinel file for forcing secondary key rotation is present. This
-     * is only for testing purposes.
-     */
-    private boolean isForceRotationTestSentinelPresent() {
-        File file = new File(mContext.getFilesDir(), SENTINEL_FILE_PATH);
-        if (file.exists()) {
-            file.delete();
-            return true;
-        }
-        return false;
-    }
-
-    /** Start the key rotation task if it's time to do so */
-    public void startRotationIfScheduled() {
-        if (isForceRotationTestSentinelPresent()) {
-            Slog.i(TAG, "Found force flag for secondary rotation. Starting now.");
-            startRotation();
-            return;
-        }
-
-        Optional<Long> maybeLastRotated = mCryptoSettings.getSecondaryLastRotated();
-        if (!maybeLastRotated.isPresent()) {
-            Slog.v(TAG, "No previous rotation, scheduling from now.");
-            scheduleRotationFromNow();
-            return;
-        }
-
-        long lastRotated = maybeLastRotated.get();
-        long now = mClock.millis();
-
-        if (lastRotated > now) {
-            Slog.i(TAG, "Last rotation was in the future. Clock must have changed. Rotate now.");
-            startRotation();
-            return;
-        }
-
-        long millisSinceLastRotation = now - lastRotated;
-        long rotationInterval = mCryptoSettings.backupSecondaryKeyRotationIntervalMs();
-        if (millisSinceLastRotation >= rotationInterval) {
-            Slog.i(
-                    TAG,
-                    "Last rotation was more than "
-                            + rotationInterval
-                            + "ms ("
-                            + millisSinceLastRotation
-                            + "ms) in the past. Rotate now.");
-            startRotation();
-        }
-
-        Slog.v(TAG, "No rotation required, last " + lastRotated + ".");
-    }
-
-    private void startRotation() {
-        scheduleRotationFromNow();
-        new StartSecondaryKeyRotationTask(mCryptoSettings, mSecondaryKeyManager).run();
-    }
-
-    private void scheduleRotationFromNow() {
-        mCryptoSettings.setSecondaryLastRotated(mClock.millis());
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/TertiaryKeyGenerator.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/TertiaryKeyGenerator.java
deleted file mode 100644
index a425c72..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/TertiaryKeyGenerator.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.keys;
-
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-
-import javax.crypto.KeyGenerator;
-import javax.crypto.SecretKey;
-
-/** 256-bit AES key generator. Each app should have its own separate AES key. */
-public class TertiaryKeyGenerator {
-    private static final int KEY_SIZE_BITS = 256;
-    private static final String KEY_ALGORITHM = "AES";
-
-    private final KeyGenerator mKeyGenerator;
-
-    /** New instance generating keys using {@code secureRandom}. */
-    public TertiaryKeyGenerator(SecureRandom secureRandom) {
-        try {
-            mKeyGenerator = KeyGenerator.getInstance(KEY_ALGORITHM);
-            mKeyGenerator.init(KEY_SIZE_BITS, secureRandom);
-        } catch (NoSuchAlgorithmException e) {
-            throw new AssertionError(
-                    "Impossible condition: JCE thinks it does not support AES.", e);
-        }
-    }
-
-    /** Generates a new random AES key. */
-    public SecretKey generate() {
-        return mKeyGenerator.generateKey();
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/TertiaryKeyManager.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/TertiaryKeyManager.java
deleted file mode 100644
index a783579..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/TertiaryKeyManager.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.keys;
-
-import android.annotation.Nullable;
-import android.content.Context;
-import android.util.Slog;
-
-import com.android.server.backup.encryption.protos.nano.WrappedKeyProto;
-
-import java.io.IOException;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.util.Optional;
-
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.SecretKey;
-
-/**
- * Gets the correct tertiary key to use during a backup, rotating it if required.
- *
- * <p>Calling any method on this class will count a incremental backup against the app, and the key
- * will be rotated if required.
- */
-public class TertiaryKeyManager {
-
-    private static final String TAG = "TertiaryKeyMgr";
-
-    private final TertiaryKeyStore mKeyStore;
-    private final TertiaryKeyGenerator mKeyGenerator;
-    private final TertiaryKeyRotationScheduler mTertiaryKeyRotationScheduler;
-    private final RecoverableKeyStoreSecondaryKey mSecondaryKey;
-    private final String mPackageName;
-
-    private boolean mKeyRotated;
-    @Nullable private SecretKey mTertiaryKey;
-
-    public TertiaryKeyManager(
-            Context context,
-            SecureRandom secureRandom,
-            TertiaryKeyRotationScheduler tertiaryKeyRotationScheduler,
-            RecoverableKeyStoreSecondaryKey secondaryKey,
-            String packageName) {
-        mSecondaryKey = secondaryKey;
-        mPackageName = packageName;
-        mKeyGenerator = new TertiaryKeyGenerator(secureRandom);
-        mKeyStore = TertiaryKeyStore.newInstance(context, secondaryKey);
-        mTertiaryKeyRotationScheduler = tertiaryKeyRotationScheduler;
-    }
-
-    /**
-     * Returns either the previously used tertiary key, or a new tertiary key if there was no
-     * previous key or it needed to be rotated.
-     */
-    public SecretKey getKey()
-            throws InvalidKeyException, IOException, IllegalBlockSizeException,
-                    NoSuchPaddingException, NoSuchAlgorithmException,
-                    InvalidAlgorithmParameterException {
-        init();
-        return mTertiaryKey;
-    }
-
-    /** Returns the key given by {@link #getKey()} wrapped by the secondary key. */
-    public WrappedKeyProto.WrappedKey getWrappedKey()
-            throws InvalidKeyException, IOException, IllegalBlockSizeException,
-                    NoSuchPaddingException, NoSuchAlgorithmException,
-                    InvalidAlgorithmParameterException {
-        init();
-        return KeyWrapUtils.wrap(mSecondaryKey.getSecretKey(), mTertiaryKey);
-    }
-
-    /**
-     * Returns {@code true} if a new tertiary key was generated at the start of this session,
-     * otherwise {@code false}.
-     */
-    public boolean wasKeyRotated()
-            throws InvalidKeyException, IllegalBlockSizeException, IOException,
-                    NoSuchPaddingException, NoSuchAlgorithmException,
-                    InvalidAlgorithmParameterException {
-        init();
-        return mKeyRotated;
-    }
-
-    private void init()
-            throws IllegalBlockSizeException, InvalidKeyException, IOException,
-                    NoSuchAlgorithmException, NoSuchPaddingException,
-                    InvalidAlgorithmParameterException {
-        if (mTertiaryKey != null) {
-            return;
-        }
-
-        Optional<SecretKey> key = getExistingKeyIfNotRotated();
-
-        if (!key.isPresent()) {
-            Slog.d(TAG, "Generating new tertiary key for " + mPackageName);
-
-            key = Optional.of(mKeyGenerator.generate());
-            mKeyRotated = true;
-            mTertiaryKeyRotationScheduler.recordKeyRotation(mPackageName);
-            mKeyStore.save(mPackageName, key.get());
-        }
-
-        mTertiaryKey = key.get();
-
-        mTertiaryKeyRotationScheduler.recordBackup(mPackageName);
-    }
-
-    private Optional<SecretKey> getExistingKeyIfNotRotated()
-            throws InvalidKeyException, IOException, InvalidAlgorithmParameterException,
-                    NoSuchAlgorithmException, NoSuchPaddingException {
-        if (mTertiaryKeyRotationScheduler.isKeyRotationDue(mPackageName)) {
-            Slog.i(TAG, "Tertiary key rotation was required for " + mPackageName);
-            return Optional.empty();
-        } else {
-            Slog.i(TAG, "Tertiary key rotation was not required");
-            return mKeyStore.load(mPackageName);
-        }
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/TertiaryKeyRotationScheduler.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/TertiaryKeyRotationScheduler.java
deleted file mode 100644
index f16a68d..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/TertiaryKeyRotationScheduler.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.keys;
-
-import android.content.Context;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-/**
- * Schedules tertiary key rotations in a staggered fashion.
- *
- * <p>Apps are due a key rotation after a certain number of backups. Rotations are then staggerered
- * over a period of time, through restricting the number of rotations allowed in a 24-hour window.
- * This will causes the apps to enter a staggered cycle of regular rotations.
- *
- * <p>Note: the methods in this class are not optimized to be super fast. They make blocking IO to
- * ensure that scheduler information is committed to disk, so that it is available after the user
- * turns their device off and on. This ought to be fine as
- *
- * <ul>
- *   <li>It will be invoked before a backup, so should never be invoked on the UI thread
- *   <li>It will be invoked before a backup, so the vast amount of time is spent on the backup, not
- *       writing tiny amounts of data to disk.
- * </ul>
- */
-public class TertiaryKeyRotationScheduler {
-    /** Default number of key rotations allowed within 24 hours. */
-    private static final int KEY_ROTATION_LIMIT = 2;
-
-    /** A new instance, using {@code context} to determine where to store state. */
-    public static TertiaryKeyRotationScheduler getInstance(Context context) {
-        TertiaryKeyRotationWindowedCount windowedCount =
-                TertiaryKeyRotationWindowedCount.getInstance(context);
-        TertiaryKeyRotationTracker tracker = TertiaryKeyRotationTracker.getInstance(context);
-        return new TertiaryKeyRotationScheduler(tracker, windowedCount, KEY_ROTATION_LIMIT);
-    }
-
-    private final TertiaryKeyRotationTracker mTracker;
-    private final TertiaryKeyRotationWindowedCount mWindowedCount;
-    private final int mMaximumRotationsPerWindow;
-
-    /**
-     * A new instance.
-     *
-     * @param tracker Tracks how many times each application has backed up.
-     * @param windowedCount Tracks how many rotations have happened in the last 24 hours.
-     * @param maximumRotationsPerWindow The maximum number of key rotations allowed per 24 hours.
-     */
-    @VisibleForTesting
-    TertiaryKeyRotationScheduler(
-            TertiaryKeyRotationTracker tracker,
-            TertiaryKeyRotationWindowedCount windowedCount,
-            int maximumRotationsPerWindow) {
-        mTracker = tracker;
-        mWindowedCount = windowedCount;
-        mMaximumRotationsPerWindow = maximumRotationsPerWindow;
-    }
-
-    /**
-     * Returns {@code true} if the app with {@code packageName} is due having its key rotated.
-     *
-     * <p>This ought to be queried before backing up an app, to determine whether to do an
-     * incremental backup or a full backup. (A full backup forces key rotation.)
-     */
-    public boolean isKeyRotationDue(String packageName) {
-        if (mWindowedCount.getCount() >= mMaximumRotationsPerWindow) {
-            return false;
-        }
-        return mTracker.isKeyRotationDue(packageName);
-    }
-
-    /**
-     * Records that a backup happened for the app with the given {@code packageName}.
-     *
-     * <p>Each backup brings the app closer to the point at which a key rotation is due.
-     */
-    public void recordBackup(String packageName) {
-        mTracker.recordBackup(packageName);
-    }
-
-    /**
-     * Records a key rotation happened for the app with the given {@code packageName}.
-     *
-     * <p>This resets the countdown until the next key rotation is due.
-     */
-    public void recordKeyRotation(String packageName) {
-        mTracker.resetCountdown(packageName);
-        mWindowedCount.record();
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/TertiaryKeyRotationTracker.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/TertiaryKeyRotationTracker.java
deleted file mode 100644
index 1a281e7..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/TertiaryKeyRotationTracker.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.keys;
-
-import static com.android.internal.util.Preconditions.checkArgument;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.util.Slog;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.util.Locale;
-
-/**
- * Tracks when a tertiary key rotation is due.
- *
- * <p>After a certain number of incremental backups, the device schedules a full backup, which will
- * generate a new encryption key, effecting a key rotation. We should do this on a regular basis so
- * that if a key does become compromised it has limited value to the attacker.
- *
- * <p>No additional synchronization of this class is provided. Only one instance should be used at
- * any time. This should be fine as there should be no parallelism in backups.
- */
-public class TertiaryKeyRotationTracker {
-    private static final int MAX_BACKUPS_UNTIL_TERTIARY_KEY_ROTATION = 31;
-    private static final String SHARED_PREFERENCES_NAME = "tertiary_key_rotation_tracker";
-
-    private static final String TAG = "TertiaryKeyRotationTracker";
-    private static final boolean DEBUG = false;
-
-    /**
-     * A new instance, using {@code context} to commit data to disk via {@link SharedPreferences}.
-     */
-    public static TertiaryKeyRotationTracker getInstance(Context context) {
-        return new TertiaryKeyRotationTracker(
-                context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE),
-                MAX_BACKUPS_UNTIL_TERTIARY_KEY_ROTATION);
-    }
-
-    private final SharedPreferences mSharedPreferences;
-    private final int mMaxBackupsTillRotation;
-
-    /**
-     * New instance, storing data in {@code sharedPreferences} and initializing backup countdown to
-     * {@code maxBackupsTillRotation}.
-     */
-    @VisibleForTesting
-    TertiaryKeyRotationTracker(SharedPreferences sharedPreferences, int maxBackupsTillRotation) {
-        checkArgument(
-                maxBackupsTillRotation >= 0,
-                String.format(
-                        Locale.US,
-                        "maxBackupsTillRotation should be non-negative but was %d",
-                        maxBackupsTillRotation));
-        mSharedPreferences = sharedPreferences;
-        mMaxBackupsTillRotation = maxBackupsTillRotation;
-    }
-
-    /**
-     * Returns {@code true} if the given app is due having its key rotated.
-     *
-     * @param packageName The package name of the app.
-     */
-    public boolean isKeyRotationDue(String packageName) {
-        return getBackupsSinceRotation(packageName) >= mMaxBackupsTillRotation;
-    }
-
-    /**
-     * Records that an incremental backup has occurred. Each incremental backup brings the app
-     * closer to the time when its key should be rotated.
-     *
-     * @param packageName The package name of the app for which the backup occurred.
-     */
-    public void recordBackup(String packageName) {
-        int backupsSinceRotation = getBackupsSinceRotation(packageName) + 1;
-        mSharedPreferences.edit().putInt(packageName, backupsSinceRotation).apply();
-        if (DEBUG) {
-            Slog.d(
-                    TAG,
-                    String.format(
-                            Locale.US,
-                            "Incremental backup for %s. %d backups until key rotation.",
-                            packageName,
-                            Math.max(
-                                    0,
-                                    mMaxBackupsTillRotation
-                                            - backupsSinceRotation)));
-        }
-    }
-
-    /**
-     * Resets the rotation delay for the given app. Should be invoked after a key rotation.
-     *
-     * @param packageName Package name of the app whose key has rotated.
-     */
-    public void resetCountdown(String packageName) {
-        mSharedPreferences.edit().putInt(packageName, 0).apply();
-    }
-
-    /** Marks all enrolled packages for key rotation. */
-    public void markAllForRotation() {
-        SharedPreferences.Editor editor = mSharedPreferences.edit();
-        for (String packageName : mSharedPreferences.getAll().keySet()) {
-            editor.putInt(packageName, mMaxBackupsTillRotation);
-        }
-        editor.apply();
-    }
-
-    private int getBackupsSinceRotation(String packageName) {
-        return mSharedPreferences.getInt(packageName, 0);
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/TertiaryKeyRotationWindowedCount.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/TertiaryKeyRotationWindowedCount.java
deleted file mode 100644
index b90343a..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/TertiaryKeyRotationWindowedCount.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.keys;
-
-import android.content.Context;
-import android.util.Slog;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.EOFException;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.time.Clock;
-import java.util.ArrayList;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Tracks (and commits to disk) how many key rotations have happened in the last 24 hours. This
- * allows us to limit (and therefore stagger) the number of key rotations in a given period of time.
- *
- * <p>Note to engineers thinking of replacing the below with fancier algorithms and data structures:
- * we expect the total size of this count at any time to be below however many rotations we allow in
- * the window, which is going to be in single digits. Any changes that mean we write to disk more
- * frequently, that the code is no longer resistant to clock changes, or that the code is more
- * difficult to understand are almost certainly not worthwhile.
- */
-public class TertiaryKeyRotationWindowedCount {
-    private static final String TAG = "TertiaryKeyRotCount";
-
-    private static final int WINDOW_IN_HOURS = 24;
-    private static final String LOG_FILE_NAME = "tertiary_key_rotation_windowed_count";
-
-    private final Clock mClock;
-    private final File mFile;
-    private ArrayList<Long> mEvents;
-
-    /** Returns a new instance, persisting state to the files dir of {@code context}. */
-    public static TertiaryKeyRotationWindowedCount getInstance(Context context) {
-        File logFile = new File(context.getFilesDir(), LOG_FILE_NAME);
-        return new TertiaryKeyRotationWindowedCount(logFile, Clock.systemDefaultZone());
-    }
-
-    /** A new instance, committing state to {@code file}, and reading time from {@code clock}. */
-    @VisibleForTesting
-    TertiaryKeyRotationWindowedCount(File file, Clock clock) {
-        mFile = file;
-        mClock = clock;
-        mEvents = new ArrayList<>();
-        try {
-            loadFromFile();
-        } catch (IOException e) {
-            Slog.e(TAG, "Error reading " + LOG_FILE_NAME, e);
-        }
-    }
-
-    /** Records a key rotation at the current time. */
-    public void record() {
-        mEvents.add(mClock.millis());
-        compact();
-        try {
-            saveToFile();
-        } catch (IOException e) {
-            Slog.e(TAG, "Error saving " + LOG_FILE_NAME, e);
-        }
-    }
-
-    /** Returns the number of key rotation that have been recorded in the window. */
-    public int getCount() {
-        compact();
-        return mEvents.size();
-    }
-
-    private void compact() {
-        long minimumTimestamp = getMinimumTimestamp();
-        long now = mClock.millis();
-        ArrayList<Long> compacted = new ArrayList<>();
-        for (long event : mEvents) {
-            if (event >= minimumTimestamp && event <= now) {
-                compacted.add(event);
-            }
-        }
-        mEvents = compacted;
-    }
-
-    private long getMinimumTimestamp() {
-        return mClock.millis() - TimeUnit.HOURS.toMillis(WINDOW_IN_HOURS) + 1;
-    }
-
-    private void loadFromFile() throws IOException {
-        if (!mFile.exists()) {
-            return;
-        }
-        try (FileInputStream fis = new FileInputStream(mFile);
-                DataInputStream dis = new DataInputStream(fis)) {
-            while (true) {
-                mEvents.add(dis.readLong());
-            }
-        } catch (EOFException eof) {
-            // expected
-        }
-    }
-
-    private void saveToFile() throws IOException {
-        // File size is maximum number of key rotations in window multiplied by 8 bytes, which is
-        // why
-        // we just overwrite it each time. We expect it will always be less than 100 bytes in size.
-        try (FileOutputStream fos = new FileOutputStream(mFile);
-                DataOutputStream dos = new DataOutputStream(fos)) {
-            for (long event : mEvents) {
-                dos.writeLong(event);
-            }
-        }
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/TertiaryKeyStore.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/TertiaryKeyStore.java
deleted file mode 100644
index 01444bf..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/keys/TertiaryKeyStore.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.keys;
-
-import static com.android.internal.util.Preconditions.checkArgument;
-
-import android.content.Context;
-import android.util.ArrayMap;
-
-import com.android.server.backup.encryption.protos.nano.WrappedKeyProto;
-import com.android.server.backup.encryption.storage.BackupEncryptionDb;
-import com.android.server.backup.encryption.storage.TertiaryKey;
-import com.android.server.backup.encryption.storage.TertiaryKeysTable;
-
-import com.google.protobuf.nano.CodedOutputByteBufferNano;
-
-import java.io.IOException;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.util.Map;
-import java.util.Optional;
-
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.SecretKey;
-
-/**
- * Stores backup package keys. Each application package has its own {@link SecretKey}, which is used
- * to encrypt the backup data. These keys are then wrapped by a master backup key, and stored in
- * their wrapped form on disk and on the backup server.
- *
- * <p>For now this code only implements writing to disk. Once the backup server is ready, it will be
- * extended to sync the keys there, also.
- */
-public class TertiaryKeyStore {
-
-    private final RecoverableKeyStoreSecondaryKey mSecondaryKey;
-    private final BackupEncryptionDb mDatabase;
-
-    /**
-     * Creates an instance, using {@code secondaryKey} to wrap tertiary keys, and storing them in
-     * the database.
-     */
-    public static TertiaryKeyStore newInstance(
-            Context context, RecoverableKeyStoreSecondaryKey secondaryKey) {
-        return new TertiaryKeyStore(secondaryKey, BackupEncryptionDb.newInstance(context));
-    }
-
-    private TertiaryKeyStore(
-            RecoverableKeyStoreSecondaryKey secondaryKey, BackupEncryptionDb database) {
-        mSecondaryKey = secondaryKey;
-        mDatabase = database;
-    }
-
-    /**
-     * Saves the given key.
-     *
-     * @param applicationName The package name of the application for which this key will be used to
-     *     encrypt data. e.g., "com.example.app".
-     * @param key The key.
-     * @throws InvalidKeyException if the backup key is not capable of wrapping.
-     * @throws IOException if there is an issue writing to the database.
-     */
-    public void save(String applicationName, SecretKey key)
-            throws IOException, InvalidKeyException, IllegalBlockSizeException,
-                    NoSuchPaddingException, NoSuchAlgorithmException {
-        checkApplicationName(applicationName);
-
-        byte[] keyBytes = getEncodedKey(KeyWrapUtils.wrap(mSecondaryKey.getSecretKey(), key));
-
-        long pk;
-        try {
-            pk =
-                    mDatabase
-                            .getTertiaryKeysTable()
-                            .addKey(
-                                    new TertiaryKey(
-                                            mSecondaryKey.getAlias(), applicationName, keyBytes));
-        } finally {
-            mDatabase.close();
-        }
-
-        if (pk == -1) {
-            throw new IOException("Failed to commit to db");
-        }
-    }
-
-    /**
-     * Tries to load a key for the given application.
-     *
-     * @param applicationName The package name of the application, e.g. "com.example.app".
-     * @return The key if it is exists, {@link Optional#empty()} ()} otherwise.
-     * @throws InvalidKeyException if the backup key is not good for unwrapping.
-     * @throws IOException if there is a problem loading the key from the database.
-     */
-    public Optional<SecretKey> load(String applicationName)
-            throws IOException, InvalidKeyException, InvalidAlgorithmParameterException,
-                    NoSuchAlgorithmException, NoSuchPaddingException {
-        checkApplicationName(applicationName);
-
-        Optional<TertiaryKey> keyFromDb;
-        try {
-            keyFromDb =
-                    mDatabase
-                            .getTertiaryKeysTable()
-                            .getKey(mSecondaryKey.getAlias(), applicationName);
-        } finally {
-            mDatabase.close();
-        }
-
-        if (!keyFromDb.isPresent()) {
-            return Optional.empty();
-        }
-
-        WrappedKeyProto.WrappedKey wrappedKey =
-                WrappedKeyProto.WrappedKey.parseFrom(keyFromDb.get().getWrappedKeyBytes());
-        return Optional.of(KeyWrapUtils.unwrap(mSecondaryKey.getSecretKey(), wrappedKey));
-    }
-
-    /**
-     * Loads keys for all applications.
-     *
-     * @return All of the keys in a map keyed by package name.
-     * @throws IOException if there is an issue loading from the database.
-     * @throws InvalidKeyException if the backup key is not an appropriate key for unwrapping.
-     */
-    public Map<String, SecretKey> getAll()
-            throws IOException, InvalidKeyException, InvalidAlgorithmParameterException,
-                    NoSuchAlgorithmException, NoSuchPaddingException {
-        Map<String, TertiaryKey> tertiaries;
-        try {
-            tertiaries = mDatabase.getTertiaryKeysTable().getAllKeys(mSecondaryKey.getAlias());
-        } finally {
-            mDatabase.close();
-        }
-
-        Map<String, SecretKey> unwrappedKeys = new ArrayMap<>();
-        for (String applicationName : tertiaries.keySet()) {
-            WrappedKeyProto.WrappedKey wrappedKey =
-                    WrappedKeyProto.WrappedKey.parseFrom(
-                            tertiaries.get(applicationName).getWrappedKeyBytes());
-            unwrappedKeys.put(
-                    applicationName, KeyWrapUtils.unwrap(mSecondaryKey.getSecretKey(), wrappedKey));
-        }
-
-        return unwrappedKeys;
-    }
-
-    /**
-     * Adds all wrapped keys to the database.
-     *
-     * @throws IOException if an error occurred adding a wrapped key.
-     */
-    public void putAll(Map<String, WrappedKeyProto.WrappedKey> wrappedKeysByApplicationName)
-            throws IOException {
-        TertiaryKeysTable tertiaryKeysTable = mDatabase.getTertiaryKeysTable();
-        try {
-
-            for (String applicationName : wrappedKeysByApplicationName.keySet()) {
-                byte[] keyBytes = getEncodedKey(wrappedKeysByApplicationName.get(applicationName));
-                long primaryKey =
-                        tertiaryKeysTable.addKey(
-                                new TertiaryKey(
-                                        mSecondaryKey.getAlias(), applicationName, keyBytes));
-
-                if (primaryKey == -1) {
-                    throw new IOException("Failed to commit to db");
-                }
-            }
-
-        } finally {
-            mDatabase.close();
-        }
-    }
-
-    private static void checkApplicationName(String applicationName) {
-        checkArgument(!applicationName.isEmpty(), "applicationName must not be empty string.");
-        checkArgument(!applicationName.contains("/"), "applicationName must not contain slash.");
-    }
-
-    private byte[] getEncodedKey(WrappedKeyProto.WrappedKey key) throws IOException {
-        byte[] buffer = new byte[key.getSerializedSize()];
-        CodedOutputByteBufferNano out = CodedOutputByteBufferNano.newInstance(buffer);
-        key.writeTo(out);
-        return buffer;
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/kv/DecryptedChunkKvOutput.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/kv/DecryptedChunkKvOutput.java
deleted file mode 100644
index 56e1c05..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/kv/DecryptedChunkKvOutput.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.kv;
-
-import static com.android.internal.util.Preconditions.checkState;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.server.backup.encryption.chunk.ChunkHash;
-import com.android.server.backup.encryption.chunking.ChunkHasher;
-import com.android.server.backup.encryption.protos.nano.KeyValuePairProto;
-import com.android.server.backup.encryption.tasks.DecryptedChunkOutput;
-
-import java.io.IOException;
-import java.security.InvalidKeyException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-/**
- * Builds a key value backup set from plaintext chunks. Computes a digest over the sorted SHA-256
- * hashes of the chunks.
- */
-public class DecryptedChunkKvOutput implements DecryptedChunkOutput {
-    @VisibleForTesting static final String DIGEST_ALGORITHM = "SHA-256";
-
-    private final ChunkHasher mChunkHasher;
-    private final List<KeyValuePairProto.KeyValuePair> mUnsortedPairs = new ArrayList<>();
-    private final List<ChunkHash> mUnsortedHashes = new ArrayList<>();
-    private boolean mClosed;
-
-    /** Constructs a new instance which computers the digest using the given hasher. */
-    public DecryptedChunkKvOutput(ChunkHasher chunkHasher) {
-        mChunkHasher = chunkHasher;
-    }
-
-    @Override
-    public DecryptedChunkOutput open() {
-        // As we don't have any resources there is nothing to open.
-        return this;
-    }
-
-    @Override
-    public void processChunk(byte[] plaintextBuffer, int length)
-            throws IOException, InvalidKeyException {
-        checkState(!mClosed, "Cannot process chunk after close()");
-        KeyValuePairProto.KeyValuePair kvPair = new KeyValuePairProto.KeyValuePair();
-        KeyValuePairProto.KeyValuePair.mergeFrom(kvPair, plaintextBuffer, 0, length);
-        mUnsortedPairs.add(kvPair);
-        // TODO(b/71492289): Update ChunkHasher to accept offset and length so we don't have to copy
-        // the buffer into a smaller array.
-        mUnsortedHashes.add(mChunkHasher.computeHash(Arrays.copyOf(plaintextBuffer, length)));
-    }
-
-    @Override
-    public void close() {
-        // As we don't have any resources there is nothing to close.
-        mClosed = true;
-    }
-
-    @Override
-    public byte[] getDigest() throws NoSuchAlgorithmException {
-        checkState(mClosed, "Must close() before getDigest()");
-        MessageDigest digest = getMessageDigest();
-        Collections.sort(mUnsortedHashes);
-        for (ChunkHash hash : mUnsortedHashes) {
-            digest.update(hash.getHash());
-        }
-        return digest.digest();
-    }
-
-    private static MessageDigest getMessageDigest() throws NoSuchAlgorithmException {
-        return MessageDigest.getInstance(DIGEST_ALGORITHM);
-    }
-
-    /**
-     * Returns the key value pairs from the backup, sorted lexicographically by key.
-     *
-     * <p>You must call {@link #close} first.
-     */
-    public List<KeyValuePairProto.KeyValuePair> getPairs() {
-        checkState(mClosed, "Must close() before getPairs()");
-        Collections.sort(
-                mUnsortedPairs,
-                new Comparator<KeyValuePairProto.KeyValuePair>() {
-                    @Override
-                    public int compare(
-                            KeyValuePairProto.KeyValuePair o1, KeyValuePairProto.KeyValuePair o2) {
-                        return o1.key.compareTo(o2.key);
-                    }
-                });
-        return mUnsortedPairs;
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/kv/KeyValueListingBuilder.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/kv/KeyValueListingBuilder.java
deleted file mode 100644
index 217304c..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/kv/KeyValueListingBuilder.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.kv;
-
-import static com.android.internal.util.Preconditions.checkArgument;
-
-import com.android.server.backup.encryption.chunk.ChunkHash;
-import com.android.server.backup.encryption.protos.nano.KeyValueListingProto;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Objects;
-
-/**
- * Builds a {@link KeyValueListingProto.KeyValueListing}, which is a nano proto and so has no
- * builder.
- */
-public class KeyValueListingBuilder {
-    private final List<KeyValueListingProto.KeyValueEntry> mEntries = new ArrayList<>();
-
-    /** Adds a new pair entry to the listing. */
-    public KeyValueListingBuilder addPair(String key, ChunkHash hash) {
-        checkArgument(key.length() != 0, "Key must have non-zero length");
-        Objects.requireNonNull(hash, "Hash must not be null");
-
-        KeyValueListingProto.KeyValueEntry entry = new KeyValueListingProto.KeyValueEntry();
-        entry.key = key;
-        entry.hash = hash.getHash();
-        mEntries.add(entry);
-
-        return this;
-    }
-
-    /** Adds all pairs contained in a map, where the map is from key to hash. */
-    public KeyValueListingBuilder addAll(Map<String, ChunkHash> map) {
-        for (Entry<String, ChunkHash> entry : map.entrySet()) {
-            addPair(entry.getKey(), entry.getValue());
-        }
-
-        return this;
-    }
-
-    /** Returns a new listing containing all the pairs added so far. */
-    public KeyValueListingProto.KeyValueListing build() {
-        if (mEntries.size() == 0) {
-            return emptyListing();
-        }
-
-        KeyValueListingProto.KeyValueListing listing = new KeyValueListingProto.KeyValueListing();
-        listing.entries = new KeyValueListingProto.KeyValueEntry[mEntries.size()];
-        mEntries.toArray(listing.entries);
-        return listing;
-    }
-
-    /** Returns a new listing which does not contain any pairs. */
-    public static KeyValueListingProto.KeyValueListing emptyListing() {
-        KeyValueListingProto.KeyValueListing listing = new KeyValueListingProto.KeyValueListing();
-        listing.entries = KeyValueListingProto.KeyValueEntry.emptyArray();
-        return listing;
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/storage/BackupEncryptionDb.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/storage/BackupEncryptionDb.java
deleted file mode 100644
index 9f6c03a..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/storage/BackupEncryptionDb.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.storage;
-
-import android.content.Context;
-
-/**
- * Backup encryption SQLite database. All instances are threadsafe.
- *
- * <p>The database is automatically opened when accessing one of the tables. After the caller is
- * done they must call {@link #close()}.
- */
-public class BackupEncryptionDb {
-    private final BackupEncryptionDbHelper mHelper;
-
-    /** A new instance, using the storage defined by {@code context}. */
-    public static BackupEncryptionDb newInstance(Context context) {
-        BackupEncryptionDbHelper helper = new BackupEncryptionDbHelper(context);
-        helper.setWriteAheadLoggingEnabled(true);
-        return new BackupEncryptionDb(helper);
-    }
-
-    private BackupEncryptionDb(BackupEncryptionDbHelper helper) {
-        mHelper = helper;
-    }
-
-    public TertiaryKeysTable getTertiaryKeysTable() {
-        return new TertiaryKeysTable(mHelper);
-    }
-
-    /** Deletes the database. */
-    public void clear() throws EncryptionDbException {
-        mHelper.resetDatabase();
-    }
-
-    /**
-     * Closes the database if it is open.
-     *
-     * <p>After calling this, the caller may access one of the tables again which will automatically
-     * reopen the database.
-     */
-    public void close() {
-        mHelper.close();
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/storage/BackupEncryptionDbContract.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/storage/BackupEncryptionDbContract.java
deleted file mode 100644
index 5e8a8d9..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/storage/BackupEncryptionDbContract.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.storage;
-
-import android.provider.BaseColumns;
-
-/** Contract for the backup encryption database. Describes tables present. */
-class BackupEncryptionDbContract {
-    /**
-     * Table containing tertiary keys belonging to the user. Tertiary keys are wrapped by a
-     * secondary key, which never leaves {@code AndroidKeyStore} (a provider for {@link
-     * java.security.KeyStore}). Each application has a tertiary key, which is used to encrypt the
-     * backup data.
-     */
-    static class TertiaryKeysEntry implements BaseColumns {
-        static final String TABLE_NAME = "tertiary_keys";
-
-        /** Alias of the secondary key used to wrap the tertiary key. */
-        static final String COLUMN_NAME_SECONDARY_KEY_ALIAS = "secondary_key_alias";
-
-        /** Name of the package to which the tertiary key belongs. */
-        static final String COLUMN_NAME_PACKAGE_NAME = "package_name";
-
-        /** Encrypted bytes of the tertiary key. */
-        static final String COLUMN_NAME_WRAPPED_KEY_BYTES = "wrapped_key_bytes";
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/storage/BackupEncryptionDbHelper.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/storage/BackupEncryptionDbHelper.java
deleted file mode 100644
index c706342..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/storage/BackupEncryptionDbHelper.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.storage;
-
-import static com.android.server.backup.encryption.storage.BackupEncryptionDbContract.TertiaryKeysEntry;
-
-import android.content.Context;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteException;
-import android.database.sqlite.SQLiteOpenHelper;
-
-/** Helper for creating an instance of the backup encryption database. */
-class BackupEncryptionDbHelper extends SQLiteOpenHelper {
-    private static final int DATABASE_VERSION = 1;
-    static final String DATABASE_NAME = "backupencryption.db";
-
-    private static final String SQL_CREATE_TERTIARY_KEYS_ENTRY =
-            "CREATE TABLE "
-                    + TertiaryKeysEntry.TABLE_NAME
-                    + " ( "
-                    + TertiaryKeysEntry._ID
-                    + " INTEGER PRIMARY KEY,"
-                    + TertiaryKeysEntry.COLUMN_NAME_SECONDARY_KEY_ALIAS
-                    + " TEXT,"
-                    + TertiaryKeysEntry.COLUMN_NAME_PACKAGE_NAME
-                    + " TEXT,"
-                    + TertiaryKeysEntry.COLUMN_NAME_WRAPPED_KEY_BYTES
-                    + " BLOB,"
-                    + "UNIQUE("
-                    + TertiaryKeysEntry.COLUMN_NAME_SECONDARY_KEY_ALIAS
-                    + ","
-                    + TertiaryKeysEntry.COLUMN_NAME_PACKAGE_NAME
-                    + "))";
-
-    private static final String SQL_DROP_TERTIARY_KEYS_ENTRY =
-            "DROP TABLE IF EXISTS " + TertiaryKeysEntry.TABLE_NAME;
-
-    BackupEncryptionDbHelper(Context context) {
-        super(context, DATABASE_NAME, /*factory=*/ null, DATABASE_VERSION);
-    }
-
-    public void resetDatabase() throws EncryptionDbException {
-        SQLiteDatabase db = getWritableDatabaseSafe();
-        db.execSQL(SQL_DROP_TERTIARY_KEYS_ENTRY);
-        onCreate(db);
-    }
-
-    @Override
-    public void onCreate(SQLiteDatabase db) {
-        db.execSQL(SQL_CREATE_TERTIARY_KEYS_ENTRY);
-    }
-
-    @Override
-    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
-        db.execSQL(SQL_DROP_TERTIARY_KEYS_ENTRY);
-        onCreate(db);
-    }
-
-    @Override
-    public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
-        db.execSQL(SQL_DROP_TERTIARY_KEYS_ENTRY);
-        onCreate(db);
-    }
-
-    /**
-     * Calls {@link #getWritableDatabase()}, but catches the unchecked {@link SQLiteException} and
-     * rethrows {@link EncryptionDbException}.
-     */
-    public SQLiteDatabase getWritableDatabaseSafe() throws EncryptionDbException {
-        try {
-            return super.getWritableDatabase();
-        } catch (SQLiteException e) {
-            throw new EncryptionDbException(e);
-        }
-    }
-
-    /**
-     * Calls {@link #getReadableDatabase()}, but catches the unchecked {@link SQLiteException} and
-     * rethrows {@link EncryptionDbException}.
-     */
-    public SQLiteDatabase getReadableDatabaseSafe() throws EncryptionDbException {
-        try {
-            return super.getReadableDatabase();
-        } catch (SQLiteException e) {
-            throw new EncryptionDbException(e);
-        }
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/storage/EncryptionDbException.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/storage/EncryptionDbException.java
deleted file mode 100644
index 82f7dea..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/storage/EncryptionDbException.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.storage;
-
-import java.io.IOException;
-
-/** Thrown when there is a problem reading or writing the encryption database. */
-public class EncryptionDbException extends IOException {
-    public EncryptionDbException(Throwable cause) {
-        super(cause);
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/storage/TertiaryKey.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/storage/TertiaryKey.java
deleted file mode 100644
index 39a2c6e..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/storage/TertiaryKey.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.storage;
-
-/** Wrapped bytes of a tertiary key. */
-public class TertiaryKey {
-    private final String mSecondaryKeyAlias;
-    private final String mPackageName;
-    private final byte[] mWrappedKeyBytes;
-
-    /**
-     * Creates a new instance.
-     *
-     * @param secondaryKeyAlias Alias of the secondary used to wrap the key.
-     * @param packageName The package name of the app to which the key belongs.
-     * @param wrappedKeyBytes The wrapped key bytes.
-     */
-    public TertiaryKey(String secondaryKeyAlias, String packageName, byte[] wrappedKeyBytes) {
-        mSecondaryKeyAlias = secondaryKeyAlias;
-        mPackageName = packageName;
-        mWrappedKeyBytes = wrappedKeyBytes;
-    }
-
-    /** Returns the alias of the secondary key used to wrap this tertiary key. */
-    public String getSecondaryKeyAlias() {
-        return mSecondaryKeyAlias;
-    }
-
-    /** Returns the package name of the application this key relates to. */
-    public String getPackageName() {
-        return mPackageName;
-    }
-
-    /** Returns the wrapped bytes of the key. */
-    public byte[] getWrappedKeyBytes() {
-        return mWrappedKeyBytes;
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/storage/TertiaryKeysTable.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/storage/TertiaryKeysTable.java
deleted file mode 100644
index d8d40c4..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/storage/TertiaryKeysTable.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.storage;
-
-import static com.android.server.backup.encryption.storage.BackupEncryptionDbContract.TertiaryKeysEntry;
-
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.util.ArrayMap;
-
-import java.util.Collections;
-import java.util.Map;
-import java.util.Optional;
-
-/** Database table for storing and retrieving tertiary keys. */
-public class TertiaryKeysTable {
-    private final BackupEncryptionDbHelper mHelper;
-
-    TertiaryKeysTable(BackupEncryptionDbHelper helper) {
-        mHelper = helper;
-    }
-
-    /**
-     * Adds the {@code tertiaryKey} to the database.
-     *
-     * @return The primary key of the inserted row if successful, -1 otherwise.
-     */
-    public long addKey(TertiaryKey tertiaryKey) throws EncryptionDbException {
-        SQLiteDatabase db = mHelper.getWritableDatabaseSafe();
-        ContentValues values = new ContentValues();
-        values.put(
-                TertiaryKeysEntry.COLUMN_NAME_SECONDARY_KEY_ALIAS,
-                tertiaryKey.getSecondaryKeyAlias());
-        values.put(TertiaryKeysEntry.COLUMN_NAME_PACKAGE_NAME, tertiaryKey.getPackageName());
-        values.put(
-                TertiaryKeysEntry.COLUMN_NAME_WRAPPED_KEY_BYTES, tertiaryKey.getWrappedKeyBytes());
-        return db.replace(TertiaryKeysEntry.TABLE_NAME, /*nullColumnHack=*/ null, values);
-    }
-
-    /** Gets the key wrapped by {@code secondaryKeyAlias} for app with {@code packageName}. */
-    public Optional<TertiaryKey> getKey(String secondaryKeyAlias, String packageName)
-            throws EncryptionDbException {
-        SQLiteDatabase db = mHelper.getReadableDatabaseSafe();
-        String[] projection = {
-            TertiaryKeysEntry._ID,
-            TertiaryKeysEntry.COLUMN_NAME_SECONDARY_KEY_ALIAS,
-            TertiaryKeysEntry.COLUMN_NAME_PACKAGE_NAME,
-            TertiaryKeysEntry.COLUMN_NAME_WRAPPED_KEY_BYTES
-        };
-        String selection =
-                TertiaryKeysEntry.COLUMN_NAME_SECONDARY_KEY_ALIAS
-                        + " = ? AND "
-                        + TertiaryKeysEntry.COLUMN_NAME_PACKAGE_NAME
-                        + " = ?";
-        String[] selectionArguments = {secondaryKeyAlias, packageName};
-
-        try (Cursor cursor =
-                db.query(
-                        TertiaryKeysEntry.TABLE_NAME,
-                        projection,
-                        selection,
-                        selectionArguments,
-                        /*groupBy=*/ null,
-                        /*having=*/ null,
-                        /*orderBy=*/ null)) {
-            int count = cursor.getCount();
-            if (count == 0) {
-                return Optional.empty();
-            }
-
-            cursor.moveToFirst();
-            byte[] wrappedKeyBytes =
-                    cursor.getBlob(
-                            cursor.getColumnIndexOrThrow(
-                                    TertiaryKeysEntry.COLUMN_NAME_WRAPPED_KEY_BYTES));
-            return Optional.of(new TertiaryKey(secondaryKeyAlias, packageName, wrappedKeyBytes));
-        }
-    }
-
-    /** Returns all keys wrapped with {@code tertiaryKeyAlias} as an unmodifiable map. */
-    public Map<String, TertiaryKey> getAllKeys(String secondaryKeyAlias)
-            throws EncryptionDbException {
-        SQLiteDatabase db = mHelper.getReadableDatabaseSafe();
-        String[] projection = {
-            TertiaryKeysEntry._ID,
-            TertiaryKeysEntry.COLUMN_NAME_SECONDARY_KEY_ALIAS,
-            TertiaryKeysEntry.COLUMN_NAME_PACKAGE_NAME,
-            TertiaryKeysEntry.COLUMN_NAME_WRAPPED_KEY_BYTES
-        };
-        String selection = TertiaryKeysEntry.COLUMN_NAME_SECONDARY_KEY_ALIAS + " = ?";
-        String[] selectionArguments = {secondaryKeyAlias};
-
-        Map<String, TertiaryKey> keysByPackageName = new ArrayMap<>();
-        try (Cursor cursor =
-                db.query(
-                        TertiaryKeysEntry.TABLE_NAME,
-                        projection,
-                        selection,
-                        selectionArguments,
-                        /*groupBy=*/ null,
-                        /*having=*/ null,
-                        /*orderBy=*/ null)) {
-            while (cursor.moveToNext()) {
-                String packageName =
-                        cursor.getString(
-                                cursor.getColumnIndexOrThrow(
-                                        TertiaryKeysEntry.COLUMN_NAME_PACKAGE_NAME));
-                byte[] wrappedKeyBytes =
-                        cursor.getBlob(
-                                cursor.getColumnIndexOrThrow(
-                                        TertiaryKeysEntry.COLUMN_NAME_WRAPPED_KEY_BYTES));
-                keysByPackageName.put(
-                        packageName,
-                        new TertiaryKey(secondaryKeyAlias, packageName, wrappedKeyBytes));
-            }
-        }
-        return Collections.unmodifiableMap(keysByPackageName);
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/ActiveSecondaryNotInKeychainException.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/ActiveSecondaryNotInKeychainException.java
deleted file mode 100644
index 2e8a61f..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/ActiveSecondaryNotInKeychainException.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.tasks;
-
-/**
- * Error thrown when the server's active secondary key does not exist in the user's recoverable
- * keychain. This means the backup data cannot be decrypted, and should be wiped.
- */
-public class ActiveSecondaryNotInKeychainException extends Exception {
-    public ActiveSecondaryNotInKeychainException(String message) {
-        super(message);
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/BackupEncrypter.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/BackupEncrypter.java
deleted file mode 100644
index 95d0d97..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/BackupEncrypter.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.tasks;
-
-import static java.util.Collections.unmodifiableList;
-
-import android.annotation.Nullable;
-
-import com.android.server.backup.encryption.chunk.ChunkHash;
-import com.android.server.backup.encryption.chunking.EncryptedChunk;
-
-import java.io.IOException;
-import java.security.GeneralSecurityException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-
-import javax.crypto.SecretKey;
-
-/** Task which reads data from some source, splits it into chunks and encrypts new chunks. */
-public interface BackupEncrypter {
-    /** The algorithm which we use to compute the digest of the backup file plaintext. */
-    String MESSAGE_DIGEST_ALGORITHM = "SHA-256";
-
-    /**
-     * Splits the backup input into encrypted chunks and encrypts new chunks.
-     *
-     * @param secretKey Key used to encrypt backup.
-     * @param fingerprintMixerSalt Fingerprint mixer salt used for content-defined chunking during a
-     *     full backup. Should be {@code null} for a key-value backup.
-     * @param existingChunks Set of the SHA-256 Macs of chunks the server already has.
-     * @return a result containing an array of new encrypted chunks to upload, and an ordered
-     *     listing of the chunks in the backup file.
-     * @throws IOException if a problem occurs reading from the backup data.
-     * @throws GeneralSecurityException if there is a problem encrypting the data.
-     */
-    Result backup(
-            SecretKey secretKey,
-            @Nullable byte[] fingerprintMixerSalt,
-            Set<ChunkHash> existingChunks)
-            throws IOException, GeneralSecurityException;
-
-    /**
-     * The result of an incremental backup. Contains new encrypted chunks to upload, and an ordered
-     * list of the chunks in the backup file.
-     */
-    class Result {
-        private final List<ChunkHash> mAllChunks;
-        private final List<EncryptedChunk> mNewChunks;
-        private final byte[] mDigest;
-
-        public Result(List<ChunkHash> allChunks, List<EncryptedChunk> newChunks, byte[] digest) {
-            mAllChunks = unmodifiableList(new ArrayList<>(allChunks));
-            mDigest = digest;
-            mNewChunks = unmodifiableList(new ArrayList<>(newChunks));
-        }
-
-        /**
-         * Returns an unmodifiable list of the hashes of all the chunks in the backup, in the order
-         * they appear in the plaintext.
-         */
-        public List<ChunkHash> getAllChunks() {
-            return mAllChunks;
-        }
-
-        /** Returns an unmodifiable list of the new chunks in the backup. */
-        public List<EncryptedChunk> getNewChunks() {
-            return mNewChunks;
-        }
-
-        /** Returns the message digest of the backup. */
-        public byte[] getDigest() {
-            return mDigest;
-        }
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/BackupFileDecryptorTask.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/BackupFileDecryptorTask.java
deleted file mode 100644
index 9bf148d..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/BackupFileDecryptorTask.java
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.tasks;
-
-import android.util.Slog;
-import android.util.SparseIntArray;
-
-import com.android.server.backup.encryption.protos.nano.ChunksMetadataProto;
-import com.android.server.backup.encryption.protos.nano.ChunksMetadataProto.ChunkOrdering;
-import com.android.server.backup.encryption.protos.nano.ChunksMetadataProto.ChunksMetadata;
-
-import com.google.protobuf.nano.InvalidProtocolBufferNanoException;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.util.Arrays;
-import java.util.Locale;
-
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.SecretKey;
-import javax.crypto.ShortBufferException;
-import javax.crypto.spec.GCMParameterSpec;
-
-/**
- * A backup file consists of, in order:
- *
- * <ul>
- *   <li>A randomly ordered sequence of encrypted chunks
- *   <li>A plaintext {@link ChunksMetadata} proto, containing the bytes of an encrypted {@link
- *       ChunkOrdering} proto.
- *   <li>A 64-bit long denoting the offset of the file at which the ChunkOrdering proto starts.
- * </ul>
- *
- * <p>This task decrypts such a blob and writes the plaintext to another file.
- *
- * <p>The backup file has two formats to indicate the boundaries of the chunks in the encrypted
- * file. In {@link ChunksMetadataProto#EXPLICIT_STARTS} mode the chunk ordering contains the start
- * positions of each chunk and the decryptor outputs the chunks in the order they appeared in the
- * plaintext file. In {@link ChunksMetadataProto#INLINE_LENGTHS} mode the length of each encrypted
- * chunk is prepended to the chunk in the file and the decryptor outputs the chunks in no specific
- * order.
- *
- * <p>{@link ChunksMetadataProto#EXPLICIT_STARTS} is for use with full backup (Currently used for
- * all backups as b/77188289 is not implemented yet), {@link ChunksMetadataProto#INLINE_LENGTHS}
- * will be used for kv backup (once b/77188289 is implemented) to avoid re-uploading the chunk
- * ordering (see b/70782620).
- */
-public class BackupFileDecryptorTask {
-    private static final String TAG = "BackupFileDecryptorTask";
-
-    private static final String CIPHER_ALGORITHM = "AES/GCM/NoPadding";
-    private static final int GCM_NONCE_LENGTH_BYTES = 12;
-    private static final int GCM_TAG_LENGTH_BYTES = 16;
-    private static final int BITS_PER_BYTE = 8;
-    private static final String READ_MODE = "r";
-    private static final int BYTES_PER_LONG = 64 / BITS_PER_BYTE;
-
-    private final Cipher mCipher;
-    private final SecretKey mSecretKey;
-
-    /**
-     * A new instance.
-     *
-     * @param secretKey The tertiary key used to encrypt the backup blob.
-     */
-    public BackupFileDecryptorTask(SecretKey secretKey)
-            throws NoSuchPaddingException, NoSuchAlgorithmException {
-        this.mCipher = Cipher.getInstance(CIPHER_ALGORITHM);
-        this.mSecretKey = secretKey;
-    }
-
-    /**
-     * Runs the task, reading the encrypted data from {@code input} and writing the plaintext data
-     * to {@code output}.
-     *
-     * @param inputFile The encrypted backup file.
-     * @param decryptedChunkOutput Unopened output to write the plaintext to, which this class will
-     *     open and close during decryption.
-     * @throws IOException if an error occurred reading the encrypted file or writing the plaintext,
-     *     or if one of the protos could not be deserialized.
-     */
-    public void decryptFile(File inputFile, DecryptedChunkOutput decryptedChunkOutput)
-            throws IOException, EncryptedRestoreException, IllegalBlockSizeException,
-                    BadPaddingException, InvalidAlgorithmParameterException, InvalidKeyException,
-                    ShortBufferException, NoSuchAlgorithmException {
-        RandomAccessFile input = new RandomAccessFile(inputFile, READ_MODE);
-
-        long metadataOffset = getChunksMetadataOffset(input);
-        ChunksMetadataProto.ChunksMetadata chunksMetadata =
-                getChunksMetadata(input, metadataOffset);
-        ChunkOrdering chunkOrdering = decryptChunkOrdering(chunksMetadata);
-
-        if (chunksMetadata.chunkOrderingType == ChunksMetadataProto.CHUNK_ORDERING_TYPE_UNSPECIFIED
-                || chunksMetadata.chunkOrderingType == ChunksMetadataProto.EXPLICIT_STARTS) {
-            Slog.d(TAG, "Using explicit starts");
-            decryptFileWithExplicitStarts(
-                    input, decryptedChunkOutput, chunkOrdering, metadataOffset);
-
-        } else if (chunksMetadata.chunkOrderingType == ChunksMetadataProto.INLINE_LENGTHS) {
-            Slog.d(TAG, "Using inline lengths");
-            decryptFileWithInlineLengths(input, decryptedChunkOutput, metadataOffset);
-
-        } else {
-            throw new UnsupportedEncryptedFileException(
-                    "Unknown chunk ordering type:" + chunksMetadata.chunkOrderingType);
-        }
-
-        if (!Arrays.equals(decryptedChunkOutput.getDigest(), chunkOrdering.checksum)) {
-            throw new MessageDigestMismatchException("Checksums did not match");
-        }
-    }
-
-    private void decryptFileWithExplicitStarts(
-            RandomAccessFile input,
-            DecryptedChunkOutput decryptedChunkOutput,
-            ChunkOrdering chunkOrdering,
-            long metadataOffset)
-            throws IOException, InvalidKeyException, IllegalBlockSizeException,
-                    InvalidAlgorithmParameterException, ShortBufferException, BadPaddingException,
-                    NoSuchAlgorithmException {
-        SparseIntArray chunkLengthsByPosition =
-                getChunkLengths(chunkOrdering.starts, (int) metadataOffset);
-        int largestChunkLength = getLargestChunkLength(chunkLengthsByPosition);
-        byte[] encryptedChunkBuffer = new byte[largestChunkLength];
-        // largestChunkLength is 0 if the backup file contains zero chunks e.g. 0 kv pairs.
-        int plaintextBufferLength =
-                Math.max(0, largestChunkLength - GCM_NONCE_LENGTH_BYTES - GCM_TAG_LENGTH_BYTES);
-        byte[] plaintextChunkBuffer = new byte[plaintextBufferLength];
-
-        try (DecryptedChunkOutput output = decryptedChunkOutput.open()) {
-            for (int start : chunkOrdering.starts) {
-                int length = chunkLengthsByPosition.get(start);
-
-                input.seek(start);
-                input.readFully(encryptedChunkBuffer, 0, length);
-                int plaintextLength =
-                        decryptChunk(encryptedChunkBuffer, length, plaintextChunkBuffer);
-                outputChunk(output, plaintextChunkBuffer, plaintextLength);
-            }
-        }
-    }
-
-    private void decryptFileWithInlineLengths(
-            RandomAccessFile input, DecryptedChunkOutput decryptedChunkOutput, long metadataOffset)
-            throws MalformedEncryptedFileException, IOException, IllegalBlockSizeException,
-                    BadPaddingException, InvalidAlgorithmParameterException, ShortBufferException,
-                    InvalidKeyException, NoSuchAlgorithmException {
-        input.seek(0);
-        try (DecryptedChunkOutput output = decryptedChunkOutput.open()) {
-            while (input.getFilePointer() < metadataOffset) {
-                long start = input.getFilePointer();
-                int encryptedChunkLength = input.readInt();
-
-                if (encryptedChunkLength <= 0) {
-                    // If the length of the encrypted chunk is not positive we will not make
-                    // progress reading the file and so will loop forever.
-                    throw new MalformedEncryptedFileException(
-                            "Encrypted chunk length not positive:" + encryptedChunkLength);
-                }
-
-                if (start + encryptedChunkLength > metadataOffset) {
-                    throw new MalformedEncryptedFileException(
-                            String.format(
-                                    Locale.US,
-                                    "Encrypted chunk longer (%d) than file (%d)",
-                                    encryptedChunkLength,
-                                    metadataOffset));
-                }
-
-                byte[] plaintextChunk = new byte[encryptedChunkLength];
-                byte[] plaintext =
-                        new byte
-                                [encryptedChunkLength
-                                        - GCM_NONCE_LENGTH_BYTES
-                                        - GCM_TAG_LENGTH_BYTES];
-
-                input.readFully(plaintextChunk);
-
-                int plaintextChunkLength =
-                        decryptChunk(plaintextChunk, encryptedChunkLength, plaintext);
-                outputChunk(output, plaintext, plaintextChunkLength);
-            }
-        }
-    }
-
-    private void outputChunk(
-            DecryptedChunkOutput output, byte[] plaintextChunkBuffer, int plaintextLength)
-            throws IOException, InvalidKeyException, NoSuchAlgorithmException {
-        output.processChunk(plaintextChunkBuffer, plaintextLength);
-    }
-
-    /**
-     * Decrypts chunk and returns the length of the plaintext.
-     *
-     * @param encryptedChunkBuffer The encrypted data, prefixed by the nonce.
-     * @param encryptedChunkBufferLength The length of the encrypted chunk (including nonce).
-     * @param plaintextChunkBuffer The buffer into which to write the plaintext chunk.
-     * @return The length of the plaintext chunk.
-     */
-    private int decryptChunk(
-            byte[] encryptedChunkBuffer,
-            int encryptedChunkBufferLength,
-            byte[] plaintextChunkBuffer)
-            throws InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException,
-                    ShortBufferException, IllegalBlockSizeException {
-
-        mCipher.init(
-                Cipher.DECRYPT_MODE,
-                mSecretKey,
-                new GCMParameterSpec(
-                        GCM_TAG_LENGTH_BYTES * BITS_PER_BYTE,
-                        encryptedChunkBuffer,
-                        0,
-                        GCM_NONCE_LENGTH_BYTES));
-
-        return mCipher.doFinal(
-                encryptedChunkBuffer,
-                GCM_NONCE_LENGTH_BYTES,
-                encryptedChunkBufferLength - GCM_NONCE_LENGTH_BYTES,
-                plaintextChunkBuffer);
-    }
-
-    /** Given all the lengths, returns the largest length. */
-    private int getLargestChunkLength(SparseIntArray lengths) {
-        int maxSeen = 0;
-        for (int i = 0; i < lengths.size(); i++) {
-            maxSeen = Math.max(maxSeen, lengths.valueAt(i));
-        }
-        return maxSeen;
-    }
-
-    /**
-     * From a list of the starting position of each chunk in the correct order of the backup data,
-     * calculates a mapping from start position to length of that chunk.
-     *
-     * @param starts The start positions of chunks, in order.
-     * @param chunkOrderingPosition Where the {@link ChunkOrdering} proto starts, used to calculate
-     *     the length of the last chunk.
-     * @return The mapping.
-     */
-    private SparseIntArray getChunkLengths(int[] starts, int chunkOrderingPosition) {
-        int[] boundaries = Arrays.copyOf(starts, starts.length + 1);
-        boundaries[boundaries.length - 1] = chunkOrderingPosition;
-        Arrays.sort(boundaries);
-
-        SparseIntArray lengths = new SparseIntArray();
-        for (int i = 0; i < boundaries.length - 1; i++) {
-            lengths.put(boundaries[i], boundaries[i + 1] - boundaries[i]);
-        }
-        return lengths;
-    }
-
-    /**
-     * Reads and decrypts the {@link ChunkOrdering} from the {@link ChunksMetadata}.
-     *
-     * @param metadata The metadata.
-     * @return The ordering.
-     * @throws InvalidProtocolBufferNanoException if there is an issue deserializing the proto.
-     */
-    private ChunkOrdering decryptChunkOrdering(ChunksMetadata metadata)
-            throws InvalidProtocolBufferNanoException, InvalidAlgorithmParameterException,
-                    InvalidKeyException, BadPaddingException, IllegalBlockSizeException,
-                    UnsupportedEncryptedFileException {
-        assertCryptoSupported(metadata);
-
-        mCipher.init(
-                Cipher.DECRYPT_MODE,
-                mSecretKey,
-                new GCMParameterSpec(
-                        GCM_TAG_LENGTH_BYTES * BITS_PER_BYTE,
-                        metadata.chunkOrdering,
-                        0,
-                        GCM_NONCE_LENGTH_BYTES));
-
-        byte[] decrypted =
-                mCipher.doFinal(
-                        metadata.chunkOrdering,
-                        GCM_NONCE_LENGTH_BYTES,
-                        metadata.chunkOrdering.length - GCM_NONCE_LENGTH_BYTES);
-
-        return ChunkOrdering.parseFrom(decrypted);
-    }
-
-    /**
-     * Asserts that the Cipher and MessageDigest algorithms in the backup metadata are supported.
-     * For now we only support SHA-256 for checksum and 256-bit AES/GCM/NoPadding for the Cipher.
-     *
-     * @param chunksMetadata The file metadata.
-     * @throws UnsupportedEncryptedFileException if any algorithm is unsupported.
-     */
-    private void assertCryptoSupported(ChunksMetadata chunksMetadata)
-            throws UnsupportedEncryptedFileException {
-        if (chunksMetadata.checksumType != ChunksMetadataProto.SHA_256) {
-            // For now we only support SHA-256.
-            throw new UnsupportedEncryptedFileException(
-                    "Unrecognized checksum type for backup (this version of backup only supports"
-                        + " SHA-256): "
-                            + chunksMetadata.checksumType);
-        }
-
-        if (chunksMetadata.cipherType != ChunksMetadataProto.AES_256_GCM) {
-            throw new UnsupportedEncryptedFileException(
-                    "Unrecognized cipher type for backup (this version of backup only supports"
-                        + " AES-256-GCM: "
-                            + chunksMetadata.cipherType);
-        }
-    }
-
-    /**
-     * Reads the offset of the {@link ChunksMetadata} proto from the end of the file.
-     *
-     * @return The offset.
-     * @throws IOException if there is an error reading.
-     */
-    private long getChunksMetadataOffset(RandomAccessFile input) throws IOException {
-        input.seek(input.length() - BYTES_PER_LONG);
-        return input.readLong();
-    }
-
-    /**
-     * Reads the {@link ChunksMetadata} proto from the given position in the file.
-     *
-     * @param input The encrypted file.
-     * @param position The position where the proto starts.
-     * @return The proto.
-     * @throws IOException if there is an issue reading the file or deserializing the proto.
-     */
-    private ChunksMetadata getChunksMetadata(RandomAccessFile input, long position)
-            throws IOException, MalformedEncryptedFileException {
-        long length = input.length();
-        if (position >= length || position < 0) {
-            throw new MalformedEncryptedFileException(
-                    String.format(
-                            Locale.US,
-                            "%d is not valid position for chunks metadata in file of %d bytes",
-                            position,
-                            length));
-        }
-
-        // Read chunk ordering bytes
-        input.seek(position);
-        long chunksMetadataLength = input.length() - BYTES_PER_LONG - position;
-        byte[] chunksMetadataBytes = new byte[(int) chunksMetadataLength];
-        input.readFully(chunksMetadataBytes);
-
-        try {
-            return ChunksMetadata.parseFrom(chunksMetadataBytes);
-        } catch (InvalidProtocolBufferNanoException e) {
-            throw new MalformedEncryptedFileException(
-                    String.format(
-                            Locale.US,
-                            "Could not read chunks metadata at position %d of file of %d bytes",
-                            position,
-                            length));
-        }
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/BackupStreamEncrypter.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/BackupStreamEncrypter.java
deleted file mode 100644
index 45798d3..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/BackupStreamEncrypter.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.tasks;
-
-import android.util.Slog;
-
-import com.android.server.backup.encryption.chunk.ChunkHash;
-import com.android.server.backup.encryption.chunking.ChunkEncryptor;
-import com.android.server.backup.encryption.chunking.ChunkHasher;
-import com.android.server.backup.encryption.chunking.EncryptedChunk;
-import com.android.server.backup.encryption.chunking.cdc.ContentDefinedChunker;
-import com.android.server.backup.encryption.chunking.cdc.FingerprintMixer;
-import com.android.server.backup.encryption.chunking.cdc.IsChunkBreakpoint;
-import com.android.server.backup.encryption.chunking.cdc.RabinFingerprint64;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.GeneralSecurityException;
-import java.security.MessageDigest;
-import java.security.SecureRandom;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import javax.crypto.SecretKey;
-
-/**
- * Splits backup data into variable-sized chunks using content-defined chunking, then encrypts the
- * chunks. Given a hash of the SHA-256s of existing chunks, performs an incremental backup (i.e.,
- * only encrypts new chunks).
- */
-public class BackupStreamEncrypter implements BackupEncrypter {
-    private static final String TAG = "BackupStreamEncryptor";
-
-    private final InputStream mData;
-    private final int mMinChunkSizeBytes;
-    private final int mMaxChunkSizeBytes;
-    private final int mAverageChunkSizeBytes;
-
-    /**
-     * A new instance over the given distribution of chunk sizes.
-     *
-     * @param data The data to be backed up.
-     * @param minChunkSizeBytes The minimum chunk size. No chunk will be smaller than this.
-     * @param maxChunkSizeBytes The maximum chunk size. No chunk will be larger than this.
-     * @param averageChunkSizeBytes The average chunk size. The mean size of chunks will be roughly
-     *     this (with a few tens of bytes of overhead for the initialization vector and message
-     *     authentication code).
-     */
-    public BackupStreamEncrypter(
-            InputStream data,
-            int minChunkSizeBytes,
-            int maxChunkSizeBytes,
-            int averageChunkSizeBytes) {
-        this.mData = data;
-        this.mMinChunkSizeBytes = minChunkSizeBytes;
-        this.mMaxChunkSizeBytes = maxChunkSizeBytes;
-        this.mAverageChunkSizeBytes = averageChunkSizeBytes;
-    }
-
-    @Override
-    public Result backup(
-            SecretKey secretKey, byte[] fingerprintMixerSalt, Set<ChunkHash> existingChunks)
-            throws IOException, GeneralSecurityException {
-        MessageDigest messageDigest =
-                MessageDigest.getInstance(BackupEncrypter.MESSAGE_DIGEST_ALGORITHM);
-        RabinFingerprint64 rabinFingerprint64 = new RabinFingerprint64();
-        FingerprintMixer fingerprintMixer = new FingerprintMixer(secretKey, fingerprintMixerSalt);
-        IsChunkBreakpoint isChunkBreakpoint =
-                new IsChunkBreakpoint(mAverageChunkSizeBytes - mMinChunkSizeBytes);
-        ContentDefinedChunker chunker =
-                new ContentDefinedChunker(
-                        mMinChunkSizeBytes,
-                        mMaxChunkSizeBytes,
-                        rabinFingerprint64,
-                        fingerprintMixer,
-                        isChunkBreakpoint);
-        ChunkHasher chunkHasher = new ChunkHasher(secretKey);
-        ChunkEncryptor encryptor = new ChunkEncryptor(secretKey, new SecureRandom());
-        Set<ChunkHash> includedChunks = new HashSet<>();
-        // New chunks will be added only once to this list, even if they occur multiple times.
-        List<EncryptedChunk> newChunks = new ArrayList<>();
-        // All chunks (including multiple occurrences) will be added to the chunkListing.
-        List<ChunkHash> chunkListing = new ArrayList<>();
-
-        includedChunks.addAll(existingChunks);
-
-        chunker.chunkify(
-                mData,
-                chunk -> {
-                    messageDigest.update(chunk);
-                    ChunkHash key = chunkHasher.computeHash(chunk);
-
-                    if (!includedChunks.contains(key)) {
-                        newChunks.add(encryptor.encrypt(key, chunk));
-                        includedChunks.add(key);
-                    }
-                    chunkListing.add(key);
-                });
-
-        Slog.i(
-                TAG,
-                String.format(
-                        "Chunks: %d total, %d unique, %d new",
-                        chunkListing.size(), new HashSet<>(chunkListing).size(), newChunks.size()));
-        return new Result(
-                Collections.unmodifiableList(chunkListing),
-                Collections.unmodifiableList(newChunks),
-                messageDigest.digest());
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/ClearCryptoStateTask.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/ClearCryptoStateTask.java
deleted file mode 100644
index 8f35db6..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/ClearCryptoStateTask.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.tasks;
-
-import android.content.Context;
-import android.util.Slog;
-
-import com.android.server.backup.encryption.CryptoSettings;
-import com.android.server.backup.encryption.chunking.ProtoStore;
-import com.android.server.backup.encryption.storage.BackupEncryptionDb;
-import com.android.server.backup.encryption.storage.EncryptionDbException;
-
-import java.io.IOException;
-
-/**
- * Task to clear local crypto state.
- *
- * <p>Needs to run whenever the user changes their backup account.
- */
-public class ClearCryptoStateTask {
-    private static final String TAG = "ClearCryptoStateTask";
-
-    private final Context mContext;
-    private final CryptoSettings mCryptoSettings;
-
-    /**
-     * A new instance.
-     *
-     * @param context for finding local storage.
-     * @param cryptoSettings to clear
-     */
-    public ClearCryptoStateTask(Context context, CryptoSettings cryptoSettings) {
-        mContext = context;
-        mCryptoSettings = cryptoSettings;
-    }
-
-    /** Deletes all local state for backup (not restore). */
-    public void run() {
-        Slog.d(TAG, "Clearing local crypto state.");
-        try {
-            BackupEncryptionDb.newInstance(mContext).clear();
-        } catch (EncryptionDbException e) {
-            Slog.e(TAG, "Error clearing encryption database", e);
-        }
-        mCryptoSettings.clearAllSettingsForBackup();
-        try {
-            ProtoStore.createChunkListingStore(mContext).deleteAllProtos();
-        } catch (IOException e) {
-            Slog.e(TAG, "Error clearing chunk listing store", e);
-        }
-        try {
-            ProtoStore.createKeyValueListingStore(mContext).deleteAllProtos();
-        } catch (IOException e) {
-            Slog.e(TAG, "Error clearing key-value store", e);
-        }
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/DecryptedChunkOutput.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/DecryptedChunkOutput.java
deleted file mode 100644
index f67f100..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/DecryptedChunkOutput.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.tasks;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-
-/**
- * Accepts the plaintext bytes of decrypted chunks and writes them to some output. Also keeps track
- * of the message digest of the chunks.
- */
-public interface DecryptedChunkOutput extends Closeable {
-    /**
-     * Opens whatever output the implementation chooses, ready to process chunks.
-     *
-     * @return {@code this}, to allow use with try-with-resources
-     */
-    DecryptedChunkOutput open() throws IOException, NoSuchAlgorithmException;
-
-    /**
-     * Writes the plaintext bytes of chunk to whatever output the implementation chooses. Also
-     * updates the digest with the chunk.
-     *
-     * <p>You must call {@link #open()} before this method, and you may not call it after calling
-     * {@link Closeable#close()}.
-     *
-     * @param plaintextBuffer An array containing the bytes of the plaintext of the chunk, starting
-     *     at index 0.
-     * @param length The length in bytes of the plaintext contained in {@code plaintextBuffer}.
-     */
-    void processChunk(byte[] plaintextBuffer, int length)
-            throws IOException, InvalidKeyException, NoSuchAlgorithmException;
-
-    /**
-     * Returns the message digest of all the chunks processed by {@link #processChunk}.
-     *
-     * <p>You must call {@link Closeable#close()} before calling this method.
-     */
-    byte[] getDigest() throws NoSuchAlgorithmException;
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/EncryptedBackupTask.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/EncryptedBackupTask.java
deleted file mode 100644
index ef13f23..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/EncryptedBackupTask.java
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.tasks;
-
-import android.annotation.Nullable;
-import android.annotation.TargetApi;
-import android.os.Build.VERSION_CODES;
-import android.util.Slog;
-
-import com.android.server.backup.encryption.chunk.ChunkHash;
-import com.android.server.backup.encryption.chunking.BackupFileBuilder;
-import com.android.server.backup.encryption.chunking.EncryptedChunk;
-import com.android.server.backup.encryption.client.CryptoBackupServer;
-import com.android.server.backup.encryption.protos.nano.ChunksMetadataProto;
-import com.android.server.backup.encryption.protos.nano.WrappedKeyProto;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.security.GeneralSecurityException;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.CancellationException;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.SecretKey;
-import javax.crypto.ShortBufferException;
-import javax.crypto.spec.GCMParameterSpec;
-
-/**
- * Task which reads encrypted chunks from a {@link BackupEncrypter}, builds a backup file and
- * uploads it to the server.
- */
-@TargetApi(VERSION_CODES.P)
-public class EncryptedBackupTask {
-    private static final String CIPHER_ALGORITHM = "AES/GCM/NoPadding";
-    private static final int GCM_NONCE_LENGTH_BYTES = 12;
-    private static final int GCM_TAG_LENGTH_BYTES = 16;
-    private static final int BITS_PER_BYTE = 8;
-
-    private static final String TAG = "EncryptedBackupTask";
-
-    private final CryptoBackupServer mCryptoBackupServer;
-    private final SecureRandom mSecureRandom;
-    private final String mPackageName;
-    private final ByteArrayOutputStream mBackupDataOutput;
-    private final BackupEncrypter mBackupEncrypter;
-    private final AtomicBoolean mCancelled;
-
-    /** Creates a new instance which reads data from the given input stream. */
-    public EncryptedBackupTask(
-            CryptoBackupServer cryptoBackupServer,
-            SecureRandom secureRandom,
-            String packageName,
-            BackupEncrypter backupEncrypter) {
-        mCryptoBackupServer = cryptoBackupServer;
-        mSecureRandom = secureRandom;
-        mPackageName = packageName;
-        mBackupEncrypter = backupEncrypter;
-
-        mBackupDataOutput = new ByteArrayOutputStream();
-        mCancelled = new AtomicBoolean(false);
-    }
-
-    /**
-     * Creates a non-incremental backup file and uploads it to the server.
-     *
-     * @param fingerprintMixerSalt Fingerprint mixer salt used for content-defined chunking during a
-     *     full backup. May be {@code null} for a key-value backup.
-     */
-    public ChunksMetadataProto.ChunkListing performNonIncrementalBackup(
-            SecretKey tertiaryKey,
-            WrappedKeyProto.WrappedKey wrappedTertiaryKey,
-            @Nullable byte[] fingerprintMixerSalt)
-            throws IOException, GeneralSecurityException {
-
-        ChunksMetadataProto.ChunkListing newChunkListing =
-                performBackup(
-                        tertiaryKey,
-                        fingerprintMixerSalt,
-                        BackupFileBuilder.createForNonIncremental(mBackupDataOutput),
-                        new HashSet<>());
-
-        throwIfCancelled();
-
-        newChunkListing.documentId =
-                mCryptoBackupServer.uploadNonIncrementalBackup(
-                        mPackageName, mBackupDataOutput.toByteArray(), wrappedTertiaryKey);
-
-        return newChunkListing;
-    }
-
-    /** Creates an incremental backup file and uploads it to the server. */
-    public ChunksMetadataProto.ChunkListing performIncrementalBackup(
-            SecretKey tertiaryKey,
-            WrappedKeyProto.WrappedKey wrappedTertiaryKey,
-            ChunksMetadataProto.ChunkListing oldChunkListing)
-            throws IOException, GeneralSecurityException {
-
-        ChunksMetadataProto.ChunkListing newChunkListing =
-                performBackup(
-                        tertiaryKey,
-                        oldChunkListing.fingerprintMixerSalt,
-                        BackupFileBuilder.createForIncremental(mBackupDataOutput, oldChunkListing),
-                        getChunkHashes(oldChunkListing));
-
-        throwIfCancelled();
-
-        String oldDocumentId = oldChunkListing.documentId;
-        Slog.v(TAG, "Old doc id: " + oldDocumentId);
-
-        newChunkListing.documentId =
-                mCryptoBackupServer.uploadIncrementalBackup(
-                        mPackageName,
-                        oldDocumentId,
-                        mBackupDataOutput.toByteArray(),
-                        wrappedTertiaryKey);
-        return newChunkListing;
-    }
-
-    /**
-     * Signals to the task that the backup has been cancelled. If the upload has not yet started
-     * then the task will not upload any data to the server or save the new chunk listing.
-     */
-    public void cancel() {
-        mCancelled.getAndSet(true);
-    }
-
-    private void throwIfCancelled() {
-        if (mCancelled.get()) {
-            throw new CancellationException("EncryptedBackupTask was cancelled");
-        }
-    }
-
-    private ChunksMetadataProto.ChunkListing performBackup(
-            SecretKey tertiaryKey,
-            @Nullable byte[] fingerprintMixerSalt,
-            BackupFileBuilder backupFileBuilder,
-            Set<ChunkHash> existingChunkHashes)
-            throws IOException, GeneralSecurityException {
-        BackupEncrypter.Result result =
-                mBackupEncrypter.backup(tertiaryKey, fingerprintMixerSalt, existingChunkHashes);
-        backupFileBuilder.writeChunks(result.getAllChunks(), buildChunkMap(result.getNewChunks()));
-
-        ChunksMetadataProto.ChunkOrdering chunkOrdering =
-                backupFileBuilder.getNewChunkOrdering(result.getDigest());
-        backupFileBuilder.finish(buildMetadata(tertiaryKey, chunkOrdering));
-
-        return backupFileBuilder.getNewChunkListing(fingerprintMixerSalt);
-    }
-
-    /** Returns a set containing the hashes of every chunk in the given listing. */
-    private static Set<ChunkHash> getChunkHashes(ChunksMetadataProto.ChunkListing chunkListing) {
-        Set<ChunkHash> hashes = new HashSet<>();
-        for (ChunksMetadataProto.Chunk chunk : chunkListing.chunks) {
-            hashes.add(new ChunkHash(chunk.hash));
-        }
-        return hashes;
-    }
-
-    /** Returns a map from chunk hash to chunk containing every chunk in the given list. */
-    private static Map<ChunkHash, EncryptedChunk> buildChunkMap(List<EncryptedChunk> chunks) {
-        Map<ChunkHash, EncryptedChunk> chunkMap = new HashMap<>();
-        for (EncryptedChunk chunk : chunks) {
-            chunkMap.put(chunk.key(), chunk);
-        }
-        return chunkMap;
-    }
-
-    private ChunksMetadataProto.ChunksMetadata buildMetadata(
-            SecretKey tertiaryKey, ChunksMetadataProto.ChunkOrdering chunkOrdering)
-            throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException,
-                    InvalidAlgorithmParameterException, NoSuchAlgorithmException,
-                    ShortBufferException, NoSuchPaddingException {
-        ChunksMetadataProto.ChunksMetadata metaData = new ChunksMetadataProto.ChunksMetadata();
-        metaData.cipherType = ChunksMetadataProto.AES_256_GCM;
-        metaData.checksumType = ChunksMetadataProto.SHA_256;
-        metaData.chunkOrdering = encryptChunkOrdering(tertiaryKey, chunkOrdering);
-        return metaData;
-    }
-
-    private byte[] encryptChunkOrdering(
-            SecretKey tertiaryKey, ChunksMetadataProto.ChunkOrdering chunkOrdering)
-            throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException,
-                    NoSuchPaddingException, NoSuchAlgorithmException,
-                    InvalidAlgorithmParameterException, ShortBufferException {
-        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
-
-        byte[] nonce = generateNonce();
-
-        cipher.init(
-                Cipher.ENCRYPT_MODE,
-                tertiaryKey,
-                new GCMParameterSpec(GCM_TAG_LENGTH_BYTES * BITS_PER_BYTE, nonce));
-
-        byte[] orderingBytes = ChunksMetadataProto.ChunkOrdering.toByteArray(chunkOrdering);
-        // We prepend the nonce to the ordering.
-        byte[] output =
-                Arrays.copyOf(
-                        nonce,
-                        GCM_NONCE_LENGTH_BYTES + orderingBytes.length + GCM_TAG_LENGTH_BYTES);
-
-        cipher.doFinal(
-                orderingBytes,
-                /*inputOffset=*/ 0,
-                /*inputLen=*/ orderingBytes.length,
-                output,
-                /*outputOffset=*/ GCM_NONCE_LENGTH_BYTES);
-
-        return output;
-    }
-
-    private byte[] generateNonce() {
-        byte[] nonce = new byte[GCM_NONCE_LENGTH_BYTES];
-        mSecureRandom.nextBytes(nonce);
-        return nonce;
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/EncryptedFullBackupDataProcessor.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/EncryptedFullBackupDataProcessor.java
deleted file mode 100644
index 71588f6..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/EncryptedFullBackupDataProcessor.java
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.tasks;
-
-import static com.android.internal.util.Preconditions.checkState;
-
-import android.annotation.Nullable;
-import android.app.backup.BackupTransport;
-import android.content.Context;
-import android.util.Slog;
-
-import com.android.server.backup.encryption.FullBackupDataProcessor;
-import com.android.server.backup.encryption.StreamUtils;
-import com.android.server.backup.encryption.client.CryptoBackupServer;
-import com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKey;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PipedInputStream;
-import java.io.PipedOutputStream;
-import java.security.SecureRandom;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
-
-/**
- * Accepts backup data from a {@link InputStream} and passes it to the encrypted full data backup
- * path.
- */
-public class EncryptedFullBackupDataProcessor implements FullBackupDataProcessor {
-
-    private static final String TAG = "EncryptedFullBackupDP";
-
-    private final Context mContext;
-    private final ExecutorService mExecutorService;
-    private final CryptoBackupServer mCryptoBackupServer;
-    private final SecureRandom mSecureRandom;
-    private final RecoverableKeyStoreSecondaryKey mSecondaryKey;
-    private final String mPackageName;
-
-    @Nullable private InputStream mInputStream;
-    @Nullable private PipedOutputStream mOutputStream;
-    @Nullable private EncryptedFullBackupTask mBackupTask;
-    @Nullable private Future<Void> mBackupTaskFuture;
-    @Nullable private FullBackupCallbacks mFullBackupCallbacks;
-
-    public EncryptedFullBackupDataProcessor(
-            Context context,
-            ExecutorService executorService,
-            CryptoBackupServer cryptoBackupServer,
-            SecureRandom secureRandom,
-            RecoverableKeyStoreSecondaryKey secondaryKey,
-            String packageName) {
-        mContext = Objects.requireNonNull(context);
-        mExecutorService = Objects.requireNonNull(executorService);
-        mCryptoBackupServer = Objects.requireNonNull(cryptoBackupServer);
-        mSecureRandom = Objects.requireNonNull(secureRandom);
-        mSecondaryKey = Objects.requireNonNull(secondaryKey);
-        mPackageName = Objects.requireNonNull(packageName);
-    }
-
-    @Override
-    public boolean initiate(InputStream inputStream) throws IOException {
-        checkState(mBackupTask == null, "initiate() twice");
-
-        this.mInputStream = inputStream;
-        mOutputStream = new PipedOutputStream();
-
-        mBackupTask =
-                EncryptedFullBackupTask.newInstance(
-                        mContext,
-                        mCryptoBackupServer,
-                        mSecureRandom,
-                        mSecondaryKey,
-                        mPackageName,
-                        new PipedInputStream(mOutputStream));
-
-        return true;
-    }
-
-    @Override
-    public void start() {
-        checkState(mBackupTask != null, "start() before initiate()");
-        mBackupTaskFuture = mExecutorService.submit(mBackupTask);
-    }
-
-    @Override
-    public int pushData(int numBytes) {
-        checkState(
-                mBackupTaskFuture != null && mInputStream != null && mOutputStream != null,
-                "pushData() before start()");
-
-        // If the upload has failed then stop without pushing any more bytes.
-        if (mBackupTaskFuture.isDone()) {
-            Optional<Exception> exception = getTaskException();
-            Slog.e(TAG, "Encrypted upload failed", exception.orElse(null));
-            if (exception.isPresent()) {
-                reportNetworkFailureIfNecessary(exception.get());
-
-                if (exception.get().getCause() instanceof SizeQuotaExceededException) {
-                    return BackupTransport.TRANSPORT_QUOTA_EXCEEDED;
-                }
-            }
-
-            return BackupTransport.TRANSPORT_ERROR;
-        }
-
-        try {
-            StreamUtils.copyStream(mInputStream, mOutputStream, numBytes);
-        } catch (IOException e) {
-            Slog.e(TAG, "IOException when processing backup", e);
-            return BackupTransport.TRANSPORT_ERROR;
-        }
-
-        return BackupTransport.TRANSPORT_OK;
-    }
-
-    @Override
-    public void cancel() {
-        checkState(mBackupTaskFuture != null && mBackupTask != null, "cancel() before start()");
-        mBackupTask.cancel();
-        closeStreams();
-    }
-
-    @Override
-    public int finish() {
-        checkState(mBackupTaskFuture != null, "finish() before start()");
-
-        // getTaskException() waits for the task to finish. We must close the streams first, which
-        // causes the task to finish, otherwise it will block forever.
-        closeStreams();
-        Optional<Exception> exception = getTaskException();
-
-        if (exception.isPresent()) {
-            Slog.e(TAG, "Exception during encrypted full backup", exception.get());
-            reportNetworkFailureIfNecessary(exception.get());
-
-            if (exception.get().getCause() instanceof SizeQuotaExceededException) {
-                return BackupTransport.TRANSPORT_QUOTA_EXCEEDED;
-            }
-            return BackupTransport.TRANSPORT_ERROR;
-
-        } else {
-            if (mFullBackupCallbacks != null) {
-                mFullBackupCallbacks.onSuccess();
-            }
-
-            return BackupTransport.TRANSPORT_OK;
-        }
-    }
-
-    private void closeStreams() {
-        StreamUtils.closeQuietly(mInputStream);
-        StreamUtils.closeQuietly(mOutputStream);
-    }
-
-    @Override
-    public void handleCheckSizeRejectionZeroBytes() {
-        cancel();
-    }
-
-    @Override
-    public void handleCheckSizeRejectionQuotaExceeded() {
-        cancel();
-    }
-
-    @Override
-    public void handleSendBytesQuotaExceeded() {
-        cancel();
-    }
-
-    @Override
-    public void attachCallbacks(FullBackupCallbacks fullBackupCallbacks) {
-        this.mFullBackupCallbacks = fullBackupCallbacks;
-    }
-
-    private void reportNetworkFailureIfNecessary(Exception exception) {
-        if (!(exception.getCause() instanceof SizeQuotaExceededException)
-                && mFullBackupCallbacks != null) {
-            mFullBackupCallbacks.onTransferFailed();
-        }
-    }
-
-    private Optional<Exception> getTaskException() {
-        if (mBackupTaskFuture != null) {
-            try {
-                mBackupTaskFuture.get();
-            } catch (InterruptedException | ExecutionException e) {
-                return Optional.of(e);
-            }
-        }
-        return Optional.empty();
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/EncryptedFullBackupTask.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/EncryptedFullBackupTask.java
deleted file mode 100644
index a938d71..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/EncryptedFullBackupTask.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.tasks;
-
-import android.content.Context;
-import android.util.Slog;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.server.backup.encryption.StreamUtils;
-import com.android.server.backup.encryption.chunking.ProtoStore;
-import com.android.server.backup.encryption.chunking.cdc.FingerprintMixer;
-import com.android.server.backup.encryption.client.CryptoBackupServer;
-import com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKey;
-import com.android.server.backup.encryption.keys.TertiaryKeyManager;
-import com.android.server.backup.encryption.keys.TertiaryKeyRotationScheduler;
-import com.android.server.backup.encryption.protos.nano.ChunksMetadataProto.ChunkListing;
-import com.android.server.backup.encryption.protos.nano.WrappedKeyProto;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.SecureRandom;
-import java.util.Arrays;
-import java.util.Optional;
-import java.util.concurrent.Callable;
-
-import javax.crypto.SecretKey;
-
-/**
- * Task which reads a stream of plaintext full backup data, chunks it, encrypts it and uploads it to
- * the server.
- *
- * <p>Once the backup completes or fails, closes the input stream.
- */
-public class EncryptedFullBackupTask implements Callable<Void> {
-    private static final String TAG = "EncryptedFullBackupTask";
-
-    private static final int MIN_CHUNK_SIZE_BYTES = 2 * 1024;
-    private static final int MAX_CHUNK_SIZE_BYTES = 64 * 1024;
-    private static final int AVERAGE_CHUNK_SIZE_BYTES = 4 * 1024;
-
-    // TODO(b/69350270): Remove this hard-coded salt and related logic once we feel confident that
-    // incremental backup has happened at least once for all existing packages/users since we moved
-    // to
-    // using a randomly generated salt.
-    //
-    // The hard-coded fingerprint mixer salt was used for a short time period before replaced by one
-    // that is randomly generated on initial non-incremental backup and stored in ChunkListing to be
-    // reused for succeeding incremental backups. If an old ChunkListing does not have a
-    // fingerprint_mixer_salt, we assume that it was last backed up before a randomly generated salt
-    // is used so we use the hardcoded salt and set ChunkListing#fingerprint_mixer_salt to this
-    // value.
-    // Eventually all backup ChunkListings will have this field set and then we can remove the
-    // default
-    // value in the code.
-    static final byte[] DEFAULT_FINGERPRINT_MIXER_SALT =
-            Arrays.copyOf(new byte[] {20, 23}, FingerprintMixer.SALT_LENGTH_BYTES);
-
-    private final ProtoStore<ChunkListing> mChunkListingStore;
-    private final TertiaryKeyManager mTertiaryKeyManager;
-    private final InputStream mInputStream;
-    private final EncryptedBackupTask mTask;
-    private final String mPackageName;
-    private final SecureRandom mSecureRandom;
-
-    /** Creates a new instance with the default min, max and average chunk sizes. */
-    public static EncryptedFullBackupTask newInstance(
-            Context context,
-            CryptoBackupServer cryptoBackupServer,
-            SecureRandom secureRandom,
-            RecoverableKeyStoreSecondaryKey secondaryKey,
-            String packageName,
-            InputStream inputStream)
-            throws IOException {
-        EncryptedBackupTask encryptedBackupTask =
-                new EncryptedBackupTask(
-                        cryptoBackupServer,
-                        secureRandom,
-                        packageName,
-                        new BackupStreamEncrypter(
-                                inputStream,
-                                MIN_CHUNK_SIZE_BYTES,
-                                MAX_CHUNK_SIZE_BYTES,
-                                AVERAGE_CHUNK_SIZE_BYTES));
-        TertiaryKeyManager tertiaryKeyManager =
-                new TertiaryKeyManager(
-                        context,
-                        secureRandom,
-                        TertiaryKeyRotationScheduler.getInstance(context),
-                        secondaryKey,
-                        packageName);
-
-        return new EncryptedFullBackupTask(
-                ProtoStore.createChunkListingStore(context),
-                tertiaryKeyManager,
-                encryptedBackupTask,
-                inputStream,
-                packageName,
-                new SecureRandom());
-    }
-
-    @VisibleForTesting
-    EncryptedFullBackupTask(
-            ProtoStore<ChunkListing> chunkListingStore,
-            TertiaryKeyManager tertiaryKeyManager,
-            EncryptedBackupTask task,
-            InputStream inputStream,
-            String packageName,
-            SecureRandom secureRandom) {
-        mChunkListingStore = chunkListingStore;
-        mTertiaryKeyManager = tertiaryKeyManager;
-        mInputStream = inputStream;
-        mTask = task;
-        mPackageName = packageName;
-        mSecureRandom = secureRandom;
-    }
-
-    @Override
-    public Void call() throws Exception {
-        try {
-            Optional<ChunkListing> maybeOldChunkListing =
-                    mChunkListingStore.loadProto(mPackageName);
-
-            if (maybeOldChunkListing.isPresent()) {
-                Slog.i(TAG, "Found previous chunk listing for " + mPackageName);
-            }
-
-            // If the key has been rotated then we must re-encrypt all of the backup data.
-            if (mTertiaryKeyManager.wasKeyRotated()) {
-                Slog.i(
-                        TAG,
-                        "Key was rotated or newly generated for "
-                                + mPackageName
-                                + ", so performing a full backup.");
-                maybeOldChunkListing = Optional.empty();
-                mChunkListingStore.deleteProto(mPackageName);
-            }
-
-            SecretKey tertiaryKey = mTertiaryKeyManager.getKey();
-            WrappedKeyProto.WrappedKey wrappedTertiaryKey = mTertiaryKeyManager.getWrappedKey();
-
-            ChunkListing newChunkListing;
-            if (!maybeOldChunkListing.isPresent()) {
-                byte[] fingerprintMixerSalt = new byte[FingerprintMixer.SALT_LENGTH_BYTES];
-                mSecureRandom.nextBytes(fingerprintMixerSalt);
-                newChunkListing =
-                        mTask.performNonIncrementalBackup(
-                                tertiaryKey, wrappedTertiaryKey, fingerprintMixerSalt);
-            } else {
-                ChunkListing oldChunkListing = maybeOldChunkListing.get();
-
-                if (oldChunkListing.fingerprintMixerSalt == null
-                        || oldChunkListing.fingerprintMixerSalt.length == 0) {
-                    oldChunkListing.fingerprintMixerSalt = DEFAULT_FINGERPRINT_MIXER_SALT;
-                }
-
-                newChunkListing =
-                        mTask.performIncrementalBackup(
-                                tertiaryKey, wrappedTertiaryKey, oldChunkListing);
-            }
-
-            mChunkListingStore.saveProto(mPackageName, newChunkListing);
-            Slog.v(TAG, "Saved chunk listing for " + mPackageName);
-        } catch (IOException e) {
-            Slog.e(TAG, "Storage exception, wiping state");
-            mChunkListingStore.deleteProto(mPackageName);
-            throw e;
-        } finally {
-            StreamUtils.closeQuietly(mInputStream);
-        }
-
-        return null;
-    }
-
-    /**
-     * Signals to the task that the backup has been cancelled. If the upload has not yet started
-     * then the task will not upload any data to the server or save the new chunk listing.
-     *
-     * <p>You must then terminate the input stream.
-     */
-    public void cancel() {
-        mTask.cancel();
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/EncryptedFullRestoreTask.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/EncryptedFullRestoreTask.java
deleted file mode 100644
index 04381af..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/EncryptedFullRestoreTask.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.tasks;
-
-import static com.android.internal.util.Preconditions.checkArgument;
-
-import android.annotation.Nullable;
-import android.content.Context;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.server.backup.encryption.FullRestoreDataProcessor;
-import com.android.server.backup.encryption.FullRestoreDownloader;
-import com.android.server.backup.encryption.StreamUtils;
-import com.android.server.backup.encryption.chunking.DecryptedChunkFileOutput;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-
-import javax.crypto.BadPaddingException;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.SecretKey;
-import javax.crypto.ShortBufferException;
-
-/** Downloads the encrypted backup file, decrypts it and passes the data to backup manager. */
-public class EncryptedFullRestoreTask implements FullRestoreDataProcessor {
-    private static final String DEFAULT_TEMPORARY_FOLDER = "encrypted_restore_temp";
-    private static final String ENCRYPTED_FILE_NAME = "encrypted_restore";
-    private static final String DECRYPTED_FILE_NAME = "decrypted_restore";
-
-    private final FullRestoreToFileTask mFullRestoreToFileTask;
-    private final BackupFileDecryptorTask mBackupFileDecryptorTask;
-    private final File mEncryptedFile;
-    private final File mDecryptedFile;
-    @Nullable private InputStream mDecryptedFileInputStream;
-
-    /**
-     * Creates a new task which stores temporary files in the files directory.
-     *
-     * @param fullRestoreDownloader which will download the backup file
-     * @param tertiaryKey which the backup file is encrypted with
-     */
-    public static EncryptedFullRestoreTask newInstance(
-            Context context, FullRestoreDownloader fullRestoreDownloader, SecretKey tertiaryKey)
-            throws NoSuchAlgorithmException, NoSuchPaddingException {
-        File temporaryFolder = new File(context.getFilesDir(), DEFAULT_TEMPORARY_FOLDER);
-        temporaryFolder.mkdirs();
-        return new EncryptedFullRestoreTask(
-                temporaryFolder, fullRestoreDownloader, new BackupFileDecryptorTask(tertiaryKey));
-    }
-
-    @VisibleForTesting
-    EncryptedFullRestoreTask(
-            File temporaryFolder,
-            FullRestoreDownloader fullRestoreDownloader,
-            BackupFileDecryptorTask backupFileDecryptorTask) {
-        checkArgument(temporaryFolder.isDirectory(), "Temporary folder must be existing directory");
-
-        mEncryptedFile = new File(temporaryFolder, ENCRYPTED_FILE_NAME);
-        mDecryptedFile = new File(temporaryFolder, DECRYPTED_FILE_NAME);
-
-        mFullRestoreToFileTask = new FullRestoreToFileTask(fullRestoreDownloader);
-        mBackupFileDecryptorTask = backupFileDecryptorTask;
-    }
-
-    /**
-     * Reads the next decrypted bytes into the given buffer.
-     *
-     * <p>During the first call this method will download the backup file from the server, decrypt
-     * it and save it to disk. It will then read the bytes from the file on disk.
-     *
-     * <p>Once this method has read all the bytes of the file, the caller must call {@link #finish}
-     * to clean up.
-     *
-     * @return the number of bytes read, or {@code -1} on reaching the end of the file
-     */
-    @Override
-    public int readNextChunk(byte[] buffer) throws IOException {
-        if (mDecryptedFileInputStream == null) {
-            try {
-                mDecryptedFileInputStream = downloadAndDecryptBackup();
-            } catch (BadPaddingException
-                    | InvalidKeyException
-                    | NoSuchAlgorithmException
-                    | IllegalBlockSizeException
-                    | ShortBufferException
-                    | EncryptedRestoreException
-                    | InvalidAlgorithmParameterException e) {
-                throw new IOException("Encryption issue", e);
-            }
-        }
-
-        return mDecryptedFileInputStream.read(buffer);
-    }
-
-    private InputStream downloadAndDecryptBackup()
-            throws IOException, BadPaddingException, InvalidKeyException, NoSuchAlgorithmException,
-                    IllegalBlockSizeException, ShortBufferException, EncryptedRestoreException,
-                    InvalidAlgorithmParameterException {
-        mFullRestoreToFileTask.restoreToFile(mEncryptedFile);
-        mBackupFileDecryptorTask.decryptFile(
-                mEncryptedFile, new DecryptedChunkFileOutput(mDecryptedFile));
-        mEncryptedFile.delete();
-        return new BufferedInputStream(new FileInputStream(mDecryptedFile));
-    }
-
-    /** Cleans up temporary files. */
-    @Override
-    public void finish(FullRestoreDownloader.FinishType unusedFinishType) {
-        // The download is finished and log sent during RestoreToFileTask#restoreToFile(), so we
-        // don't need to do either of those things here.
-
-        StreamUtils.closeQuietly(mDecryptedFileInputStream);
-        mEncryptedFile.delete();
-        mDecryptedFile.delete();
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/EncryptedKvBackupTask.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/EncryptedKvBackupTask.java
deleted file mode 100644
index 619438c..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/EncryptedKvBackupTask.java
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.tasks;
-
-import android.annotation.Nullable;
-import android.app.backup.BackupDataInput;
-import android.content.Context;
-import android.os.ParcelFileDescriptor;
-import android.security.keystore.recovery.InternalRecoveryServiceException;
-import android.security.keystore.recovery.LockScreenRequiredException;
-import android.util.Pair;
-import android.util.Slog;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.server.backup.encryption.CryptoSettings;
-import com.android.server.backup.encryption.chunking.ProtoStore;
-import com.android.server.backup.encryption.client.CryptoBackupServer;
-import com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKey;
-import com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKeyManager;
-import com.android.server.backup.encryption.keys.TertiaryKeyManager;
-import com.android.server.backup.encryption.keys.TertiaryKeyRotationScheduler;
-import com.android.server.backup.encryption.protos.nano.ChunksMetadataProto;
-import com.android.server.backup.encryption.protos.nano.KeyValueListingProto;
-
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.security.GeneralSecurityException;
-import java.security.InvalidKeyException;
-import java.security.SecureRandom;
-import java.security.UnrecoverableKeyException;
-import java.util.Optional;
-
-// TODO(b/141975695): Create a base class for EncryptedKvBackupTask and EncryptedFullBackupTask.
-/** Performs encrypted key value backup, handling rotating the tertiary key as necessary. */
-public class EncryptedKvBackupTask {
-    private static final String TAG = "EncryptedKvBackupTask";
-
-    private final TertiaryKeyManager mTertiaryKeyManager;
-    private final RecoverableKeyStoreSecondaryKey mSecondaryKey;
-    private final ProtoStore<KeyValueListingProto.KeyValueListing> mKeyValueListingStore;
-    private final ProtoStore<ChunksMetadataProto.ChunkListing> mChunkListingStore;
-    private final KvBackupEncrypter mKvBackupEncrypter;
-    private final EncryptedBackupTask mEncryptedBackupTask;
-    private final String mPackageName;
-
-    /** Constructs new instances of {@link EncryptedKvBackupTask}. */
-    public static class EncryptedKvBackupTaskFactory {
-        /**
-         * Creates a new instance.
-         *
-         * <p>Either initializes encrypted backup or loads an existing secondary key as necessary.
-         *
-         * @param cryptoSettings to load secondary key state from
-         * @param fileDescriptor to read the backup data from
-         */
-        public EncryptedKvBackupTask newInstance(
-                Context context,
-                SecureRandom secureRandom,
-                CryptoBackupServer cryptoBackupServer,
-                CryptoSettings cryptoSettings,
-                RecoverableKeyStoreSecondaryKeyManager
-                                .RecoverableKeyStoreSecondaryKeyManagerProvider
-                        recoverableSecondaryKeyManagerProvider,
-                ParcelFileDescriptor fileDescriptor,
-                String packageName)
-                throws IOException, UnrecoverableKeyException, LockScreenRequiredException,
-                        InternalRecoveryServiceException, InvalidKeyException {
-            RecoverableKeyStoreSecondaryKey secondaryKey =
-                    new InitializeRecoverableSecondaryKeyTask(
-                                    context,
-                                    cryptoSettings,
-                                    recoverableSecondaryKeyManagerProvider.get(),
-                                    cryptoBackupServer)
-                            .run();
-            KvBackupEncrypter backupEncrypter =
-                    new KvBackupEncrypter(new BackupDataInput(fileDescriptor.getFileDescriptor()));
-            TertiaryKeyManager tertiaryKeyManager =
-                    new TertiaryKeyManager(
-                            context,
-                            secureRandom,
-                            TertiaryKeyRotationScheduler.getInstance(context),
-                            secondaryKey,
-                            packageName);
-
-            return new EncryptedKvBackupTask(
-                    tertiaryKeyManager,
-                    ProtoStore.createKeyValueListingStore(context),
-                    secondaryKey,
-                    ProtoStore.createChunkListingStore(context),
-                    backupEncrypter,
-                    new EncryptedBackupTask(
-                            cryptoBackupServer, secureRandom, packageName, backupEncrypter),
-                    packageName);
-        }
-    }
-
-    @VisibleForTesting
-    EncryptedKvBackupTask(
-            TertiaryKeyManager tertiaryKeyManager,
-            ProtoStore<KeyValueListingProto.KeyValueListing> keyValueListingStore,
-            RecoverableKeyStoreSecondaryKey secondaryKey,
-            ProtoStore<ChunksMetadataProto.ChunkListing> chunkListingStore,
-            KvBackupEncrypter kvBackupEncrypter,
-            EncryptedBackupTask encryptedBackupTask,
-            String packageName) {
-        mTertiaryKeyManager = tertiaryKeyManager;
-        mSecondaryKey = secondaryKey;
-        mKeyValueListingStore = keyValueListingStore;
-        mChunkListingStore = chunkListingStore;
-        mKvBackupEncrypter = kvBackupEncrypter;
-        mEncryptedBackupTask = encryptedBackupTask;
-        mPackageName = packageName;
-    }
-
-    /**
-     * Reads backup data from the file descriptor provided in the construtor, encrypts it and
-     * uploads it to the server.
-     *
-     * <p>The {@code incremental} flag indicates if the backup data provided is incremental or a
-     * complete set. Incremental backup is not possible if no previous crypto state exists, or the
-     * tertiary key must be rotated in the next backup. If the caller requests incremental backup
-     * but it is not possible, then the backup will not start and this method will throw {@link
-     * NonIncrementalBackupRequiredException}.
-     *
-     * <p>TODO(b/70704456): Update return code to indicate that we require non-incremental backup.
-     *
-     * @param incremental {@code true} if the data provided is a diff from the previous backup,
-     *     {@code false} if it is a complete set
-     * @throws NonIncrementalBackupRequiredException if the caller provides an incremental backup but the task
-     *     requires non-incremental backup
-     */
-    public void performBackup(boolean incremental)
-            throws GeneralSecurityException, IOException, NoSuchMethodException,
-            InstantiationException, IllegalAccessException, InvocationTargetException,
-            NonIncrementalBackupRequiredException {
-        if (mTertiaryKeyManager.wasKeyRotated()) {
-            Slog.d(TAG, "Tertiary key is new so clearing package state.");
-            deleteListings(mPackageName);
-        }
-
-        Optional<Pair<KeyValueListingProto.KeyValueListing, ChunksMetadataProto.ChunkListing>>
-                oldListings = getListingsAndEnsureConsistency(mPackageName);
-
-        if (oldListings.isPresent() && !incremental) {
-            Slog.d(
-                    TAG,
-                    "Non-incremental backup requested but incremental state existed, clearing it");
-            deleteListings(mPackageName);
-            oldListings = Optional.empty();
-        }
-
-        if (!oldListings.isPresent() && incremental) {
-            // If we don't have any state then we require a non-incremental backup, but this backup
-            // is incremental.
-            throw new NonIncrementalBackupRequiredException();
-        }
-
-        if (oldListings.isPresent()) {
-            mKvBackupEncrypter.setOldKeyValueListing(oldListings.get().first);
-        }
-
-        ChunksMetadataProto.ChunkListing newChunkListing;
-        if (oldListings.isPresent()) {
-            Slog.v(TAG, "Old listings existed, performing incremental backup");
-            newChunkListing =
-                    mEncryptedBackupTask.performIncrementalBackup(
-                            mTertiaryKeyManager.getKey(),
-                            mTertiaryKeyManager.getWrappedKey(),
-                            oldListings.get().second);
-        } else {
-            Slog.v(TAG, "Old listings did not exist, performing non-incremental backup");
-            // kv backups don't use this salt because they don't involve content-defined chunking.
-            byte[] fingerprintMixerSalt = null;
-            newChunkListing =
-                    mEncryptedBackupTask.performNonIncrementalBackup(
-                            mTertiaryKeyManager.getKey(),
-                            mTertiaryKeyManager.getWrappedKey(),
-                            fingerprintMixerSalt);
-        }
-
-        Slog.v(TAG, "Backup and upload succeeded, saving new listings");
-        saveListings(mPackageName, mKvBackupEncrypter.getNewKeyValueListing(), newChunkListing);
-    }
-
-    private Optional<Pair<KeyValueListingProto.KeyValueListing, ChunksMetadataProto.ChunkListing>>
-            getListingsAndEnsureConsistency(String packageName)
-                    throws IOException, InvocationTargetException, NoSuchMethodException,
-                            InstantiationException, IllegalAccessException {
-        Optional<KeyValueListingProto.KeyValueListing> keyValueListing =
-                mKeyValueListingStore.loadProto(packageName);
-        Optional<ChunksMetadataProto.ChunkListing> chunkListing =
-                mChunkListingStore.loadProto(packageName);
-
-        // Normally either both protos exist or neither exist, but we correct this just in case.
-        boolean bothPresent = keyValueListing.isPresent() && chunkListing.isPresent();
-        if (!bothPresent) {
-            Slog.d(
-                    TAG,
-                    "Both listing were not present, clearing state, key value="
-                            + keyValueListing.isPresent()
-                            + ", chunk="
-                            + chunkListing.isPresent());
-            deleteListings(packageName);
-            return Optional.empty();
-        }
-
-        return Optional.of(Pair.create(keyValueListing.get(), chunkListing.get()));
-    }
-
-    private void saveListings(
-            String packageName,
-            KeyValueListingProto.KeyValueListing keyValueListing,
-            ChunksMetadataProto.ChunkListing chunkListing) {
-        try {
-            mKeyValueListingStore.saveProto(packageName, keyValueListing);
-            mChunkListingStore.saveProto(packageName, chunkListing);
-        } catch (IOException e) {
-            // If a problem occurred while saving either listing then they may be inconsistent, so
-            // delete
-            // both.
-            Slog.w(TAG, "Unable to save listings, deleting both for consistency", e);
-            deleteListings(packageName);
-        }
-    }
-
-    private void deleteListings(String packageName) {
-        mKeyValueListingStore.deleteProto(packageName);
-        mChunkListingStore.deleteProto(packageName);
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/EncryptedKvRestoreTask.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/EncryptedKvRestoreTask.java
deleted file mode 100644
index 12b4459..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/EncryptedKvRestoreTask.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.tasks;
-
-import static com.android.internal.util.Preconditions.checkArgument;
-
-import android.app.backup.BackupDataOutput;
-import android.content.Context;
-import android.os.ParcelFileDescriptor;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.server.backup.encryption.FullRestoreDownloader;
-import com.android.server.backup.encryption.chunking.ChunkHasher;
-import com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKeyManager;
-import com.android.server.backup.encryption.keys.RestoreKeyFetcher;
-import com.android.server.backup.encryption.kv.DecryptedChunkKvOutput;
-import com.android.server.backup.encryption.protos.nano.KeyValuePairProto;
-import com.android.server.backup.encryption.protos.nano.WrappedKeyProto;
-
-import java.io.File;
-import java.io.IOException;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.KeyException;
-import java.security.NoSuchAlgorithmException;
-
-import javax.crypto.BadPaddingException;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.SecretKey;
-import javax.crypto.ShortBufferException;
-
-/**
- * Performs a key value restore by downloading the backup set, decrypting it and writing it to the
- * file provided by backup manager.
- */
-public class EncryptedKvRestoreTask {
-    private static final String ENCRYPTED_FILE_NAME = "encrypted_kv";
-
-    private final File mTemporaryFolder;
-    private final ChunkHasher mChunkHasher;
-    private final FullRestoreToFileTask mFullRestoreToFileTask;
-    private final BackupFileDecryptorTask mBackupFileDecryptorTask;
-
-    /** Constructs new instances of the task. */
-    public static class EncryptedKvRestoreTaskFactory {
-        /**
-         * Constructs a new instance.
-         *
-         * <p>Fetches the appropriate secondary key and uses this to unwrap the tertiary key. Stores
-         * temporary files in {@link Context#getFilesDir()}.
-         */
-        public EncryptedKvRestoreTask newInstance(
-                Context context,
-                RecoverableKeyStoreSecondaryKeyManager
-                                .RecoverableKeyStoreSecondaryKeyManagerProvider
-                        recoverableSecondaryKeyManagerProvider,
-                FullRestoreDownloader fullRestoreDownloader,
-                String secondaryKeyAlias,
-                WrappedKeyProto.WrappedKey wrappedTertiaryKey)
-                throws EncryptedRestoreException, NoSuchAlgorithmException, NoSuchPaddingException,
-                        KeyException, InvalidAlgorithmParameterException {
-            SecretKey tertiaryKey =
-                    RestoreKeyFetcher.unwrapTertiaryKey(
-                            recoverableSecondaryKeyManagerProvider,
-                            secondaryKeyAlias,
-                            wrappedTertiaryKey);
-
-            return new EncryptedKvRestoreTask(
-                    context.getFilesDir(),
-                    new ChunkHasher(tertiaryKey),
-                    new FullRestoreToFileTask(fullRestoreDownloader),
-                    new BackupFileDecryptorTask(tertiaryKey));
-        }
-    }
-
-    @VisibleForTesting
-    EncryptedKvRestoreTask(
-            File temporaryFolder,
-            ChunkHasher chunkHasher,
-            FullRestoreToFileTask fullRestoreToFileTask,
-            BackupFileDecryptorTask backupFileDecryptorTask) {
-        checkArgument(
-                temporaryFolder.isDirectory(), "Temporary folder must be an existing directory");
-
-        mTemporaryFolder = temporaryFolder;
-        mChunkHasher = chunkHasher;
-        mFullRestoreToFileTask = fullRestoreToFileTask;
-        mBackupFileDecryptorTask = backupFileDecryptorTask;
-    }
-
-    /**
-     * Runs the restore, writing the pairs in lexicographical order to the given file descriptor.
-     *
-     * <p>This will block for the duration of the restore.
-     *
-     * @throws EncryptedRestoreException if there is a problem decrypting or verifying the backup
-     */
-    public void getRestoreData(ParcelFileDescriptor output)
-            throws IOException, EncryptedRestoreException, BadPaddingException,
-                    InvalidAlgorithmParameterException, NoSuchAlgorithmException,
-                    IllegalBlockSizeException, ShortBufferException, InvalidKeyException {
-        File encryptedFile = new File(mTemporaryFolder, ENCRYPTED_FILE_NAME);
-        try {
-            downloadDecryptAndWriteBackup(encryptedFile, output);
-        } finally {
-            encryptedFile.delete();
-        }
-    }
-
-    private void downloadDecryptAndWriteBackup(File encryptedFile, ParcelFileDescriptor output)
-            throws EncryptedRestoreException, IOException, BadPaddingException, InvalidKeyException,
-                    NoSuchAlgorithmException, IllegalBlockSizeException, ShortBufferException,
-                    InvalidAlgorithmParameterException {
-        mFullRestoreToFileTask.restoreToFile(encryptedFile);
-        DecryptedChunkKvOutput decryptedChunkKvOutput = new DecryptedChunkKvOutput(mChunkHasher);
-        mBackupFileDecryptorTask.decryptFile(encryptedFile, decryptedChunkKvOutput);
-
-        BackupDataOutput backupDataOutput = new BackupDataOutput(output.getFileDescriptor());
-        for (KeyValuePairProto.KeyValuePair pair : decryptedChunkKvOutput.getPairs()) {
-            backupDataOutput.writeEntityHeader(pair.key, pair.value.length);
-            backupDataOutput.writeEntityData(pair.value, pair.value.length);
-        }
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/EncryptedRestoreException.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/EncryptedRestoreException.java
deleted file mode 100644
index 487c0d9..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/EncryptedRestoreException.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.tasks;
-
-/** Wraps any exception related to encryption which occurs during restore. */
-public class EncryptedRestoreException extends Exception {
-    public EncryptedRestoreException(String message) {
-        super(message);
-    }
-
-    public EncryptedRestoreException(Throwable cause) {
-        super(cause);
-    }
-
-    public EncryptedRestoreException(String message, Throwable cause) {
-        super(message, cause);
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/FullRestoreToFileTask.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/FullRestoreToFileTask.java
deleted file mode 100644
index 82f83f9..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/FullRestoreToFileTask.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.tasks;
-
-import static com.android.internal.util.Preconditions.checkArgument;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.server.backup.encryption.FullRestoreDownloader;
-import com.android.server.backup.encryption.FullRestoreDownloader.FinishType;
-
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-
-/**
- * Reads a stream from a {@link FullRestoreDownloader} and writes it to a file for consumption by
- * {@link BackupFileDecryptorTask}.
- */
-public class FullRestoreToFileTask {
-    /**
-     * Maximum number of bytes which the framework can request from the full restore data stream in
-     * one call to {@link BackupTransport#getNextFullRestoreDataChunk}.
-     */
-    public static final int MAX_BYTES_FULL_RESTORE_CHUNK = 1024 * 32;
-
-    /** Returned when the end of a backup stream has been reached. */
-    private static final int END_OF_STREAM = -1;
-
-    private final FullRestoreDownloader mFullRestoreDownloader;
-    private final int mBufferSize;
-
-    /**
-     * Constructs a new instance which reads from the given package wrapper, using a buffer of size
-     * {@link #MAX_BYTES_FULL_RESTORE_CHUNK}.
-     */
-    public FullRestoreToFileTask(FullRestoreDownloader fullRestoreDownloader) {
-        this(fullRestoreDownloader, MAX_BYTES_FULL_RESTORE_CHUNK);
-    }
-
-    @VisibleForTesting
-    FullRestoreToFileTask(FullRestoreDownloader fullRestoreDownloader, int bufferSize) {
-        checkArgument(bufferSize > 0, "Buffer must have positive size");
-
-        this.mFullRestoreDownloader = fullRestoreDownloader;
-        this.mBufferSize = bufferSize;
-    }
-
-    /**
-     * Downloads the backup file from the server and writes it to the given file.
-     *
-     * <p>At the end of the download (success or failure), closes the connection and sends a
-     * Clearcut log.
-     */
-    public void restoreToFile(File targetFile) throws IOException {
-        try (BufferedOutputStream outputStream =
-                new BufferedOutputStream(new FileOutputStream(targetFile))) {
-            byte[] buffer = new byte[mBufferSize];
-            int bytesRead = mFullRestoreDownloader.readNextChunk(buffer);
-            while (bytesRead != END_OF_STREAM) {
-                outputStream.write(buffer, /* off=*/ 0, bytesRead);
-                bytesRead = mFullRestoreDownloader.readNextChunk(buffer);
-            }
-
-            outputStream.flush();
-
-            mFullRestoreDownloader.finish(FinishType.FINISHED);
-        } catch (IOException e) {
-            mFullRestoreDownloader.finish(FinishType.TRANSFER_FAILURE);
-            throw e;
-        }
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/InitializeRecoverableSecondaryKeyTask.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/InitializeRecoverableSecondaryKeyTask.java
deleted file mode 100644
index d436554..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/InitializeRecoverableSecondaryKeyTask.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.tasks;
-
-import android.content.Context;
-import android.security.keystore.recovery.InternalRecoveryServiceException;
-import android.security.keystore.recovery.LockScreenRequiredException;
-import android.security.keystore.recovery.RecoveryController;
-import android.util.Slog;
-
-import com.android.server.backup.encryption.CryptoSettings;
-import com.android.server.backup.encryption.client.CryptoBackupServer;
-import com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKey;
-import com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKeyManager;
-
-import java.security.InvalidKeyException;
-import java.security.UnrecoverableKeyException;
-import java.util.Collections;
-import java.util.Optional;
-
-/**
- * Initializes the device for encrypted backup, through generating a secondary key, and setting its
- * alias in the settings.
- *
- * <p>If the device is already initialized, this is a no-op.
- */
-public class InitializeRecoverableSecondaryKeyTask {
-    private static final String TAG = "InitializeRecoverableSecondaryKeyTask";
-
-    private final Context mContext;
-    private final CryptoSettings mCryptoSettings;
-    private final RecoverableKeyStoreSecondaryKeyManager mSecondaryKeyManager;
-    private final CryptoBackupServer mBackupServer;
-
-    /**
-     * A new instance.
-     *
-     * @param cryptoSettings Settings to store the active key alias.
-     * @param secondaryKeyManager Key manager to generate the new active secondary key.
-     * @param backupServer Server with which to sync the active key alias.
-     */
-    public InitializeRecoverableSecondaryKeyTask(
-            Context context,
-            CryptoSettings cryptoSettings,
-            RecoverableKeyStoreSecondaryKeyManager secondaryKeyManager,
-            CryptoBackupServer backupServer) {
-        mContext = context;
-        mCryptoSettings = cryptoSettings;
-        mSecondaryKeyManager = secondaryKeyManager;
-        mBackupServer = backupServer;
-    }
-
-    /**
-     * Initializes the device for encrypted backup, by generating a recoverable secondary key, then
-     * sending that alias to the backup server and saving it in local settings.
-     *
-     * <p>If there is already an active secondary key then does nothing. If the active secondary key
-     * is destroyed then throws {@link InvalidKeyException}.
-     *
-     * <p>If a key rotation is pending and able to finish (i.e., the new key has synced with the
-     * remote trusted hardware module), then it completes the rotation before returning the key.
-     *
-     * @return The active secondary key.
-     * @throws InvalidKeyException if the secondary key is in a bad state.
-     */
-    public RecoverableKeyStoreSecondaryKey run()
-            throws InvalidKeyException, LockScreenRequiredException, UnrecoverableKeyException,
-                    InternalRecoveryServiceException {
-        // Complete any pending key rotations
-        new RotateSecondaryKeyTask(
-                        mContext,
-                        mSecondaryKeyManager,
-                        mBackupServer,
-                        mCryptoSettings,
-                        RecoveryController.getInstance(mContext))
-                .run();
-
-        return runInternal();
-    }
-
-    private RecoverableKeyStoreSecondaryKey runInternal()
-            throws InvalidKeyException, LockScreenRequiredException, UnrecoverableKeyException,
-                    InternalRecoveryServiceException {
-        Optional<RecoverableKeyStoreSecondaryKey> maybeActiveKey = loadFromSetting();
-
-        if (maybeActiveKey.isPresent()) {
-            assertKeyNotDestroyed(maybeActiveKey.get());
-            Slog.d(TAG, "Secondary key already initialized: " + maybeActiveKey.get().getAlias());
-            return maybeActiveKey.get();
-        }
-
-        Slog.v(TAG, "Initializing for crypto: generating a secondary key.");
-        RecoverableKeyStoreSecondaryKey key = mSecondaryKeyManager.generate();
-
-        String alias = key.getAlias();
-        Slog.i(TAG, "Generated new secondary key " + alias);
-
-        // No tertiary keys yet as we are creating a brand new secondary (without rotation).
-        mBackupServer.setActiveSecondaryKeyAlias(alias, /*tertiaryKeys=*/ Collections.emptyMap());
-        Slog.v(TAG, "Successfully synced %s " + alias + " with server.");
-
-        mCryptoSettings.initializeWithKeyAlias(alias);
-        Slog.v(TAG, "Successfully saved " + alias + " as active secondary to disk.");
-
-        return key;
-    }
-
-    private void assertKeyNotDestroyed(RecoverableKeyStoreSecondaryKey key)
-            throws InvalidKeyException {
-        if (key.getStatus(mContext) == RecoverableKeyStoreSecondaryKey.Status.DESTROYED) {
-            throw new InvalidKeyException("Key destroyed: " + key.getAlias());
-        }
-    }
-
-    private Optional<RecoverableKeyStoreSecondaryKey> loadFromSetting()
-            throws InvalidKeyException, UnrecoverableKeyException,
-                    InternalRecoveryServiceException {
-
-        // TODO: b/141856950.
-        if (!mCryptoSettings.getIsInitialized()) {
-            return Optional.empty();
-        }
-
-        Optional<String> maybeAlias = mCryptoSettings.getActiveSecondaryKeyAlias();
-        if (!maybeAlias.isPresent()) {
-            throw new InvalidKeyException(
-                    "Settings said crypto was initialized, but there was no active secondary"
-                            + " alias");
-        }
-
-        String alias = maybeAlias.get();
-
-        Optional<RecoverableKeyStoreSecondaryKey> key;
-        key = mSecondaryKeyManager.get(alias);
-
-        if (!key.isPresent()) {
-            throw new InvalidKeyException(
-                    "Initialized with key but it was not in key store: " + alias);
-        }
-
-        return key;
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/KvBackupEncrypter.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/KvBackupEncrypter.java
deleted file mode 100644
index d20cd4c..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/KvBackupEncrypter.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.tasks;
-
-import static com.android.internal.util.Preconditions.checkState;
-
-import android.annotation.Nullable;
-import android.app.backup.BackupDataInput;
-
-import com.android.server.backup.encryption.chunk.ChunkHash;
-import com.android.server.backup.encryption.chunking.ChunkEncryptor;
-import com.android.server.backup.encryption.chunking.ChunkHasher;
-import com.android.server.backup.encryption.chunking.EncryptedChunk;
-import com.android.server.backup.encryption.kv.KeyValueListingBuilder;
-import com.android.server.backup.encryption.protos.nano.KeyValueListingProto;
-import com.android.server.backup.encryption.protos.nano.KeyValuePairProto;
-
-import java.io.IOException;
-import java.security.GeneralSecurityException;
-import java.security.InvalidKeyException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.SecretKey;
-
-/**
- * Reads key value backup data from an input, converts each pair into a chunk and encrypts the
- * chunks.
- *
- * <p>The caller should pass in the key value listing from the previous backup, if there is one.
- * This class emits chunks for both existing and new pairs, using the provided listing to
- * determine the hashes of pairs that already exist. During the backup it computes the new listing,
- * which the caller should store on disk and pass in at the start of the next backup.
- *
- * <p>Also computes the message digest, which is {@code SHA-256(chunk hashes sorted
- * lexicographically)}.
- */
-public class KvBackupEncrypter implements BackupEncrypter {
-    private final BackupDataInput mBackupDataInput;
-
-    private KeyValueListingProto.KeyValueListing mOldKeyValueListing;
-    @Nullable private KeyValueListingBuilder mNewKeyValueListing;
-
-    /**
-     * Constructs a new instance which reads data from the given input.
-     *
-     * <p>By default this performs non-incremental backup, call {@link #setOldKeyValueListing} to
-     * perform incremental backup.
-     */
-    public KvBackupEncrypter(BackupDataInput backupDataInput) {
-        mBackupDataInput = backupDataInput;
-        mOldKeyValueListing = KeyValueListingBuilder.emptyListing();
-    }
-
-    /** Sets the old listing to perform incremental backup against. */
-    public void setOldKeyValueListing(KeyValueListingProto.KeyValueListing oldKeyValueListing) {
-        mOldKeyValueListing = oldKeyValueListing;
-    }
-
-    @Override
-    public Result backup(
-            SecretKey secretKey,
-            @Nullable byte[] unusedFingerprintMixerSalt,
-            Set<ChunkHash> unusedExistingChunks)
-            throws IOException, GeneralSecurityException {
-        ChunkHasher chunkHasher = new ChunkHasher(secretKey);
-        ChunkEncryptor chunkEncryptor = new ChunkEncryptor(secretKey, new SecureRandom());
-        mNewKeyValueListing = new KeyValueListingBuilder();
-        List<ChunkHash> allChunks = new ArrayList<>();
-        List<EncryptedChunk> newChunks = new ArrayList<>();
-
-        Map<String, ChunkHash> existingChunksToReuse = buildPairMap(mOldKeyValueListing);
-
-        while (mBackupDataInput.readNextHeader()) {
-            String key = mBackupDataInput.getKey();
-            Optional<byte[]> value = readEntireValue(mBackupDataInput);
-
-            // As this pair exists in the new backup, we don't need to add it from the previous
-            // backup.
-            existingChunksToReuse.remove(key);
-
-            // If the value is not present then this key has been deleted.
-            if (value.isPresent()) {
-                EncryptedChunk newChunk =
-                        createEncryptedChunk(chunkHasher, chunkEncryptor, key, value.get());
-                allChunks.add(newChunk.key());
-                newChunks.add(newChunk);
-                mNewKeyValueListing.addPair(key, newChunk.key());
-            }
-        }
-
-        allChunks.addAll(existingChunksToReuse.values());
-
-        mNewKeyValueListing.addAll(existingChunksToReuse);
-
-        return new Result(allChunks, newChunks, createMessageDigest(allChunks));
-    }
-
-    /**
-     * Returns a listing containing the pairs in the new backup.
-     *
-     * <p>You must call {@link #backup} first.
-     */
-    public KeyValueListingProto.KeyValueListing getNewKeyValueListing() {
-        checkState(mNewKeyValueListing != null, "Must call backup() first");
-        return mNewKeyValueListing.build();
-    }
-
-    private static Map<String, ChunkHash> buildPairMap(
-            KeyValueListingProto.KeyValueListing listing) {
-        Map<String, ChunkHash> map = new HashMap<>();
-        for (KeyValueListingProto.KeyValueEntry entry : listing.entries) {
-            map.put(entry.key, new ChunkHash(entry.hash));
-        }
-        return map;
-    }
-
-    private EncryptedChunk createEncryptedChunk(
-            ChunkHasher chunkHasher, ChunkEncryptor chunkEncryptor, String key, byte[] value)
-            throws InvalidKeyException, IllegalBlockSizeException {
-        KeyValuePairProto.KeyValuePair pair = new KeyValuePairProto.KeyValuePair();
-        pair.key = key;
-        pair.value = Arrays.copyOf(value, value.length);
-
-        byte[] plaintext = KeyValuePairProto.KeyValuePair.toByteArray(pair);
-        return chunkEncryptor.encrypt(chunkHasher.computeHash(plaintext), plaintext);
-    }
-
-    private static byte[] createMessageDigest(List<ChunkHash> allChunks)
-            throws NoSuchAlgorithmException {
-        MessageDigest messageDigest =
-                MessageDigest.getInstance(BackupEncrypter.MESSAGE_DIGEST_ALGORITHM);
-        // TODO:b/141531271 Extract sorted chunks code to utility class
-        List<ChunkHash> sortedChunks = new ArrayList<>(allChunks);
-        Collections.sort(sortedChunks);
-        for (ChunkHash hash : sortedChunks) {
-            messageDigest.update(hash.getHash());
-        }
-        return messageDigest.digest();
-    }
-
-    private static Optional<byte[]> readEntireValue(BackupDataInput input) throws IOException {
-        // A negative data size indicates that this key should be deleted.
-        if (input.getDataSize() < 0) {
-            return Optional.empty();
-        }
-
-        byte[] value = new byte[input.getDataSize()];
-        int bytesRead = 0;
-        while (bytesRead < value.length) {
-            bytesRead += input.readEntityData(value, bytesRead, value.length - bytesRead);
-        }
-        return Optional.of(value);
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/MalformedEncryptedFileException.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/MalformedEncryptedFileException.java
deleted file mode 100644
index 78c370b..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/MalformedEncryptedFileException.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.tasks;
-
-/** Exception thrown when we cannot parse the encrypted backup file. */
-public class MalformedEncryptedFileException extends EncryptedRestoreException {
-    public MalformedEncryptedFileException(String message) {
-        super(message);
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/MessageDigestMismatchException.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/MessageDigestMismatchException.java
deleted file mode 100644
index 1e4f43b..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/MessageDigestMismatchException.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.tasks;
-
-/**
- * Error thrown if the message digest of the plaintext backup does not match that in the {@link
- * com.android.server.backup.encryption.protos.ChunksMetadataProto.ChunkOrdering}.
- */
-public class MessageDigestMismatchException extends EncryptedRestoreException {
-    public MessageDigestMismatchException(String message) {
-        super(message);
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/NoActiveSecondaryKeyException.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/NoActiveSecondaryKeyException.java
deleted file mode 100644
index 72e8a89..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/NoActiveSecondaryKeyException.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.tasks;
-
-/**
- * Error thrown if attempting to rotate key when there is no current active secondary key set
- * locally. This means the device needs to re-initialize, asking the backup server what the active
- * secondary key is.
- */
-public class NoActiveSecondaryKeyException extends Exception {
-    public NoActiveSecondaryKeyException(String message) {
-        super(message);
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/NonIncrementalBackupRequiredException.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/NonIncrementalBackupRequiredException.java
deleted file mode 100644
index a3eda7d..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/NonIncrementalBackupRequiredException.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.tasks;
-
-// TODO(141840878): Update documentation.
-/**
- * Exception thrown when the framework provides an incremental backup but the transport requires a
- * non-incremental backup.
- */
-public class NonIncrementalBackupRequiredException extends Exception {}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/RotateSecondaryKeyTask.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/RotateSecondaryKeyTask.java
deleted file mode 100644
index e5e2c1c..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/RotateSecondaryKeyTask.java
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.tasks;
-
-import static android.os.Build.VERSION_CODES.P;
-
-import android.content.Context;
-import android.security.keystore.recovery.InternalRecoveryServiceException;
-import android.security.keystore.recovery.RecoveryController;
-import android.util.Slog;
-
-import com.android.server.backup.encryption.CryptoSettings;
-import com.android.server.backup.encryption.client.CryptoBackupServer;
-import com.android.server.backup.encryption.keys.KeyWrapUtils;
-import com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKey;
-import com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKeyManager;
-import com.android.server.backup.encryption.keys.TertiaryKeyStore;
-import com.android.server.backup.encryption.protos.nano.WrappedKeyProto;
-
-import java.io.IOException;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.UnrecoverableKeyException;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.SecretKey;
-
-/**
- * Finishes a rotation for a {@link
- * com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKey}.
- */
-public class RotateSecondaryKeyTask {
-    private static final String TAG = "RotateSecondaryKeyTask";
-
-    private final Context mContext;
-    private final RecoverableKeyStoreSecondaryKeyManager mSecondaryKeyManager;
-    private final CryptoBackupServer mBackupServer;
-    private final CryptoSettings mCryptoSettings;
-    private final RecoveryController mRecoveryController;
-
-    /**
-     * A new instance.
-     *
-     * @param secondaryKeyManager For loading the currently active and next secondary key.
-     * @param backupServer For loading and storing tertiary keys and for setting active secondary
-     *     key.
-     * @param cryptoSettings For checking the stored aliases for the next and active key.
-     * @param recoveryController For communicating with the Framework apis.
-     */
-    public RotateSecondaryKeyTask(
-            Context context,
-            RecoverableKeyStoreSecondaryKeyManager secondaryKeyManager,
-            CryptoBackupServer backupServer,
-            CryptoSettings cryptoSettings,
-            RecoveryController recoveryController) {
-        mContext = context;
-        mSecondaryKeyManager = Objects.requireNonNull(secondaryKeyManager);
-        mCryptoSettings = Objects.requireNonNull(cryptoSettings);
-        mBackupServer = Objects.requireNonNull(backupServer);
-        mRecoveryController = Objects.requireNonNull(recoveryController);
-    }
-
-    /** Runs the task. */
-    public void run() {
-        // Never run more than one of these at the same time.
-        synchronized (RotateSecondaryKeyTask.class) {
-            runInternal();
-        }
-    }
-
-    private void runInternal() {
-        Optional<RecoverableKeyStoreSecondaryKey> maybeNextKey;
-        try {
-            maybeNextKey = getNextKey();
-        } catch (Exception e) {
-            Slog.e(TAG, "Error checking for next key", e);
-            return;
-        }
-
-        if (!maybeNextKey.isPresent()) {
-            Slog.d(TAG, "No secondary key rotation task pending. Exiting.");
-            return;
-        }
-
-        RecoverableKeyStoreSecondaryKey nextKey = maybeNextKey.get();
-        boolean isReady;
-        try {
-            isReady = isSecondaryKeyRotationReady(nextKey);
-        } catch (InternalRecoveryServiceException e) {
-            Slog.e(TAG, "Error encountered checking whether next secondary key is synced", e);
-            return;
-        }
-
-        if (!isReady) {
-            return;
-        }
-
-        try {
-            rotateToKey(nextKey);
-        } catch (Exception e) {
-            Slog.e(TAG, "Error trying to rotate to new secondary key", e);
-        }
-    }
-
-    private Optional<RecoverableKeyStoreSecondaryKey> getNextKey()
-            throws InternalRecoveryServiceException, UnrecoverableKeyException {
-        Optional<String> maybeNextAlias = mCryptoSettings.getNextSecondaryKeyAlias();
-        if (!maybeNextAlias.isPresent()) {
-            return Optional.empty();
-        }
-        return mSecondaryKeyManager.get(maybeNextAlias.get());
-    }
-
-    private boolean isSecondaryKeyRotationReady(RecoverableKeyStoreSecondaryKey nextKey)
-            throws InternalRecoveryServiceException {
-        String nextAlias = nextKey.getAlias();
-        Slog.i(TAG, "Key rotation to " + nextAlias + " is pending. Checking key sync status.");
-        int status = mRecoveryController.getRecoveryStatus(nextAlias);
-
-        if (status == RecoveryController.RECOVERY_STATUS_PERMANENT_FAILURE) {
-            Slog.e(
-                    TAG,
-                    "Permanent failure to sync " + nextAlias + ". Cannot possibly rotate to it.");
-            mCryptoSettings.removeNextSecondaryKeyAlias();
-            return false;
-        }
-
-        if (status == RecoveryController.RECOVERY_STATUS_SYNCED) {
-            Slog.i(TAG, "Secondary key " + nextAlias + " has now synced! Commencing rotation.");
-        } else {
-            Slog.i(TAG, "Sync still pending for " + nextAlias);
-        }
-        return status == RecoveryController.RECOVERY_STATUS_SYNCED;
-    }
-
-    /**
-     * @throws ActiveSecondaryNotInKeychainException if the currently active secondary key is not in
-     *     the keychain.
-     * @throws IOException if there is an IO issue communicating with the server or loading from
-     *     disk.
-     * @throws NoActiveSecondaryKeyException if there is no active key set.
-     * @throws IllegalBlockSizeException if there is an issue decrypting a tertiary key.
-     * @throws InvalidKeyException if any of the secondary keys cannot be used for wrapping or
-     *     unwrapping tertiary keys.
-     */
-    private void rotateToKey(RecoverableKeyStoreSecondaryKey newSecondaryKey)
-            throws ActiveSecondaryNotInKeychainException, IOException,
-                    NoActiveSecondaryKeyException, IllegalBlockSizeException, InvalidKeyException,
-                    InternalRecoveryServiceException, UnrecoverableKeyException,
-                    InvalidAlgorithmParameterException, NoSuchAlgorithmException,
-                    NoSuchPaddingException {
-        RecoverableKeyStoreSecondaryKey activeSecondaryKey = getActiveSecondaryKey();
-        String activeSecondaryKeyAlias = activeSecondaryKey.getAlias();
-        String newSecondaryKeyAlias = newSecondaryKey.getAlias();
-        if (newSecondaryKeyAlias.equals(activeSecondaryKeyAlias)) {
-            Slog.i(TAG, activeSecondaryKeyAlias + " was already the active alias.");
-            return;
-        }
-
-        TertiaryKeyStore tertiaryKeyStore =
-                TertiaryKeyStore.newInstance(mContext, activeSecondaryKey);
-        Map<String, SecretKey> tertiaryKeys = tertiaryKeyStore.getAll();
-
-        if (tertiaryKeys.isEmpty()) {
-            Slog.i(
-                    TAG,
-                    "No tertiary keys for " + activeSecondaryKeyAlias + ". No need to rewrap. ");
-            mBackupServer.setActiveSecondaryKeyAlias(
-                    newSecondaryKeyAlias, /*tertiaryKeys=*/ Collections.emptyMap());
-        } else {
-            Map<String, WrappedKeyProto.WrappedKey> rewrappedTertiaryKeys =
-                    rewrapAll(newSecondaryKey, tertiaryKeys);
-            TertiaryKeyStore.newInstance(mContext, newSecondaryKey).putAll(rewrappedTertiaryKeys);
-            Slog.i(
-                    TAG,
-                    "Successfully rewrapped " + rewrappedTertiaryKeys.size() + " tertiary keys");
-            mBackupServer.setActiveSecondaryKeyAlias(newSecondaryKeyAlias, rewrappedTertiaryKeys);
-            Slog.i(
-                    TAG,
-                    "Successfully uploaded new set of tertiary keys to "
-                            + newSecondaryKeyAlias
-                            + " alias");
-        }
-
-        mCryptoSettings.setActiveSecondaryKeyAlias(newSecondaryKeyAlias);
-        mCryptoSettings.removeNextSecondaryKeyAlias();
-        try {
-            mRecoveryController.removeKey(activeSecondaryKeyAlias);
-        } catch (InternalRecoveryServiceException e) {
-            Slog.e(TAG, "Error removing old secondary key from RecoverableKeyStoreLoader", e);
-        }
-    }
-
-    private RecoverableKeyStoreSecondaryKey getActiveSecondaryKey()
-            throws NoActiveSecondaryKeyException, ActiveSecondaryNotInKeychainException,
-                    InternalRecoveryServiceException, UnrecoverableKeyException {
-
-        Optional<String> activeSecondaryAlias = mCryptoSettings.getActiveSecondaryKeyAlias();
-
-        if (!activeSecondaryAlias.isPresent()) {
-            Slog.i(
-                    TAG,
-                    "Was asked to rotate secondary key, but local config did not have a secondary "
-                            + "key alias set.");
-            throw new NoActiveSecondaryKeyException("No local active secondary key set.");
-        }
-
-        String activeSecondaryKeyAlias = activeSecondaryAlias.get();
-        Optional<RecoverableKeyStoreSecondaryKey> secondaryKey =
-                mSecondaryKeyManager.get(activeSecondaryKeyAlias);
-
-        if (!secondaryKey.isPresent()) {
-            throw new ActiveSecondaryNotInKeychainException(
-                    String.format(
-                            Locale.US,
-                            "Had local active recoverable key alias of %s but key was not in"
-                                + " user's keychain.",
-                            activeSecondaryKeyAlias));
-        }
-
-        return secondaryKey.get();
-    }
-
-    /**
-     * Rewraps all the tertiary keys.
-     *
-     * @param newSecondaryKey The secondary key with which to rewrap the tertiaries.
-     * @param tertiaryKeys The tertiary keys, by package name.
-     * @return The newly wrapped tertiary keys, by package name.
-     * @throws InvalidKeyException if any key is unusable.
-     * @throws IllegalBlockSizeException if could not decrypt.
-     */
-    private Map<String, WrappedKeyProto.WrappedKey> rewrapAll(
-            RecoverableKeyStoreSecondaryKey newSecondaryKey, Map<String, SecretKey> tertiaryKeys)
-            throws InvalidKeyException, IllegalBlockSizeException, NoSuchPaddingException,
-                    NoSuchAlgorithmException {
-        Map<String, WrappedKeyProto.WrappedKey> wrappedKeys = new HashMap<>();
-
-        for (String packageName : tertiaryKeys.keySet()) {
-            SecretKey tertiaryKey = tertiaryKeys.get(packageName);
-            wrappedKeys.put(
-                    packageName, KeyWrapUtils.wrap(newSecondaryKey.getSecretKey(), tertiaryKey));
-        }
-
-        return wrappedKeys;
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/SizeQuotaExceededException.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/SizeQuotaExceededException.java
deleted file mode 100644
index 515db86..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/SizeQuotaExceededException.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.tasks;
-
-/** Exception thrown when aa backup has exceeded the space allowed for that user */
-public class SizeQuotaExceededException extends RuntimeException {
-    public SizeQuotaExceededException() {
-        super("Backup size quota exceeded.");
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/StartSecondaryKeyRotationTask.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/StartSecondaryKeyRotationTask.java
deleted file mode 100644
index 81169e2..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/StartSecondaryKeyRotationTask.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.tasks;
-
-import android.security.keystore.recovery.InternalRecoveryServiceException;
-import android.security.keystore.recovery.LockScreenRequiredException;
-import android.util.Slog;
-
-import com.android.internal.util.Preconditions;
-import com.android.server.backup.encryption.CryptoSettings;
-import com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKey;
-import com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKeyManager;
-
-import java.security.UnrecoverableKeyException;
-import java.util.Objects;
-import java.util.Optional;
-
-/**
- * Starts rotating to a new secondary key. Cannot complete until the screen is unlocked and the new
- * key is synced.
- */
-public class StartSecondaryKeyRotationTask {
-    private static final String TAG = "BE-StSecondaryKeyRotTsk";
-
-    private final CryptoSettings mCryptoSettings;
-    private final RecoverableKeyStoreSecondaryKeyManager mSecondaryKeyManager;
-
-    public StartSecondaryKeyRotationTask(
-            CryptoSettings cryptoSettings,
-            RecoverableKeyStoreSecondaryKeyManager secondaryKeyManager) {
-        mCryptoSettings = Objects.requireNonNull(cryptoSettings);
-        mSecondaryKeyManager = Objects.requireNonNull(secondaryKeyManager);
-    }
-
-    /** Begin the key rotation */
-    public void run() {
-        Slog.i(TAG, "Attempting to initiate a secondary key rotation.");
-
-        Optional<String> maybeCurrentAlias = mCryptoSettings.getActiveSecondaryKeyAlias();
-        if (!maybeCurrentAlias.isPresent()) {
-            Slog.w(TAG, "No active current alias. Cannot trigger a secondary rotation.");
-            return;
-        }
-        String currentAlias = maybeCurrentAlias.get();
-
-        Optional<String> maybeNextAlias = mCryptoSettings.getNextSecondaryKeyAlias();
-        if (maybeNextAlias.isPresent()) {
-            String nextAlias = maybeNextAlias.get();
-            if (nextAlias.equals(currentAlias)) {
-                // Shouldn't be possible, but guard against accidentally deleting the active key.
-                Slog.e(TAG, "Was already trying to rotate to what is already the active key.");
-            } else {
-                Slog.w(TAG, "Was already rotating to another key. Cancelling that.");
-                try {
-                    mSecondaryKeyManager.remove(nextAlias);
-                } catch (Exception e) {
-                    Slog.wtf(TAG, "Could not remove old key", e);
-                }
-            }
-            mCryptoSettings.removeNextSecondaryKeyAlias();
-        }
-
-        RecoverableKeyStoreSecondaryKey newSecondaryKey;
-        try {
-            newSecondaryKey = mSecondaryKeyManager.generate();
-        } catch (LockScreenRequiredException e) {
-            Slog.e(TAG, "No lock screen is set - cannot generate a new key to rotate to.", e);
-            return;
-        } catch (InternalRecoveryServiceException e) {
-            Slog.e(TAG, "Internal error in Recovery Controller, failed to rotate key.", e);
-            return;
-        } catch (UnrecoverableKeyException e) {
-            Slog.e(TAG, "Failed to get key after generating, failed to rotate", e);
-            return;
-        }
-
-        String alias = newSecondaryKey.getAlias();
-        Slog.i(TAG, "Generated a new secondary key with alias '" + alias + "'.");
-        try {
-            mCryptoSettings.setNextSecondaryAlias(alias);
-            Slog.i(TAG, "Successfully set '" + alias + "' as next key to rotate to");
-        } catch (IllegalArgumentException e) {
-            Slog.e(TAG, "Unexpected error setting next alias", e);
-            try {
-                mSecondaryKeyManager.remove(alias);
-            } catch (Exception err) {
-                Slog.wtf(TAG, "Failed to remove generated key after encountering error", err);
-            }
-        }
-    }
-}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/UnsupportedEncryptedFileException.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/UnsupportedEncryptedFileException.java
deleted file mode 100644
index 9a97e38..0000000
--- a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/UnsupportedEncryptedFileException.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.tasks;
-
-/**
- * Thrown when the backup file provided by the server uses encryption algorithms this version of
- * backup does not support. This could happen if the backup was created with a newer version of the
- * code.
- */
-public class UnsupportedEncryptedFileException extends EncryptedRestoreException {
-    public UnsupportedEncryptedFileException(String message) {
-        super(message);
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric-integration/Android.bp b/packages/BackupEncryption/test/robolectric-integration/Android.bp
deleted file mode 100644
index c842e42..0000000
--- a/packages/BackupEncryption/test/robolectric-integration/Android.bp
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (C) 2019 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 {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "frameworks_base_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["frameworks_base_license"],
-}
-
-android_robolectric_test {
-    name: "BackupEncryptionRoboIntegTests",
-    srcs: [
-        "src/**/*.java",
-    ],
-    java_resource_dirs: ["config"],
-    libs: [
-        "backup-encryption-protos",
-        "platform-test-annotations",
-        "testng",
-        "truth-prebuilt",
-        "BackupEncryptionRoboTests",
-    ],
-    static_libs: [
-        "androidx.test.core",
-        "androidx.test.runner",
-        "androidx.test.rules",
-    ],
-    instrumentation_for: "BackupEncryption",
-}
diff --git a/packages/BackupEncryption/test/robolectric-integration/AndroidManifest.xml b/packages/BackupEncryption/test/robolectric-integration/AndroidManifest.xml
deleted file mode 100644
index c3930cc..0000000
--- a/packages/BackupEncryption/test/robolectric-integration/AndroidManifest.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2019 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.
-  -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          coreApp="true"
-          package="com.android.server.backup.encryption.robointeg">
-
-    <application/>
-
-</manifest>
diff --git a/packages/BackupEncryption/test/robolectric-integration/config/robolectric.properties b/packages/BackupEncryption/test/robolectric-integration/config/robolectric.properties
deleted file mode 100644
index 26fceb3..0000000
--- a/packages/BackupEncryption/test/robolectric-integration/config/robolectric.properties
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# Copyright (C) 2019 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.
-#
-
-sdk=NEWEST_SDK
diff --git a/packages/BackupEncryption/test/robolectric-integration/src/com/android/server/backup/encryption/RoundTripTest.java b/packages/BackupEncryption/test/robolectric-integration/src/com/android/server/backup/encryption/RoundTripTest.java
deleted file mode 100644
index a432d91..0000000
--- a/packages/BackupEncryption/test/robolectric-integration/src/com/android/server/backup/encryption/RoundTripTest.java
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.Context;
-import android.os.ParcelFileDescriptor;
-import android.security.keystore.recovery.InternalRecoveryServiceException;
-import android.security.keystore.recovery.RecoveryController;
-
-import androidx.test.core.app.ApplicationProvider;
-
-import com.android.server.backup.encryption.client.CryptoBackupServer;
-import com.android.server.backup.encryption.keys.KeyWrapUtils;
-import com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKey;
-import com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKeyManager;
-import com.android.server.backup.encryption.keys.TertiaryKeyManager;
-import com.android.server.backup.encryption.keys.TertiaryKeyRotationScheduler;
-import com.android.server.backup.encryption.protos.nano.WrappedKeyProto;
-import com.android.server.backup.encryption.tasks.EncryptedFullBackupTask;
-import com.android.server.backup.encryption.tasks.EncryptedFullRestoreTask;
-import com.android.server.backup.encryption.tasks.EncryptedKvBackupTask;
-import com.android.server.backup.encryption.tasks.EncryptedKvRestoreTask;
-import com.android.server.testing.shadows.DataEntity;
-import com.android.server.testing.shadows.ShadowBackupDataInput;
-import com.android.server.testing.shadows.ShadowBackupDataOutput;
-import com.android.server.testing.shadows.ShadowRecoveryController;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.util.Optional;
-import java.util.Map;
-import java.util.Set;
-
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.KeyGenerator;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.SecretKey;
-
-@Config(
-        shadows = {
-            ShadowBackupDataInput.class,
-            ShadowBackupDataOutput.class,
-            ShadowRecoveryController.class
-        })
-@RunWith(RobolectricTestRunner.class)
-public class RoundTripTest {
-    private static final DataEntity[] KEY_VALUE_DATA = {
-        new DataEntity("test_key_1", "test_value_1"),
-        new DataEntity("test_key_2", "test_value_2"),
-        new DataEntity("test_key_3", "test_value_3")
-    };
-
-    /** Amount of data we want to round trip in this test */
-    private static final int TEST_DATA_SIZE = 1024 * 1024; // 1MB
-
-    /** Buffer size used when reading data from the restore task */
-    private static final int READ_BUFFER_SIZE = 1024; // 1024 byte buffer.
-
-    /** Key parameters used for the secondary encryption key */
-    private static final String KEY_ALGORITHM = "AES";
-
-    private static final int KEY_SIZE_BITS = 256;
-
-    /** Package name for our test package */
-    private static final String TEST_PACKAGE_NAME = "com.android.backup.test";
-
-    /** The name we use to refer to our secondary key */
-    private static final String TEST_KEY_ALIAS = "test/backup/KEY_ALIAS";
-
-    /** Original data used for comparison after round trip */
-    private final byte[] mOriginalData = new byte[TEST_DATA_SIZE];
-
-    /** App context, used to store the key data and chunk listings */
-    private Context mContext;
-
-    /** The secondary key we're using for the test */
-    private RecoverableKeyStoreSecondaryKey mSecondaryKey;
-
-    /** Source of random material which is considered non-predictable in its' generation */
-    private final SecureRandom mSecureRandom = new SecureRandom();
-
-    private RecoverableKeyStoreSecondaryKeyManager.RecoverableKeyStoreSecondaryKeyManagerProvider
-            mSecondaryKeyManagerProvider;
-    private DummyServer mDummyServer;
-    private RecoveryController mRecoveryController;
-
-    @Mock private ParcelFileDescriptor mParcelFileDescriptor;
-
-    @Before
-    public void setUp() throws NoSuchAlgorithmException, InternalRecoveryServiceException {
-        MockitoAnnotations.initMocks(this);
-
-        ShadowBackupDataInput.reset();
-        ShadowBackupDataOutput.reset();
-
-        mContext = ApplicationProvider.getApplicationContext();
-        mSecondaryKey = new RecoverableKeyStoreSecondaryKey(TEST_KEY_ALIAS, generateAesKey());
-        mDummyServer = new DummyServer();
-        mSecondaryKeyManagerProvider =
-                () ->
-                        new RecoverableKeyStoreSecondaryKeyManager(
-                                RecoveryController.getInstance(mContext), mSecureRandom);
-
-        fillBuffer(mOriginalData);
-    }
-
-    @Test
-    public void testFull_nonIncrementalBackupAndRestoreAreSuccessful() throws Exception {
-        byte[] backupData = performFullBackup(mOriginalData);
-        assertThat(backupData).isNotEqualTo(mOriginalData);
-        byte[] restoredData = performFullRestore(backupData);
-        assertThat(restoredData).isEqualTo(mOriginalData);
-    }
-
-    @Test
-    public void testKeyValue_nonIncrementalBackupAndRestoreAreSuccessful() throws Exception {
-        byte[] backupData = performNonIncrementalKeyValueBackup(KEY_VALUE_DATA);
-
-        // Get the secondary key used to do backup.
-        Optional<RecoverableKeyStoreSecondaryKey> secondaryKey =
-                mSecondaryKeyManagerProvider.get().get(mDummyServer.mSecondaryKeyAlias);
-        assertThat(secondaryKey.isPresent()).isTrue();
-
-        Set<DataEntity> restoredData = performKeyValueRestore(backupData, secondaryKey.get());
-
-        assertThat(restoredData).containsExactly(KEY_VALUE_DATA).inOrder();
-    }
-
-    /** Perform a key/value backup and return the backed-up representation of the data */
-    private byte[] performNonIncrementalKeyValueBackup(DataEntity[] backupData)
-            throws Exception {
-        // Populate test key/value data.
-        for (DataEntity entity : backupData) {
-            ShadowBackupDataInput.addEntity(entity);
-        }
-
-        EncryptedKvBackupTask.EncryptedKvBackupTaskFactory backupTaskFactory =
-                new EncryptedKvBackupTask.EncryptedKvBackupTaskFactory();
-        EncryptedKvBackupTask backupTask =
-                backupTaskFactory.newInstance(
-                        mContext,
-                        mSecureRandom,
-                        mDummyServer,
-                        CryptoSettings.getInstance(mContext),
-                        mSecondaryKeyManagerProvider,
-                        mParcelFileDescriptor,
-                        TEST_PACKAGE_NAME);
-
-        backupTask.performBackup(/* incremental */ false);
-
-        return mDummyServer.mStoredData;
-    }
-
-    /** Perform a full backup and return the backed-up representation of the data */
-    private byte[] performFullBackup(byte[] backupData) throws Exception {
-        DummyServer dummyServer = new DummyServer();
-        EncryptedFullBackupTask backupTask =
-                EncryptedFullBackupTask.newInstance(
-                        mContext,
-                        dummyServer,
-                        mSecureRandom,
-                        mSecondaryKey,
-                        TEST_PACKAGE_NAME,
-                        new ByteArrayInputStream(backupData));
-        backupTask.call();
-        return dummyServer.mStoredData;
-    }
-
-    private Set<DataEntity> performKeyValueRestore(
-            byte[] backupData, RecoverableKeyStoreSecondaryKey secondaryKey) throws Exception {
-        EncryptedKvRestoreTask.EncryptedKvRestoreTaskFactory restoreTaskFactory =
-                new EncryptedKvRestoreTask.EncryptedKvRestoreTaskFactory();
-        EncryptedKvRestoreTask restoreTask =
-                restoreTaskFactory.newInstance(
-                        mContext,
-                        mSecondaryKeyManagerProvider,
-                        new FakeFullRestoreDownloader(backupData),
-                        secondaryKey.getAlias(),
-                        KeyWrapUtils.wrap(
-                                secondaryKey.getSecretKey(), getTertiaryKey(secondaryKey)));
-        restoreTask.getRestoreData(mParcelFileDescriptor);
-        return ShadowBackupDataOutput.getEntities();
-    }
-
-    /** Perform a full restore and return the bytes obtained from the restore process */
-    private byte[] performFullRestore(byte[] backupData)
-            throws IOException, NoSuchAlgorithmException, NoSuchPaddingException,
-                    InvalidAlgorithmParameterException, InvalidKeyException,
-                    IllegalBlockSizeException {
-        ByteArrayOutputStream decryptedOutput = new ByteArrayOutputStream();
-
-        EncryptedFullRestoreTask restoreTask =
-                EncryptedFullRestoreTask.newInstance(
-                        mContext,
-                        new FakeFullRestoreDownloader(backupData),
-                        getTertiaryKey(mSecondaryKey));
-
-        byte[] buffer = new byte[READ_BUFFER_SIZE];
-        int bytesRead = restoreTask.readNextChunk(buffer);
-        while (bytesRead != -1) {
-            decryptedOutput.write(buffer, 0, bytesRead);
-            bytesRead = restoreTask.readNextChunk(buffer);
-        }
-
-        return decryptedOutput.toByteArray();
-    }
-
-    /** Get the tertiary key for our test package from the key manager */
-    private SecretKey getTertiaryKey(RecoverableKeyStoreSecondaryKey secondaryKey)
-            throws IllegalBlockSizeException, InvalidAlgorithmParameterException,
-                    NoSuchAlgorithmException, IOException, NoSuchPaddingException,
-                    InvalidKeyException {
-        TertiaryKeyManager tertiaryKeyManager =
-                new TertiaryKeyManager(
-                        mContext,
-                        mSecureRandom,
-                        TertiaryKeyRotationScheduler.getInstance(mContext),
-                        secondaryKey,
-                        TEST_PACKAGE_NAME);
-        return tertiaryKeyManager.getKey();
-    }
-
-    /** Fill a buffer with data in a predictable way */
-    private void fillBuffer(byte[] buffer) {
-        byte loopingCounter = 0;
-        for (int i = 0; i < buffer.length; i++) {
-            buffer[i] = loopingCounter;
-            loopingCounter++;
-        }
-    }
-
-    /** Generate a new, random, AES key */
-    public static SecretKey generateAesKey() throws NoSuchAlgorithmException {
-        KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_ALGORITHM);
-        keyGenerator.init(KEY_SIZE_BITS);
-        return keyGenerator.generateKey();
-    }
-
-    /**
-     * Dummy backup data endpoint. This stores the data so we can use it in subsequent test steps.
-     */
-    private static class DummyServer implements CryptoBackupServer {
-        private static final String DUMMY_DOC_ID = "DummyDoc";
-
-        byte[] mStoredData = null;
-        String mSecondaryKeyAlias;
-
-        @Override
-        public String uploadIncrementalBackup(
-                String packageName,
-                String oldDocId,
-                byte[] diffScript,
-                WrappedKeyProto.WrappedKey tertiaryKey) {
-            throw new RuntimeException("Not Implemented");
-        }
-
-        @Override
-        public String uploadNonIncrementalBackup(
-                String packageName, byte[] data, WrappedKeyProto.WrappedKey tertiaryKey) {
-            assertThat(packageName).isEqualTo(TEST_PACKAGE_NAME);
-            mStoredData = data;
-            return DUMMY_DOC_ID;
-        }
-
-        @Override
-        public void setActiveSecondaryKeyAlias(
-                String keyAlias, Map<String, WrappedKeyProto.WrappedKey> tertiaryKeys) {
-            mSecondaryKeyAlias = keyAlias;
-        }
-    }
-
-    /** Fake package wrapper which returns data from a byte array. */
-    private static class FakeFullRestoreDownloader extends FullRestoreDownloader {
-        private final ByteArrayInputStream mData;
-
-        FakeFullRestoreDownloader(byte[] data) {
-            // We override all methods of the superclass, so it does not require any collaborators.
-            super();
-            mData = new ByteArrayInputStream(data);
-        }
-
-        @Override
-        public int readNextChunk(byte[] buffer) throws IOException {
-            return mData.read(buffer);
-        }
-
-        @Override
-        public void finish(FinishType finishType) {
-            // Do nothing.
-        }
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/Android.bp b/packages/BackupEncryption/test/robolectric/Android.bp
deleted file mode 100644
index 7665d8f..0000000
--- a/packages/BackupEncryption/test/robolectric/Android.bp
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (C) 2018 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 {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "frameworks_base_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["frameworks_base_license"],
-}
-
-android_robolectric_test {
-    name: "BackupEncryptionRoboTests",
-    srcs: [
-        "src/**/*.java",
-//        ":FrameworksServicesRoboShadows",
-    ],
-    java_resource_dirs: ["config"],
-    libs: [
-        "backup-encryption-protos",
-        "platform-test-annotations",
-        "testng",
-        "truth-prebuilt",
-    ],
-    static_libs: [
-        "androidx.test.core",
-        "androidx.test.runner",
-        "androidx.test.rules",
-    ],
-    instrumentation_for: "BackupEncryption",
-}
-
-filegroup {
-    name: "BackupEncryptionRoboShadows",
-    srcs: ["src/com/android/server/testing/shadows/**/*.java"],
-}
diff --git a/packages/BackupEncryption/test/robolectric/AndroidManifest.xml b/packages/BackupEncryption/test/robolectric/AndroidManifest.xml
deleted file mode 100644
index ae5cdd9..0000000
--- a/packages/BackupEncryption/test/robolectric/AndroidManifest.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2019 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.
-  -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          coreApp="true"
-          package="com.android.server.backup.encryption.robotests">
-
-    <application/>
-
-</manifest>
diff --git a/packages/BackupEncryption/test/robolectric/config/robolectric.properties b/packages/BackupEncryption/test/robolectric/config/robolectric.properties
deleted file mode 100644
index 26fceb3..0000000
--- a/packages/BackupEncryption/test/robolectric/config/robolectric.properties
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# Copyright (C) 2019 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.
-#
-
-sdk=NEWEST_SDK
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/CryptoSettingsTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/CryptoSettingsTest.java
deleted file mode 100644
index 979b3d5..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/CryptoSettingsTest.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.testng.Assert.assertThrows;
-
-import android.app.Application;
-import android.security.keystore.recovery.RecoveryController;
-
-import androidx.test.core.app.ApplicationProvider;
-
-import com.android.server.testing.shadows.ShadowRecoveryController;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-import java.util.Optional;
-
-@RunWith(RobolectricTestRunner.class)
-@Config(shadows = ShadowRecoveryController.class)
-public class CryptoSettingsTest {
-
-    private static final String TEST_KEY_ALIAS =
-            "com.android.server.backup.encryption/keystore/08120c326b928ff34c73b9c58581da63";
-
-    private CryptoSettings mCryptoSettings;
-    private Application mApplication;
-
-    @Before
-    public void setUp() {
-        ShadowRecoveryController.reset();
-
-        mApplication = ApplicationProvider.getApplicationContext();
-        mCryptoSettings = CryptoSettings.getInstanceForTesting(mApplication);
-    }
-
-    @Test
-    public void getActiveSecondaryAlias_isInitiallyAbsent() {
-        assertThat(mCryptoSettings.getActiveSecondaryKeyAlias().isPresent()).isFalse();
-    }
-
-    @Test
-    public void getActiveSecondaryAlias_returnsAliasIfKeyIsInRecoveryController() throws Exception {
-        setAliasIsInRecoveryController(TEST_KEY_ALIAS);
-        mCryptoSettings.setActiveSecondaryKeyAlias(TEST_KEY_ALIAS);
-        assertThat(mCryptoSettings.getActiveSecondaryKeyAlias().get()).isEqualTo(TEST_KEY_ALIAS);
-    }
-
-    @Test
-    public void getNextSecondaryAlias_isInitiallyAbsent() {
-        assertThat(mCryptoSettings.getNextSecondaryKeyAlias().isPresent()).isFalse();
-    }
-
-    @Test
-    public void getNextSecondaryAlias_returnsAliasIfKeyIsInRecoveryController() throws Exception {
-        setAliasIsInRecoveryController(TEST_KEY_ALIAS);
-        mCryptoSettings.setNextSecondaryAlias(TEST_KEY_ALIAS);
-        assertThat(mCryptoSettings.getNextSecondaryKeyAlias().get()).isEqualTo(TEST_KEY_ALIAS);
-    }
-
-    @Test
-    public void isInitialized_isInitiallyFalse() {
-        assertThat(mCryptoSettings.getIsInitialized()).isFalse();
-    }
-
-    @Test
-    public void setActiveSecondaryAlias_throwsIfKeyIsNotInRecoveryController() {
-        assertThrows(
-                IllegalArgumentException.class,
-                () -> mCryptoSettings.setActiveSecondaryKeyAlias(TEST_KEY_ALIAS));
-    }
-
-    @Test
-    public void setNextSecondaryAlias_inRecoveryController_setsAlias() throws Exception {
-        setAliasIsInRecoveryController(TEST_KEY_ALIAS);
-
-        mCryptoSettings.setNextSecondaryAlias(TEST_KEY_ALIAS);
-
-        assertThat(mCryptoSettings.getNextSecondaryKeyAlias().get()).isEqualTo(TEST_KEY_ALIAS);
-    }
-
-    @Test
-    public void setNextSecondaryAlias_throwsIfKeyIsNotInRecoveryController() {
-        assertThrows(
-                IllegalArgumentException.class,
-                () -> mCryptoSettings.setNextSecondaryAlias(TEST_KEY_ALIAS));
-    }
-
-    @Test
-    public void removeNextSecondaryAlias_removesIt() throws Exception {
-        setAliasIsInRecoveryController(TEST_KEY_ALIAS);
-        mCryptoSettings.setNextSecondaryAlias(TEST_KEY_ALIAS);
-
-        mCryptoSettings.removeNextSecondaryKeyAlias();
-
-        assertThat(mCryptoSettings.getNextSecondaryKeyAlias().isPresent()).isFalse();
-    }
-
-    @Test
-    public void initializeWithKeyAlias_setsAsInitialized() throws Exception {
-        setAliasIsInRecoveryController(TEST_KEY_ALIAS);
-        mCryptoSettings.initializeWithKeyAlias(TEST_KEY_ALIAS);
-        assertThat(mCryptoSettings.getIsInitialized()).isTrue();
-    }
-
-    @Test
-    public void initializeWithKeyAlias_setsActiveAlias() throws Exception {
-        setAliasIsInRecoveryController(TEST_KEY_ALIAS);
-        mCryptoSettings.initializeWithKeyAlias(TEST_KEY_ALIAS);
-        assertThat(mCryptoSettings.getActiveSecondaryKeyAlias().get()).isEqualTo(TEST_KEY_ALIAS);
-    }
-
-    @Test
-    public void initializeWithKeyAlias_throwsIfKeyIsNotInRecoveryController() {
-        assertThrows(
-                IllegalArgumentException.class,
-                () -> mCryptoSettings.initializeWithKeyAlias(TEST_KEY_ALIAS));
-    }
-
-    @Test
-    public void initializeWithKeyAlias_throwsIfAlreadyInitialized() throws Exception {
-        setAliasIsInRecoveryController(TEST_KEY_ALIAS);
-        mCryptoSettings.initializeWithKeyAlias(TEST_KEY_ALIAS);
-
-        assertThrows(
-                IllegalStateException.class,
-                () -> mCryptoSettings.initializeWithKeyAlias(TEST_KEY_ALIAS));
-    }
-
-    @Test
-    public void getSecondaryLastRotated_returnsEmptyInitially() {
-        assertThat(mCryptoSettings.getSecondaryLastRotated()).isEqualTo(Optional.empty());
-    }
-
-    @Test
-    public void getSecondaryLastRotated_returnsTimestampAfterItIsSet() {
-        long timestamp = 1000001;
-
-        mCryptoSettings.setSecondaryLastRotated(timestamp);
-
-        assertThat(mCryptoSettings.getSecondaryLastRotated().get()).isEqualTo(timestamp);
-    }
-
-    @Test
-    public void getAncestralSecondaryKeyVersion_notSet_returnsOptionalAbsent() {
-        assertThat(mCryptoSettings.getAncestralSecondaryKeyVersion().isPresent()).isFalse();
-    }
-
-    @Test
-    public void getAncestralSecondaryKeyVersion_isSet_returnsSetValue() {
-        String secondaryKeyVersion = "some_secondary_key";
-        mCryptoSettings.setAncestralSecondaryKeyVersion(secondaryKeyVersion);
-
-        assertThat(mCryptoSettings.getAncestralSecondaryKeyVersion().get())
-                .isEqualTo(secondaryKeyVersion);
-    }
-
-    @Test
-    public void getAncestralSecondaryKeyVersion_isSetMultipleTimes_returnsLastSetValue() {
-        String secondaryKeyVersion1 = "some_secondary_key";
-        String secondaryKeyVersion2 = "another_secondary_key";
-        mCryptoSettings.setAncestralSecondaryKeyVersion(secondaryKeyVersion1);
-        mCryptoSettings.setAncestralSecondaryKeyVersion(secondaryKeyVersion2);
-
-        assertThat(mCryptoSettings.getAncestralSecondaryKeyVersion().get())
-                .isEqualTo(secondaryKeyVersion2);
-    }
-
-    @Test
-    public void clearAllSettingsForBackup_clearsStateForBackup() throws Exception {
-        String key1 = "key1";
-        String key2 = "key2";
-        String ancestralKey = "ancestral_key";
-        setAliasIsInRecoveryController(key1);
-        setAliasIsInRecoveryController(key2);
-        mCryptoSettings.setActiveSecondaryKeyAlias(key1);
-        mCryptoSettings.setNextSecondaryAlias(key2);
-        mCryptoSettings.setSecondaryLastRotated(100001);
-        mCryptoSettings.setAncestralSecondaryKeyVersion(ancestralKey);
-
-        mCryptoSettings.clearAllSettingsForBackup();
-
-        assertThat(mCryptoSettings.getActiveSecondaryKeyAlias().isPresent()).isFalse();
-        assertThat(mCryptoSettings.getNextSecondaryKeyAlias().isPresent()).isFalse();
-        assertThat(mCryptoSettings.getSecondaryLastRotated().isPresent()).isFalse();
-        assertThat(mCryptoSettings.getAncestralSecondaryKeyVersion().get()).isEqualTo(ancestralKey);
-    }
-
-    private void setAliasIsInRecoveryController(String alias) throws Exception {
-        RecoveryController recoveryController = RecoveryController.getInstance(mApplication);
-        recoveryController.generateKey(alias);
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/StreamUtilsTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/StreamUtilsTest.java
deleted file mode 100644
index a95e87e..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/StreamUtilsTest.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-@RunWith(RobolectricTestRunner.class)
-public class StreamUtilsTest {
-    private static final int SOURCE_DATA_SIZE = 64;
-
-    private byte[] mSourceData;
-
-    private InputStream mSource;
-    private ByteArrayOutputStream mDestination;
-
-    @Before
-    public void setUp() {
-        mSourceData = new byte[SOURCE_DATA_SIZE];
-        for (byte i = 0; i < SOURCE_DATA_SIZE; i++) {
-            mSourceData[i] = i;
-        }
-        mSource = new ByteArrayInputStream(mSourceData);
-        mDestination = new ByteArrayOutputStream();
-    }
-
-    @Test
-    public void copyStream_copiesAllBytesIfAsked() throws IOException {
-        StreamUtils.copyStream(mSource, mDestination, mSourceData.length);
-        assertOutputHasBytes(mSourceData.length);
-    }
-
-    @Test
-    public void copyStream_stopsShortIfAsked() throws IOException {
-        StreamUtils.copyStream(mSource, mDestination, mSourceData.length - 10);
-        assertOutputHasBytes(mSourceData.length - 10);
-    }
-
-    @Test
-    public void copyStream_stopsShortIfAskedToCopyMoreThanAvailable() throws IOException {
-        StreamUtils.copyStream(mSource, mDestination, mSourceData.length + 10);
-        assertOutputHasBytes(mSourceData.length);
-    }
-
-    private void assertOutputHasBytes(int count) {
-        byte[] output = mDestination.toByteArray();
-        assertThat(output.length).isEqualTo(count);
-        for (int i = 0; i < count; i++) {
-            assertThat(output[i]).isEqualTo(mSourceData[i]);
-        }
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunk/ChunkHashTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunk/ChunkHashTest.java
deleted file mode 100644
index c12464c..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunk/ChunkHashTest.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.chunk;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.platform.test.annotations.Presubmit;
-
-import com.google.common.primitives.Bytes;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-
-import java.util.Arrays;
-
-@RunWith(RobolectricTestRunner.class)
-@Presubmit
-public class ChunkHashTest {
-    private static final int HASH_LENGTH_BYTES = 256 / 8;
-    private static final byte[] TEST_HASH_1 = Arrays.copyOf(new byte[] {1}, HASH_LENGTH_BYTES);
-    private static final byte[] TEST_HASH_2 = Arrays.copyOf(new byte[] {2}, HASH_LENGTH_BYTES);
-
-    @Test
-    public void testGetHash_returnsHash() {
-        ChunkHash chunkHash = new ChunkHash(TEST_HASH_1);
-
-        byte[] hash = chunkHash.getHash();
-
-        assertThat(hash).asList().containsExactlyElementsIn(Bytes.asList(TEST_HASH_1)).inOrder();
-    }
-
-    @Test
-    public void testEquals() {
-        ChunkHash chunkHash1 = new ChunkHash(TEST_HASH_1);
-        ChunkHash equalChunkHash1 = new ChunkHash(TEST_HASH_1);
-        ChunkHash chunkHash2 = new ChunkHash(TEST_HASH_2);
-
-        assertThat(chunkHash1).isEqualTo(equalChunkHash1);
-        assertThat(chunkHash1).isNotEqualTo(chunkHash2);
-    }
-
-    @Test
-    public void testHashCode() {
-        ChunkHash chunkHash1 = new ChunkHash(TEST_HASH_1);
-        ChunkHash equalChunkHash1 = new ChunkHash(TEST_HASH_1);
-        ChunkHash chunkHash2 = new ChunkHash(TEST_HASH_2);
-
-        int hash1 = chunkHash1.hashCode();
-        int equalHash1 = equalChunkHash1.hashCode();
-        int hash2 = chunkHash2.hashCode();
-
-        assertThat(hash1).isEqualTo(equalHash1);
-        assertThat(hash1).isNotEqualTo(hash2);
-    }
-
-    @Test
-    public void testCompareTo_whenEqual_returnsZero() {
-        ChunkHash chunkHash = new ChunkHash(TEST_HASH_1);
-        ChunkHash equalChunkHash = new ChunkHash(TEST_HASH_1);
-
-        int result = chunkHash.compareTo(equalChunkHash);
-
-        assertThat(result).isEqualTo(0);
-    }
-
-    @Test
-    public void testCompareTo_whenArgumentGreater_returnsNegative() {
-        ChunkHash chunkHash1 = new ChunkHash(TEST_HASH_1);
-        ChunkHash chunkHash2 = new ChunkHash(TEST_HASH_2);
-
-        int result = chunkHash1.compareTo(chunkHash2);
-
-        assertThat(result).isLessThan(0);
-    }
-
-    @Test
-    public void testCompareTo_whenArgumentSmaller_returnsPositive() {
-        ChunkHash chunkHash1 = new ChunkHash(TEST_HASH_1);
-        ChunkHash chunkHash2 = new ChunkHash(TEST_HASH_2);
-
-        int result = chunkHash2.compareTo(chunkHash1);
-
-        assertThat(result).isGreaterThan(0);
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunk/ChunkListingMapTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunk/ChunkListingMapTest.java
deleted file mode 100644
index c5f78c2..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunk/ChunkListingMapTest.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.chunk;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.platform.test.annotations.Presubmit;
-
-import com.android.server.backup.encryption.protos.nano.ChunksMetadataProto;
-
-import com.google.common.base.Charsets;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-
-import java.util.Arrays;
-
-@RunWith(RobolectricTestRunner.class)
-@Presubmit
-public class ChunkListingMapTest {
-    private static final ChunkHash CHUNK_A_HASH = getHash("CHUNK_A");
-    private static final ChunkHash CHUNK_B_HASH = getHash("CHUNK_B");
-    private static final ChunkHash CHUNK_C_HASH = getHash("CHUNK_C");
-
-    private static final int CHUNK_A_LENGTH = 256;
-    private static final int CHUNK_B_LENGTH = 1024;
-    private static final int CHUNK_C_LENGTH = 4055;
-
-    private static final int CHUNK_A_START = 0;
-    private static final int CHUNK_B_START = CHUNK_A_START + CHUNK_A_LENGTH;
-    private static final int CHUNK_C_START = CHUNK_B_START + CHUNK_B_LENGTH;
-
-    private ChunkListingMap mChunkListingMap;
-
-    @Before
-    public void setUp() {
-        mChunkListingMap = createFromFixture();
-    }
-
-    @Test
-    public void hasChunk_isTrueForExistingChunks() {
-        assertThat(mChunkListingMap.hasChunk(CHUNK_A_HASH)).isTrue();
-        assertThat(mChunkListingMap.hasChunk(CHUNK_B_HASH)).isTrue();
-        assertThat(mChunkListingMap.hasChunk(CHUNK_C_HASH)).isTrue();
-    }
-
-    @Test
-    public void hasChunk_isFalseForNonexistentChunks() {
-        assertThat(mChunkListingMap.hasChunk(getHash("CHUNK_D"))).isFalse();
-        assertThat(mChunkListingMap.hasChunk(getHash(""))).isFalse();
-    }
-
-    @Test
-    public void getChunkListing_hasCorrectLengths() {
-        assertThat(mChunkListingMap.getChunkEntry(CHUNK_A_HASH).getLength())
-                .isEqualTo(CHUNK_A_LENGTH);
-        assertThat(mChunkListingMap.getChunkEntry(CHUNK_B_HASH).getLength())
-                .isEqualTo(CHUNK_B_LENGTH);
-        assertThat(mChunkListingMap.getChunkEntry(CHUNK_C_HASH).getLength())
-                .isEqualTo(CHUNK_C_LENGTH);
-    }
-
-    @Test
-    public void getChunkListing_hasCorrectStarts() {
-        assertThat(mChunkListingMap.getChunkEntry(CHUNK_A_HASH).getStart())
-                .isEqualTo(CHUNK_A_START);
-        assertThat(mChunkListingMap.getChunkEntry(CHUNK_B_HASH).getStart())
-                .isEqualTo(CHUNK_B_START);
-        assertThat(mChunkListingMap.getChunkEntry(CHUNK_C_HASH).getStart())
-                .isEqualTo(CHUNK_C_START);
-    }
-
-    @Test
-    public void getChunkListing_isNullForNonExistentChunks() {
-        assertThat(mChunkListingMap.getChunkEntry(getHash("Hey"))).isNull();
-    }
-
-    private static ChunkListingMap createFromFixture() {
-        ChunksMetadataProto.ChunkListing chunkListing = new ChunksMetadataProto.ChunkListing();
-        chunkListing.chunks = new ChunksMetadataProto.Chunk[3];
-        chunkListing.chunks[0] = newChunk(CHUNK_A_HASH.getHash(), CHUNK_A_LENGTH);
-        chunkListing.chunks[1] = newChunk(CHUNK_B_HASH.getHash(), CHUNK_B_LENGTH);
-        chunkListing.chunks[2] = newChunk(CHUNK_C_HASH.getHash(), CHUNK_C_LENGTH);
-        return ChunkListingMap.fromProto(chunkListing);
-    }
-
-    private static ChunkHash getHash(String name) {
-        return new ChunkHash(
-                Arrays.copyOf(name.getBytes(Charsets.UTF_8), ChunkHash.HASH_LENGTH_BYTES));
-    }
-
-    public static ChunksMetadataProto.Chunk newChunk(byte[] hash, int length) {
-        ChunksMetadataProto.Chunk newChunk = new ChunksMetadataProto.Chunk();
-        newChunk.hash = Arrays.copyOf(hash, hash.length);
-        newChunk.length = length;
-        return newChunk;
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunk/EncryptedChunkOrderingTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunk/EncryptedChunkOrderingTest.java
deleted file mode 100644
index c6b29b7b..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunk/EncryptedChunkOrderingTest.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.chunk;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.platform.test.annotations.Presubmit;
-
-import com.google.common.primitives.Bytes;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-
-@RunWith(RobolectricTestRunner.class)
-@Presubmit
-public class EncryptedChunkOrderingTest {
-    private static final byte[] TEST_BYTE_ARRAY_1 = new byte[] {1, 2, 3, 4, 5};
-    private static final byte[] TEST_BYTE_ARRAY_2 = new byte[] {5, 4, 3, 2, 1};
-
-    @Test
-    public void testEncryptedChunkOrdering_returnsValue() {
-        EncryptedChunkOrdering encryptedChunkOrdering =
-                EncryptedChunkOrdering.create(TEST_BYTE_ARRAY_1);
-
-        byte[] bytes = encryptedChunkOrdering.encryptedChunkOrdering();
-
-        assertThat(bytes)
-                .asList()
-                .containsExactlyElementsIn(Bytes.asList(TEST_BYTE_ARRAY_1))
-                .inOrder();
-    }
-
-    @Test
-    public void testEquals() {
-        EncryptedChunkOrdering chunkOrdering1 = EncryptedChunkOrdering.create(TEST_BYTE_ARRAY_1);
-        EncryptedChunkOrdering equalChunkOrdering1 =
-                EncryptedChunkOrdering.create(TEST_BYTE_ARRAY_1);
-        EncryptedChunkOrdering chunkOrdering2 = EncryptedChunkOrdering.create(TEST_BYTE_ARRAY_2);
-
-        assertThat(chunkOrdering1).isEqualTo(equalChunkOrdering1);
-        assertThat(chunkOrdering1).isNotEqualTo(chunkOrdering2);
-    }
-
-    @Test
-    public void testHashCode() {
-        EncryptedChunkOrdering chunkOrdering1 = EncryptedChunkOrdering.create(TEST_BYTE_ARRAY_1);
-        EncryptedChunkOrdering equalChunkOrdering1 =
-                EncryptedChunkOrdering.create(TEST_BYTE_ARRAY_1);
-        EncryptedChunkOrdering chunkOrdering2 = EncryptedChunkOrdering.create(TEST_BYTE_ARRAY_2);
-
-        int hash1 = chunkOrdering1.hashCode();
-        int equalHash1 = equalChunkOrdering1.hashCode();
-        int hash2 = chunkOrdering2.hashCode();
-
-        assertThat(hash1).isEqualTo(equalHash1);
-        assertThat(hash1).isNotEqualTo(hash2);
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/BackupFileBuilderTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/BackupFileBuilderTest.java
deleted file mode 100644
index 590938e..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/BackupFileBuilderTest.java
+++ /dev/null
@@ -1,614 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.chunking;
-
-import static com.android.server.backup.encryption.protos.nano.ChunksMetadataProto.AES_256_GCM;
-import static com.android.server.backup.encryption.protos.nano.ChunksMetadataProto.CHUNK_ORDERING_TYPE_UNSPECIFIED;
-import static com.android.server.backup.testing.CryptoTestUtils.newChunk;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import static junit.framework.Assert.fail;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.testng.Assert.assertThrows;
-
-import static java.nio.charset.StandardCharsets.UTF_8;
-
-import android.platform.test.annotations.Presubmit;
-
-import com.android.server.backup.encryption.chunk.ChunkHash;
-import com.android.server.backup.encryption.protos.nano.ChunksMetadataProto;
-import com.android.server.backup.encryption.testing.DiffScriptProcessor;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.io.Files;
-import com.google.common.primitives.Bytes;
-import com.google.common.primitives.Longs;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-@RunWith(RobolectricTestRunner.class)
-@Presubmit
-public class BackupFileBuilderTest {
-    private static final String TEST_DATA_1 =
-            "I'm already there or close to [T7-9/executive level] in terms of big-picture vision";
-    private static final String TEST_DATA_2 =
-            "I was known for Real Games and should have been brought in for advice";
-    private static final String TEST_DATA_3 =
-            "Pride is rooted in the delusional belief held by all humans in an unchanging self";
-
-    private static final byte[] TEST_FINGERPRINT_MIXER_SALT =
-            Arrays.copyOf(new byte[] {22}, ChunkHash.HASH_LENGTH_BYTES);
-
-    private static final ChunkHash TEST_HASH_1 =
-            new ChunkHash(Arrays.copyOf(new byte[] {0}, EncryptedChunk.KEY_LENGTH_BYTES));
-    private static final ChunkHash TEST_HASH_2 =
-            new ChunkHash(Arrays.copyOf(new byte[] {1}, EncryptedChunk.KEY_LENGTH_BYTES));
-    private static final ChunkHash TEST_HASH_3 =
-            new ChunkHash(Arrays.copyOf(new byte[] {2}, EncryptedChunk.KEY_LENGTH_BYTES));
-
-    private static final byte[] TEST_NONCE =
-            Arrays.copyOf(new byte[] {3}, EncryptedChunk.NONCE_LENGTH_BYTES);
-
-    private static final EncryptedChunk TEST_CHUNK_1 =
-            EncryptedChunk.create(TEST_HASH_1, TEST_NONCE, TEST_DATA_1.getBytes(UTF_8));
-    private static final EncryptedChunk TEST_CHUNK_2 =
-            EncryptedChunk.create(TEST_HASH_2, TEST_NONCE, TEST_DATA_2.getBytes(UTF_8));
-    private static final EncryptedChunk TEST_CHUNK_3 =
-            EncryptedChunk.create(TEST_HASH_3, TEST_NONCE, TEST_DATA_3.getBytes(UTF_8));
-
-    private static final byte[] TEST_CHECKSUM = {1, 2, 3, 4, 5, 6};
-
-    @Rule public TemporaryFolder mTemporaryFolder = new TemporaryFolder();
-
-    private File mOldFile;
-    private ChunksMetadataProto.ChunkListing mOldChunkListing;
-    private EncryptedChunkEncoder mEncryptedChunkEncoder;
-
-    @Before
-    public void setUp() {
-        mEncryptedChunkEncoder = new LengthlessEncryptedChunkEncoder();
-    }
-
-    @Test
-    public void writeChunks_nonIncremental_writesCorrectRawData() throws Exception {
-        ByteArrayOutputStream output = new ByteArrayOutputStream();
-        BackupFileBuilder backupFileBuilder = BackupFileBuilder.createForNonIncremental(output);
-
-        backupFileBuilder.writeChunks(
-                ImmutableList.of(TEST_HASH_1, TEST_HASH_2),
-                getNewChunkMap(TEST_HASH_1, TEST_HASH_2));
-
-        byte[] actual = output.toByteArray();
-        byte[] expected =
-                Bytes.concat(
-                        TEST_CHUNK_1.nonce(),
-                        TEST_CHUNK_1.encryptedBytes(),
-                        TEST_CHUNK_2.nonce(),
-                        TEST_CHUNK_2.encryptedBytes());
-        assertThat(actual).asList().containsExactlyElementsIn(Bytes.asList(expected)).inOrder();
-    }
-
-    @Test
-    public void writeChunks_nonIncrementalWithDuplicates_writesEachChunkOnlyOnce()
-            throws Exception {
-        ByteArrayOutputStream output = new ByteArrayOutputStream();
-        BackupFileBuilder backupFileBuilder = BackupFileBuilder.createForNonIncremental(output);
-
-        backupFileBuilder.writeChunks(
-                ImmutableList.of(TEST_HASH_1, TEST_HASH_2, TEST_HASH_1),
-                getNewChunkMap(TEST_HASH_1, TEST_HASH_2));
-
-        byte[] actual = output.toByteArray();
-        byte[] expected =
-                Bytes.concat(
-                        TEST_CHUNK_1.nonce(),
-                        TEST_CHUNK_1.encryptedBytes(),
-                        TEST_CHUNK_2.nonce(),
-                        TEST_CHUNK_2.encryptedBytes());
-        assertThat(actual).asList().containsExactlyElementsIn(Bytes.asList(expected)).inOrder();
-    }
-
-    @Test
-    public void writeChunks_incremental_writesParsableDiffScript() throws Exception {
-        // We will insert chunk 2 in between chunks 1 and 3.
-        setUpOldBackupWithChunks(ImmutableList.of(TEST_CHUNK_1, TEST_CHUNK_3));
-        ByteArrayOutputStream diffOutputStream = new ByteArrayOutputStream();
-        BackupFileBuilder backupFileBuilder =
-                BackupFileBuilder.createForIncremental(diffOutputStream, mOldChunkListing);
-
-        backupFileBuilder.writeChunks(
-                ImmutableList.of(TEST_HASH_1, TEST_HASH_2, TEST_HASH_3),
-                getNewChunkMap(TEST_HASH_2));
-        backupFileBuilder.finish(getTestMetadata());
-
-        byte[] actual =
-                stripMetadataAndPositionFromOutput(parseDiffScript(diffOutputStream.toByteArray()));
-        byte[] expected =
-                Bytes.concat(
-                        TEST_CHUNK_1.nonce(),
-                        TEST_CHUNK_1.encryptedBytes(),
-                        TEST_CHUNK_2.nonce(),
-                        TEST_CHUNK_2.encryptedBytes(),
-                        TEST_CHUNK_3.nonce(),
-                        TEST_CHUNK_3.encryptedBytes());
-        assertThat(actual).asList().containsExactlyElementsIn(Bytes.asList(expected)).inOrder();
-    }
-
-    @Test
-    public void writeChunks_incrementalWithDuplicates_writesEachChunkOnlyOnce() throws Exception {
-        // We will insert chunk 2 twice in between chunks 1 and 3.
-        setUpOldBackupWithChunks(ImmutableList.of(TEST_CHUNK_1, TEST_CHUNK_3));
-        ByteArrayOutputStream diffOutputStream = new ByteArrayOutputStream();
-        BackupFileBuilder backupFileBuilder =
-                BackupFileBuilder.createForIncremental(diffOutputStream, mOldChunkListing);
-
-        backupFileBuilder.writeChunks(
-                ImmutableList.of(TEST_HASH_1, TEST_HASH_2, TEST_HASH_2, TEST_HASH_3),
-                getNewChunkMap(TEST_HASH_2));
-        backupFileBuilder.finish(getTestMetadata());
-
-        byte[] actual =
-                stripMetadataAndPositionFromOutput(parseDiffScript(diffOutputStream.toByteArray()));
-        byte[] expected =
-                Bytes.concat(
-                        TEST_CHUNK_1.nonce(),
-                        TEST_CHUNK_1.encryptedBytes(),
-                        TEST_CHUNK_2.nonce(),
-                        TEST_CHUNK_2.encryptedBytes(),
-                        TEST_CHUNK_3.nonce(),
-                        TEST_CHUNK_3.encryptedBytes());
-        assertThat(actual).asList().containsExactlyElementsIn(Bytes.asList(expected)).inOrder();
-    }
-
-    @Test
-    public void writeChunks_writesChunksInOrderOfHash() throws Exception {
-        setUpOldBackupWithChunks(ImmutableList.of());
-        ByteArrayOutputStream diffOutputStream = new ByteArrayOutputStream();
-        BackupFileBuilder backupFileBuilder =
-                BackupFileBuilder.createForIncremental(diffOutputStream, mOldChunkListing);
-
-        // Write chunks out of order.
-        backupFileBuilder.writeChunks(
-                ImmutableList.of(TEST_HASH_2, TEST_HASH_1),
-                getNewChunkMap(TEST_HASH_2, TEST_HASH_1));
-        backupFileBuilder.finish(getTestMetadata());
-
-        byte[] actual =
-                stripMetadataAndPositionFromOutput(parseDiffScript(diffOutputStream.toByteArray()));
-        byte[] expected =
-                Bytes.concat(
-                        TEST_CHUNK_1.nonce(),
-                        TEST_CHUNK_1.encryptedBytes(),
-                        TEST_CHUNK_2.nonce(),
-                        TEST_CHUNK_2.encryptedBytes());
-        assertThat(actual).asList().containsExactlyElementsIn(Bytes.asList(expected)).inOrder();
-    }
-
-    @Test
-    public void writeChunks_alreadyFlushed_throwsException() throws Exception {
-        BackupFileBuilder backupFileBuilder =
-                BackupFileBuilder.createForIncremental(
-                        new ByteArrayOutputStream(), new ChunksMetadataProto.ChunkListing());
-        backupFileBuilder.finish(getTestMetadata());
-
-        assertThrows(
-                IllegalStateException.class,
-                () -> backupFileBuilder.writeChunks(ImmutableList.of(), getNewChunkMap()));
-    }
-
-    @Test
-    public void getNewChunkListing_hasChunksInOrderOfKey() throws Exception {
-        // We will insert chunk 2 in between chunks 1 and 3.
-        setUpOldBackupWithChunks(ImmutableList.of(TEST_CHUNK_1, TEST_CHUNK_3));
-        BackupFileBuilder backupFileBuilder =
-                BackupFileBuilder.createForIncremental(
-                        new ByteArrayOutputStream(), mOldChunkListing);
-
-        // Write chunks out of order.
-        backupFileBuilder.writeChunks(
-                ImmutableList.of(TEST_HASH_1, TEST_HASH_3, TEST_HASH_2),
-                getNewChunkMap(TEST_HASH_2));
-        backupFileBuilder.finish(getTestMetadata());
-
-        ChunksMetadataProto.ChunkListing expected = expectedChunkListing();
-        ChunksMetadataProto.ChunkListing actual =
-                backupFileBuilder.getNewChunkListing(TEST_FINGERPRINT_MIXER_SALT);
-        assertListingsEqual(actual, expected);
-    }
-
-    @Test
-    public void getNewChunkListing_writeChunksInTwoBatches_returnsListingContainingAllChunks()
-            throws Exception {
-        // We will insert chunk 2 in between chunks 1 and 3.
-        setUpOldBackupWithChunks(ImmutableList.of(TEST_CHUNK_1, TEST_CHUNK_3));
-        BackupFileBuilder backupFileBuilder =
-                BackupFileBuilder.createForIncremental(
-                        new ByteArrayOutputStream(), mOldChunkListing);
-
-        backupFileBuilder.writeChunks(
-                ImmutableList.of(TEST_HASH_1, TEST_HASH_2), getNewChunkMap(TEST_HASH_2));
-        backupFileBuilder.writeChunks(ImmutableList.of(TEST_HASH_3), getNewChunkMap(TEST_HASH_2));
-        backupFileBuilder.finish(getTestMetadata());
-
-        ChunksMetadataProto.ChunkListing expected = expectedChunkListing();
-        ChunksMetadataProto.ChunkListing actual =
-                backupFileBuilder.getNewChunkListing(TEST_FINGERPRINT_MIXER_SALT);
-        assertListingsEqual(actual, expected);
-    }
-
-    @Test
-    public void getNewChunkListing_writeDuplicateChunks_writesEachChunkOnlyOnce() throws Exception {
-        // We will append [2][3][3][2] onto [1].
-        setUpOldBackupWithChunks(ImmutableList.of(TEST_CHUNK_1));
-        BackupFileBuilder backupFileBuilder =
-                BackupFileBuilder.createForIncremental(
-                        new ByteArrayOutputStream(), mOldChunkListing);
-
-        backupFileBuilder.writeChunks(
-                ImmutableList.of(TEST_HASH_1, TEST_HASH_2, TEST_HASH_3),
-                getNewChunkMap(TEST_HASH_3, TEST_HASH_2));
-        backupFileBuilder.writeChunks(
-                ImmutableList.of(TEST_HASH_3, TEST_HASH_2),
-                getNewChunkMap(TEST_HASH_3, TEST_HASH_2));
-        backupFileBuilder.finish(getTestMetadata());
-
-        ChunksMetadataProto.ChunkListing expected = expectedChunkListing();
-        ChunksMetadataProto.ChunkListing actual =
-                backupFileBuilder.getNewChunkListing(TEST_FINGERPRINT_MIXER_SALT);
-        assertListingsEqual(actual, expected);
-    }
-
-    @Test
-    public void getNewChunkListing_nonIncrementalWithNoSalt_doesNotThrowOnSerialisation() {
-        BackupFileBuilder backupFileBuilder =
-                BackupFileBuilder.createForNonIncremental(new ByteArrayOutputStream());
-
-        ChunksMetadataProto.ChunkListing newChunkListing =
-                backupFileBuilder.getNewChunkListing(/*fingerprintMixerSalt=*/ null);
-
-        // Does not throw.
-        ChunksMetadataProto.ChunkListing.toByteArray(newChunkListing);
-    }
-
-    @Test
-    public void getNewChunkListing_incrementalWithNoSalt_doesNotThrowOnSerialisation()
-            throws Exception {
-
-        setUpOldBackupWithChunks(ImmutableList.of());
-        BackupFileBuilder backupFileBuilder =
-                BackupFileBuilder.createForIncremental(
-                        new ByteArrayOutputStream(), mOldChunkListing);
-
-        ChunksMetadataProto.ChunkListing newChunkListing =
-                backupFileBuilder.getNewChunkListing(/*fingerprintMixerSalt=*/ null);
-
-        // Does not throw.
-        ChunksMetadataProto.ChunkListing.toByteArray(newChunkListing);
-    }
-
-    @Test
-    public void getNewChunkListing_nonIncrementalWithNoSalt_hasEmptySalt() {
-        BackupFileBuilder backupFileBuilder =
-                BackupFileBuilder.createForNonIncremental(new ByteArrayOutputStream());
-
-        ChunksMetadataProto.ChunkListing newChunkListing =
-                backupFileBuilder.getNewChunkListing(/*fingerprintMixerSalt=*/ null);
-
-        assertThat(newChunkListing.fingerprintMixerSalt).isEmpty();
-    }
-
-    @Test
-    public void getNewChunkListing_incrementalWithNoSalt_hasEmptySalt() throws Exception {
-        setUpOldBackupWithChunks(ImmutableList.of());
-        BackupFileBuilder backupFileBuilder =
-                BackupFileBuilder.createForIncremental(
-                        new ByteArrayOutputStream(), mOldChunkListing);
-
-        ChunksMetadataProto.ChunkListing newChunkListing =
-                backupFileBuilder.getNewChunkListing(/*fingerprintMixerSalt=*/ null);
-
-        assertThat(newChunkListing.fingerprintMixerSalt).isEmpty();
-    }
-
-    @Test
-    public void getNewChunkListing_nonIncrementalWithSalt_hasGivenSalt() {
-        BackupFileBuilder backupFileBuilder =
-                BackupFileBuilder.createForNonIncremental(new ByteArrayOutputStream());
-
-        ChunksMetadataProto.ChunkListing newChunkListing =
-                backupFileBuilder.getNewChunkListing(TEST_FINGERPRINT_MIXER_SALT);
-
-        assertThat(newChunkListing.fingerprintMixerSalt).isEqualTo(TEST_FINGERPRINT_MIXER_SALT);
-    }
-
-    @Test
-    public void getNewChunkListing_incrementalWithSalt_hasGivenSalt() throws Exception {
-        setUpOldBackupWithChunks(ImmutableList.of());
-        BackupFileBuilder backupFileBuilder =
-                BackupFileBuilder.createForIncremental(
-                        new ByteArrayOutputStream(), mOldChunkListing);
-
-        ChunksMetadataProto.ChunkListing newChunkListing =
-                backupFileBuilder.getNewChunkListing(TEST_FINGERPRINT_MIXER_SALT);
-
-        assertThat(newChunkListing.fingerprintMixerSalt).isEqualTo(TEST_FINGERPRINT_MIXER_SALT);
-    }
-
-    @Test
-    public void getNewChunkListing_nonIncremental_hasCorrectCipherTypeAndChunkOrderingType() {
-        BackupFileBuilder backupFileBuilder =
-                BackupFileBuilder.createForNonIncremental(new ByteArrayOutputStream());
-
-        ChunksMetadataProto.ChunkListing newChunkListing =
-                backupFileBuilder.getNewChunkListing(/*fingerprintMixerSalt=*/ null);
-
-        assertThat(newChunkListing.cipherType).isEqualTo(ChunksMetadataProto.AES_256_GCM);
-        assertThat(newChunkListing.chunkOrderingType)
-                .isEqualTo(ChunksMetadataProto.CHUNK_ORDERING_TYPE_UNSPECIFIED);
-    }
-
-    @Test
-    public void getNewChunkListing_incremental_hasCorrectCipherTypeAndChunkOrderingType()
-            throws Exception {
-        setUpOldBackupWithChunks(ImmutableList.of());
-        BackupFileBuilder backupFileBuilder =
-                BackupFileBuilder.createForIncremental(
-                        new ByteArrayOutputStream(), mOldChunkListing);
-
-        ChunksMetadataProto.ChunkListing newChunkListing =
-                backupFileBuilder.getNewChunkListing(/*fingerprintMixerSalt=*/ null);
-
-        assertThat(newChunkListing.cipherType).isEqualTo(ChunksMetadataProto.AES_256_GCM);
-        assertThat(newChunkListing.chunkOrderingType)
-                .isEqualTo(ChunksMetadataProto.CHUNK_ORDERING_TYPE_UNSPECIFIED);
-    }
-
-    @Test
-    public void getNewChunkOrdering_chunksHaveCorrectStartPositions() throws Exception {
-        BackupFileBuilder backupFileBuilder =
-                BackupFileBuilder.createForIncremental(
-                        new ByteArrayOutputStream(), new ChunksMetadataProto.ChunkListing());
-
-        // Write out of order by key to check that ordering is maintained.
-        backupFileBuilder.writeChunks(
-                ImmutableList.of(TEST_HASH_1, TEST_HASH_3, TEST_HASH_2),
-                getNewChunkMap(TEST_HASH_1, TEST_HASH_3, TEST_HASH_2));
-        backupFileBuilder.finish(getTestMetadata());
-
-        ChunksMetadataProto.ChunkOrdering actual =
-                backupFileBuilder.getNewChunkOrdering(TEST_CHECKSUM);
-        // The chunks are listed in the order they are written above, but the start positions are
-        // determined by the order in the encrypted blob (which is lexicographical by key).
-        int chunk1Start = 0;
-        int chunk2Start =
-                chunk1Start + mEncryptedChunkEncoder.getEncodedLengthOfChunk(TEST_CHUNK_1);
-        int chunk3Start =
-                chunk2Start + mEncryptedChunkEncoder.getEncodedLengthOfChunk(TEST_CHUNK_2);
-
-        int[] expected = {chunk1Start, chunk3Start, chunk2Start};
-        assertThat(actual.starts.length).isEqualTo(expected.length);
-        for (int i = 0; i < actual.starts.length; i++) {
-            assertThat(expected[i]).isEqualTo(actual.starts[i]);
-        }
-    }
-
-    @Test
-    public void getNewChunkOrdering_duplicateChunks_writesDuplicates() throws Exception {
-        BackupFileBuilder backupFileBuilder =
-                BackupFileBuilder.createForIncremental(
-                        new ByteArrayOutputStream(), new ChunksMetadataProto.ChunkListing());
-
-        backupFileBuilder.writeChunks(
-                ImmutableList.of(TEST_HASH_1, TEST_HASH_2, TEST_HASH_2),
-                getNewChunkMap(TEST_HASH_1, TEST_HASH_2));
-        backupFileBuilder.writeChunks(
-                ImmutableList.of(TEST_HASH_3, TEST_HASH_3), getNewChunkMap(TEST_HASH_3));
-        backupFileBuilder.finish(getTestMetadata());
-
-        ChunksMetadataProto.ChunkOrdering actual =
-                backupFileBuilder.getNewChunkOrdering(TEST_CHECKSUM);
-        int chunk1Start = 0;
-        int chunk2Start =
-                chunk1Start + mEncryptedChunkEncoder.getEncodedLengthOfChunk(TEST_CHUNK_1);
-        int chunk3Start =
-                chunk2Start + mEncryptedChunkEncoder.getEncodedLengthOfChunk(TEST_CHUNK_2);
-
-        int[] expected = {chunk1Start, chunk2Start, chunk2Start, chunk3Start, chunk3Start};
-        assertThat(actual.starts.length).isEqualTo(expected.length);
-        for (int i = 0; i < actual.starts.length; i++) {
-            assertThat(expected[i]).isEqualTo(actual.starts[i]);
-        }
-    }
-
-    @Test
-    public void getNewChunkOrdering_returnsOrderingWithChecksum() throws Exception {
-        BackupFileBuilder backupFileBuilder =
-                BackupFileBuilder.createForIncremental(
-                        new ByteArrayOutputStream(), new ChunksMetadataProto.ChunkListing());
-
-        backupFileBuilder.writeChunks(ImmutableList.of(TEST_HASH_1), getNewChunkMap(TEST_HASH_1));
-        backupFileBuilder.finish(getTestMetadata());
-
-        ChunksMetadataProto.ChunkOrdering actual =
-                backupFileBuilder.getNewChunkOrdering(TEST_CHECKSUM);
-        assertThat(actual.checksum).isEqualTo(TEST_CHECKSUM);
-    }
-
-    @Test
-    public void finish_writesMetadata() throws Exception {
-        ByteArrayOutputStream output = new ByteArrayOutputStream();
-        BackupFileBuilder builder = BackupFileBuilder.createForNonIncremental(output);
-        ChunksMetadataProto.ChunksMetadata expectedMetadata = getTestMetadata();
-
-        builder.finish(expectedMetadata);
-
-        // The output is [metadata]+[long giving size of metadata].
-        byte[] metadataBytes =
-                Arrays.copyOfRange(output.toByteArray(), 0, output.size() - Long.BYTES);
-        ChunksMetadataProto.ChunksMetadata actualMetadata =
-                ChunksMetadataProto.ChunksMetadata.parseFrom(metadataBytes);
-        assertThat(actualMetadata.checksumType).isEqualTo(ChunksMetadataProto.SHA_256);
-        assertThat(actualMetadata.cipherType).isEqualTo(ChunksMetadataProto.AES_256_GCM);
-    }
-
-    @Test
-    public void finish_writesMetadataPosition() throws Exception {
-        ByteArrayOutputStream output = new ByteArrayOutputStream();
-        BackupFileBuilder builder = BackupFileBuilder.createForNonIncremental(output);
-
-        builder.writeChunks(
-                ImmutableList.of(TEST_HASH_1, TEST_HASH_2),
-                getNewChunkMap(TEST_HASH_1, TEST_HASH_2));
-        builder.writeChunks(ImmutableList.of(TEST_HASH_3), getNewChunkMap(TEST_HASH_3));
-        builder.finish(getTestMetadata());
-
-        long expectedPosition =
-                (long) mEncryptedChunkEncoder.getEncodedLengthOfChunk(TEST_CHUNK_1)
-                        + mEncryptedChunkEncoder.getEncodedLengthOfChunk(TEST_CHUNK_2)
-                        + mEncryptedChunkEncoder.getEncodedLengthOfChunk(TEST_CHUNK_3);
-        long actualPosition =
-                Longs.fromByteArray(
-                        Arrays.copyOfRange(
-                                output.toByteArray(), output.size() - Long.BYTES, output.size()));
-        assertThat(actualPosition).isEqualTo(expectedPosition);
-    }
-
-    @Test
-    public void finish_flushesOutputStream() throws Exception {
-        OutputStream diffOutputStream = mock(OutputStream.class);
-        BackupFileBuilder backupFileBuilder =
-                BackupFileBuilder.createForIncremental(
-                        diffOutputStream, new ChunksMetadataProto.ChunkListing());
-
-        backupFileBuilder.writeChunks(ImmutableList.of(TEST_HASH_1), getNewChunkMap(TEST_HASH_1));
-        diffOutputStream.flush();
-
-        verify(diffOutputStream).flush();
-    }
-
-    private void setUpOldBackupWithChunks(List<EncryptedChunk> chunks) throws Exception {
-        mOldFile = mTemporaryFolder.newFile();
-        ChunksMetadataProto.ChunkListing chunkListing = new ChunksMetadataProto.ChunkListing();
-        chunkListing.fingerprintMixerSalt =
-                Arrays.copyOf(TEST_FINGERPRINT_MIXER_SALT, TEST_FINGERPRINT_MIXER_SALT.length);
-        chunkListing.cipherType = AES_256_GCM;
-        chunkListing.chunkOrderingType = CHUNK_ORDERING_TYPE_UNSPECIFIED;
-
-        List<ChunksMetadataProto.Chunk> knownChunks = new ArrayList<>();
-        try (FileOutputStream outputStream = new FileOutputStream(mOldFile)) {
-            for (EncryptedChunk chunk : chunks) {
-                // Chunks are encoded in the format [nonce]+[data].
-                outputStream.write(chunk.nonce());
-                outputStream.write(chunk.encryptedBytes());
-
-                knownChunks.add(createChunkFor(chunk));
-            }
-
-            outputStream.flush();
-        }
-
-        chunkListing.chunks = knownChunks.toArray(new ChunksMetadataProto.Chunk[0]);
-        mOldChunkListing = chunkListing;
-    }
-
-    private byte[] parseDiffScript(byte[] diffScript) throws Exception {
-        File newFile = mTemporaryFolder.newFile();
-        new DiffScriptProcessor(mOldFile, newFile).process(new ByteArrayInputStream(diffScript));
-        return Files.toByteArray(newFile);
-    }
-
-    private void assertListingsEqual(
-            ChunksMetadataProto.ChunkListing result, ChunksMetadataProto.ChunkListing expected) {
-        assertThat(result.chunks.length).isEqualTo(expected.chunks.length);
-        for (int i = 0; i < result.chunks.length; i++) {
-            assertWithMessage("Chunk " + i)
-                    .that(result.chunks[i].length)
-                    .isEqualTo(expected.chunks[i].length);
-            assertWithMessage("Chunk " + i)
-                    .that(result.chunks[i].hash)
-                    .isEqualTo(expected.chunks[i].hash);
-        }
-    }
-
-    private static ImmutableMap<ChunkHash, EncryptedChunk> getNewChunkMap(ChunkHash... hashes) {
-        ImmutableMap.Builder<ChunkHash, EncryptedChunk> builder = ImmutableMap.builder();
-        for (ChunkHash hash : hashes) {
-            if (TEST_HASH_1.equals(hash)) {
-                builder.put(TEST_HASH_1, TEST_CHUNK_1);
-            } else if (TEST_HASH_2.equals(hash)) {
-                builder.put(TEST_HASH_2, TEST_CHUNK_2);
-            } else if (TEST_HASH_3.equals(hash)) {
-                builder.put(TEST_HASH_3, TEST_CHUNK_3);
-            } else {
-                fail("Hash was not recognised: " + hash);
-            }
-        }
-        return builder.build();
-    }
-
-    private static ChunksMetadataProto.ChunksMetadata getTestMetadata() {
-        ChunksMetadataProto.ChunksMetadata metadata = new ChunksMetadataProto.ChunksMetadata();
-        metadata.checksumType = ChunksMetadataProto.SHA_256;
-        metadata.cipherType = AES_256_GCM;
-        return metadata;
-    }
-
-    private static byte[] stripMetadataAndPositionFromOutput(byte[] output) {
-        long metadataStart =
-                Longs.fromByteArray(
-                        Arrays.copyOfRange(output, output.length - Long.BYTES, output.length));
-        return Arrays.copyOfRange(output, 0, (int) metadataStart);
-    }
-
-    private ChunksMetadataProto.ChunkListing expectedChunkListing() {
-        ChunksMetadataProto.ChunkListing chunkListing = new ChunksMetadataProto.ChunkListing();
-        chunkListing.fingerprintMixerSalt =
-                Arrays.copyOf(TEST_FINGERPRINT_MIXER_SALT, TEST_FINGERPRINT_MIXER_SALT.length);
-        chunkListing.cipherType = AES_256_GCM;
-        chunkListing.chunkOrderingType = CHUNK_ORDERING_TYPE_UNSPECIFIED;
-        chunkListing.chunks = new ChunksMetadataProto.Chunk[3];
-        chunkListing.chunks[0] = createChunkFor(TEST_CHUNK_1);
-        chunkListing.chunks[1] = createChunkFor(TEST_CHUNK_2);
-        chunkListing.chunks[2] = createChunkFor(TEST_CHUNK_3);
-        return chunkListing;
-    }
-
-    private ChunksMetadataProto.Chunk createChunkFor(EncryptedChunk encryptedChunk) {
-        byte[] chunkHash = encryptedChunk.key().getHash();
-        byte[] hashCopy = Arrays.copyOf(chunkHash, chunkHash.length);
-        return newChunk(hashCopy, mEncryptedChunkEncoder.getEncodedLengthOfChunk(encryptedChunk));
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/ByteRangeTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/ByteRangeTest.java
deleted file mode 100644
index 8df0826..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/ByteRangeTest.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.chunking;
-
-import static org.junit.Assert.assertEquals;
-import static org.testng.Assert.assertThrows;
-
-import android.platform.test.annotations.Presubmit;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-
-/** Tests for {@link ByteRange}. */
-@RunWith(RobolectricTestRunner.class)
-@Presubmit
-public class ByteRangeTest {
-    @Test
-    public void getLength_includesEnd() throws Exception {
-        ByteRange byteRange = new ByteRange(5, 10);
-
-        int length = byteRange.getLength();
-
-        assertEquals(6, length);
-    }
-
-    @Test
-    public void constructor_rejectsNegativeStart() {
-        assertThrows(IllegalArgumentException.class, () -> new ByteRange(-1, 10));
-    }
-
-    @Test
-    public void constructor_rejectsEndBeforeStart() {
-        assertThrows(IllegalArgumentException.class, () -> new ByteRange(10, 9));
-    }
-
-    @Test
-    public void extend_withZeroLength_throwsException() {
-        ByteRange byteRange = new ByteRange(5, 10);
-
-        assertThrows(IllegalArgumentException.class, () -> byteRange.extend(0));
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/ChunkEncryptorTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/ChunkEncryptorTest.java
deleted file mode 100644
index 19e3b28..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/ChunkEncryptorTest.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.chunking;
-
-import static com.android.server.backup.testing.CryptoTestUtils.generateAesKey;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.mock;
-
-import static java.nio.charset.StandardCharsets.UTF_8;
-
-import android.platform.test.annotations.Presubmit;
-
-import com.android.server.backup.encryption.chunk.ChunkHash;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-import org.robolectric.RobolectricTestRunner;
-
-import java.security.SecureRandom;
-
-import javax.crypto.Cipher;
-import javax.crypto.Mac;
-import javax.crypto.SecretKey;
-import javax.crypto.spec.GCMParameterSpec;
-
-@RunWith(RobolectricTestRunner.class)
-@Presubmit
-public class ChunkEncryptorTest {
-    private static final String MAC_ALGORITHM = "HmacSHA256";
-    private static final String CIPHER_ALGORITHM = "AES/GCM/NoPadding";
-    private static final int GCM_NONCE_LENGTH_BYTES = 12;
-    private static final int GCM_TAG_LENGTH_BYTES = 16;
-    private static final String CHUNK_PLAINTEXT =
-            "A little Learning is a dang'rous Thing;\n"
-                    + "Drink deep, or taste not the Pierian Spring:\n"
-                    + "There shallow Draughts intoxicate the Brain,\n"
-                    + "And drinking largely sobers us again.";
-    private static final byte[] PLAINTEXT_BYTES = CHUNK_PLAINTEXT.getBytes(UTF_8);
-    private static final byte[] NONCE_1 = "0123456789abc".getBytes(UTF_8);
-    private static final byte[] NONCE_2 = "123456789abcd".getBytes(UTF_8);
-
-    private static final byte[][] NONCES = new byte[][] {NONCE_1, NONCE_2};
-
-    @Mock private SecureRandom mSecureRandomMock;
-    private SecretKey mSecretKey;
-    private ChunkHash mPlaintextHash;
-    private ChunkEncryptor mChunkEncryptor;
-
-    @Before
-    public void setUp() throws Exception {
-        mSecretKey = generateAesKey();
-        ChunkHasher chunkHasher = new ChunkHasher(mSecretKey);
-        mPlaintextHash = chunkHasher.computeHash(PLAINTEXT_BYTES);
-        mSecureRandomMock = mock(SecureRandom.class);
-        mChunkEncryptor = new ChunkEncryptor(mSecretKey, mSecureRandomMock);
-
-        // Return NONCE_1, then NONCE_2 for invocations of mSecureRandomMock.nextBytes().
-        doAnswer(
-                    new Answer<Void>() {
-                        private int mInvocation = 0;
-
-                        @Override
-                        public Void answer(InvocationOnMock invocation) {
-                            byte[] nonceDestination = invocation.getArgument(0);
-                            System.arraycopy(
-                                    NONCES[this.mInvocation],
-                                    0,
-                                    nonceDestination,
-                                    0,
-                                    GCM_NONCE_LENGTH_BYTES);
-                            this.mInvocation++;
-                            return null;
-                        }
-                    })
-                .when(mSecureRandomMock)
-                .nextBytes(any(byte[].class));
-    }
-
-    @Test
-    public void encrypt_withHash_resultContainsHashAsKey() throws Exception {
-        EncryptedChunk chunk = mChunkEncryptor.encrypt(mPlaintextHash, PLAINTEXT_BYTES);
-
-        assertThat(chunk.key()).isEqualTo(mPlaintextHash);
-    }
-
-    @Test
-    public void encrypt_generatesHmacOfPlaintext() throws Exception {
-        EncryptedChunk chunk = mChunkEncryptor.encrypt(mPlaintextHash, PLAINTEXT_BYTES);
-
-        byte[] generatedHash = chunk.key().getHash();
-        Mac mac = Mac.getInstance(MAC_ALGORITHM);
-        mac.init(mSecretKey);
-        byte[] plaintextHmac = mac.doFinal(PLAINTEXT_BYTES);
-        assertThat(generatedHash).isEqualTo(plaintextHmac);
-    }
-
-    @Test
-    public void encrypt_whenInvokedAgain_generatesNewNonce() throws Exception {
-        EncryptedChunk chunk1 = mChunkEncryptor.encrypt(mPlaintextHash, PLAINTEXT_BYTES);
-
-        EncryptedChunk chunk2 = mChunkEncryptor.encrypt(mPlaintextHash, PLAINTEXT_BYTES);
-
-        assertThat(chunk1.nonce()).isNotEqualTo(chunk2.nonce());
-    }
-
-    @Test
-    public void encrypt_whenInvokedAgain_generatesNewCiphertext() throws Exception {
-        EncryptedChunk chunk1 = mChunkEncryptor.encrypt(mPlaintextHash, PLAINTEXT_BYTES);
-
-        EncryptedChunk chunk2 = mChunkEncryptor.encrypt(mPlaintextHash, PLAINTEXT_BYTES);
-
-        assertThat(chunk1.encryptedBytes()).isNotEqualTo(chunk2.encryptedBytes());
-    }
-
-    @Test
-    public void encrypt_generates12ByteNonce() throws Exception {
-        EncryptedChunk encryptedChunk = mChunkEncryptor.encrypt(mPlaintextHash, PLAINTEXT_BYTES);
-
-        byte[] nonce = encryptedChunk.nonce();
-        assertThat(nonce).hasLength(GCM_NONCE_LENGTH_BYTES);
-    }
-
-    @Test
-    public void encrypt_decryptedResultCorrespondsToPlaintext() throws Exception {
-        EncryptedChunk chunk = mChunkEncryptor.encrypt(mPlaintextHash, PLAINTEXT_BYTES);
-
-        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
-        cipher.init(
-                Cipher.DECRYPT_MODE,
-                mSecretKey,
-                new GCMParameterSpec(GCM_TAG_LENGTH_BYTES * 8, chunk.nonce()));
-        byte[] decrypted = cipher.doFinal(chunk.encryptedBytes());
-        assertThat(decrypted).isEqualTo(PLAINTEXT_BYTES);
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/ChunkHasherTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/ChunkHasherTest.java
deleted file mode 100644
index 72a927d..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/ChunkHasherTest.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.chunking;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.platform.test.annotations.Presubmit;
-
-import com.android.server.backup.encryption.chunk.ChunkHash;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-
-import javax.crypto.Mac;
-import javax.crypto.SecretKey;
-import javax.crypto.spec.SecretKeySpec;
-
-@RunWith(RobolectricTestRunner.class)
-@Presubmit
-public class ChunkHasherTest {
-    private static final String KEY_ALGORITHM = "AES";
-    private static final String MAC_ALGORITHM = "HmacSHA256";
-
-    private static final byte[] TEST_KEY = {100, 120};
-    private static final byte[] TEST_DATA = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
-
-    private SecretKey mSecretKey;
-    private ChunkHasher mChunkHasher;
-
-    @Before
-    public void setUp() throws Exception {
-        mSecretKey = new SecretKeySpec(TEST_KEY, KEY_ALGORITHM);
-        mChunkHasher = new ChunkHasher(mSecretKey);
-    }
-
-    @Test
-    public void computeHash_returnsHmacForData() throws Exception {
-        ChunkHash chunkHash = mChunkHasher.computeHash(TEST_DATA);
-
-        byte[] hash = chunkHash.getHash();
-        Mac mac = Mac.getInstance(MAC_ALGORITHM);
-        mac.init(mSecretKey);
-        byte[] expectedHash = mac.doFinal(TEST_DATA);
-        assertThat(hash).isEqualTo(expectedHash);
-    }
-
-    @Test
-    public void computeHash_generates256BitHmac() throws Exception {
-        int expectedLength = 256 / Byte.SIZE;
-
-        byte[] hash = mChunkHasher.computeHash(TEST_DATA).getHash();
-
-        assertThat(hash).hasLength(expectedLength);
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/DecryptedChunkFileOutputTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/DecryptedChunkFileOutputTest.java
deleted file mode 100644
index 823a63c..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/DecryptedChunkFileOutputTest.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.chunking;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.testng.Assert.assertThrows;
-
-import android.platform.test.annotations.Presubmit;
-
-import com.android.server.backup.encryption.tasks.DecryptedChunkOutput;
-
-import com.google.common.io.Files;
-import com.google.common.primitives.Bytes;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.security.MessageDigest;
-import java.util.Arrays;
-
-@RunWith(RobolectricTestRunner.class)
-@Presubmit
-public class DecryptedChunkFileOutputTest {
-    private static final byte[] TEST_CHUNK_1 = {1, 2, 3};
-    private static final byte[] TEST_CHUNK_2 = {4, 5, 6, 7, 8, 9, 10};
-    private static final int TEST_BUFFER_LENGTH =
-            Math.max(TEST_CHUNK_1.length, TEST_CHUNK_2.length);
-
-    @Rule
-    public TemporaryFolder temporaryFolder = new TemporaryFolder();
-
-    private File mOutputFile;
-    private DecryptedChunkFileOutput mDecryptedChunkFileOutput;
-
-    @Before
-    public void setUp() throws Exception {
-        mOutputFile = temporaryFolder.newFile();
-        mDecryptedChunkFileOutput = new DecryptedChunkFileOutput(mOutputFile);
-    }
-
-    @Test
-    public void open_returnsInstance() throws Exception {
-        DecryptedChunkOutput result = mDecryptedChunkFileOutput.open();
-        assertThat(result).isEqualTo(mDecryptedChunkFileOutput);
-    }
-
-    @Test
-    public void open_nonExistentOutputFolder_throwsException() throws Exception {
-        mDecryptedChunkFileOutput =
-                new DecryptedChunkFileOutput(
-                        new File(temporaryFolder.newFolder(), "mOutput/directory"));
-        assertThrows(FileNotFoundException.class, () -> mDecryptedChunkFileOutput.open());
-    }
-
-    @Test
-    public void open_whenRunTwice_throwsException() throws Exception {
-        mDecryptedChunkFileOutput.open();
-        assertThrows(IllegalStateException.class, () -> mDecryptedChunkFileOutput.open());
-    }
-
-    @Test
-    public void processChunk_beforeOpen_throwsException() throws Exception {
-        assertThrows(IllegalStateException.class,
-                () -> mDecryptedChunkFileOutput.processChunk(new byte[0], 0));
-    }
-
-    @Test
-    public void processChunk_writesChunksToFile() throws Exception {
-        processTestChunks();
-
-        assertThat(Files.toByteArray(mOutputFile))
-                .isEqualTo(Bytes.concat(TEST_CHUNK_1, TEST_CHUNK_2));
-    }
-
-    @Test
-    public void getDigest_beforeClose_throws() throws Exception {
-        mDecryptedChunkFileOutput.open();
-        assertThrows(IllegalStateException.class, () -> mDecryptedChunkFileOutput.getDigest());
-    }
-
-    @Test
-    public void getDigest_returnsCorrectDigest() throws Exception {
-        processTestChunks();
-
-        byte[] actualDigest = mDecryptedChunkFileOutput.getDigest();
-
-        MessageDigest expectedDigest =
-                MessageDigest.getInstance(DecryptedChunkFileOutput.DIGEST_ALGORITHM);
-        expectedDigest.update(TEST_CHUNK_1);
-        expectedDigest.update(TEST_CHUNK_2);
-        assertThat(actualDigest).isEqualTo(expectedDigest.digest());
-    }
-
-    @Test
-    public void getDigest_whenRunTwice_returnsIdenticalDigestBothTimes() throws Exception {
-        processTestChunks();
-
-        byte[] digest1 = mDecryptedChunkFileOutput.getDigest();
-        byte[] digest2 = mDecryptedChunkFileOutput.getDigest();
-
-        assertThat(digest1).isEqualTo(digest2);
-    }
-
-    private void processTestChunks() throws IOException {
-        mDecryptedChunkFileOutput.open();
-        mDecryptedChunkFileOutput.processChunk(Arrays.copyOf(TEST_CHUNK_1, TEST_BUFFER_LENGTH),
-                TEST_CHUNK_1.length);
-        mDecryptedChunkFileOutput.processChunk(Arrays.copyOf(TEST_CHUNK_2, TEST_BUFFER_LENGTH),
-                TEST_CHUNK_2.length);
-        mDecryptedChunkFileOutput.close();
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/DiffScriptBackupWriterTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/DiffScriptBackupWriterTest.java
deleted file mode 100644
index 2af6f2b..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/DiffScriptBackupWriterTest.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.chunking;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import android.platform.test.annotations.Presubmit;
-
-import com.google.common.primitives.Bytes;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.robolectric.RobolectricTestRunner;
-
-import java.io.IOException;
-
-/** Tests for {@link DiffScriptBackupWriter}. */
-@RunWith(RobolectricTestRunner.class)
-@Presubmit
-public class DiffScriptBackupWriterTest {
-    private static final byte[] TEST_BYTES = {1, 2, 3, 4, 5, 6, 7, 8, 9};
-
-    @Captor private ArgumentCaptor<Byte> mBytesCaptor;
-    @Mock private SingleStreamDiffScriptWriter mDiffScriptWriter;
-    private BackupWriter mBackupWriter;
-
-    @Before
-    public void setUp() {
-        mDiffScriptWriter = mock(SingleStreamDiffScriptWriter.class);
-        mBackupWriter = new DiffScriptBackupWriter(mDiffScriptWriter);
-        mBytesCaptor = ArgumentCaptor.forClass(Byte.class);
-    }
-
-    @Test
-    public void writeBytes_writesBytesToWriter() throws Exception {
-        mBackupWriter.writeBytes(TEST_BYTES);
-
-        verify(mDiffScriptWriter, atLeastOnce()).writeByte(mBytesCaptor.capture());
-        assertThat(mBytesCaptor.getAllValues())
-                .containsExactlyElementsIn(Bytes.asList(TEST_BYTES))
-                .inOrder();
-    }
-
-    @Test
-    public void writeChunk_writesChunkToWriter() throws Exception {
-        mBackupWriter.writeChunk(0, 10);
-
-        verify(mDiffScriptWriter).writeChunk(0, 10);
-    }
-
-    @Test
-    public void getBytesWritten_returnsTotalSum() throws Exception {
-        mBackupWriter.writeBytes(TEST_BYTES);
-        mBackupWriter.writeBytes(TEST_BYTES);
-        mBackupWriter.writeChunk(/*start=*/ 0, /*length=*/ 10);
-
-        long bytesWritten = mBackupWriter.getBytesWritten();
-
-        assertThat(bytesWritten).isEqualTo(2 * TEST_BYTES.length + 10);
-    }
-
-    @Test
-    public void flush_flushesWriter() throws IOException {
-        mBackupWriter.flush();
-
-        verify(mDiffScriptWriter).flush();
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/EncryptedChunkTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/EncryptedChunkTest.java
deleted file mode 100644
index 325b601..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/EncryptedChunkTest.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.chunking;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.testng.Assert.assertThrows;
-
-import android.platform.test.annotations.Presubmit;
-
-import com.android.server.backup.encryption.chunk.ChunkHash;
-
-import com.google.common.primitives.Bytes;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-
-import java.util.Arrays;
-
-@RunWith(RobolectricTestRunner.class)
-@Presubmit
-public class EncryptedChunkTest {
-    private static final byte[] CHUNK_HASH_1_BYTES =
-            Arrays.copyOf(new byte[] {1}, ChunkHash.HASH_LENGTH_BYTES);
-    private static final byte[] NONCE_1 =
-            Arrays.copyOf(new byte[] {2}, EncryptedChunk.NONCE_LENGTH_BYTES);
-    private static final byte[] ENCRYPTED_BYTES_1 =
-            Arrays.copyOf(new byte[] {3}, EncryptedChunk.KEY_LENGTH_BYTES);
-
-    private static final byte[] CHUNK_HASH_2_BYTES =
-            Arrays.copyOf(new byte[] {4}, ChunkHash.HASH_LENGTH_BYTES);
-    private static final byte[] NONCE_2 =
-            Arrays.copyOf(new byte[] {5}, EncryptedChunk.NONCE_LENGTH_BYTES);
-    private static final byte[] ENCRYPTED_BYTES_2 =
-            Arrays.copyOf(new byte[] {6}, EncryptedChunk.KEY_LENGTH_BYTES);
-
-    @Test
-    public void testCreate_withIncorrectLength_throwsException() {
-        ChunkHash chunkHash = new ChunkHash(CHUNK_HASH_1_BYTES);
-        byte[] shortNonce = Arrays.copyOf(new byte[] {2}, EncryptedChunk.NONCE_LENGTH_BYTES - 1);
-
-        assertThrows(
-                IllegalArgumentException.class,
-                () -> EncryptedChunk.create(chunkHash, shortNonce, ENCRYPTED_BYTES_1));
-    }
-
-    @Test
-    public void testEncryptedBytes_forNewlyCreatedObject_returnsCorrectValue() {
-        ChunkHash chunkHash = new ChunkHash(CHUNK_HASH_1_BYTES);
-        EncryptedChunk encryptedChunk =
-                EncryptedChunk.create(chunkHash, NONCE_1, ENCRYPTED_BYTES_1);
-
-        byte[] returnedBytes = encryptedChunk.encryptedBytes();
-
-        assertThat(returnedBytes)
-                .asList()
-                .containsExactlyElementsIn(Bytes.asList(ENCRYPTED_BYTES_1))
-                .inOrder();
-    }
-
-    @Test
-    public void testKey_forNewlyCreatedObject_returnsCorrectValue() {
-        ChunkHash chunkHash = new ChunkHash(CHUNK_HASH_1_BYTES);
-        EncryptedChunk encryptedChunk =
-                EncryptedChunk.create(chunkHash, NONCE_1, ENCRYPTED_BYTES_1);
-
-        ChunkHash returnedKey = encryptedChunk.key();
-
-        assertThat(returnedKey).isEqualTo(chunkHash);
-    }
-
-    @Test
-    public void testNonce_forNewlycreatedObject_returnCorrectValue() {
-        ChunkHash chunkHash = new ChunkHash(CHUNK_HASH_1_BYTES);
-        EncryptedChunk encryptedChunk =
-                EncryptedChunk.create(chunkHash, NONCE_1, ENCRYPTED_BYTES_1);
-
-        byte[] returnedNonce = encryptedChunk.nonce();
-
-        assertThat(returnedNonce).asList().containsExactlyElementsIn(Bytes.asList(NONCE_1));
-    }
-
-    @Test
-    public void testEquals() {
-        ChunkHash chunkHash1 = new ChunkHash(CHUNK_HASH_1_BYTES);
-        ChunkHash equalChunkHash1 = new ChunkHash(CHUNK_HASH_1_BYTES);
-        ChunkHash chunkHash2 = new ChunkHash(CHUNK_HASH_2_BYTES);
-        EncryptedChunk encryptedChunk1 =
-                EncryptedChunk.create(chunkHash1, NONCE_1, ENCRYPTED_BYTES_1);
-        EncryptedChunk equalEncryptedChunk1 =
-                EncryptedChunk.create(equalChunkHash1, NONCE_1, ENCRYPTED_BYTES_1);
-        EncryptedChunk encryptedChunk2 =
-                EncryptedChunk.create(chunkHash2, NONCE_2, ENCRYPTED_BYTES_2);
-
-        assertThat(encryptedChunk1).isEqualTo(equalEncryptedChunk1);
-        assertThat(encryptedChunk1).isNotEqualTo(encryptedChunk2);
-    }
-
-    @Test
-    public void testHashCode() {
-        ChunkHash chunkHash1 = new ChunkHash(CHUNK_HASH_1_BYTES);
-        ChunkHash equalChunkHash1 = new ChunkHash(CHUNK_HASH_1_BYTES);
-        ChunkHash chunkHash2 = new ChunkHash(CHUNK_HASH_2_BYTES);
-        EncryptedChunk encryptedChunk1 =
-                EncryptedChunk.create(chunkHash1, NONCE_1, ENCRYPTED_BYTES_1);
-        EncryptedChunk equalEncryptedChunk1 =
-                EncryptedChunk.create(equalChunkHash1, NONCE_1, ENCRYPTED_BYTES_1);
-        EncryptedChunk encryptedChunk2 =
-                EncryptedChunk.create(chunkHash2, NONCE_2, ENCRYPTED_BYTES_2);
-
-        int hash1 = encryptedChunk1.hashCode();
-        int equalHash1 = equalEncryptedChunk1.hashCode();
-        int hash2 = encryptedChunk2.hashCode();
-
-        assertThat(hash1).isEqualTo(equalHash1);
-        assertThat(hash1).isNotEqualTo(hash2);
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/InlineLengthsEncryptedChunkEncoderTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/InlineLengthsEncryptedChunkEncoderTest.java
deleted file mode 100644
index 7e1fded..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/InlineLengthsEncryptedChunkEncoderTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.chunking;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.mock;
-
-import android.platform.test.annotations.Presubmit;
-
-import com.android.server.backup.encryption.chunk.ChunkHash;
-import com.android.server.backup.encryption.protos.nano.ChunksMetadataProto;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.InOrder;
-import org.mockito.Mock;
-import org.robolectric.RobolectricTestRunner;
-
-import java.util.Arrays;
-
-@RunWith(RobolectricTestRunner.class)
-@Presubmit
-public class InlineLengthsEncryptedChunkEncoderTest {
-
-    private static final byte[] TEST_NONCE =
-            Arrays.copyOf(new byte[] {1}, EncryptedChunk.NONCE_LENGTH_BYTES);
-    private static final byte[] TEST_KEY_DATA =
-            Arrays.copyOf(new byte[] {2}, EncryptedChunk.KEY_LENGTH_BYTES);
-    private static final byte[] TEST_DATA = {5, 4, 5, 7, 10, 12, 1, 2, 9};
-
-    @Mock private BackupWriter mMockBackupWriter;
-    private ChunkHash mTestKey;
-    private EncryptedChunk mTestChunk;
-    private EncryptedChunkEncoder mEncoder;
-
-    @Before
-    public void setUp() throws Exception {
-        mMockBackupWriter = mock(BackupWriter.class);
-        mTestKey = new ChunkHash(TEST_KEY_DATA);
-        mTestChunk = EncryptedChunk.create(mTestKey, TEST_NONCE, TEST_DATA);
-        mEncoder = new InlineLengthsEncryptedChunkEncoder();
-    }
-
-    @Test
-    public void writeChunkToWriter_writesLengthThenNonceThenData() throws Exception {
-        mEncoder.writeChunkToWriter(mMockBackupWriter, mTestChunk);
-
-        InOrder inOrder = inOrder(mMockBackupWriter);
-        inOrder.verify(mMockBackupWriter)
-                .writeBytes(
-                        InlineLengthsEncryptedChunkEncoder.toByteArray(
-                                TEST_NONCE.length + TEST_DATA.length));
-        inOrder.verify(mMockBackupWriter).writeBytes(TEST_NONCE);
-        inOrder.verify(mMockBackupWriter).writeBytes(TEST_DATA);
-    }
-
-    @Test
-    public void getEncodedLengthOfChunk_returnsSumOfNonceAndDataLengths() {
-        int encodedLength = mEncoder.getEncodedLengthOfChunk(mTestChunk);
-
-        assertThat(encodedLength).isEqualTo(Integer.BYTES + TEST_NONCE.length + TEST_DATA.length);
-    }
-
-    @Test
-    public void getChunkOrderingType_returnsExplicitStartsType() {
-        assertThat(mEncoder.getChunkOrderingType()).isEqualTo(ChunksMetadataProto.INLINE_LENGTHS);
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/LengthlessEncryptedChunkEncoderTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/LengthlessEncryptedChunkEncoderTest.java
deleted file mode 100644
index 6f58ee1..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/LengthlessEncryptedChunkEncoderTest.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.chunking;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.mock;
-
-import android.platform.test.annotations.Presubmit;
-
-import com.android.server.backup.encryption.chunk.ChunkHash;
-import com.android.server.backup.encryption.protos.nano.ChunksMetadataProto;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.InOrder;
-import org.mockito.Mock;
-import org.robolectric.RobolectricTestRunner;
-
-import java.util.Arrays;
-
-@RunWith(RobolectricTestRunner.class)
-@Presubmit
-public class LengthlessEncryptedChunkEncoderTest {
-    private static final byte[] TEST_NONCE =
-            Arrays.copyOf(new byte[] {1}, EncryptedChunk.NONCE_LENGTH_BYTES);
-    private static final byte[] TEST_KEY_DATA =
-            Arrays.copyOf(new byte[] {2}, EncryptedChunk.KEY_LENGTH_BYTES);
-    private static final byte[] TEST_DATA = {5, 4, 5, 7, 10, 12, 1, 2, 9};
-
-    @Mock private BackupWriter mMockBackupWriter;
-    private ChunkHash mTestKey;
-    private EncryptedChunk mTestChunk;
-    private EncryptedChunkEncoder mEncoder;
-
-    @Before
-    public void setUp() throws Exception {
-        mMockBackupWriter = mock(BackupWriter.class);
-        mTestKey = new ChunkHash(TEST_KEY_DATA);
-        mTestChunk = EncryptedChunk.create(mTestKey, TEST_NONCE, TEST_DATA);
-        mEncoder = new LengthlessEncryptedChunkEncoder();
-    }
-
-    @Test
-    public void writeChunkToWriter_writesNonceThenData() throws Exception {
-        mEncoder.writeChunkToWriter(mMockBackupWriter, mTestChunk);
-
-        InOrder inOrder = inOrder(mMockBackupWriter);
-        inOrder.verify(mMockBackupWriter).writeBytes(TEST_NONCE);
-        inOrder.verify(mMockBackupWriter).writeBytes(TEST_DATA);
-    }
-
-    @Test
-    public void getEncodedLengthOfChunk_returnsSumOfNonceAndDataLengths() {
-        int encodedLength = mEncoder.getEncodedLengthOfChunk(mTestChunk);
-
-        assertThat(encodedLength).isEqualTo(TEST_NONCE.length + TEST_DATA.length);
-    }
-
-    @Test
-    public void getChunkOrderingType_returnsExplicitStartsType() {
-        assertThat(mEncoder.getChunkOrderingType()).isEqualTo(ChunksMetadataProto.EXPLICIT_STARTS);
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/ProtoStoreTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/ProtoStoreTest.java
deleted file mode 100644
index d73c8e4..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/ProtoStoreTest.java
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.chunking;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import static org.testng.Assert.assertThrows;
-
-import android.content.Context;
-import android.platform.test.annotations.Presubmit;
-
-import androidx.test.core.app.ApplicationProvider;
-
-import com.android.server.backup.encryption.chunk.ChunkHash;
-import com.android.server.backup.encryption.protos.nano.ChunksMetadataProto;
-import com.android.server.backup.encryption.protos.nano.KeyValueListingProto;
-
-import com.google.common.collect.ImmutableMap;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map.Entry;
-import java.util.Optional;
-
-@RunWith(RobolectricTestRunner.class)
-@Presubmit
-public class ProtoStoreTest {
-    private static final String TEST_KEY_1 = "test_key_1";
-    private static final ChunkHash TEST_HASH_1 =
-            new ChunkHash(Arrays.copyOf(new byte[] {1}, EncryptedChunk.KEY_LENGTH_BYTES));
-    private static final ChunkHash TEST_HASH_2 =
-            new ChunkHash(Arrays.copyOf(new byte[] {2}, EncryptedChunk.KEY_LENGTH_BYTES));
-    private static final int TEST_LENGTH_1 = 10;
-    private static final int TEST_LENGTH_2 = 18;
-
-    private static final String TEST_PACKAGE_1 = "com.example.test1";
-    private static final String TEST_PACKAGE_2 = "com.example.test2";
-
-    @Rule public TemporaryFolder mTemporaryFolder = new TemporaryFolder();
-
-    private File mStoreFolder;
-    private ProtoStore<ChunksMetadataProto.ChunkListing> mProtoStore;
-
-    @Before
-    public void setUp() throws Exception {
-        mStoreFolder = mTemporaryFolder.newFolder();
-        mProtoStore = new ProtoStore<>(ChunksMetadataProto.ChunkListing.class, mStoreFolder);
-    }
-
-    @Test
-    public void differentStoreTypes_operateSimultaneouslyWithoutInterfering() throws Exception {
-        ChunksMetadataProto.ChunkListing chunkListing =
-                createChunkListing(ImmutableMap.of(TEST_HASH_1, TEST_LENGTH_1));
-        KeyValueListingProto.KeyValueListing keyValueListing =
-                new KeyValueListingProto.KeyValueListing();
-        keyValueListing.entries = new KeyValueListingProto.KeyValueEntry[1];
-        keyValueListing.entries[0] = new KeyValueListingProto.KeyValueEntry();
-        keyValueListing.entries[0].key = TEST_KEY_1;
-        keyValueListing.entries[0].hash = TEST_HASH_1.getHash();
-
-        Context application = ApplicationProvider.getApplicationContext();
-        ProtoStore<ChunksMetadataProto.ChunkListing> chunkListingStore =
-                ProtoStore.createChunkListingStore(application);
-        ProtoStore<KeyValueListingProto.KeyValueListing> keyValueListingStore =
-                ProtoStore.createKeyValueListingStore(application);
-
-        chunkListingStore.saveProto(TEST_PACKAGE_1, chunkListing);
-        keyValueListingStore.saveProto(TEST_PACKAGE_1, keyValueListing);
-
-        ChunksMetadataProto.ChunkListing actualChunkListing =
-                chunkListingStore.loadProto(TEST_PACKAGE_1).get();
-        KeyValueListingProto.KeyValueListing actualKeyValueListing =
-                keyValueListingStore.loadProto(TEST_PACKAGE_1).get();
-        assertListingsEqual(actualChunkListing, chunkListing);
-        assertThat(actualKeyValueListing.entries.length).isEqualTo(1);
-        assertThat(actualKeyValueListing.entries[0].key).isEqualTo(TEST_KEY_1);
-        assertThat(actualKeyValueListing.entries[0].hash).isEqualTo(TEST_HASH_1.getHash());
-    }
-
-    @Test
-    public void construct_storeLocationIsFile_throws() throws Exception {
-        assertThrows(
-                IOException.class,
-                () ->
-                        new ProtoStore<>(
-                                ChunksMetadataProto.ChunkListing.class,
-                                mTemporaryFolder.newFile()));
-    }
-
-    @Test
-    public void loadChunkListing_noListingExists_returnsEmptyListing() throws Exception {
-        Optional<ChunksMetadataProto.ChunkListing> chunkListing =
-                mProtoStore.loadProto(TEST_PACKAGE_1);
-        assertThat(chunkListing.isPresent()).isFalse();
-    }
-
-    @Test
-    public void loadChunkListing_listingExists_returnsExistingListing() throws Exception {
-        ChunksMetadataProto.ChunkListing expected =
-                createChunkListing(
-                        ImmutableMap.of(TEST_HASH_1, TEST_LENGTH_1, TEST_HASH_2, TEST_LENGTH_2));
-        mProtoStore.saveProto(TEST_PACKAGE_1, expected);
-
-        ChunksMetadataProto.ChunkListing result = mProtoStore.loadProto(TEST_PACKAGE_1).get();
-
-        assertListingsEqual(result, expected);
-    }
-
-    @Test
-    public void loadProto_emptyPackageName_throwsException() throws Exception {
-        assertThrows(IllegalArgumentException.class, () -> mProtoStore.loadProto(""));
-    }
-
-    @Test
-    public void loadProto_nullPackageName_throwsException() throws Exception {
-        assertThrows(IllegalArgumentException.class, () -> mProtoStore.loadProto(null));
-    }
-
-    @Test
-    public void loadProto_packageNameContainsSlash_throwsException() throws Exception {
-        assertThrows(
-                IllegalArgumentException.class, () -> mProtoStore.loadProto(TEST_PACKAGE_1 + "/"));
-    }
-
-    @Test
-    public void saveProto_persistsToNewInstance() throws Exception {
-        ChunksMetadataProto.ChunkListing expected =
-                createChunkListing(
-                        ImmutableMap.of(TEST_HASH_1, TEST_LENGTH_1, TEST_HASH_2, TEST_LENGTH_2));
-        mProtoStore.saveProto(TEST_PACKAGE_1, expected);
-        mProtoStore = new ProtoStore<>(ChunksMetadataProto.ChunkListing.class, mStoreFolder);
-
-        ChunksMetadataProto.ChunkListing result = mProtoStore.loadProto(TEST_PACKAGE_1).get();
-
-        assertListingsEqual(result, expected);
-    }
-
-    @Test
-    public void saveProto_emptyPackageName_throwsException() throws Exception {
-        assertThrows(
-                IllegalArgumentException.class,
-                () -> mProtoStore.saveProto("", new ChunksMetadataProto.ChunkListing()));
-    }
-
-    @Test
-    public void saveProto_nullPackageName_throwsException() throws Exception {
-        assertThrows(
-                IllegalArgumentException.class,
-                () -> mProtoStore.saveProto(null, new ChunksMetadataProto.ChunkListing()));
-    }
-
-    @Test
-    public void saveProto_packageNameContainsSlash_throwsException() throws Exception {
-        assertThrows(
-                IllegalArgumentException.class,
-                () ->
-                        mProtoStore.saveProto(
-                                TEST_PACKAGE_1 + "/", new ChunksMetadataProto.ChunkListing()));
-    }
-
-    @Test
-    public void saveProto_nullListing_throwsException() throws Exception {
-        assertThrows(NullPointerException.class, () -> mProtoStore.saveProto(TEST_PACKAGE_1, null));
-    }
-
-    @Test
-    public void deleteProto_noListingExists_doesNothing() throws Exception {
-        ChunksMetadataProto.ChunkListing listing =
-                createChunkListing(ImmutableMap.of(TEST_HASH_1, TEST_LENGTH_1));
-        mProtoStore.saveProto(TEST_PACKAGE_1, listing);
-
-        mProtoStore.deleteProto(TEST_PACKAGE_2);
-
-        assertThat(mProtoStore.loadProto(TEST_PACKAGE_1).get().chunks.length).isEqualTo(1);
-    }
-
-    @Test
-    public void deleteProto_listingExists_deletesListing() throws Exception {
-        ChunksMetadataProto.ChunkListing listing =
-                createChunkListing(ImmutableMap.of(TEST_HASH_1, TEST_LENGTH_1));
-        mProtoStore.saveProto(TEST_PACKAGE_1, listing);
-
-        mProtoStore.deleteProto(TEST_PACKAGE_1);
-
-        assertThat(mProtoStore.loadProto(TEST_PACKAGE_1).isPresent()).isFalse();
-    }
-
-    @Test
-    public void deleteAllProtos_deletesAllProtos() throws Exception {
-        ChunksMetadataProto.ChunkListing listing1 =
-                createChunkListing(ImmutableMap.of(TEST_HASH_1, TEST_LENGTH_1));
-        ChunksMetadataProto.ChunkListing listing2 =
-                createChunkListing(ImmutableMap.of(TEST_HASH_2, TEST_LENGTH_2));
-        mProtoStore.saveProto(TEST_PACKAGE_1, listing1);
-        mProtoStore.saveProto(TEST_PACKAGE_2, listing2);
-
-        mProtoStore.deleteAllProtos();
-
-        assertThat(mProtoStore.loadProto(TEST_PACKAGE_1).isPresent()).isFalse();
-        assertThat(mProtoStore.loadProto(TEST_PACKAGE_2).isPresent()).isFalse();
-    }
-
-    @Test
-    public void deleteAllProtos_folderDeleted_doesNotCrash() throws Exception {
-        mStoreFolder.delete();
-
-        mProtoStore.deleteAllProtos();
-    }
-
-    private static ChunksMetadataProto.ChunkListing createChunkListing(
-            ImmutableMap<ChunkHash, Integer> chunks) {
-        ChunksMetadataProto.ChunkListing listing = new ChunksMetadataProto.ChunkListing();
-        listing.cipherType = ChunksMetadataProto.AES_256_GCM;
-        listing.chunkOrderingType = ChunksMetadataProto.CHUNK_ORDERING_TYPE_UNSPECIFIED;
-
-        List<ChunksMetadataProto.Chunk> chunkProtos = new ArrayList<>();
-        for (Entry<ChunkHash, Integer> entry : chunks.entrySet()) {
-            ChunksMetadataProto.Chunk chunk = new ChunksMetadataProto.Chunk();
-            chunk.hash = entry.getKey().getHash();
-            chunk.length = entry.getValue();
-            chunkProtos.add(chunk);
-        }
-        listing.chunks = chunkProtos.toArray(new ChunksMetadataProto.Chunk[0]);
-        return listing;
-    }
-
-    private void assertListingsEqual(
-            ChunksMetadataProto.ChunkListing result, ChunksMetadataProto.ChunkListing expected) {
-        assertThat(result.chunks.length).isEqualTo(expected.chunks.length);
-        for (int i = 0; i < result.chunks.length; i++) {
-            assertWithMessage("Chunk " + i)
-                    .that(result.chunks[i].length)
-                    .isEqualTo(expected.chunks[i].length);
-            assertWithMessage("Chunk " + i)
-                    .that(result.chunks[i].hash)
-                    .isEqualTo(expected.chunks[i].hash);
-        }
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/RawBackupWriterTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/RawBackupWriterTest.java
deleted file mode 100644
index 966d3e2..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/RawBackupWriterTest.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.chunking;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.testng.Assert.assertThrows;
-
-import android.platform.test.annotations.Presubmit;
-
-import com.google.common.primitives.Bytes;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-
-import java.io.ByteArrayOutputStream;
-
-@RunWith(RobolectricTestRunner.class)
-@Presubmit
-public class RawBackupWriterTest {
-    private static final byte[] TEST_BYTES = {1, 2, 3, 4, 5, 6};
-
-    private BackupWriter mWriter;
-    private ByteArrayOutputStream mOutput;
-
-    @Before
-    public void setUp() {
-        mOutput = new ByteArrayOutputStream();
-        mWriter = new RawBackupWriter(mOutput);
-    }
-
-    @Test
-    public void writeBytes_writesToOutputStream() throws Exception {
-        mWriter.writeBytes(TEST_BYTES);
-
-        assertThat(mOutput.toByteArray())
-                .asList()
-                .containsExactlyElementsIn(Bytes.asList(TEST_BYTES))
-                .inOrder();
-    }
-
-    @Test
-    public void writeChunk_throwsUnsupportedOperationException() throws Exception {
-        assertThrows(UnsupportedOperationException.class, () -> mWriter.writeChunk(0, 0));
-    }
-
-    @Test
-    public void getBytesWritten_returnsTotalSum() throws Exception {
-        mWriter.writeBytes(TEST_BYTES);
-        mWriter.writeBytes(TEST_BYTES);
-
-        long bytesWritten = mWriter.getBytesWritten();
-
-        assertThat(bytesWritten).isEqualTo(2 * TEST_BYTES.length);
-    }
-
-    @Test
-    public void flush_flushesOutputStream() throws Exception {
-        mOutput = mock(ByteArrayOutputStream.class);
-        mWriter = new RawBackupWriter(mOutput);
-
-        mWriter.flush();
-
-        verify(mOutput).flush();
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/SingleStreamDiffScriptWriterTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/SingleStreamDiffScriptWriterTest.java
deleted file mode 100644
index 73baf80..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/SingleStreamDiffScriptWriterTest.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.chunking;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.testng.Assert.assertThrows;
-
-import android.platform.test.annotations.Presubmit;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.util.Locale;
-
-/** Tests for {@link SingleStreamDiffScriptWriter}. */
-@RunWith(RobolectricTestRunner.class)
-@Presubmit
-public class SingleStreamDiffScriptWriterTest {
-    private static final int MAX_CHUNK_SIZE_IN_BYTES = 256;
-    /** By default this Locale does not use Arabic numbers for %d formatting. */
-    private static final Locale HINDI = new Locale("hi", "IN");
-
-    private Locale mDefaultLocale;
-    private ByteArrayOutputStream mOutputStream;
-    private SingleStreamDiffScriptWriter mDiffScriptWriter;
-
-    @Before
-    public void setUp() {
-        mDefaultLocale = Locale.getDefault();
-        mOutputStream = new ByteArrayOutputStream();
-        mDiffScriptWriter =
-                new SingleStreamDiffScriptWriter(mOutputStream, MAX_CHUNK_SIZE_IN_BYTES);
-    }
-
-    @After
-    public void tearDown() {
-        Locale.setDefault(mDefaultLocale);
-    }
-
-    @Test
-    public void writeChunk_withNegativeStart_throwsException() {
-        assertThrows(
-                IllegalArgumentException.class,
-                () -> mDiffScriptWriter.writeChunk(-1, 50));
-    }
-
-    @Test
-    public void writeChunk_withZeroLength_throwsException() {
-        assertThrows(
-                IllegalArgumentException.class,
-                () -> mDiffScriptWriter.writeChunk(0, 0));
-    }
-
-    @Test
-    public void writeChunk_withExistingBytesInBuffer_writesBufferFirst()
-            throws IOException {
-        String testString = "abcd";
-        writeStringAsBytesToWriter(testString, mDiffScriptWriter);
-
-        mDiffScriptWriter.writeChunk(0, 20);
-        mDiffScriptWriter.flush();
-
-        // Expected format: length of abcd, newline, abcd, newline, chunk start - chunk end
-        assertThat(mOutputStream.toString("UTF-8")).isEqualTo(
-                String.format("%d\n%s\n%d-%d\n", testString.length(), testString, 0, 19));
-    }
-
-    @Test
-    public void writeChunk_overlappingPreviousChunk_combinesChunks() throws IOException {
-        mDiffScriptWriter.writeChunk(3, 4);
-
-        mDiffScriptWriter.writeChunk(7, 5);
-        mDiffScriptWriter.flush();
-
-        assertThat(mOutputStream.toString("UTF-8")).isEqualTo(String.format("3-11\n"));
-    }
-
-    @Test
-    public void writeChunk_formatsByteIndexesUsingArabicNumbers() throws Exception {
-        Locale.setDefault(HINDI);
-
-        mDiffScriptWriter.writeChunk(0, 12345);
-        mDiffScriptWriter.flush();
-
-        assertThat(mOutputStream.toString("UTF-8")).isEqualTo("0-12344\n");
-    }
-
-    @Test
-    public void flush_flushesOutputStream() throws IOException {
-        ByteArrayOutputStream mockOutputStream = mock(ByteArrayOutputStream.class);
-        SingleStreamDiffScriptWriter diffScriptWriter =
-                new SingleStreamDiffScriptWriter(mockOutputStream, MAX_CHUNK_SIZE_IN_BYTES);
-
-        diffScriptWriter.flush();
-
-        verify(mockOutputStream).flush();
-    }
-
-    private void writeStringAsBytesToWriter(String string, SingleStreamDiffScriptWriter writer)
-            throws IOException {
-        byte[] bytes = string.getBytes("UTF-8");
-        for (int i = 0; i < bytes.length; i++) {
-            writer.writeByte(bytes[i]);
-        }
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/cdc/ContentDefinedChunkerTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/cdc/ContentDefinedChunkerTest.java
deleted file mode 100644
index 77b7347..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/cdc/ContentDefinedChunkerTest.java
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.chunking.cdc;
-
-import static com.android.server.backup.testing.CryptoTestUtils.generateAesKey;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.testng.Assert.assertThrows;
-
-import static java.nio.charset.StandardCharsets.UTF_8;
-
-import android.platform.test.annotations.Presubmit;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.security.GeneralSecurityException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Random;
-
-import javax.crypto.SecretKey;
-
-/** Tests for {@link ContentDefinedChunker}. */
-@RunWith(RobolectricTestRunner.class)
-@Presubmit
-public class ContentDefinedChunkerTest {
-    private static final int WINDOW_SIZE_BYTES = 31;
-    private static final int MIN_SIZE_BYTES = 40;
-    private static final int MAX_SIZE_BYTES = 300;
-    private static final String CHUNK_BOUNDARY = "<----------BOUNDARY----------->";
-    private static final byte[] CHUNK_BOUNDARY_BYTES = CHUNK_BOUNDARY.getBytes(UTF_8);
-    private static final String CHUNK_1 = "This is the first chunk";
-    private static final String CHUNK_2 = "And this is the second chunk";
-    private static final String CHUNK_3 = "And finally here is the third chunk";
-    private static final String SMALL_CHUNK = "12345678";
-
-    private FingerprintMixer mFingerprintMixer;
-    private RabinFingerprint64 mRabinFingerprint64;
-    private ContentDefinedChunker mChunker;
-
-    /** Set up a {@link ContentDefinedChunker} and dependencies for use in the tests. */
-    @Before
-    public void setUp() throws Exception {
-        SecretKey secretKey = generateAesKey();
-        byte[] salt = new byte[FingerprintMixer.SALT_LENGTH_BYTES];
-        Random random = new Random();
-        random.nextBytes(salt);
-        mFingerprintMixer = new FingerprintMixer(secretKey, salt);
-
-        mRabinFingerprint64 = new RabinFingerprint64();
-        long chunkBoundaryFingerprint = calculateFingerprint(CHUNK_BOUNDARY_BYTES);
-        mChunker =
-                new ContentDefinedChunker(
-                        MIN_SIZE_BYTES,
-                        MAX_SIZE_BYTES,
-                        mRabinFingerprint64,
-                        mFingerprintMixer,
-                        (fingerprint) -> fingerprint == chunkBoundaryFingerprint);
-    }
-
-    /**
-     * Creating a {@link ContentDefinedChunker} with a minimum chunk size that is smaller than the
-     * window size should throw an {@link IllegalArgumentException}.
-     */
-    @Test
-    public void create_withMinChunkSizeSmallerThanWindowSize_throwsIllegalArgumentException() {
-        assertThrows(
-                IllegalArgumentException.class,
-                () ->
-                        new ContentDefinedChunker(
-                                WINDOW_SIZE_BYTES - 1,
-                                MAX_SIZE_BYTES,
-                                mRabinFingerprint64,
-                                mFingerprintMixer,
-                                null));
-    }
-
-    /**
-     * Creating a {@link ContentDefinedChunker} with a maximum chunk size that is smaller than the
-     * minimum chunk size should throw an {@link IllegalArgumentException}.
-     */
-    @Test
-    public void create_withMaxChunkSizeSmallerThanMinChunkSize_throwsIllegalArgumentException() {
-        assertThrows(
-                IllegalArgumentException.class,
-                () ->
-                        new ContentDefinedChunker(
-                                MIN_SIZE_BYTES,
-                                MIN_SIZE_BYTES - 1,
-                                mRabinFingerprint64,
-                                mFingerprintMixer,
-                                null));
-    }
-
-    /**
-     * {@link ContentDefinedChunker#chunkify(InputStream, Chunker.ChunkConsumer)} should split the
-     * input stream across chunk boundaries by default.
-     */
-    @Test
-    public void chunkify_withLargeChunks_splitsIntoChunksAcrossBoundaries() throws Exception {
-        byte[] input =
-                (CHUNK_1 + CHUNK_BOUNDARY + CHUNK_2 + CHUNK_BOUNDARY + CHUNK_3).getBytes(UTF_8);
-        ByteArrayInputStream inputStream = new ByteArrayInputStream(input);
-        ArrayList<String> result = new ArrayList<>();
-
-        mChunker.chunkify(inputStream, (chunk) -> result.add(new String(chunk, UTF_8)));
-
-        assertThat(result)
-                .containsExactly(CHUNK_1 + CHUNK_BOUNDARY, CHUNK_2 + CHUNK_BOUNDARY, CHUNK_3)
-                .inOrder();
-    }
-
-    /** Chunks should be combined across boundaries until they reach the minimum chunk size. */
-    @Test
-    public void chunkify_withSmallChunks_combinesChunksUntilMinSize() throws Exception {
-        byte[] input =
-                (SMALL_CHUNK + CHUNK_BOUNDARY + CHUNK_2 + CHUNK_BOUNDARY + CHUNK_3).getBytes(UTF_8);
-        ByteArrayInputStream inputStream = new ByteArrayInputStream(input);
-        ArrayList<String> result = new ArrayList<>();
-
-        mChunker.chunkify(inputStream, (chunk) -> result.add(new String(chunk, UTF_8)));
-
-        assertThat(result)
-                .containsExactly(SMALL_CHUNK + CHUNK_BOUNDARY + CHUNK_2 + CHUNK_BOUNDARY, CHUNK_3)
-                .inOrder();
-        assertThat(result.get(0).length()).isAtLeast(MIN_SIZE_BYTES);
-    }
-
-    /** Chunks can not be larger than the maximum chunk size. */
-    @Test
-    public void chunkify_doesNotProduceChunksLargerThanMaxSize() throws Exception {
-        byte[] largeInput = new byte[MAX_SIZE_BYTES * 10];
-        Arrays.fill(largeInput, "a".getBytes(UTF_8)[0]);
-        ByteArrayInputStream inputStream = new ByteArrayInputStream(largeInput);
-        ArrayList<String> result = new ArrayList<>();
-
-        mChunker.chunkify(inputStream, (chunk) -> result.add(new String(chunk, UTF_8)));
-
-        byte[] expectedChunkBytes = new byte[MAX_SIZE_BYTES];
-        Arrays.fill(expectedChunkBytes, "a".getBytes(UTF_8)[0]);
-        String expectedChunk = new String(expectedChunkBytes, UTF_8);
-        assertThat(result)
-                .containsExactly(
-                        expectedChunk,
-                        expectedChunk,
-                        expectedChunk,
-                        expectedChunk,
-                        expectedChunk,
-                        expectedChunk,
-                        expectedChunk,
-                        expectedChunk,
-                        expectedChunk,
-                        expectedChunk)
-                .inOrder();
-    }
-
-    /**
-     * If the input stream signals zero availablility, {@link
-     * ContentDefinedChunker#chunkify(InputStream, Chunker.ChunkConsumer)} should still work.
-     */
-    @Test
-    public void chunkify_withInputStreamReturningZeroAvailability_returnsChunks() throws Exception {
-        byte[] input = (SMALL_CHUNK + CHUNK_BOUNDARY + CHUNK_2).getBytes(UTF_8);
-        ZeroAvailabilityInputStream zeroAvailabilityInputStream =
-                new ZeroAvailabilityInputStream(input);
-        ArrayList<String> result = new ArrayList<>();
-
-        mChunker.chunkify(
-                zeroAvailabilityInputStream, (chunk) -> result.add(new String(chunk, UTF_8)));
-
-        assertThat(result).containsExactly(SMALL_CHUNK + CHUNK_BOUNDARY + CHUNK_2).inOrder();
-    }
-
-    /**
-     * {@link ContentDefinedChunker#chunkify(InputStream, Chunker.ChunkConsumer)} should rethrow any
-     * exception thrown by its consumer.
-     */
-    @Test
-    public void chunkify_whenConsumerThrowsException_rethrowsException() throws Exception {
-        ByteArrayInputStream inputStream = new ByteArrayInputStream(new byte[] {1});
-
-        assertThrows(
-                GeneralSecurityException.class,
-                () ->
-                        mChunker.chunkify(
-                                inputStream,
-                                (chunk) -> {
-                                    throw new GeneralSecurityException();
-                                }));
-    }
-
-    private long calculateFingerprint(byte[] bytes) {
-        long fingerprint = 0;
-        for (byte inByte : bytes) {
-            fingerprint =
-                    mRabinFingerprint64.computeFingerprint64(
-                            /*inChar=*/ inByte, /*outChar=*/ (byte) 0, fingerprint);
-        }
-        return mFingerprintMixer.mix(fingerprint);
-    }
-
-    private static class ZeroAvailabilityInputStream extends ByteArrayInputStream {
-        ZeroAvailabilityInputStream(byte[] wrapped) {
-            super(wrapped);
-        }
-
-        @Override
-        public synchronized int available() {
-            return 0;
-        }
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/cdc/FingerprintMixerTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/cdc/FingerprintMixerTest.java
deleted file mode 100644
index 936b5dc..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/cdc/FingerprintMixerTest.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.chunking.cdc;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.testng.Assert.assertThrows;
-
-import android.platform.test.annotations.Presubmit;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-
-import java.security.InvalidKeyException;
-import java.security.Key;
-import java.util.HashSet;
-import java.util.Random;
-
-import javax.crypto.SecretKey;
-import javax.crypto.spec.SecretKeySpec;
-
-/** Tests for {@link FingerprintMixer}. */
-@RunWith(RobolectricTestRunner.class)
-@Presubmit
-public class FingerprintMixerTest {
-    private static final String KEY_ALGORITHM = "AES";
-    private static final int SEED = 42;
-    private static final int SALT_LENGTH_BYTES = 256 / 8;
-    private static final int KEY_SIZE_BITS = 256;
-
-    private Random mSeededRandom;
-    private FingerprintMixer mFingerprintMixer;
-
-    /** Set up a {@link FingerprintMixer} with deterministic key and salt generation. */
-    @Before
-    public void setUp() throws Exception {
-        // Seed so that the tests are deterministic.
-        mSeededRandom = new Random(SEED);
-        mFingerprintMixer = new FingerprintMixer(randomKey(), randomSalt());
-    }
-
-    /**
-     * Construcing a {@link FingerprintMixer} with a salt that is too small should throw an {@link
-     * IllegalArgumentException}.
-     */
-    @Test
-    public void create_withIncorrectSaltSize_throwsIllegalArgumentException() {
-        byte[] tooSmallSalt = new byte[SALT_LENGTH_BYTES - 1];
-
-        assertThrows(
-                IllegalArgumentException.class,
-                () -> new FingerprintMixer(randomKey(), tooSmallSalt));
-    }
-
-    /**
-     * Constructing a {@link FingerprintMixer} with a secret key that can't be encoded should throw
-     * an {@link InvalidKeyException}.
-     */
-    @Test
-    public void create_withUnencodableSecretKey_throwsInvalidKeyException() {
-        byte[] keyBytes = new byte[KEY_SIZE_BITS / 8];
-        UnencodableSecretKeySpec keySpec =
-                new UnencodableSecretKeySpec(keyBytes, 0, keyBytes.length, KEY_ALGORITHM);
-
-        assertThrows(InvalidKeyException.class, () -> new FingerprintMixer(keySpec, randomSalt()));
-    }
-
-    /**
-     * {@link FingerprintMixer#getAddend()} should not return the same addend for two different
-     * keys.
-     */
-    @Test
-    public void getAddend_withDifferentKey_returnsDifferentResult() throws Exception {
-        int iterations = 100_000;
-        HashSet<Long> returnedAddends = new HashSet<>();
-        byte[] salt = randomSalt();
-
-        for (int i = 0; i < iterations; i++) {
-            FingerprintMixer fingerprintMixer = new FingerprintMixer(randomKey(), salt);
-            long addend = fingerprintMixer.getAddend();
-            returnedAddends.add(addend);
-        }
-
-        assertThat(returnedAddends).containsNoDuplicates();
-    }
-
-    /**
-     * {@link FingerprintMixer#getMultiplicand()} should not return the same multiplicand for two
-     * different keys.
-     */
-    @Test
-    public void getMultiplicand_withDifferentKey_returnsDifferentResult() throws Exception {
-        int iterations = 100_000;
-        HashSet<Long> returnedMultiplicands = new HashSet<>();
-        byte[] salt = randomSalt();
-
-        for (int i = 0; i < iterations; i++) {
-            FingerprintMixer fingerprintMixer = new FingerprintMixer(randomKey(), salt);
-            long multiplicand = fingerprintMixer.getMultiplicand();
-            returnedMultiplicands.add(multiplicand);
-        }
-
-        assertThat(returnedMultiplicands).containsNoDuplicates();
-    }
-
-    /** The multiplicant returned by {@link FingerprintMixer} should always be odd. */
-    @Test
-    public void getMultiplicand_isOdd() throws Exception {
-        int iterations = 100_000;
-
-        for (int i = 0; i < iterations; i++) {
-            FingerprintMixer fingerprintMixer = new FingerprintMixer(randomKey(), randomSalt());
-
-            long multiplicand = fingerprintMixer.getMultiplicand();
-
-            assertThat(isOdd(multiplicand)).isTrue();
-        }
-    }
-
-    /** {@link FingerprintMixer#mix(long)} should have a random distribution. */
-    @Test
-    public void mix_randomlyDistributesBits() throws Exception {
-        int iterations = 100_000;
-        float tolerance = 0.1f;
-        int[] totals = new int[64];
-
-        for (int i = 0; i < iterations; i++) {
-            long n = mFingerprintMixer.mix(mSeededRandom.nextLong());
-            for (int j = 0; j < 64; j++) {
-                int bit = (int) (n >> j & 1);
-                totals[j] += bit;
-            }
-        }
-
-        for (int i = 0; i < 64; i++) {
-            float mean = ((float) totals[i]) / iterations;
-            float diff = Math.abs(mean - 0.5f);
-            assertThat(diff).isLessThan(tolerance);
-        }
-    }
-
-    /**
-     * {@link FingerprintMixer#mix(long)} should always produce a number that's different from the
-     * input.
-     */
-    @Test
-    public void mix_doesNotProduceSameNumberAsInput() {
-        int iterations = 100_000;
-
-        for (int i = 0; i < iterations; i++) {
-            assertThat(mFingerprintMixer.mix(i)).isNotEqualTo(i);
-        }
-    }
-
-    private byte[] randomSalt() {
-        byte[] salt = new byte[SALT_LENGTH_BYTES];
-        mSeededRandom.nextBytes(salt);
-        return salt;
-    }
-
-    /**
-     * Not a secure way of generating keys. We want to deterministically generate the same keys for
-     * each test run, though, to ensure the test is deterministic.
-     */
-    private SecretKey randomKey() {
-        byte[] keyBytes = new byte[KEY_SIZE_BITS / 8];
-        mSeededRandom.nextBytes(keyBytes);
-        return new SecretKeySpec(keyBytes, 0, keyBytes.length, KEY_ALGORITHM);
-    }
-
-    private static boolean isOdd(long n) {
-        return Math.abs(n % 2) == 1;
-    }
-
-    /**
-     * Subclass of {@link SecretKeySpec} that does not provide an encoded version. As per its
-     * contract in {@link Key}, that means {@code getEncoded()} always returns null.
-     */
-    private class UnencodableSecretKeySpec extends SecretKeySpec {
-        UnencodableSecretKeySpec(byte[] key, int offset, int len, String algorithm) {
-            super(key, offset, len, algorithm);
-        }
-
-        @Override
-        public byte[] getEncoded() {
-            return null;
-        }
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/cdc/HkdfTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/cdc/HkdfTest.java
deleted file mode 100644
index 5494374..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/cdc/HkdfTest.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.chunking.cdc;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.testng.Assert.assertThrows;
-
-import android.platform.test.annotations.Presubmit;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-
-/** Tests for {@link Hkdf}. */
-@RunWith(RobolectricTestRunner.class)
-@Presubmit
-public class HkdfTest {
-    /** HKDF Test Case 1 IKM from RFC 5869 */
-    private static final byte[] HKDF_CASE1_IKM = {
-        0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-        0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-        0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-        0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
-        0x0b, 0x0b
-    };
-
-    /** HKDF Test Case 1 salt from RFC 5869 */
-    private static final byte[] HKDF_CASE1_SALT = {
-        0x00, 0x01, 0x02, 0x03, 0x04,
-        0x05, 0x06, 0x07, 0x08, 0x09,
-        0x0a, 0x0b, 0x0c
-    };
-
-    /** HKDF Test Case 1 info from RFC 5869 */
-    private static final byte[] HKDF_CASE1_INFO = {
-        (byte) 0xf0, (byte) 0xf1, (byte) 0xf2, (byte) 0xf3, (byte) 0xf4,
-        (byte) 0xf5, (byte) 0xf6, (byte) 0xf7, (byte) 0xf8, (byte) 0xf9
-    };
-
-    /** First 32 bytes of HKDF Test Case 1 OKM (output) from RFC 5869 */
-    private static final byte[] HKDF_CASE1_OKM = {
-        (byte) 0x3c, (byte) 0xb2, (byte) 0x5f, (byte) 0x25, (byte) 0xfa,
-        (byte) 0xac, (byte) 0xd5, (byte) 0x7a, (byte) 0x90, (byte) 0x43,
-        (byte) 0x4f, (byte) 0x64, (byte) 0xd0, (byte) 0x36, (byte) 0x2f,
-        (byte) 0x2a, (byte) 0x2d, (byte) 0x2d, (byte) 0x0a, (byte) 0x90,
-        (byte) 0xcf, (byte) 0x1a, (byte) 0x5a, (byte) 0x4c, (byte) 0x5d,
-        (byte) 0xb0, (byte) 0x2d, (byte) 0x56, (byte) 0xec, (byte) 0xc4,
-        (byte) 0xc5, (byte) 0xbf
-    };
-
-    /** Test the example from RFC 5869. */
-    @Test
-    public void hkdf_derivesKeyMaterial() throws Exception {
-        byte[] result = Hkdf.hkdf(HKDF_CASE1_IKM, HKDF_CASE1_SALT, HKDF_CASE1_INFO);
-
-        assertThat(result).isEqualTo(HKDF_CASE1_OKM);
-    }
-
-    /** Providing a key that is null should throw a {@link java.lang.NullPointerException}. */
-    @Test
-    public void hkdf_withNullKey_throwsNullPointerException() throws Exception {
-        assertThrows(
-                NullPointerException.class,
-                () -> Hkdf.hkdf(null, HKDF_CASE1_SALT, HKDF_CASE1_INFO));
-    }
-
-    /** Providing a salt that is null should throw a {@link java.lang.NullPointerException}. */
-    @Test
-    public void hkdf_withNullSalt_throwsNullPointerException() throws Exception {
-        assertThrows(
-                NullPointerException.class, () -> Hkdf.hkdf(HKDF_CASE1_IKM, null, HKDF_CASE1_INFO));
-    }
-
-    /** Providing data that is null should throw a {@link java.lang.NullPointerException}. */
-    @Test
-    public void hkdf_withNullData_throwsNullPointerException() throws Exception {
-        assertThrows(
-                NullPointerException.class, () -> Hkdf.hkdf(HKDF_CASE1_IKM, HKDF_CASE1_SALT, null));
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/cdc/IsChunkBreakpointTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/cdc/IsChunkBreakpointTest.java
deleted file mode 100644
index 277dc37..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/cdc/IsChunkBreakpointTest.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.chunking.cdc;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.testng.Assert.assertThrows;
-
-import android.platform.test.annotations.Presubmit;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-
-import java.util.Random;
-
-/** Tests for {@link IsChunkBreakpoint}. */
-@RunWith(RobolectricTestRunner.class)
-@Presubmit
-public class IsChunkBreakpointTest {
-    private static final int RANDOM_SEED = 42;
-    private static final double TOLERANCE = 0.01;
-    private static final int NUMBER_OF_TESTS = 10000;
-    private static final int BITS_PER_LONG = 64;
-
-    private Random mRandom;
-
-    /** Make sure that tests are deterministic. */
-    @Before
-    public void setUp() {
-        mRandom = new Random(RANDOM_SEED);
-    }
-
-    /**
-     * Providing a negative average number of trials should throw an {@link
-     * IllegalArgumentException}.
-     */
-    @Test
-    public void create_withNegativeAverageNumberOfTrials_throwsIllegalArgumentException() {
-        assertThrows(IllegalArgumentException.class, () -> new IsChunkBreakpoint(-1));
-    }
-
-    // Note: the following three tests are compute-intensive, so be cautious adding more.
-
-    /**
-     * If the provided average number of trials is zero, a breakpoint should be expected after one
-     * trial on average.
-     */
-    @Test
-    public void
-            isBreakpoint_withZeroAverageNumberOfTrials_isTrueOnAverageAfterOneTrial() {
-        assertExpectedTrials(new IsChunkBreakpoint(0), /*expectedTrials=*/ 1);
-    }
-
-    /**
-     * If the provided average number of trials is 512, a breakpoint should be expected after 512
-     * trials on average.
-     */
-    @Test
-    public void
-            isBreakpoint_with512AverageNumberOfTrials_isTrueOnAverageAfter512Trials() {
-        assertExpectedTrials(new IsChunkBreakpoint(512), /*expectedTrials=*/ 512);
-    }
-
-    /**
-     * If the provided average number of trials is 1024, a breakpoint should be expected after 1024
-     * trials on average.
-     */
-    @Test
-    public void
-            isBreakpoint_with1024AverageNumberOfTrials_isTrueOnAverageAfter1024Trials() {
-        assertExpectedTrials(new IsChunkBreakpoint(1024), /*expectedTrials=*/ 1024);
-    }
-
-    /** The number of leading zeros should be the logarithm of the average number of trials. */
-    @Test
-    public void getLeadingZeros_squaredIsAverageNumberOfTrials() {
-        for (int i = 0; i < BITS_PER_LONG; i++) {
-            long averageNumberOfTrials = (long) Math.pow(2, i);
-
-            int leadingZeros = new IsChunkBreakpoint(averageNumberOfTrials).getLeadingZeros();
-
-            assertThat(leadingZeros).isEqualTo(i);
-        }
-    }
-
-    private void assertExpectedTrials(IsChunkBreakpoint isChunkBreakpoint, long expectedTrials) {
-        long sum = 0;
-        for (int i = 0; i < NUMBER_OF_TESTS; i++) {
-            sum += numberOfTrialsTillBreakpoint(isChunkBreakpoint);
-        }
-        long averageTrials = sum / NUMBER_OF_TESTS;
-        assertThat((double) Math.abs(averageTrials - expectedTrials))
-                .isLessThan(TOLERANCE * expectedTrials);
-    }
-
-    private int numberOfTrialsTillBreakpoint(IsChunkBreakpoint isChunkBreakpoint) {
-        int trials = 0;
-
-        while (true) {
-            trials++;
-            if (isChunkBreakpoint.isBreakpoint(mRandom.nextLong())) {
-                return trials;
-            }
-        }
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/cdc/RabinFingerprint64Test.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/cdc/RabinFingerprint64Test.java
deleted file mode 100644
index 729580c..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/chunking/cdc/RabinFingerprint64Test.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.chunking.cdc;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static java.nio.charset.StandardCharsets.UTF_8;
-
-import android.platform.test.annotations.Presubmit;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-
-/** Tests for {@link RabinFingerprint64}. */
-@RunWith(RobolectricTestRunner.class)
-@Presubmit
-public class RabinFingerprint64Test {
-    private static final int WINDOW_SIZE = 31;
-    private static final ImmutableList<String> TEST_STRINGS =
-            ImmutableList.of(
-                    "ervHTtChYXO6eXivYqThlyyzqkbRaOR",
-                    "IxaVunH9ZC3qneWfhj1GkBH4ys9CYqz",
-                    "wZRVjlE1p976icCFPX9pibk4PEBvjSH",
-                    "pHIVaT8x8If9D6s9croksgNmJpmGYWI");
-
-    private final RabinFingerprint64 mRabinFingerprint64 = new RabinFingerprint64();
-
-    /**
-     * No matter where in the input buffer a string occurs, {@link
-     * RabinFingerprint64#computeFingerprint64(byte, byte, long)} should return the same
-     * fingerprint.
-     */
-    @Test
-    public void computeFingerprint64_forSameWindow_returnsSameFingerprint() {
-        long fingerprint1 =
-                computeFingerprintAtPosition(getBytes(TEST_STRINGS.get(0)), WINDOW_SIZE - 1);
-        long fingerprint2 =
-                computeFingerprintAtPosition(
-                        getBytes(TEST_STRINGS.get(1), TEST_STRINGS.get(0)), WINDOW_SIZE * 2 - 1);
-        long fingerprint3 =
-                computeFingerprintAtPosition(
-                        getBytes(TEST_STRINGS.get(2), TEST_STRINGS.get(3), TEST_STRINGS.get(0)),
-                        WINDOW_SIZE * 3 - 1);
-        String stub = "abc";
-        long fingerprint4 =
-                computeFingerprintAtPosition(
-                        getBytes(stub, TEST_STRINGS.get(0)), WINDOW_SIZE + stub.length() - 1);
-
-        // Assert that all fingerprints are exactly the same
-        assertThat(ImmutableSet.of(fingerprint1, fingerprint2, fingerprint3, fingerprint4))
-                .hasSize(1);
-    }
-
-    /** The computed fingerprint should be different for different inputs. */
-    @Test
-    public void computeFingerprint64_withDifferentInput_returnsDifferentFingerprint() {
-        long fingerprint1 = computeFingerprintOf(TEST_STRINGS.get(0));
-        long fingerprint2 = computeFingerprintOf(TEST_STRINGS.get(1));
-        long fingerprint3 = computeFingerprintOf(TEST_STRINGS.get(2));
-        long fingerprint4 = computeFingerprintOf(TEST_STRINGS.get(3));
-
-        assertThat(ImmutableList.of(fingerprint1, fingerprint2, fingerprint3, fingerprint4))
-                .containsNoDuplicates();
-    }
-
-    /**
-     * An input with the same characters in a different order should return a different fingerprint.
-     */
-    @Test
-    public void computeFingerprint64_withSameInputInDifferentOrder_returnsDifferentFingerprint() {
-        long fingerprint1 = computeFingerprintOf("abcdefghijklmnopqrstuvwxyz12345");
-        long fingerprint2 = computeFingerprintOf("54321zyxwvutsrqponmlkjihgfedcba");
-        long fingerprint3 = computeFingerprintOf("4bcdefghijklmnopqrstuvwxyz123a5");
-        long fingerprint4 = computeFingerprintOf("bacdefghijklmnopqrstuvwxyz12345");
-
-        assertThat(ImmutableList.of(fingerprint1, fingerprint2, fingerprint3, fingerprint4))
-                .containsNoDuplicates();
-    }
-
-    /** UTF-8 bytes of all the given strings in order. */
-    private byte[] getBytes(String... strings) {
-        StringBuilder sb = new StringBuilder();
-        for (String s : strings) {
-            sb.append(s);
-        }
-        return sb.toString().getBytes(UTF_8);
-    }
-
-    /**
-     * The Rabin fingerprint of a window of bytes ending at {@code position} in the {@code bytes}
-     * array.
-     */
-    private long computeFingerprintAtPosition(byte[] bytes, int position) {
-        assertThat(position).isAtMost(bytes.length - 1);
-        long fingerprint = 0;
-        for (int i = 0; i <= position; i++) {
-            byte outChar;
-            if (i >= WINDOW_SIZE) {
-                outChar = bytes[i - WINDOW_SIZE];
-            } else {
-                outChar = (byte) 0;
-            }
-            fingerprint =
-                    mRabinFingerprint64.computeFingerprint64(
-                            /*inChar=*/ bytes[i], outChar, fingerprint);
-        }
-        return fingerprint;
-    }
-
-    private long computeFingerprintOf(String s) {
-        assertThat(s.length()).isEqualTo(WINDOW_SIZE);
-        return computeFingerprintAtPosition(s.getBytes(UTF_8), WINDOW_SIZE - 1);
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/KeyWrapUtilsTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/KeyWrapUtilsTest.java
deleted file mode 100644
index b607404..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/KeyWrapUtilsTest.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.keys;
-
-import static com.android.server.backup.testing.CryptoTestUtils.generateAesKey;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.platform.test.annotations.Presubmit;
-
-import com.android.server.backup.encryption.protos.nano.WrappedKeyProto;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-
-import java.security.InvalidKeyException;
-
-import javax.crypto.SecretKey;
-
-/** Key wrapping tests */
-@RunWith(RobolectricTestRunner.class)
-@Presubmit
-public class KeyWrapUtilsTest {
-    private static final int KEY_SIZE_BITS = 256;
-    private static final int BITS_PER_BYTE = 8;
-    private static final int GCM_NONCE_LENGTH_BYTES = 16;
-    private static final int GCM_TAG_LENGTH_BYTES = 16;
-
-    /** Test a wrapped key has metadata */
-    @Test
-    public void wrap_addsMetadata() throws Exception {
-        WrappedKeyProto.WrappedKey wrappedKey =
-                KeyWrapUtils.wrap(
-                        /*secondaryKey=*/ generateAesKey(), /*tertiaryKey=*/ generateAesKey());
-        assertThat(wrappedKey.metadata).isNotNull();
-        assertThat(wrappedKey.metadata.type).isEqualTo(WrappedKeyProto.KeyMetadata.AES_256_GCM);
-    }
-
-    /** Test a wrapped key has an algorithm specified */
-    @Test
-    public void wrap_addsWrapAlgorithm() throws Exception {
-        WrappedKeyProto.WrappedKey wrappedKey =
-                KeyWrapUtils.wrap(
-                        /*secondaryKey=*/ generateAesKey(), /*tertiaryKey=*/ generateAesKey());
-        assertThat(wrappedKey.wrapAlgorithm).isEqualTo(WrappedKeyProto.WrappedKey.AES_256_GCM);
-    }
-
-    /** Test a wrapped key haas an nonce of the right length */
-    @Test
-    public void wrap_addsNonceOfAppropriateLength() throws Exception {
-        WrappedKeyProto.WrappedKey wrappedKey =
-                KeyWrapUtils.wrap(
-                        /*secondaryKey=*/ generateAesKey(), /*tertiaryKey=*/ generateAesKey());
-        assertThat(wrappedKey.nonce).hasLength(GCM_NONCE_LENGTH_BYTES);
-    }
-
-    /** Test a wrapped key has a key of the right length */
-    @Test
-    public void wrap_addsTagOfAppropriateLength() throws Exception {
-        WrappedKeyProto.WrappedKey wrappedKey =
-                KeyWrapUtils.wrap(
-                        /*secondaryKey=*/ generateAesKey(), /*tertiaryKey=*/ generateAesKey());
-        assertThat(wrappedKey.key).hasLength(KEY_SIZE_BITS / BITS_PER_BYTE + GCM_TAG_LENGTH_BYTES);
-    }
-
-    /** Ensure a key can be wrapped and unwrapped again */
-    @Test
-    public void unwrap_unwrapsEncryptedKey() throws Exception {
-        SecretKey secondaryKey = generateAesKey();
-        SecretKey tertiaryKey = generateAesKey();
-        WrappedKeyProto.WrappedKey wrappedKey = KeyWrapUtils.wrap(secondaryKey, tertiaryKey);
-        SecretKey unwrappedKey = KeyWrapUtils.unwrap(secondaryKey, wrappedKey);
-        assertThat(unwrappedKey).isEqualTo(tertiaryKey);
-    }
-
-    /** Ensure the unwrap method rejects keys with bad algorithms */
-    @Test(expected = InvalidKeyException.class)
-    public void unwrap_throwsForBadWrapAlgorithm() throws Exception {
-        SecretKey secondaryKey = generateAesKey();
-        WrappedKeyProto.WrappedKey wrappedKey = KeyWrapUtils.wrap(secondaryKey, generateAesKey());
-        wrappedKey.wrapAlgorithm = WrappedKeyProto.WrappedKey.UNKNOWN;
-
-        KeyWrapUtils.unwrap(secondaryKey, wrappedKey);
-    }
-
-    /** Ensure the unwrap method rejects metadata indicating the encryption type is unknown */
-    @Test(expected = InvalidKeyException.class)
-    public void unwrap_throwsForBadKeyAlgorithm() throws Exception {
-        SecretKey secondaryKey = generateAesKey();
-        WrappedKeyProto.WrappedKey wrappedKey = KeyWrapUtils.wrap(secondaryKey, generateAesKey());
-        wrappedKey.metadata.type = WrappedKeyProto.KeyMetadata.UNKNOWN;
-
-        KeyWrapUtils.unwrap(secondaryKey, wrappedKey);
-    }
-
-    /** Ensure the unwrap method rejects wrapped keys missing the metadata */
-    @Test(expected = InvalidKeyException.class)
-    public void unwrap_throwsForMissingMetadata() throws Exception {
-        SecretKey secondaryKey = generateAesKey();
-        WrappedKeyProto.WrappedKey wrappedKey = KeyWrapUtils.wrap(secondaryKey, generateAesKey());
-        wrappedKey.metadata = null;
-
-        KeyWrapUtils.unwrap(secondaryKey, wrappedKey);
-    }
-
-    /** Ensure unwrap rejects invalid secondary keys */
-    @Test(expected = InvalidKeyException.class)
-    public void unwrap_throwsForBadSecondaryKey() throws Exception {
-        WrappedKeyProto.WrappedKey wrappedKey =
-                KeyWrapUtils.wrap(
-                        /*secondaryKey=*/ generateAesKey(), /*tertiaryKey=*/ generateAesKey());
-
-        KeyWrapUtils.unwrap(generateAesKey(), wrappedKey);
-    }
-
-    /** Ensure rewrap can rewrap keys */
-    @Test
-    public void rewrap_canBeUnwrappedWithNewSecondaryKey() throws Exception {
-        SecretKey tertiaryKey = generateAesKey();
-        SecretKey oldSecondaryKey = generateAesKey();
-        SecretKey newSecondaryKey = generateAesKey();
-        WrappedKeyProto.WrappedKey wrappedWithOld = KeyWrapUtils.wrap(oldSecondaryKey, tertiaryKey);
-
-        WrappedKeyProto.WrappedKey wrappedWithNew =
-                KeyWrapUtils.rewrap(oldSecondaryKey, newSecondaryKey, wrappedWithOld);
-
-        assertThat(KeyWrapUtils.unwrap(newSecondaryKey, wrappedWithNew)).isEqualTo(tertiaryKey);
-    }
-
-    /** Ensure rewrap doesn't create something decryptable by an old key */
-    @Test(expected = InvalidKeyException.class)
-    public void rewrap_cannotBeUnwrappedWithOldSecondaryKey() throws Exception {
-        SecretKey tertiaryKey = generateAesKey();
-        SecretKey oldSecondaryKey = generateAesKey();
-        SecretKey newSecondaryKey = generateAesKey();
-        WrappedKeyProto.WrappedKey wrappedWithOld = KeyWrapUtils.wrap(oldSecondaryKey, tertiaryKey);
-
-        WrappedKeyProto.WrappedKey wrappedWithNew =
-                KeyWrapUtils.rewrap(oldSecondaryKey, newSecondaryKey, wrappedWithOld);
-
-        KeyWrapUtils.unwrap(oldSecondaryKey, wrappedWithNew);
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyManagerTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyManagerTest.java
deleted file mode 100644
index 5342efa..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyManagerTest.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.keys;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.testng.Assert.assertThrows;
-
-import android.content.Context;
-import android.platform.test.annotations.Presubmit;
-import android.security.keystore.recovery.InternalRecoveryServiceException;
-import android.security.keystore.recovery.RecoveryController;
-
-import com.android.server.testing.shadows.ShadowInternalRecoveryServiceException;
-import com.android.server.testing.shadows.ShadowRecoveryController;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-import java.security.SecureRandom;
-import java.util.Optional;
-
-/** Tests for {@link RecoverableKeyStoreSecondaryKeyManager}. */
-@RunWith(RobolectricTestRunner.class)
-@Presubmit
-@Config(shadows = {ShadowRecoveryController.class, ShadowInternalRecoveryServiceException.class})
-public class RecoverableKeyStoreSecondaryKeyManagerTest {
-    private static final String BACKUP_KEY_ALIAS_PREFIX =
-            "com.android.server.backup/recoverablekeystore/";
-    private static final int BITS_PER_BYTE = 8;
-    private static final int BACKUP_KEY_SUFFIX_LENGTH_BYTES = 128 / BITS_PER_BYTE;
-    private static final int HEX_PER_BYTE = 2;
-    private static final int BACKUP_KEY_ALIAS_LENGTH =
-            BACKUP_KEY_ALIAS_PREFIX.length() + BACKUP_KEY_SUFFIX_LENGTH_BYTES * HEX_PER_BYTE;
-    private static final String NONEXISTENT_KEY_ALIAS = "NONEXISTENT_KEY_ALIAS";
-
-    private RecoverableKeyStoreSecondaryKeyManager mRecoverableKeyStoreSecondaryKeyManager;
-    private Context mContext;
-
-    /** Create a new {@link RecoverableKeyStoreSecondaryKeyManager} to use in tests. */
-    @Before
-    public void setUp() throws Exception {
-        mContext = RuntimeEnvironment.application;
-
-        mRecoverableKeyStoreSecondaryKeyManager =
-                new RecoverableKeyStoreSecondaryKeyManager(
-                        RecoveryController.getInstance(mContext), new SecureRandom());
-    }
-
-    /** Reset the {@link ShadowRecoveryController}. */
-    @After
-    public void tearDown() throws Exception {
-        ShadowRecoveryController.reset();
-    }
-
-    /** The generated key should always have the prefix {@code BACKUP_KEY_ALIAS_PREFIX}. */
-    @Test
-    public void generate_generatesKeyWithExpectedPrefix() throws Exception {
-        RecoverableKeyStoreSecondaryKey key = mRecoverableKeyStoreSecondaryKeyManager.generate();
-
-        assertThat(key.getAlias()).startsWith(BACKUP_KEY_ALIAS_PREFIX);
-    }
-
-    /** The generated key should always have length {@code BACKUP_KEY_ALIAS_LENGTH}. */
-    @Test
-    public void generate_generatesKeyWithExpectedLength() throws Exception {
-        RecoverableKeyStoreSecondaryKey key = mRecoverableKeyStoreSecondaryKeyManager.generate();
-
-        assertThat(key.getAlias()).hasLength(BACKUP_KEY_ALIAS_LENGTH);
-    }
-
-    /** Ensure that hidden API exceptions are rethrown when generating keys. */
-    @Test
-    public void generate_encounteringHiddenApiException_rethrowsException() {
-        ShadowRecoveryController.setThrowsInternalError(true);
-
-        assertThrows(
-                InternalRecoveryServiceException.class,
-                mRecoverableKeyStoreSecondaryKeyManager::generate);
-    }
-
-    /** Ensure that retrieved keys correspond to those generated earlier. */
-    @Test
-    public void get_getsKeyGeneratedByController() throws Exception {
-        RecoverableKeyStoreSecondaryKey key = mRecoverableKeyStoreSecondaryKeyManager.generate();
-
-        Optional<RecoverableKeyStoreSecondaryKey> retrievedKey =
-                mRecoverableKeyStoreSecondaryKeyManager.get(key.getAlias());
-
-        assertThat(retrievedKey.isPresent()).isTrue();
-        assertThat(retrievedKey.get().getAlias()).isEqualTo(key.getAlias());
-        assertThat(retrievedKey.get().getSecretKey()).isEqualTo(key.getSecretKey());
-    }
-
-    /**
-     * Ensure that a call to {@link RecoverableKeyStoreSecondaryKeyManager#get(java.lang.String)}
-     * for nonexistent aliases returns an emtpy {@link Optional}.
-     */
-    @Test
-    public void get_forNonExistentKey_returnsEmptyOptional() throws Exception {
-        Optional<RecoverableKeyStoreSecondaryKey> retrievedKey =
-                mRecoverableKeyStoreSecondaryKeyManager.get(NONEXISTENT_KEY_ALIAS);
-
-        assertThat(retrievedKey.isPresent()).isFalse();
-    }
-
-    /**
-     * Ensure that exceptions occurring during {@link
-     * RecoverableKeyStoreSecondaryKeyManager#get(java.lang.String)} are not rethrown.
-     */
-    @Test
-    public void get_encounteringInternalException_doesNotPropagateException() throws Exception {
-        ShadowRecoveryController.setThrowsInternalError(true);
-
-        // Should not throw exception
-        mRecoverableKeyStoreSecondaryKeyManager.get(NONEXISTENT_KEY_ALIAS);
-    }
-
-    /** Ensure that keys are correctly removed from the store. */
-    @Test
-    public void remove_removesKeyFromRecoverableStore() throws Exception {
-        RecoverableKeyStoreSecondaryKey key = mRecoverableKeyStoreSecondaryKeyManager.generate();
-
-        mRecoverableKeyStoreSecondaryKeyManager.remove(key.getAlias());
-
-        assertThat(RecoveryController.getInstance(mContext).getAliases())
-                .doesNotContain(key.getAlias());
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyTest.java
deleted file mode 100644
index 89977f8..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyTest.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.keys;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.testng.Assert.assertThrows;
-
-import android.content.Context;
-import android.platform.test.annotations.Presubmit;
-import android.security.keystore.recovery.RecoveryController;
-
-import com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKey.Status;
-import com.android.server.backup.testing.CryptoTestUtils;
-import com.android.server.testing.shadows.ShadowInternalRecoveryServiceException;
-import com.android.server.testing.shadows.ShadowRecoveryController;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-import javax.crypto.SecretKey;
-
-/** Tests for {@link RecoverableKeyStoreSecondaryKey}. */
-@RunWith(RobolectricTestRunner.class)
-@Presubmit
-@Config(shadows = {ShadowRecoveryController.class, ShadowInternalRecoveryServiceException.class})
-public class RecoverableKeyStoreSecondaryKeyTest {
-    private static final String TEST_ALIAS = "test";
-    private static final int NONEXISTENT_STATUS_CODE = 42;
-
-    private RecoverableKeyStoreSecondaryKey mSecondaryKey;
-    private SecretKey mGeneratedSecretKey;
-    private Context mContext;
-
-    /** Instantiate a {@link RecoverableKeyStoreSecondaryKey} to use in tests. */
-    @Before
-    public void setUp() throws Exception {
-        mContext = RuntimeEnvironment.application;
-        mGeneratedSecretKey = CryptoTestUtils.generateAesKey();
-        mSecondaryKey = new RecoverableKeyStoreSecondaryKey(TEST_ALIAS, mGeneratedSecretKey);
-    }
-
-    /** Reset the {@link ShadowRecoveryController}. */
-    @After
-    public void tearDown() throws Exception {
-        ShadowRecoveryController.reset();
-    }
-
-    /**
-     * Checks that {@link RecoverableKeyStoreSecondaryKey#getAlias()} returns the value supplied in
-     * the constructor.
-     */
-    @Test
-    public void getAlias() {
-        String alias = mSecondaryKey.getAlias();
-
-        assertThat(alias).isEqualTo(TEST_ALIAS);
-    }
-
-    /**
-     * Checks that {@link RecoverableKeyStoreSecondaryKey#getSecretKey()} returns the value supplied
-     * in the constructor.
-     */
-    @Test
-    public void getSecretKey() {
-        SecretKey secretKey = mSecondaryKey.getSecretKey();
-
-        assertThat(secretKey).isEqualTo(mGeneratedSecretKey);
-    }
-
-    /**
-     * Checks that passing a secret key that is null to the constructor throws an exception.
-     */
-    @Test
-    public void constructor_withNullSecretKey_throwsNullPointerException() {
-        assertThrows(
-                NullPointerException.class,
-                () -> new RecoverableKeyStoreSecondaryKey(TEST_ALIAS, null));
-    }
-
-    /**
-     * Checks that passing an alias that is null to the constructor throws an exception.
-     */
-    @Test
-    public void constructor_withNullAlias_throwsNullPointerException() {
-        assertThrows(
-                NullPointerException.class,
-                () -> new RecoverableKeyStoreSecondaryKey(null, mGeneratedSecretKey));
-    }
-
-    /** Checks that the synced status is returned correctly. */
-    @Test
-    public void getStatus_whenSynced_returnsSynced() throws Exception {
-        setStatus(RecoveryController.RECOVERY_STATUS_SYNCED);
-
-        int status = mSecondaryKey.getStatus(mContext);
-
-        assertThat(status).isEqualTo(Status.SYNCED);
-    }
-
-    /** Checks that the in progress sync status is returned correctly. */
-    @Test
-    public void getStatus_whenNotSynced_returnsNotSynced() throws Exception {
-        setStatus(RecoveryController.RECOVERY_STATUS_SYNC_IN_PROGRESS);
-
-        int status = mSecondaryKey.getStatus(mContext);
-
-        assertThat(status).isEqualTo(Status.NOT_SYNCED);
-    }
-
-    /** Checks that the failure status is returned correctly. */
-    @Test
-    public void getStatus_onPermanentFailure_returnsDestroyed() throws Exception {
-        setStatus(RecoveryController.RECOVERY_STATUS_PERMANENT_FAILURE);
-
-        int status = mSecondaryKey.getStatus(mContext);
-
-        assertThat(status).isEqualTo(Status.DESTROYED);
-    }
-
-    /** Checks that an unknown status results in {@code NOT_SYNCED} being returned. */
-    @Test
-    public void getStatus_forUnknownStatusCode_returnsNotSynced() throws Exception {
-        setStatus(NONEXISTENT_STATUS_CODE);
-
-        int status = mSecondaryKey.getStatus(mContext);
-
-        assertThat(status).isEqualTo(Status.NOT_SYNCED);
-    }
-
-    /** Checks that an internal error results in {@code NOT_SYNCED} being returned. */
-    @Test
-    public void getStatus_onInternalError_returnsNotSynced() throws Exception {
-        ShadowRecoveryController.setThrowsInternalError(true);
-
-        int status = mSecondaryKey.getStatus(mContext);
-
-        assertThat(status).isEqualTo(Status.NOT_SYNCED);
-    }
-
-    private void setStatus(int status) throws Exception {
-        ShadowRecoveryController.setRecoveryStatus(TEST_ALIAS, status);
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/RestoreKeyFetcherTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/RestoreKeyFetcherTest.java
deleted file mode 100644
index 004f809..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/RestoreKeyFetcherTest.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.keys;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.when;
-import static org.testng.Assert.assertThrows;
-
-import android.platform.test.annotations.Presubmit;
-
-import com.android.server.backup.encryption.protos.nano.WrappedKeyProto;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-
-import java.security.InvalidKeyException;
-import java.security.KeyException;
-import java.security.SecureRandom;
-import java.util.Optional;
-
-import javax.crypto.SecretKey;
-import javax.crypto.spec.SecretKeySpec;
-
-/** Test the restore key fetcher */
-@RunWith(RobolectricTestRunner.class)
-@Presubmit
-public class RestoreKeyFetcherTest {
-
-    private static final String KEY_GENERATOR_ALGORITHM = "AES";
-
-    private static final String TEST_SECONDARY_KEY_ALIAS = "test_2ndary_key";
-    private static final byte[] TEST_SECONDARY_KEY_BYTES = new byte[256 / Byte.SIZE];
-
-    @Mock private RecoverableKeyStoreSecondaryKeyManager mSecondaryKeyManager;
-
-    /** Initialise the mocks **/
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-    }
-
-    /** Ensure the unwrap method works as expected */
-    @Test
-    public void unwrapTertiaryKey_returnsUnwrappedKey() throws Exception {
-        RecoverableKeyStoreSecondaryKey secondaryKey = createSecondaryKey();
-        SecretKey tertiaryKey = createTertiaryKey();
-        WrappedKeyProto.WrappedKey wrappedTertiaryKey =
-                KeyWrapUtils.wrap(secondaryKey.getSecretKey(), tertiaryKey);
-        when(mSecondaryKeyManager.get(TEST_SECONDARY_KEY_ALIAS))
-                .thenReturn(Optional.of(secondaryKey));
-
-        SecretKey actualTertiaryKey =
-                RestoreKeyFetcher.unwrapTertiaryKey(
-                        () -> mSecondaryKeyManager,
-                        TEST_SECONDARY_KEY_ALIAS,
-                        wrappedTertiaryKey);
-
-        assertThat(actualTertiaryKey).isEqualTo(tertiaryKey);
-    }
-
-    /** Ensure that missing secondary keys are detected and an appropriate exception is thrown */
-    @Test
-    public void unwrapTertiaryKey_missingSecondaryKey_throwsSpecificException() throws Exception {
-        WrappedKeyProto.WrappedKey wrappedTertiaryKey =
-                KeyWrapUtils.wrap(createSecondaryKey().getSecretKey(), createTertiaryKey());
-        when(mSecondaryKeyManager.get(TEST_SECONDARY_KEY_ALIAS)).thenReturn(Optional.empty());
-
-        assertThrows(
-                KeyException.class,
-                () ->
-                        RestoreKeyFetcher.unwrapTertiaryKey(
-                                () -> mSecondaryKeyManager,
-                                TEST_SECONDARY_KEY_ALIAS,
-                                wrappedTertiaryKey));
-    }
-
-    /** Ensure that invalid secondary keys are detected and an appropriate exception is thrown */
-    @Test
-    public void unwrapTertiaryKey_badSecondaryKey_throws() throws Exception {
-        RecoverableKeyStoreSecondaryKey badSecondaryKey =
-                new RecoverableKeyStoreSecondaryKey(
-                        TEST_SECONDARY_KEY_ALIAS,
-                        new SecretKeySpec(new byte[] {0, 1}, KEY_GENERATOR_ALGORITHM));
-
-        WrappedKeyProto.WrappedKey wrappedTertiaryKey =
-                KeyWrapUtils.wrap(createSecondaryKey().getSecretKey(), createTertiaryKey());
-        when(mSecondaryKeyManager.get(TEST_SECONDARY_KEY_ALIAS))
-                .thenReturn(Optional.of(badSecondaryKey));
-
-        assertThrows(
-                InvalidKeyException.class,
-                () ->
-                        RestoreKeyFetcher.unwrapTertiaryKey(
-                                () -> mSecondaryKeyManager,
-                                TEST_SECONDARY_KEY_ALIAS,
-                                wrappedTertiaryKey));
-    }
-
-    private static RecoverableKeyStoreSecondaryKey createSecondaryKey() {
-        return new RecoverableKeyStoreSecondaryKey(
-                TEST_SECONDARY_KEY_ALIAS,
-                new SecretKeySpec(TEST_SECONDARY_KEY_BYTES, KEY_GENERATOR_ALGORITHM));
-    }
-
-    private static SecretKey createTertiaryKey() {
-        return new TertiaryKeyGenerator(new SecureRandom(new byte[] {0})).generate();
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/SecondaryKeyRotationSchedulerTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/SecondaryKeyRotationSchedulerTest.java
deleted file mode 100644
index c31d19d..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/SecondaryKeyRotationSchedulerTest.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.keys;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.platform.test.annotations.Presubmit;
-
-import androidx.test.core.app.ApplicationProvider;
-
-import com.android.server.backup.encryption.CryptoSettings;
-import com.android.server.backup.encryption.tasks.StartSecondaryKeyRotationTask;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-import org.robolectric.annotation.Implementation;
-import org.robolectric.annotation.Implements;
-import org.robolectric.annotation.Resetter;
-
-import java.io.File;
-import java.time.Clock;
-
-@Config(shadows = SecondaryKeyRotationSchedulerTest.ShadowStartSecondaryKeyRotationTask.class)
-@RunWith(RobolectricTestRunner.class)
-@Presubmit
-public class SecondaryKeyRotationSchedulerTest {
-    private static final String SENTINEL_FILE_PATH = "force_secondary_key_rotation";
-
-    @Mock private RecoverableKeyStoreSecondaryKeyManager mSecondaryKeyManager;
-    @Mock private Clock mClock;
-
-    private CryptoSettings mCryptoSettings;
-    private SecondaryKeyRotationScheduler mScheduler;
-    private long mRotationIntervalMillis;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        Context application = ApplicationProvider.getApplicationContext();
-
-        mCryptoSettings = CryptoSettings.getInstanceForTesting(application);
-        mRotationIntervalMillis = mCryptoSettings.backupSecondaryKeyRotationIntervalMs();
-
-        mScheduler =
-                new SecondaryKeyRotationScheduler(
-                        application, mSecondaryKeyManager, mCryptoSettings, mClock);
-        ShadowStartSecondaryKeyRotationTask.reset();
-    }
-
-    @Test
-    public void startRotationIfScheduled_rotatesIfRotationWasFarEnoughInThePast() {
-        long lastRotated = 100009;
-        mCryptoSettings.setSecondaryLastRotated(lastRotated);
-        setNow(lastRotated + mRotationIntervalMillis);
-
-        mScheduler.startRotationIfScheduled();
-
-        assertThat(ShadowStartSecondaryKeyRotationTask.sRan).isTrue();
-    }
-
-    @Test
-    public void startRotationIfScheduled_setsNewRotationTimeIfRotationWasFarEnoughInThePast() {
-        long lastRotated = 100009;
-        long now = lastRotated + mRotationIntervalMillis;
-        mCryptoSettings.setSecondaryLastRotated(lastRotated);
-        setNow(now);
-
-        mScheduler.startRotationIfScheduled();
-
-        assertThat(mCryptoSettings.getSecondaryLastRotated().get()).isEqualTo(now);
-    }
-
-    @Test
-    public void startRotationIfScheduled_rotatesIfClockHasChanged() {
-        long lastRotated = 100009;
-        mCryptoSettings.setSecondaryLastRotated(lastRotated);
-        setNow(lastRotated - 1);
-
-        mScheduler.startRotationIfScheduled();
-
-        assertThat(ShadowStartSecondaryKeyRotationTask.sRan).isTrue();
-    }
-
-    @Test
-    public void startRotationIfScheduled_rotatesIfSentinelFileIsPresent() throws Exception {
-        File file = new File(RuntimeEnvironment.application.getFilesDir(), SENTINEL_FILE_PATH);
-        file.createNewFile();
-
-        mScheduler.startRotationIfScheduled();
-
-        assertThat(ShadowStartSecondaryKeyRotationTask.sRan).isTrue();
-    }
-
-    @Test
-    public void startRotationIfScheduled_setsNextRotationIfClockHasChanged() {
-        long lastRotated = 100009;
-        long now = lastRotated - 1;
-        mCryptoSettings.setSecondaryLastRotated(lastRotated);
-        setNow(now);
-
-        mScheduler.startRotationIfScheduled();
-
-        assertThat(mCryptoSettings.getSecondaryLastRotated().get()).isEqualTo(now);
-    }
-
-    @Test
-    public void startRotationIfScheduled_doesNothingIfRotationWasRecentEnough() {
-        long lastRotated = 100009;
-        mCryptoSettings.setSecondaryLastRotated(lastRotated);
-        setNow(lastRotated + mRotationIntervalMillis - 1);
-
-        mScheduler.startRotationIfScheduled();
-
-        assertThat(ShadowStartSecondaryKeyRotationTask.sRan).isFalse();
-    }
-
-    @Test
-    public void startRotationIfScheduled_doesNotSetRotationTimeIfRotationWasRecentEnough() {
-        long lastRotated = 100009;
-        mCryptoSettings.setSecondaryLastRotated(lastRotated);
-        setNow(lastRotated + mRotationIntervalMillis - 1);
-
-        mScheduler.startRotationIfScheduled();
-
-        assertThat(mCryptoSettings.getSecondaryLastRotated().get()).isEqualTo(lastRotated);
-    }
-
-    @Test
-    public void startRotationIfScheduled_setsLastRotatedToNowIfNeverRotated() {
-        long now = 13295436;
-        setNow(now);
-
-        mScheduler.startRotationIfScheduled();
-
-        assertThat(mCryptoSettings.getSecondaryLastRotated().get()).isEqualTo(now);
-    }
-
-    private void setNow(long timestamp) {
-        when(mClock.millis()).thenReturn(timestamp);
-    }
-
-    @Implements(StartSecondaryKeyRotationTask.class)
-    public static class ShadowStartSecondaryKeyRotationTask {
-        private static boolean sRan = false;
-
-        @Implementation
-        public void run() {
-            sRan = true;
-        }
-
-        @Resetter
-        public static void reset() {
-            sRan = false;
-        }
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/TertiaryKeyGeneratorTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/TertiaryKeyGeneratorTest.java
deleted file mode 100644
index 48216f8..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/TertiaryKeyGeneratorTest.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.keys;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.platform.test.annotations.Presubmit;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-
-import java.security.SecureRandom;
-
-import javax.crypto.SecretKey;
-
-/** Tests for {@link TertiaryKeyGenerator}. */
-@RunWith(RobolectricTestRunner.class)
-@Presubmit
-public class TertiaryKeyGeneratorTest {
-    private static final String KEY_ALGORITHM = "AES";
-    private static final int KEY_SIZE_BITS = 256;
-
-    private TertiaryKeyGenerator mTertiaryKeyGenerator;
-
-    /** Instantiate a new {@link TertiaryKeyGenerator} for use in tests. */
-    @Before
-    public void setUp() {
-        mTertiaryKeyGenerator = new TertiaryKeyGenerator(new SecureRandom());
-    }
-
-    /** Generated keys should be AES keys. */
-    @Test
-    public void generate_generatesAESKeys() {
-        SecretKey secretKey = mTertiaryKeyGenerator.generate();
-
-        assertThat(secretKey.getAlgorithm()).isEqualTo(KEY_ALGORITHM);
-    }
-
-    /** Generated keys should be 256 bits in size. */
-    @Test
-    public void generate_generates256BitKeys() {
-        SecretKey secretKey = mTertiaryKeyGenerator.generate();
-
-        assertThat(secretKey.getEncoded()).hasLength(KEY_SIZE_BITS / 8);
-    }
-
-    /**
-     * Subsequent calls to {@link TertiaryKeyGenerator#generate()} should generate different keys.
-     */
-    @Test
-    public void generate_generatesNewKeys() {
-        SecretKey key1 = mTertiaryKeyGenerator.generate();
-        SecretKey key2 = mTertiaryKeyGenerator.generate();
-
-        assertThat(key1).isNotEqualTo(key2);
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/TertiaryKeyManagerTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/TertiaryKeyManagerTest.java
deleted file mode 100644
index 1ed8309..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/TertiaryKeyManagerTest.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.keys;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.robolectric.RuntimeEnvironment.application;
-
-import android.security.keystore.recovery.RecoveryController;
-
-import com.android.server.backup.encryption.protos.nano.WrappedKeyProto;
-import com.android.server.testing.shadows.ShadowRecoveryController;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.InOrder;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-import java.security.SecureRandom;
-
-import javax.crypto.SecretKey;
-
-@RunWith(RobolectricTestRunner.class)
-@Config(shadows = ShadowRecoveryController.class)
-public class TertiaryKeyManagerTest {
-
-    private static final String TEST_PACKAGE_1 = "com.example.app1";
-    private static final String TEST_PACKAGE_2 = "com.example.app2";
-
-    private SecureRandom mSecureRandom;
-    private RecoverableKeyStoreSecondaryKey mSecondaryKey;
-
-    @Mock private TertiaryKeyRotationScheduler mTertiaryKeyRotationScheduler;
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        mSecureRandom = new SecureRandom();
-        mSecondaryKey =
-                new RecoverableKeyStoreSecondaryKeyManager(
-                                RecoveryController.getInstance(application), mSecureRandom)
-                        .generate();
-        ShadowRecoveryController.reset();
-    }
-
-    private TertiaryKeyManager createNewManager(String packageName) {
-        return new TertiaryKeyManager(
-                application,
-                mSecureRandom,
-                mTertiaryKeyRotationScheduler,
-                mSecondaryKey,
-                packageName);
-    }
-
-    @Test
-    public void getKey_noExistingKey_returnsNewKey() throws Exception {
-        assertThat(createNewManager(TEST_PACKAGE_1).getKey()).isNotNull();
-    }
-
-    @Test
-    public void getKey_noExistingKey_recordsIncrementalBackup() throws Exception {
-        createNewManager(TEST_PACKAGE_1).getKey();
-        verify(mTertiaryKeyRotationScheduler).recordBackup(TEST_PACKAGE_1);
-    }
-
-    @Test
-    public void getKey_existingKey_returnsExistingKey() throws Exception {
-        TertiaryKeyManager manager = createNewManager(TEST_PACKAGE_1);
-        SecretKey existingKey = manager.getKey();
-
-        assertThat(manager.getKey()).isEqualTo(existingKey);
-    }
-
-    @Test
-    public void getKey_existingKey_recordsBackupButNotRotation() throws Exception {
-        createNewManager(TEST_PACKAGE_1).getKey();
-        reset(mTertiaryKeyRotationScheduler);
-
-        createNewManager(TEST_PACKAGE_1).getKey();
-
-        verify(mTertiaryKeyRotationScheduler).recordBackup(TEST_PACKAGE_1);
-        verify(mTertiaryKeyRotationScheduler, never()).recordKeyRotation(any());
-    }
-
-    @Test
-    public void getKey_existingKeyButRotationRequired_returnsNewKey() throws Exception {
-        SecretKey firstKey = createNewManager(TEST_PACKAGE_1).getKey();
-        when(mTertiaryKeyRotationScheduler.isKeyRotationDue(TEST_PACKAGE_1)).thenReturn(true);
-
-        SecretKey secondKey = createNewManager(TEST_PACKAGE_1).getKey();
-
-        assertThat(secondKey).isNotEqualTo(firstKey);
-    }
-
-    @Test
-    public void getKey_existingKeyButRotationRequired_recordsKeyRotationAndBackup()
-            throws Exception {
-        when(mTertiaryKeyRotationScheduler.isKeyRotationDue(TEST_PACKAGE_1)).thenReturn(true);
-        createNewManager(TEST_PACKAGE_1).getKey();
-
-        InOrder inOrder = inOrder(mTertiaryKeyRotationScheduler);
-        inOrder.verify(mTertiaryKeyRotationScheduler).recordKeyRotation(TEST_PACKAGE_1);
-        inOrder.verify(mTertiaryKeyRotationScheduler).recordBackup(TEST_PACKAGE_1);
-    }
-
-    @Test
-    public void getKey_twoApps_returnsDifferentKeys() throws Exception {
-        TertiaryKeyManager firstManager = createNewManager(TEST_PACKAGE_1);
-        TertiaryKeyManager secondManager = createNewManager(TEST_PACKAGE_2);
-        SecretKey firstKey = firstManager.getKey();
-
-        assertThat(secondManager.getKey()).isNotEqualTo(firstKey);
-    }
-
-    @Test
-    public void getWrappedKey_noExistingKey_returnsWrappedNewKey() throws Exception {
-        TertiaryKeyManager manager = createNewManager(TEST_PACKAGE_1);
-        SecretKey unwrappedKey = manager.getKey();
-        WrappedKeyProto.WrappedKey wrappedKey = manager.getWrappedKey();
-
-        SecretKey expectedUnwrappedKey =
-                KeyWrapUtils.unwrap(mSecondaryKey.getSecretKey(), wrappedKey);
-        assertThat(unwrappedKey).isEqualTo(expectedUnwrappedKey);
-    }
-
-    @Test
-    public void getWrappedKey_existingKey_returnsWrappedExistingKey() throws Exception {
-        TertiaryKeyManager manager = createNewManager(TEST_PACKAGE_1);
-        WrappedKeyProto.WrappedKey wrappedKey = manager.getWrappedKey();
-        SecretKey unwrappedKey = manager.getKey();
-
-        SecretKey expectedUnwrappedKey =
-                KeyWrapUtils.unwrap(mSecondaryKey.getSecretKey(), wrappedKey);
-        assertThat(unwrappedKey).isEqualTo(expectedUnwrappedKey);
-    }
-
-    @Test
-    public void wasKeyRotated_noExistingKey_returnsTrue() throws Exception {
-        TertiaryKeyManager manager = createNewManager(TEST_PACKAGE_1);
-        assertThat(manager.wasKeyRotated()).isTrue();
-    }
-
-    @Test
-    public void wasKeyRotated_existingKey_returnsFalse() throws Exception {
-        createNewManager(TEST_PACKAGE_1).getKey();
-        assertThat(createNewManager(TEST_PACKAGE_1).wasKeyRotated()).isFalse();
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/TertiaryKeyRotationSchedulerTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/TertiaryKeyRotationSchedulerTest.java
deleted file mode 100644
index dfc7e2b..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/TertiaryKeyRotationSchedulerTest.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.keys;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.when;
-import static org.robolectric.RuntimeEnvironment.application;
-
-import android.content.Context;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-
-import java.io.File;
-import java.time.Clock;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.concurrent.TimeUnit;
-
-/** Tests for the tertiary key rotation scheduler */
-@RunWith(RobolectricTestRunner.class)
-public final class TertiaryKeyRotationSchedulerTest {
-
-    private static final int MAXIMUM_ROTATIONS_PER_WINDOW = 2;
-    private static final int MAX_BACKUPS_TILL_ROTATION = 31;
-    private static final String SHARED_PREFS_NAME = "tertiary_key_rotation_tracker";
-    private static final String PACKAGE_1 = "com.android.example1";
-    private static final String PACKAGE_2 = "com.android.example2";
-
-    @Rule public final TemporaryFolder temporaryFolder = new TemporaryFolder();
-
-    @Mock private Clock mClock;
-
-    private File mFile;
-    private TertiaryKeyRotationScheduler mScheduler;
-
-    /** Setup the scheduler for test */
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-        mFile = temporaryFolder.newFile();
-        mScheduler =
-                new TertiaryKeyRotationScheduler(
-                        new TertiaryKeyRotationTracker(
-                                application.getSharedPreferences(
-                                        SHARED_PREFS_NAME, Context.MODE_PRIVATE),
-                                MAX_BACKUPS_TILL_ROTATION),
-                        new TertiaryKeyRotationWindowedCount(mFile, mClock),
-                        MAXIMUM_ROTATIONS_PER_WINDOW);
-    }
-
-    /** Test we don't trigger a rotation straight off */
-    @Test
-    public void isKeyRotationDue_isFalseInitially() {
-        assertThat(mScheduler.isKeyRotationDue(PACKAGE_1)).isFalse();
-    }
-
-    /** Test we don't prematurely trigger a rotation */
-    @Test
-    public void isKeyRotationDue_isFalseAfterInsufficientBackups() {
-        simulateBackups(MAX_BACKUPS_TILL_ROTATION - 1);
-        assertThat(mScheduler.isKeyRotationDue(PACKAGE_1)).isFalse();
-    }
-
-    /** Test we do trigger a backup */
-    @Test
-    public void isKeyRotationDue_isTrueAfterEnoughBackups() {
-        simulateBackups(MAX_BACKUPS_TILL_ROTATION);
-        assertThat(mScheduler.isKeyRotationDue(PACKAGE_1)).isTrue();
-    }
-
-    /** Test rotation will occur if the quota allows */
-    @Test
-    public void isKeyRotationDue_isTrueIfRotationQuotaRemainsInWindow() {
-        simulateBackups(MAX_BACKUPS_TILL_ROTATION);
-        mScheduler.recordKeyRotation(PACKAGE_2);
-        assertThat(mScheduler.isKeyRotationDue(PACKAGE_1)).isTrue();
-    }
-
-    /** Test rotation is blocked if the quota has been exhausted */
-    @Test
-    public void isKeyRotationDue_isFalseIfEnoughRotationsHaveHappenedInWindow() {
-        simulateBackups(MAX_BACKUPS_TILL_ROTATION);
-        mScheduler.recordKeyRotation(PACKAGE_2);
-        mScheduler.recordKeyRotation(PACKAGE_2);
-        assertThat(mScheduler.isKeyRotationDue(PACKAGE_1)).isFalse();
-    }
-
-    /** Test rotation is due after one window has passed */
-    @Test
-    public void isKeyRotationDue_isTrueAfterAWholeWindowHasPassed() {
-        simulateBackups(MAX_BACKUPS_TILL_ROTATION);
-        mScheduler.recordKeyRotation(PACKAGE_2);
-        mScheduler.recordKeyRotation(PACKAGE_2);
-        setTimeMillis(TimeUnit.HOURS.toMillis(24));
-        assertThat(mScheduler.isKeyRotationDue(PACKAGE_1)).isTrue();
-    }
-
-    /** Test the rotation state changes after a rotation */
-    @Test
-    public void isKeyRotationDue_isFalseAfterRotation() {
-        simulateBackups(MAX_BACKUPS_TILL_ROTATION);
-        mScheduler.recordKeyRotation(PACKAGE_1);
-        assertThat(mScheduler.isKeyRotationDue(PACKAGE_1)).isFalse();
-    }
-
-    /** Test the rate limiting for a given window */
-    @Test
-    public void isKeyRotationDue_neverAllowsMoreThanInWindow() {
-        List<String> apps = makeTestApps(MAXIMUM_ROTATIONS_PER_WINDOW * MAX_BACKUPS_TILL_ROTATION);
-
-        // simulate backups of all apps each night
-        for (int i = 0; i < 300; i++) {
-            setTimeMillis(i * TimeUnit.HOURS.toMillis(24));
-            int rotationsThisNight = 0;
-            for (String app : apps) {
-                if (mScheduler.isKeyRotationDue(app)) {
-                    rotationsThisNight++;
-                    mScheduler.recordKeyRotation(app);
-                } else {
-                    mScheduler.recordBackup(app);
-                }
-            }
-            assertThat(rotationsThisNight).isAtMost(MAXIMUM_ROTATIONS_PER_WINDOW);
-        }
-    }
-
-    /** Test that backups are staggered over the window */
-    @Test
-    public void isKeyRotationDue_naturallyStaggersBackupsOverTime() {
-        List<String> apps = makeTestApps(MAXIMUM_ROTATIONS_PER_WINDOW * MAX_BACKUPS_TILL_ROTATION);
-
-        HashMap<String, ArrayList<Integer>> rotationDays = new HashMap<>();
-        for (String app : apps) {
-            rotationDays.put(app, new ArrayList<>());
-        }
-
-        // simulate backups of all apps each night
-        for (int i = 0; i < 300; i++) {
-            setTimeMillis(i * TimeUnit.HOURS.toMillis(24));
-            for (String app : apps) {
-                if (mScheduler.isKeyRotationDue(app)) {
-                    rotationDays.get(app).add(i);
-                    mScheduler.recordKeyRotation(app);
-                } else {
-                    mScheduler.recordBackup(app);
-                }
-            }
-        }
-
-        for (String app : apps) {
-            List<Integer> days = rotationDays.get(app);
-            for (int i = 1; i < days.size(); i++) {
-                assertThat(days.get(i) - days.get(i - 1)).isEqualTo(MAX_BACKUPS_TILL_ROTATION + 1);
-            }
-        }
-    }
-
-    private ArrayList<String> makeTestApps(int n) {
-        ArrayList<String> apps = new ArrayList<>();
-        for (int i = 0; i < n; i++) {
-            apps.add(String.format(Locale.US, "com.android.app%d", i));
-        }
-        return apps;
-    }
-
-    private void simulateBackups(int numberOfBackups) {
-        while (numberOfBackups > 0) {
-            mScheduler.recordBackup(PACKAGE_1);
-            numberOfBackups--;
-        }
-    }
-
-    private void setTimeMillis(long timeMillis) {
-        when(mClock.millis()).thenReturn(timeMillis);
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/TertiaryKeyRotationTrackerTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/TertiaryKeyRotationTrackerTest.java
deleted file mode 100644
index 49bb410..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/TertiaryKeyRotationTrackerTest.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.keys;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.platform.test.annotations.Presubmit;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-
-/** Tests for {@link TertiaryKeyRotationTracker}. */
-@RunWith(RobolectricTestRunner.class)
-@Presubmit
-public class TertiaryKeyRotationTrackerTest {
-    private static final String PACKAGE_1 = "com.package.one";
-    private static final int NUMBER_OF_BACKUPS_BEFORE_ROTATION = 31;
-
-    private TertiaryKeyRotationTracker mTertiaryKeyRotationTracker;
-
-    /** Instantiate a {@link TertiaryKeyRotationTracker} for use in tests. */
-    @Before
-    public void setUp() {
-        mTertiaryKeyRotationTracker = newInstance();
-    }
-
-    /** New packages should not be due for key rotation. */
-    @Test
-    public void isKeyRotationDue_forNewPackage_isFalse() {
-        // Simulate a new package by not calling simulateBackups(). As a result, PACKAGE_1 hasn't
-        // been seen by mTertiaryKeyRotationTracker before.
-        boolean keyRotationDue = mTertiaryKeyRotationTracker.isKeyRotationDue(PACKAGE_1);
-
-        assertThat(keyRotationDue).isFalse();
-    }
-
-    /**
-     * Key rotation should not be due after less than {@code NUMBER_OF_BACKUPS_BEFORE_ROTATION}
-     * backups.
-     */
-    @Test
-    public void isKeyRotationDue_afterLessThanRotationAmountBackups_isFalse() {
-        simulateBackups(PACKAGE_1, NUMBER_OF_BACKUPS_BEFORE_ROTATION - 1);
-
-        boolean keyRotationDue = mTertiaryKeyRotationTracker.isKeyRotationDue(PACKAGE_1);
-
-        assertThat(keyRotationDue).isFalse();
-    }
-
-    /** Key rotation should be due after {@code NUMBER_OF_BACKUPS_BEFORE_ROTATION} backups. */
-    @Test
-    public void isKeyRotationDue_afterRotationAmountBackups_isTrue() {
-        simulateBackups(PACKAGE_1, NUMBER_OF_BACKUPS_BEFORE_ROTATION);
-
-        boolean keyRotationDue = mTertiaryKeyRotationTracker.isKeyRotationDue(PACKAGE_1);
-
-        assertThat(keyRotationDue).isTrue();
-    }
-
-    /**
-     * A call to {@link TertiaryKeyRotationTracker#resetCountdown(String)} should make sure no key
-     * rotation is due.
-     */
-    @Test
-    public void resetCountdown_makesKeyRotationNotDue() {
-        simulateBackups(PACKAGE_1, NUMBER_OF_BACKUPS_BEFORE_ROTATION);
-
-        mTertiaryKeyRotationTracker.resetCountdown(PACKAGE_1);
-
-        assertThat(mTertiaryKeyRotationTracker.isKeyRotationDue(PACKAGE_1)).isFalse();
-    }
-
-    /**
-     * New instances of {@link TertiaryKeyRotationTracker} should read state about the number of
-     * backups from disk.
-     */
-    @Test
-    public void isKeyRotationDue_forNewInstance_readsStateFromDisk() {
-        simulateBackups(PACKAGE_1, NUMBER_OF_BACKUPS_BEFORE_ROTATION);
-
-        boolean keyRotationDueForNewInstance = newInstance().isKeyRotationDue(PACKAGE_1);
-
-        assertThat(keyRotationDueForNewInstance).isTrue();
-    }
-
-    /**
-     * A call to {@link TertiaryKeyRotationTracker#markAllForRotation()} should mark all previously
-     * seen packages for rotation.
-     */
-    @Test
-    public void markAllForRotation_marksSeenPackagesForKeyRotation() {
-        simulateBackups(PACKAGE_1, /*numberOfBackups=*/ 1);
-
-        mTertiaryKeyRotationTracker.markAllForRotation();
-
-        assertThat(mTertiaryKeyRotationTracker.isKeyRotationDue(PACKAGE_1)).isTrue();
-    }
-
-    /**
-     * A call to {@link TertiaryKeyRotationTracker#markAllForRotation()} should not mark any new
-     * packages for rotation.
-     */
-    @Test
-    public void markAllForRotation_doesNotMarkUnseenPackages() {
-        mTertiaryKeyRotationTracker.markAllForRotation();
-
-        assertThat(mTertiaryKeyRotationTracker.isKeyRotationDue(PACKAGE_1)).isFalse();
-    }
-
-    private void simulateBackups(String packageName, int numberOfBackups) {
-        while (numberOfBackups > 0) {
-            mTertiaryKeyRotationTracker.recordBackup(packageName);
-            numberOfBackups--;
-        }
-    }
-
-    private static TertiaryKeyRotationTracker newInstance() {
-        return TertiaryKeyRotationTracker.getInstance(RuntimeEnvironment.application);
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/TertiaryKeyRotationWindowedCountTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/TertiaryKeyRotationWindowedCountTest.java
deleted file mode 100644
index bd30977..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/TertiaryKeyRotationWindowedCountTest.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.keys;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.when;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-
-import java.io.File;
-import java.io.IOException;
-import java.time.Clock;
-import java.util.concurrent.TimeUnit;
-
-/** Tests for {@link TertiaryKeyRotationWindowedCount}. */
-@RunWith(RobolectricTestRunner.class)
-public class TertiaryKeyRotationWindowedCountTest {
-    private static final int TIMESTAMP_SIZE_IN_BYTES = 8;
-
-    @Rule public final TemporaryFolder mTemporaryFolder = new TemporaryFolder();
-
-    @Mock private Clock mClock;
-
-    private File mFile;
-    private TertiaryKeyRotationWindowedCount mWindowedcount;
-
-    /** Setup the windowed counter for testing */
-    @Before
-    public void setUp() throws IOException {
-        MockitoAnnotations.initMocks(this);
-        mFile = mTemporaryFolder.newFile();
-        mWindowedcount = new TertiaryKeyRotationWindowedCount(mFile, mClock);
-    }
-
-    /** Test handling bad files */
-    @Test
-    public void constructor_doesNotFailForBadFile() throws IOException {
-        new TertiaryKeyRotationWindowedCount(mTemporaryFolder.newFolder(), mClock);
-    }
-
-    /** Test the count is 0 to start */
-    @Test
-    public void getCount_isZeroInitially() {
-        assertThat(mWindowedcount.getCount()).isEqualTo(0);
-    }
-
-    /** Test the count is correct for a time window */
-    @Test
-    public void getCount_includesResultsInLastTwentyFourHours() {
-        setTimeMillis(0);
-        mWindowedcount.record();
-        setTimeMillis(TimeUnit.HOURS.toMillis(4));
-        mWindowedcount.record();
-        setTimeMillis(TimeUnit.HOURS.toMillis(23));
-        mWindowedcount.record();
-        mWindowedcount.record();
-        assertThat(mWindowedcount.getCount()).isEqualTo(4);
-    }
-
-    /** Test old results are ignored */
-    @Test
-    public void getCount_ignoresResultsOlderThanTwentyFourHours() {
-        setTimeMillis(0);
-        mWindowedcount.record();
-        setTimeMillis(TimeUnit.HOURS.toMillis(24));
-        assertThat(mWindowedcount.getCount()).isEqualTo(0);
-    }
-
-    /** Test future events are removed if the clock moves backways (e.g. DST, TZ change) */
-    @Test
-    public void getCount_removesFutureEventsIfClockHasChanged() {
-        setTimeMillis(1000);
-        mWindowedcount.record();
-        setTimeMillis(0);
-        assertThat(mWindowedcount.getCount()).isEqualTo(0);
-    }
-
-    /** Check recording doesn't fail for a bad file */
-    @Test
-    public void record_doesNotFailForBadFile() throws Exception {
-        new TertiaryKeyRotationWindowedCount(mTemporaryFolder.newFolder(), mClock).record();
-    }
-
-    /** Checks the state is persisted */
-    @Test
-    public void record_persistsStateToDisk() {
-        setTimeMillis(0);
-        mWindowedcount.record();
-        assertThat(new TertiaryKeyRotationWindowedCount(mFile, mClock).getCount()).isEqualTo(1);
-    }
-
-    /** Test the file doesn't contain unnecessary data */
-    @Test
-    public void record_compactsFileToLast24Hours() {
-        setTimeMillis(0);
-        mWindowedcount.record();
-        assertThat(mFile.length()).isEqualTo(TIMESTAMP_SIZE_IN_BYTES);
-        setTimeMillis(1);
-        mWindowedcount.record();
-        assertThat(mFile.length()).isEqualTo(2 * TIMESTAMP_SIZE_IN_BYTES);
-        setTimeMillis(TimeUnit.HOURS.toMillis(24));
-        mWindowedcount.record();
-        assertThat(mFile.length()).isEqualTo(2 * TIMESTAMP_SIZE_IN_BYTES);
-    }
-
-    private void setTimeMillis(long timeMillis) {
-        when(mClock.millis()).thenReturn(timeMillis);
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/TertiaryKeyStoreTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/TertiaryKeyStoreTest.java
deleted file mode 100644
index ccc5f32..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/keys/TertiaryKeyStoreTest.java
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.keys;
-
-import static com.android.server.backup.testing.CryptoTestUtils.generateAesKey;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertThrows;
-import static org.testng.Assert.assertTrue;
-
-import android.content.Context;
-
-import com.android.server.backup.encryption.protos.nano.WrappedKeyProto;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-
-import java.security.InvalidKeyException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Optional;
-
-import javax.crypto.SecretKey;
-
-/** Tests for the tertiary key store */
-@RunWith(RobolectricTestRunner.class)
-public class TertiaryKeyStoreTest {
-
-    private static final String SECONDARY_KEY_ALIAS = "Robbo/Ranx";
-
-    private Context mApplication;
-    private TertiaryKeyStore mTertiaryKeyStore;
-    private SecretKey mSecretKey;
-
-    /** Initialise the keystore for testing */
-    @Before
-    public void setUp() throws Exception {
-        mApplication = RuntimeEnvironment.application;
-        mSecretKey = generateAesKey();
-        mTertiaryKeyStore =
-                TertiaryKeyStore.newInstance(
-                        mApplication,
-                        new RecoverableKeyStoreSecondaryKey(SECONDARY_KEY_ALIAS, mSecretKey));
-    }
-
-    /** Test a reound trip for a key */
-    @Test
-    public void load_loadsAKeyThatWasSaved() throws Exception {
-        String packageName = "com.android.example";
-        SecretKey packageKey = generateAesKey();
-        mTertiaryKeyStore.save(packageName, packageKey);
-
-        Optional<SecretKey> maybeLoadedKey = mTertiaryKeyStore.load(packageName);
-
-        assertTrue(maybeLoadedKey.isPresent());
-        assertEquals(packageKey, maybeLoadedKey.get());
-    }
-
-    /** Test isolation between packages */
-    @Test
-    public void load_doesNotLoadAKeyForAnotherSecondary() throws Exception {
-        String packageName = "com.android.example";
-        SecretKey packageKey = generateAesKey();
-        mTertiaryKeyStore.save(packageName, packageKey);
-        TertiaryKeyStore managerWithOtherSecondaryKey =
-                TertiaryKeyStore.newInstance(
-                        mApplication,
-                        new RecoverableKeyStoreSecondaryKey(
-                                "myNewSecondaryKeyAlias", generateAesKey()));
-
-        assertFalse(managerWithOtherSecondaryKey.load(packageName).isPresent());
-    }
-
-    /** Test non-existent key handling */
-    @Test
-    public void load_returnsAbsentForANonExistentKey() throws Exception {
-        assertFalse(mTertiaryKeyStore.load("mystery.package").isPresent());
-    }
-
-    /** Test handling incorrect keys */
-    @Test
-    public void load_throwsIfHasWrongBackupKey() throws Exception {
-        String packageName = "com.android.example";
-        SecretKey packageKey = generateAesKey();
-        mTertiaryKeyStore.save(packageName, packageKey);
-        TertiaryKeyStore managerWithBadKey =
-                TertiaryKeyStore.newInstance(
-                        mApplication,
-                        new RecoverableKeyStoreSecondaryKey(SECONDARY_KEY_ALIAS, generateAesKey()));
-
-        assertThrows(InvalidKeyException.class, () -> managerWithBadKey.load(packageName));
-    }
-
-    /** Test handling of empty app name */
-    @Test
-    public void load_throwsForEmptyApplicationName() throws Exception {
-        assertThrows(IllegalArgumentException.class, () -> mTertiaryKeyStore.load(""));
-    }
-
-    /** Test handling of an invalid app name */
-    @Test
-    public void load_throwsForBadApplicationName() throws Exception {
-        assertThrows(
-                IllegalArgumentException.class,
-                () -> mTertiaryKeyStore.load("com/android/example"));
-    }
-
-    /** Test key replacement */
-    @Test
-    public void save_overwritesPreviousKey() throws Exception {
-        String packageName = "com.android.example";
-        SecretKey oldKey = generateAesKey();
-        mTertiaryKeyStore.save(packageName, oldKey);
-        SecretKey newKey = generateAesKey();
-
-        mTertiaryKeyStore.save(packageName, newKey);
-
-        Optional<SecretKey> maybeLoadedKey = mTertiaryKeyStore.load(packageName);
-        assertTrue(maybeLoadedKey.isPresent());
-        SecretKey loadedKey = maybeLoadedKey.get();
-        assertThat(loadedKey).isNotEqualTo(oldKey);
-        assertThat(loadedKey).isEqualTo(newKey);
-    }
-
-    /** Test saving with an empty application name fails */
-    @Test
-    public void save_throwsForEmptyApplicationName() throws Exception {
-        assertThrows(
-                IllegalArgumentException.class, () -> mTertiaryKeyStore.save("", generateAesKey()));
-    }
-
-    /** Test saving an invalid application name fails */
-    @Test
-    public void save_throwsForBadApplicationName() throws Exception {
-        assertThrows(
-                IllegalArgumentException.class,
-                () -> mTertiaryKeyStore.save("com/android/example", generateAesKey()));
-    }
-
-    /** Test handling an empty database */
-    @Test
-    public void getAll_returnsEmptyMapForEmptyDb() throws Exception {
-        assertThat(mTertiaryKeyStore.getAll()).isEmpty();
-    }
-
-    /** Test loading all available keys works as expected */
-    @Test
-    public void getAll_returnsAllKeysSaved() throws Exception {
-        String package1 = "com.android.example";
-        SecretKey key1 = generateAesKey();
-        String package2 = "com.anndroid.example1";
-        SecretKey key2 = generateAesKey();
-        String package3 = "com.android.example2";
-        SecretKey key3 = generateAesKey();
-        mTertiaryKeyStore.save(package1, key1);
-        mTertiaryKeyStore.save(package2, key2);
-        mTertiaryKeyStore.save(package3, key3);
-
-        Map<String, SecretKey> keys = mTertiaryKeyStore.getAll();
-
-        assertThat(keys).containsExactly(package1, key1, package2, key2, package3, key3);
-    }
-
-    /** Test cross-secondary isolation */
-    @Test
-    public void getAll_doesNotReturnKeysForOtherSecondary() throws Exception {
-        String packageName = "com.android.example";
-        TertiaryKeyStore managerWithOtherSecondaryKey =
-                TertiaryKeyStore.newInstance(
-                        mApplication,
-                        new RecoverableKeyStoreSecondaryKey(
-                                "myNewSecondaryKeyAlias", generateAesKey()));
-        managerWithOtherSecondaryKey.save(packageName, generateAesKey());
-
-        assertThat(mTertiaryKeyStore.getAll()).isEmpty();
-    }
-
-    /** Test mass put into the keystore */
-    @Test
-    public void putAll_putsAllWrappedKeysInTheStore() throws Exception {
-        String packageName = "com.android.example";
-        SecretKey key = generateAesKey();
-        WrappedKeyProto.WrappedKey wrappedKey = KeyWrapUtils.wrap(mSecretKey, key);
-
-        Map<String, WrappedKeyProto.WrappedKey> testElements = new HashMap<>();
-        testElements.put(packageName, wrappedKey);
-        mTertiaryKeyStore.putAll(testElements);
-
-        assertThat(mTertiaryKeyStore.getAll()).containsKey(packageName);
-        assertThat(mTertiaryKeyStore.getAll().get(packageName).getEncoded())
-                .isEqualTo(key.getEncoded());
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/kv/DecryptedChunkKvOutputTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/kv/DecryptedChunkKvOutputTest.java
deleted file mode 100644
index 215e1cb..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/kv/DecryptedChunkKvOutputTest.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.kv;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.when;
-import static org.testng.Assert.assertThrows;
-
-import android.os.Debug;
-import android.platform.test.annotations.Presubmit;
-
-import com.android.server.backup.encryption.chunk.ChunkHash;
-import com.android.server.backup.encryption.chunking.ChunkHasher;
-import com.android.server.backup.encryption.protos.nano.KeyValuePairProto;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-
-import java.security.MessageDigest;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.stream.Stream;
-
-@RunWith(RobolectricTestRunner.class)
-@Presubmit
-public class DecryptedChunkKvOutputTest {
-    private static final String TEST_KEY_1 = "key_1";
-    private static final String TEST_KEY_2 = "key_2";
-    private static final byte[] TEST_VALUE_1 = {1, 2, 3};
-    private static final byte[] TEST_VALUE_2 = {10, 11, 12, 13};
-    private static final byte[] TEST_PAIR_1 = toByteArray(createPair(TEST_KEY_1, TEST_VALUE_1));
-    private static final byte[] TEST_PAIR_2 = toByteArray(createPair(TEST_KEY_2, TEST_VALUE_2));
-    private static final int TEST_BUFFER_SIZE = Math.max(TEST_PAIR_1.length, TEST_PAIR_2.length);
-
-    @Mock private ChunkHasher mChunkHasher;
-    private DecryptedChunkKvOutput mOutput;
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        when(mChunkHasher.computeHash(any()))
-                .thenAnswer(invocation -> fakeHash(invocation.getArgument(0)));
-        mOutput = new DecryptedChunkKvOutput(mChunkHasher);
-    }
-
-    @Test
-    public void open_returnsInstance() throws Exception {
-        assertThat(mOutput.open()).isEqualTo(mOutput);
-    }
-
-    @Test
-    public void processChunk_alreadyClosed_throws() throws Exception {
-        mOutput.open();
-        mOutput.close();
-
-        assertThrows(
-                IllegalStateException.class,
-                () -> mOutput.processChunk(TEST_PAIR_1, TEST_PAIR_1.length));
-    }
-
-    @Test
-    public void getDigest_beforeClose_throws() throws Exception {
-        // TODO: b/141356823 We should add a test which calls .open() here
-        assertThrows(IllegalStateException.class, () -> mOutput.getDigest());
-    }
-
-    @Test
-    public void getDigest_returnsDigestOfSortedHashes() throws Exception {
-        mOutput.open();
-        Debug.waitForDebugger();
-        mOutput.processChunk(Arrays.copyOf(TEST_PAIR_1, TEST_BUFFER_SIZE), TEST_PAIR_1.length);
-        mOutput.processChunk(Arrays.copyOf(TEST_PAIR_2, TEST_BUFFER_SIZE), TEST_PAIR_2.length);
-        mOutput.close();
-
-        byte[] actualDigest = mOutput.getDigest();
-
-        MessageDigest digest = MessageDigest.getInstance(DecryptedChunkKvOutput.DIGEST_ALGORITHM);
-        Stream.of(TEST_PAIR_1, TEST_PAIR_2)
-                .map(DecryptedChunkKvOutputTest::fakeHash)
-                .sorted(Comparator.naturalOrder())
-                .forEachOrdered(hash -> digest.update(hash.getHash()));
-        assertThat(actualDigest).isEqualTo(digest.digest());
-    }
-
-    @Test
-    public void getPairs_beforeClose_throws() throws Exception {
-        // TODO: b/141356823 We should add a test which calls .open() here
-        assertThrows(IllegalStateException.class, () -> mOutput.getPairs());
-    }
-
-    @Test
-    public void getPairs_returnsPairsSortedByKey() throws Exception {
-        mOutput.open();
-        // Write out of order to check that it sorts the chunks.
-        mOutput.processChunk(Arrays.copyOf(TEST_PAIR_2, TEST_BUFFER_SIZE), TEST_PAIR_2.length);
-        mOutput.processChunk(Arrays.copyOf(TEST_PAIR_1, TEST_BUFFER_SIZE), TEST_PAIR_1.length);
-        mOutput.close();
-
-        List<KeyValuePairProto.KeyValuePair> pairs = mOutput.getPairs();
-
-        assertThat(
-                        isInOrder(
-                                pairs,
-                                Comparator.comparing(
-                                        (KeyValuePairProto.KeyValuePair pair) -> pair.key)))
-                .isTrue();
-        assertThat(pairs).hasSize(2);
-        assertThat(pairs.get(0).key).isEqualTo(TEST_KEY_1);
-        assertThat(pairs.get(0).value).isEqualTo(TEST_VALUE_1);
-        assertThat(pairs.get(1).key).isEqualTo(TEST_KEY_2);
-        assertThat(pairs.get(1).value).isEqualTo(TEST_VALUE_2);
-    }
-
-    private static KeyValuePairProto.KeyValuePair createPair(String key, byte[] value) {
-        KeyValuePairProto.KeyValuePair pair = new KeyValuePairProto.KeyValuePair();
-        pair.key = key;
-        pair.value = value;
-        return pair;
-    }
-
-    private boolean isInOrder(
-            List<KeyValuePairProto.KeyValuePair> list,
-            Comparator<KeyValuePairProto.KeyValuePair> comparator) {
-        if (list.size() < 2) {
-            return true;
-        }
-
-        List<KeyValuePairProto.KeyValuePair> sortedList = new ArrayList<>(list);
-        Collections.sort(sortedList, comparator);
-        return list.equals(sortedList);
-    }
-
-    private static byte[] toByteArray(KeyValuePairProto.KeyValuePair nano) {
-        return KeyValuePairProto.KeyValuePair.toByteArray(nano);
-    }
-
-    private static ChunkHash fakeHash(byte[] data) {
-        return new ChunkHash(Arrays.copyOf(data, ChunkHash.HASH_LENGTH_BYTES));
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/kv/KeyValueListingBuilderTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/kv/KeyValueListingBuilderTest.java
deleted file mode 100644
index acc6628..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/kv/KeyValueListingBuilderTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.kv;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.testng.Assert.assertThrows;
-
-import android.platform.test.annotations.Presubmit;
-
-import com.android.server.backup.encryption.chunk.ChunkHash;
-import com.android.server.backup.encryption.protos.nano.KeyValueListingProto;
-
-import com.google.common.collect.ImmutableMap;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-
-import java.util.Arrays;
-
-@RunWith(RobolectricTestRunner.class)
-@Presubmit
-public class KeyValueListingBuilderTest {
-    private static final String TEST_KEY_1 = "test_key_1";
-    private static final String TEST_KEY_2 = "test_key_2";
-    private static final ChunkHash TEST_HASH_1 =
-            new ChunkHash(Arrays.copyOf(new byte[] {1, 2}, ChunkHash.HASH_LENGTH_BYTES));
-    private static final ChunkHash TEST_HASH_2 =
-            new ChunkHash(Arrays.copyOf(new byte[] {5, 6}, ChunkHash.HASH_LENGTH_BYTES));
-
-    private KeyValueListingBuilder mBuilder;
-
-    @Before
-    public void setUp() {
-        mBuilder = new KeyValueListingBuilder();
-    }
-
-    @Test
-    public void addPair_nullKey_throws() {
-        assertThrows(NullPointerException.class, () -> mBuilder.addPair(null, TEST_HASH_1));
-    }
-
-    @Test
-    public void addPair_emptyKey_throws() {
-        assertThrows(IllegalArgumentException.class, () -> mBuilder.addPair("", TEST_HASH_1));
-    }
-
-    @Test
-    public void addPair_nullHash_throws() {
-        assertThrows(NullPointerException.class, () -> mBuilder.addPair(TEST_KEY_1, null));
-    }
-
-    @Test
-    public void build_noPairs_buildsEmptyListing() {
-        KeyValueListingProto.KeyValueListing listing = mBuilder.build();
-
-        assertThat(listing.entries).isEmpty();
-    }
-
-    @Test
-    public void build_returnsCorrectListing() {
-        mBuilder.addPair(TEST_KEY_1, TEST_HASH_1);
-
-        KeyValueListingProto.KeyValueListing listing = mBuilder.build();
-
-        assertThat(listing.entries.length).isEqualTo(1);
-        assertThat(listing.entries[0].key).isEqualTo(TEST_KEY_1);
-        assertThat(listing.entries[0].hash).isEqualTo(TEST_HASH_1.getHash());
-    }
-
-    @Test
-    public void addAll_addsAllPairsInMap() {
-        ImmutableMap<String, ChunkHash> pairs =
-                new ImmutableMap.Builder<String, ChunkHash>()
-                        .put(TEST_KEY_1, TEST_HASH_1)
-                        .put(TEST_KEY_2, TEST_HASH_2)
-                        .build();
-
-        mBuilder.addAll(pairs);
-        KeyValueListingProto.KeyValueListing listing = mBuilder.build();
-
-        assertThat(listing.entries.length).isEqualTo(2);
-        assertThat(listing.entries[0].key).isEqualTo(TEST_KEY_1);
-        assertThat(listing.entries[0].hash).isEqualTo(TEST_HASH_1.getHash());
-        assertThat(listing.entries[1].key).isEqualTo(TEST_KEY_2);
-        assertThat(listing.entries[1].hash).isEqualTo(TEST_HASH_2.getHash());
-    }
-
-    @Test
-    public void emptyListing_returnsListingWithoutAnyPairs() {
-        KeyValueListingProto.KeyValueListing emptyListing = KeyValueListingBuilder.emptyListing();
-        assertThat(emptyListing.entries).isEmpty();
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/storage/BackupEncryptionDbTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/storage/BackupEncryptionDbTest.java
deleted file mode 100644
index 87f21bf..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/storage/BackupEncryptionDbTest.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.storage;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.platform.test.annotations.Presubmit;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-
-/** Tests for {@link BackupEncryptionDb}. */
-@RunWith(RobolectricTestRunner.class)
-@Presubmit
-public class BackupEncryptionDbTest {
-    private BackupEncryptionDb mBackupEncryptionDb;
-
-    /** Creates an empty {@link BackupEncryptionDb} */
-    @Before
-    public void setUp() {
-        mBackupEncryptionDb = BackupEncryptionDb.newInstance(RuntimeEnvironment.application);
-    }
-
-    /**
-     * Tests that the tertiary keys table gets cleared when calling {@link
-     * BackupEncryptionDb#clear()}.
-     */
-    @Test
-    public void clear_withNonEmptyTertiaryKeysTable_clearsTertiaryKeysTable() throws Exception {
-        String secondaryKeyAlias = "secondaryKeyAlias";
-        TertiaryKeysTable tertiaryKeysTable = mBackupEncryptionDb.getTertiaryKeysTable();
-        tertiaryKeysTable.addKey(new TertiaryKey(secondaryKeyAlias, "packageName", new byte[0]));
-
-        mBackupEncryptionDb.clear();
-
-        assertThat(tertiaryKeysTable.getAllKeys(secondaryKeyAlias)).isEmpty();
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/storage/TertiaryKeysTableTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/storage/TertiaryKeysTableTest.java
deleted file mode 100644
index 319ec89..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/storage/TertiaryKeysTableTest.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.encryption.storage;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.platform.test.annotations.Presubmit;
-
-import com.android.server.backup.testing.CryptoTestUtils;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-
-import java.util.Map;
-import java.util.Optional;
-
-/** Tests for {@link TertiaryKeysTable}. */
-@RunWith(RobolectricTestRunner.class)
-@Presubmit
-public class TertiaryKeysTableTest {
-    private static final int KEY_SIZE_BYTES = 32;
-    private static final String SECONDARY_ALIAS = "phoebe";
-    private static final String PACKAGE_NAME = "generic.package.name";
-
-    private TertiaryKeysTable mTertiaryKeysTable;
-
-    /** Creates an empty {@link BackupEncryptionDb}. */
-    @Before
-    public void setUp() {
-        mTertiaryKeysTable =
-                BackupEncryptionDb.newInstance(RuntimeEnvironment.application)
-                        .getTertiaryKeysTable();
-    }
-
-    /** Tests that new {@link TertiaryKey}s get successfully added to the database. */
-    @Test
-    public void addKey_onEmptyDatabase_putsKeyInDb() throws Exception {
-        byte[] key = generateRandomKey();
-        TertiaryKey keyToInsert = new TertiaryKey(SECONDARY_ALIAS, PACKAGE_NAME, key);
-
-        long result = mTertiaryKeysTable.addKey(keyToInsert);
-
-        assertThat(result).isNotEqualTo(-1);
-        Optional<TertiaryKey> maybeKeyInDb =
-                mTertiaryKeysTable.getKey(SECONDARY_ALIAS, PACKAGE_NAME);
-        assertThat(maybeKeyInDb.isPresent()).isTrue();
-        TertiaryKey keyInDb = maybeKeyInDb.get();
-        assertTertiaryKeysEqual(keyInDb, keyToInsert);
-    }
-
-    /** Tests that keys replace older keys with the same secondary alias and package name. */
-    @Test
-    public void addKey_havingSameSecondaryAliasAndPackageName_replacesOldKey() throws Exception {
-        mTertiaryKeysTable.addKey(
-                new TertiaryKey(SECONDARY_ALIAS, PACKAGE_NAME, generateRandomKey()));
-        byte[] newKey = generateRandomKey();
-
-        long result =
-                mTertiaryKeysTable.addKey(new TertiaryKey(SECONDARY_ALIAS, PACKAGE_NAME, newKey));
-
-        assertThat(result).isNotEqualTo(-1);
-        TertiaryKey keyInDb = mTertiaryKeysTable.getKey(SECONDARY_ALIAS, PACKAGE_NAME).get();
-        assertThat(keyInDb.getWrappedKeyBytes()).isEqualTo(newKey);
-    }
-
-    /**
-     * Tests that keys do not replace older keys with the same package name but a different alias.
-     */
-    @Test
-    public void addKey_havingSamePackageNameButDifferentAlias_doesNotReplaceOldKey()
-            throws Exception {
-        String alias2 = "karl";
-        TertiaryKey key1 = generateTertiaryKey(SECONDARY_ALIAS, PACKAGE_NAME);
-        TertiaryKey key2 = generateTertiaryKey(alias2, PACKAGE_NAME);
-
-        long primaryKey1 = mTertiaryKeysTable.addKey(key1);
-        long primaryKey2 = mTertiaryKeysTable.addKey(key2);
-
-        assertThat(primaryKey1).isNotEqualTo(primaryKey2);
-        assertThat(mTertiaryKeysTable.getKey(SECONDARY_ALIAS, PACKAGE_NAME).isPresent()).isTrue();
-        assertTertiaryKeysEqual(
-                mTertiaryKeysTable.getKey(SECONDARY_ALIAS, PACKAGE_NAME).get(), key1);
-        assertThat(mTertiaryKeysTable.getKey(alias2, PACKAGE_NAME).isPresent()).isTrue();
-        assertTertiaryKeysEqual(mTertiaryKeysTable.getKey(alias2, PACKAGE_NAME).get(), key2);
-    }
-
-    /**
-     * Tests that {@link TertiaryKeysTable#getKey(String, String)} returns an empty {@link Optional}
-     * for a missing key.
-     */
-    @Test
-    public void getKey_forMissingKey_returnsEmptyOptional() throws Exception {
-        Optional<TertiaryKey> key = mTertiaryKeysTable.getKey(SECONDARY_ALIAS, PACKAGE_NAME);
-
-        assertThat(key.isPresent()).isFalse();
-    }
-
-    /**
-     * Tests that {@link TertiaryKeysTable#getAllKeys(String)} returns an empty map when no keys
-     * with the secondary alias exist.
-     */
-    @Test
-    public void getAllKeys_withNoKeysForAlias_returnsEmptyMap() throws Exception {
-        assertThat(mTertiaryKeysTable.getAllKeys(SECONDARY_ALIAS)).isEmpty();
-    }
-
-    /**
-     * Tests that {@link TertiaryKeysTable#getAllKeys(String)} returns all keys corresponding to the
-     * provided secondary alias.
-     */
-    @Test
-    public void getAllKeys_withMatchingKeys_returnsAllKeysWrappedWithSecondary() throws Exception {
-        TertiaryKey key1 = generateTertiaryKey(SECONDARY_ALIAS, PACKAGE_NAME);
-        mTertiaryKeysTable.addKey(key1);
-        String package2 = "generic.package.two";
-        TertiaryKey key2 = generateTertiaryKey(SECONDARY_ALIAS, package2);
-        mTertiaryKeysTable.addKey(key2);
-        String package3 = "generic.package.three";
-        TertiaryKey key3 = generateTertiaryKey(SECONDARY_ALIAS, package3);
-        mTertiaryKeysTable.addKey(key3);
-
-        Map<String, TertiaryKey> keysByPackageName = mTertiaryKeysTable.getAllKeys(SECONDARY_ALIAS);
-
-        assertThat(keysByPackageName).hasSize(3);
-        assertThat(keysByPackageName).containsKey(PACKAGE_NAME);
-        assertTertiaryKeysEqual(keysByPackageName.get(PACKAGE_NAME), key1);
-        assertThat(keysByPackageName).containsKey(package2);
-        assertTertiaryKeysEqual(keysByPackageName.get(package2), key2);
-        assertThat(keysByPackageName).containsKey(package3);
-        assertTertiaryKeysEqual(keysByPackageName.get(package3), key3);
-    }
-
-    /**
-     * Tests that {@link TertiaryKeysTable#getAllKeys(String)} does not return any keys wrapped with
-     * another alias.
-     */
-    @Test
-    public void getAllKeys_withMatchingKeys_doesNotReturnKeysWrappedWithOtherAlias()
-            throws Exception {
-        mTertiaryKeysTable.addKey(generateTertiaryKey(SECONDARY_ALIAS, PACKAGE_NAME));
-        mTertiaryKeysTable.addKey(generateTertiaryKey("somekey", "generic.package.two"));
-
-        Map<String, TertiaryKey> keysByPackageName = mTertiaryKeysTable.getAllKeys(SECONDARY_ALIAS);
-
-        assertThat(keysByPackageName).hasSize(1);
-        assertThat(keysByPackageName).containsKey(PACKAGE_NAME);
-    }
-
-    private void assertTertiaryKeysEqual(TertiaryKey a, TertiaryKey b) {
-        assertThat(a.getSecondaryKeyAlias()).isEqualTo(b.getSecondaryKeyAlias());
-        assertThat(a.getPackageName()).isEqualTo(b.getPackageName());
-        assertThat(a.getWrappedKeyBytes()).isEqualTo(b.getWrappedKeyBytes());
-    }
-
-    private TertiaryKey generateTertiaryKey(String alias, String packageName) {
-        return new TertiaryKey(alias, packageName, generateRandomKey());
-    }
-
-    private byte[] generateRandomKey() {
-        return CryptoTestUtils.generateRandomBytes(KEY_SIZE_BYTES);
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/BackupFileDecryptorTaskTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/BackupFileDecryptorTaskTest.java
deleted file mode 100644
index 07a6fd2..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/BackupFileDecryptorTaskTest.java
+++ /dev/null
@@ -1,583 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.tasks;
-
-import static com.android.server.backup.testing.CryptoTestUtils.generateAesKey;
-import static com.android.server.backup.testing.CryptoTestUtils.newChunkOrdering;
-import static com.android.server.backup.testing.CryptoTestUtils.newChunksMetadata;
-import static com.android.server.backup.testing.CryptoTestUtils.newPair;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.testng.Assert.assertThrows;
-import static org.testng.Assert.expectThrows;
-
-import android.annotation.Nullable;
-import android.app.backup.BackupDataInput;
-import android.platform.test.annotations.Presubmit;
-
-import com.android.server.backup.encryption.chunk.ChunkHash;
-import com.android.server.backup.encryption.chunking.ChunkHasher;
-import com.android.server.backup.encryption.chunking.DecryptedChunkFileOutput;
-import com.android.server.backup.encryption.chunking.EncryptedChunk;
-import com.android.server.backup.encryption.chunking.cdc.FingerprintMixer;
-import com.android.server.backup.encryption.kv.DecryptedChunkKvOutput;
-import com.android.server.backup.encryption.protos.nano.ChunksMetadataProto;
-import com.android.server.backup.encryption.protos.nano.ChunksMetadataProto.ChunkOrdering;
-import com.android.server.backup.encryption.protos.nano.ChunksMetadataProto.ChunksMetadata;
-import com.android.server.backup.encryption.protos.nano.KeyValuePairProto.KeyValuePair;
-import com.android.server.backup.encryption.tasks.BackupEncrypter.Result;
-import com.android.server.backup.testing.CryptoTestUtils;
-import com.android.server.testing.shadows.ShadowBackupDataInput;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.protobuf.nano.MessageNano;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.junit.runner.RunWith;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.io.File;
-import java.io.FileDescriptor;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.RandomAccessFile;
-import java.nio.charset.Charset;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Random;
-import java.util.Set;
-
-import javax.crypto.AEADBadTagException;
-import javax.crypto.Cipher;
-import javax.crypto.SecretKey;
-import javax.crypto.spec.GCMParameterSpec;
-
-@Config(shadows = {ShadowBackupDataInput.class})
-@RunWith(RobolectricTestRunner.class)
-@Presubmit
-public class BackupFileDecryptorTaskTest {
-    private static final String READ_WRITE_MODE = "rw";
-    private static final int BYTES_PER_KILOBYTE = 1024;
-    private static final int MIN_CHUNK_SIZE_BYTES = 2 * BYTES_PER_KILOBYTE;
-    private static final int AVERAGE_CHUNK_SIZE_BYTES = 4 * BYTES_PER_KILOBYTE;
-    private static final int MAX_CHUNK_SIZE_BYTES = 64 * BYTES_PER_KILOBYTE;
-    private static final int BACKUP_DATA_SIZE_BYTES = 60 * BYTES_PER_KILOBYTE;
-    private static final int GCM_NONCE_LENGTH_BYTES = 12;
-    private static final int GCM_TAG_LENGTH_BYTES = 16;
-    private static final int BITS_PER_BYTE = 8;
-    private static final int CHECKSUM_LENGTH_BYTES = 256 / BITS_PER_BYTE;
-    @Nullable private static final FileDescriptor NULL_FILE_DESCRIPTOR = null;
-
-    private static final Set<KeyValuePair> TEST_KV_DATA = new HashSet<>();
-
-    static {
-        TEST_KV_DATA.add(newPair("key1", "value1"));
-        TEST_KV_DATA.add(newPair("key2", "value2"));
-    }
-
-    @Rule public final TemporaryFolder mTemporaryFolder = new TemporaryFolder();
-
-    private SecretKey mTertiaryKey;
-    private SecretKey mChunkEncryptionKey;
-    private File mInputFile;
-    private File mOutputFile;
-    private DecryptedChunkOutput mFileOutput;
-    private DecryptedChunkKvOutput mKvOutput;
-    private Random mRandom;
-    private BackupFileDecryptorTask mTask;
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        mRandom = new Random();
-        mTertiaryKey = generateAesKey();
-        // In good situations it's always the same. We allow changing it for testing when somehow it
-        // has become mismatched that we throw an error.
-        mChunkEncryptionKey = mTertiaryKey;
-        mInputFile = mTemporaryFolder.newFile();
-        mOutputFile = mTemporaryFolder.newFile();
-        mFileOutput = new DecryptedChunkFileOutput(mOutputFile);
-        mKvOutput = new DecryptedChunkKvOutput(new ChunkHasher(mTertiaryKey));
-        mTask = new BackupFileDecryptorTask(mTertiaryKey);
-    }
-
-    @Test
-    public void decryptFile_throwsForNonExistentInput() throws Exception {
-        assertThrows(
-                FileNotFoundException.class,
-                () ->
-                        mTask.decryptFile(
-                                new File(mTemporaryFolder.newFolder(), "nonexistent"),
-                                mFileOutput));
-    }
-
-    @Test
-    public void decryptFile_throwsForDirectoryInputFile() throws Exception {
-        assertThrows(
-                FileNotFoundException.class,
-                () -> mTask.decryptFile(mTemporaryFolder.newFolder(), mFileOutput));
-    }
-
-    @Test
-    public void decryptFile_withExplicitStarts_decryptsEncryptedData() throws Exception {
-        byte[] backupData = randomData(BACKUP_DATA_SIZE_BYTES);
-        createEncryptedFileUsingExplicitStarts(backupData);
-
-        mTask.decryptFile(mInputFile, mFileOutput);
-
-        assertThat(Files.readAllBytes(Paths.get(mOutputFile.toURI()))).isEqualTo(backupData);
-    }
-
-    @Test
-    public void decryptFile_withInlineLengths_decryptsEncryptedData() throws Exception {
-        createEncryptedFileUsingInlineLengths(
-                TEST_KV_DATA, chunkOrdering -> chunkOrdering, chunksMetadata -> chunksMetadata);
-        mTask.decryptFile(mInputFile, mKvOutput);
-        assertThat(asMap(mKvOutput.getPairs())).containsExactlyEntriesIn(asMap(TEST_KV_DATA));
-    }
-
-    @Test
-    public void decryptFile_withNoChunkOrderingType_decryptsUsingExplicitStarts() throws Exception {
-        byte[] backupData = randomData(BACKUP_DATA_SIZE_BYTES);
-        createEncryptedFileUsingExplicitStarts(
-                backupData,
-                chunkOrdering -> chunkOrdering,
-                chunksMetadata -> {
-                    ChunksMetadata metadata = CryptoTestUtils.clone(chunksMetadata);
-                    metadata.chunkOrderingType =
-                            ChunksMetadataProto.CHUNK_ORDERING_TYPE_UNSPECIFIED;
-                    return metadata;
-                });
-
-        mTask.decryptFile(mInputFile, mFileOutput);
-
-        assertThat(Files.readAllBytes(Paths.get(mOutputFile.toURI()))).isEqualTo(backupData);
-    }
-
-    @Test
-    public void decryptFile_withInlineLengths_throwsForZeroLengths() throws Exception {
-        createEncryptedFileUsingInlineLengths(
-                TEST_KV_DATA, chunkOrdering -> chunkOrdering, chunksMetadata -> chunksMetadata);
-
-        // Set the length of the first chunk to zero.
-        RandomAccessFile raf = new RandomAccessFile(mInputFile, READ_WRITE_MODE);
-        raf.seek(0);
-        raf.writeInt(0);
-
-        assertThrows(
-                MalformedEncryptedFileException.class,
-                () -> mTask.decryptFile(mInputFile, mKvOutput));
-    }
-
-    @Test
-    public void decryptFile_withInlineLengths_throwsForLongLengths() throws Exception {
-        createEncryptedFileUsingInlineLengths(
-                TEST_KV_DATA, chunkOrdering -> chunkOrdering, chunksMetadata -> chunksMetadata);
-
-        // Set the length of the first chunk to zero.
-        RandomAccessFile raf = new RandomAccessFile(mInputFile, READ_WRITE_MODE);
-        raf.seek(0);
-        raf.writeInt((int) mInputFile.length());
-
-        assertThrows(
-                MalformedEncryptedFileException.class,
-                () -> mTask.decryptFile(mInputFile, mKvOutput));
-    }
-
-    @Test
-    public void decryptFile_throwsForBadKey() throws Exception {
-        createEncryptedFileUsingExplicitStarts(randomData(BACKUP_DATA_SIZE_BYTES));
-
-        assertThrows(
-                AEADBadTagException.class,
-                () ->
-                        new BackupFileDecryptorTask(generateAesKey())
-                                .decryptFile(mInputFile, mFileOutput));
-    }
-
-    @Test
-    public void decryptFile_withExplicitStarts_throwsForMangledOrdering() throws Exception {
-        createEncryptedFileUsingExplicitStarts(
-                randomData(BACKUP_DATA_SIZE_BYTES),
-                chunkOrdering -> {
-                    ChunkOrdering ordering = CryptoTestUtils.clone(chunkOrdering);
-                    Arrays.sort(ordering.starts);
-                    return ordering;
-                });
-
-        assertThrows(
-                MessageDigestMismatchException.class,
-                () -> mTask.decryptFile(mInputFile, mFileOutput));
-    }
-
-    @Test
-    public void decryptFile_withExplicitStarts_noChunks_returnsNoData() throws Exception {
-        byte[] backupData = randomData(/*length=*/ 0);
-        createEncryptedFileUsingExplicitStarts(
-                backupData,
-                chunkOrdering -> {
-                    ChunkOrdering ordering = CryptoTestUtils.clone(chunkOrdering);
-                    ordering.starts = new int[0];
-                    return ordering;
-                });
-
-        mTask.decryptFile(mInputFile, mFileOutput);
-
-        assertThat(Files.readAllBytes(Paths.get(mOutputFile.toURI()))).isEqualTo(backupData);
-    }
-
-    @Test
-    public void decryptFile_throwsForMismatchedChecksum() throws Exception {
-        createEncryptedFileUsingExplicitStarts(
-                randomData(BACKUP_DATA_SIZE_BYTES),
-                chunkOrdering -> {
-                    ChunkOrdering ordering = CryptoTestUtils.clone(chunkOrdering);
-                    ordering.checksum =
-                            Arrays.copyOf(randomData(CHECKSUM_LENGTH_BYTES), CHECKSUM_LENGTH_BYTES);
-                    return ordering;
-                });
-
-        assertThrows(
-                MessageDigestMismatchException.class,
-                () -> mTask.decryptFile(mInputFile, mFileOutput));
-    }
-
-    @Test
-    public void decryptFile_throwsForBadChunksMetadataOffset() throws Exception {
-        createEncryptedFileUsingExplicitStarts(randomData(BACKUP_DATA_SIZE_BYTES));
-
-        // Replace the metadata with all 1s.
-        RandomAccessFile raf = new RandomAccessFile(mInputFile, READ_WRITE_MODE);
-        raf.seek(raf.length() - Long.BYTES);
-        int metadataOffset = (int) raf.readLong();
-        int metadataLength = (int) raf.length() - metadataOffset - Long.BYTES;
-
-        byte[] allOnes = new byte[metadataLength];
-        Arrays.fill(allOnes, (byte) 1);
-
-        raf.seek(metadataOffset);
-        raf.write(allOnes, /*off=*/ 0, metadataLength);
-
-        MalformedEncryptedFileException thrown =
-                expectThrows(
-                        MalformedEncryptedFileException.class,
-                        () -> mTask.decryptFile(mInputFile, mFileOutput));
-        assertThat(thrown)
-                .hasMessageThat()
-                .isEqualTo(
-                        "Could not read chunks metadata at position "
-                                + metadataOffset
-                                + " of file of "
-                                + raf.length()
-                                + " bytes");
-    }
-
-    @Test
-    public void decryptFile_throwsForChunksMetadataOffsetBeyondEndOfFile() throws Exception {
-        createEncryptedFileUsingExplicitStarts(randomData(BACKUP_DATA_SIZE_BYTES));
-
-        RandomAccessFile raf = new RandomAccessFile(mInputFile, READ_WRITE_MODE);
-        raf.seek(raf.length() - Long.BYTES);
-        raf.writeLong(raf.length());
-
-        MalformedEncryptedFileException thrown =
-                expectThrows(
-                        MalformedEncryptedFileException.class,
-                        () -> mTask.decryptFile(mInputFile, mFileOutput));
-        assertThat(thrown)
-                .hasMessageThat()
-                .isEqualTo(
-                        raf.length()
-                                + " is not valid position for chunks metadata in file of "
-                                + raf.length()
-                                + " bytes");
-    }
-
-    @Test
-    public void decryptFile_throwsForChunksMetadataOffsetBeforeBeginningOfFile() throws Exception {
-        createEncryptedFileUsingExplicitStarts(randomData(BACKUP_DATA_SIZE_BYTES));
-
-        RandomAccessFile raf = new RandomAccessFile(mInputFile, READ_WRITE_MODE);
-        raf.seek(raf.length() - Long.BYTES);
-        raf.writeLong(-1);
-
-        MalformedEncryptedFileException thrown =
-                expectThrows(
-                        MalformedEncryptedFileException.class,
-                        () -> mTask.decryptFile(mInputFile, mFileOutput));
-        assertThat(thrown)
-                .hasMessageThat()
-                .isEqualTo(
-                        "-1 is not valid position for chunks metadata in file of "
-                                + raf.length()
-                                + " bytes");
-    }
-
-    @Test
-    public void decryptFile_throwsForMangledChunks() throws Exception {
-        createEncryptedFileUsingExplicitStarts(randomData(BACKUP_DATA_SIZE_BYTES));
-
-        // Mess up some bits in a random byte
-        RandomAccessFile raf = new RandomAccessFile(mInputFile, READ_WRITE_MODE);
-        raf.seek(50);
-        byte fiftiethByte = raf.readByte();
-        raf.seek(50);
-        raf.write(~fiftiethByte);
-
-        assertThrows(AEADBadTagException.class, () -> mTask.decryptFile(mInputFile, mFileOutput));
-    }
-
-    @Test
-    public void decryptFile_throwsForBadChunkEncryptionKey() throws Exception {
-        mChunkEncryptionKey = generateAesKey();
-
-        createEncryptedFileUsingExplicitStarts(randomData(BACKUP_DATA_SIZE_BYTES));
-
-        assertThrows(AEADBadTagException.class, () -> mTask.decryptFile(mInputFile, mFileOutput));
-    }
-
-    @Test
-    public void decryptFile_throwsForUnsupportedCipherType() throws Exception {
-        createEncryptedFileUsingExplicitStarts(
-                randomData(BACKUP_DATA_SIZE_BYTES),
-                chunkOrdering -> chunkOrdering,
-                chunksMetadata -> {
-                    ChunksMetadata metadata = CryptoTestUtils.clone(chunksMetadata);
-                    metadata.cipherType = ChunksMetadataProto.UNKNOWN_CIPHER_TYPE;
-                    return metadata;
-                });
-
-        assertThrows(
-                UnsupportedEncryptedFileException.class,
-                () -> mTask.decryptFile(mInputFile, mFileOutput));
-    }
-
-    @Test
-    public void decryptFile_throwsForUnsupportedMessageDigestType() throws Exception {
-        createEncryptedFileUsingExplicitStarts(
-                randomData(BACKUP_DATA_SIZE_BYTES),
-                chunkOrdering -> chunkOrdering,
-                chunksMetadata -> {
-                    ChunksMetadata metadata = CryptoTestUtils.clone(chunksMetadata);
-                    metadata.checksumType = ChunksMetadataProto.UNKNOWN_CHECKSUM_TYPE;
-                    return metadata;
-                });
-
-        assertThrows(
-                UnsupportedEncryptedFileException.class,
-                () -> mTask.decryptFile(mInputFile, mFileOutput));
-    }
-
-    /**
-     * Creates an encrypted backup file from the given data.
-     *
-     * @param data The plaintext content.
-     */
-    private void createEncryptedFileUsingExplicitStarts(byte[] data) throws Exception {
-        createEncryptedFileUsingExplicitStarts(data, chunkOrdering -> chunkOrdering);
-    }
-
-    /**
-     * Creates an encrypted backup file from the given data.
-     *
-     * @param data The plaintext content.
-     * @param chunkOrderingTransformer Transforms the ordering before it's encrypted.
-     */
-    private void createEncryptedFileUsingExplicitStarts(
-            byte[] data, Transformer<ChunkOrdering> chunkOrderingTransformer) throws Exception {
-        createEncryptedFileUsingExplicitStarts(
-                data, chunkOrderingTransformer, chunksMetadata -> chunksMetadata);
-    }
-
-    /**
-     * Creates an encrypted backup file from the given data in mode {@link
-     * ChunksMetadataProto#EXPLICIT_STARTS}.
-     *
-     * @param data The plaintext content.
-     * @param chunkOrderingTransformer Transforms the ordering before it's encrypted.
-     * @param chunksMetadataTransformer Transforms the metadata before it's written.
-     */
-    private void createEncryptedFileUsingExplicitStarts(
-            byte[] data,
-            Transformer<ChunkOrdering> chunkOrderingTransformer,
-            Transformer<ChunksMetadata> chunksMetadataTransformer)
-            throws Exception {
-        Result result = backupFullData(data);
-
-        ArrayList<EncryptedChunk> chunks = new ArrayList<>(result.getNewChunks());
-        Collections.shuffle(chunks);
-        HashMap<ChunkHash, Integer> startPositions = new HashMap<>();
-
-        try (FileOutputStream fos = new FileOutputStream(mInputFile);
-                DataOutputStream dos = new DataOutputStream(fos)) {
-            int position = 0;
-
-            for (EncryptedChunk chunk : chunks) {
-                startPositions.put(chunk.key(), position);
-                dos.write(chunk.nonce());
-                dos.write(chunk.encryptedBytes());
-                position += chunk.nonce().length + chunk.encryptedBytes().length;
-            }
-
-            int[] starts = new int[chunks.size()];
-            List<ChunkHash> chunkListing = result.getAllChunks();
-
-            for (int i = 0; i < chunks.size(); i++) {
-                starts[i] = startPositions.get(chunkListing.get(i));
-            }
-
-            ChunkOrdering chunkOrdering = newChunkOrdering(starts, result.getDigest());
-            chunkOrdering = chunkOrderingTransformer.accept(chunkOrdering);
-
-            ChunksMetadata metadata =
-                    newChunksMetadata(
-                            ChunksMetadataProto.AES_256_GCM,
-                            ChunksMetadataProto.SHA_256,
-                            ChunksMetadataProto.EXPLICIT_STARTS,
-                            encrypt(chunkOrdering));
-            metadata = chunksMetadataTransformer.accept(metadata);
-
-            dos.write(MessageNano.toByteArray(metadata));
-            dos.writeLong(position);
-        }
-    }
-
-    /**
-     * Creates an encrypted backup file from the given data in mode {@link
-     * ChunksMetadataProto#INLINE_LENGTHS}.
-     *
-     * @param data The plaintext key value pairs to back up.
-     * @param chunkOrderingTransformer Transforms the ordering before it's encrypted.
-     * @param chunksMetadataTransformer Transforms the metadata before it's written.
-     */
-    private void createEncryptedFileUsingInlineLengths(
-            Set<KeyValuePair> data,
-            Transformer<ChunkOrdering> chunkOrderingTransformer,
-            Transformer<ChunksMetadata> chunksMetadataTransformer)
-            throws Exception {
-        Result result = backupKvData(data);
-
-        List<EncryptedChunk> chunks = new ArrayList<>(result.getNewChunks());
-        System.out.println("we have chunk count " + chunks.size());
-        Collections.shuffle(chunks);
-
-        try (FileOutputStream fos = new FileOutputStream(mInputFile);
-                DataOutputStream dos = new DataOutputStream(fos)) {
-            for (EncryptedChunk chunk : chunks) {
-                dos.writeInt(chunk.nonce().length + chunk.encryptedBytes().length);
-                dos.write(chunk.nonce());
-                dos.write(chunk.encryptedBytes());
-            }
-
-            ChunkOrdering chunkOrdering = newChunkOrdering(null, result.getDigest());
-            chunkOrdering = chunkOrderingTransformer.accept(chunkOrdering);
-
-            ChunksMetadata metadata =
-                    newChunksMetadata(
-                            ChunksMetadataProto.AES_256_GCM,
-                            ChunksMetadataProto.SHA_256,
-                            ChunksMetadataProto.INLINE_LENGTHS,
-                            encrypt(chunkOrdering));
-            metadata = chunksMetadataTransformer.accept(metadata);
-
-            int metadataStart = dos.size();
-            dos.write(MessageNano.toByteArray(metadata));
-            dos.writeLong(metadataStart);
-        }
-    }
-
-    /** Performs a full backup of the given data, and returns the chunks. */
-    private BackupEncrypter.Result backupFullData(byte[] data) throws Exception {
-        BackupStreamEncrypter encrypter =
-                new BackupStreamEncrypter(
-                        new ByteArrayInputStream(data),
-                        MIN_CHUNK_SIZE_BYTES,
-                        MAX_CHUNK_SIZE_BYTES,
-                        AVERAGE_CHUNK_SIZE_BYTES);
-        return encrypter.backup(
-                mChunkEncryptionKey,
-                randomData(FingerprintMixer.SALT_LENGTH_BYTES),
-                new HashSet<>());
-    }
-
-    private Result backupKvData(Set<KeyValuePair> data) throws Exception {
-        ShadowBackupDataInput.reset();
-        for (KeyValuePair pair : data) {
-            ShadowBackupDataInput.addEntity(pair.key, pair.value);
-        }
-        KvBackupEncrypter encrypter =
-                new KvBackupEncrypter(new BackupDataInput(NULL_FILE_DESCRIPTOR));
-        return encrypter.backup(
-                mChunkEncryptionKey,
-                randomData(FingerprintMixer.SALT_LENGTH_BYTES),
-                Collections.EMPTY_SET);
-    }
-
-    /** Encrypts {@code chunkOrdering} using {@link #mTertiaryKey}. */
-    private byte[] encrypt(ChunkOrdering chunkOrdering) throws Exception {
-        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
-        byte[] nonce = randomData(GCM_NONCE_LENGTH_BYTES);
-        cipher.init(
-                Cipher.ENCRYPT_MODE,
-                mTertiaryKey,
-                new GCMParameterSpec(GCM_TAG_LENGTH_BYTES * BITS_PER_BYTE, nonce));
-        byte[] nanoBytes = MessageNano.toByteArray(chunkOrdering);
-        byte[] encryptedBytes = cipher.doFinal(nanoBytes);
-
-        try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
-            out.write(nonce);
-            out.write(encryptedBytes);
-            return out.toByteArray();
-        }
-    }
-
-    /** Returns {@code length} random bytes. */
-    private byte[] randomData(int length) {
-        byte[] data = new byte[length];
-        mRandom.nextBytes(data);
-        return data;
-    }
-
-    private static ImmutableMap<String, String> asMap(Collection<KeyValuePair> pairs) {
-        ImmutableMap.Builder<String, String> map = ImmutableMap.builder();
-        for (KeyValuePair pair : pairs) {
-            map.put(pair.key, new String(pair.value, Charset.forName("UTF-8")));
-        }
-        return map.build();
-    }
-
-    private interface Transformer<T> {
-        T accept(T t);
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/BackupStreamEncrypterTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/BackupStreamEncrypterTest.java
deleted file mode 100644
index 21c4e07..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/BackupStreamEncrypterTest.java
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.tasks;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.platform.test.annotations.Presubmit;
-
-import com.android.server.backup.encryption.chunk.ChunkHash;
-import com.android.server.backup.encryption.chunking.EncryptedChunk;
-import com.android.server.backup.testing.CryptoTestUtils;
-import com.android.server.backup.testing.RandomInputStream;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-
-import java.io.ByteArrayInputStream;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Random;
-
-import javax.crypto.SecretKey;
-
-@RunWith(RobolectricTestRunner.class)
-@Presubmit
-public class BackupStreamEncrypterTest {
-    private static final int SALT_LENGTH = 32;
-    private static final int BITS_PER_BYTE = 8;
-    private static final int BYTES_PER_KILOBYTE = 1024;
-    private static final int BYTES_PER_MEGABYTE = 1024 * 1024;
-    private static final int MIN_CHUNK_SIZE = 2 * BYTES_PER_KILOBYTE;
-    private static final int AVERAGE_CHUNK_SIZE = 4 * BYTES_PER_KILOBYTE;
-    private static final int MAX_CHUNK_SIZE = 64 * BYTES_PER_KILOBYTE;
-    private static final int BACKUP_SIZE = 2 * BYTES_PER_MEGABYTE;
-    private static final int SMALL_BACKUP_SIZE = BYTES_PER_KILOBYTE;
-    // 16 bytes for the mac. iv is encoded in a separate field.
-    private static final int BYTES_OVERHEAD_PER_CHUNK = 16;
-    private static final int MESSAGE_DIGEST_SIZE_IN_BYTES = 256 / BITS_PER_BYTE;
-    private static final int RANDOM_SEED = 42;
-    private static final double TOLERANCE = 0.1;
-
-    private Random mRandom;
-    private SecretKey mSecretKey;
-    private byte[] mSalt;
-
-    @Before
-    public void setUp() throws Exception {
-        mSecretKey = CryptoTestUtils.generateAesKey();
-
-        mSalt = new byte[SALT_LENGTH];
-        // Make these tests deterministic
-        mRandom = new Random(RANDOM_SEED);
-        mRandom.nextBytes(mSalt);
-    }
-
-    @Test
-    public void testBackup_producesChunksOfTheGivenAverageSize() throws Exception {
-        BackupEncrypter.Result result = runBackup(BACKUP_SIZE);
-
-        long totalSize = 0;
-        for (EncryptedChunk chunk : result.getNewChunks()) {
-            totalSize += chunk.encryptedBytes().length;
-        }
-
-        double meanSize = totalSize / result.getNewChunks().size();
-        double expectedChunkSize = AVERAGE_CHUNK_SIZE + BYTES_OVERHEAD_PER_CHUNK;
-        assertThat(Math.abs(meanSize - expectedChunkSize) / expectedChunkSize)
-                .isLessThan(TOLERANCE);
-    }
-
-    @Test
-    public void testBackup_producesNoChunksSmallerThanMinSize() throws Exception {
-        BackupEncrypter.Result result = runBackup(BACKUP_SIZE);
-        List<EncryptedChunk> chunks = result.getNewChunks();
-
-        // Last chunk could be smaller, depending on the file size and how it is chunked
-        for (EncryptedChunk chunk : chunks.subList(0, chunks.size() - 2)) {
-            assertThat(chunk.encryptedBytes().length)
-                    .isAtLeast(MIN_CHUNK_SIZE + BYTES_OVERHEAD_PER_CHUNK);
-        }
-    }
-
-    @Test
-    public void testBackup_producesNoChunksLargerThanMaxSize() throws Exception {
-        BackupEncrypter.Result result = runBackup(BACKUP_SIZE);
-        List<EncryptedChunk> chunks = result.getNewChunks();
-
-        for (EncryptedChunk chunk : chunks) {
-            assertThat(chunk.encryptedBytes().length)
-                    .isAtMost(MAX_CHUNK_SIZE + BYTES_OVERHEAD_PER_CHUNK);
-        }
-    }
-
-    @Test
-    public void testBackup_producesAFileOfTheExpectedSize() throws Exception {
-        BackupEncrypter.Result result = runBackup(BACKUP_SIZE);
-        HashMap<ChunkHash, EncryptedChunk> chunksBySha256 =
-                chunksIndexedByKey(result.getNewChunks());
-
-        int expectedSize = BACKUP_SIZE + result.getAllChunks().size() * BYTES_OVERHEAD_PER_CHUNK;
-        int size = 0;
-        for (ChunkHash byteString : result.getAllChunks()) {
-            size += chunksBySha256.get(byteString).encryptedBytes().length;
-        }
-        assertThat(size).isEqualTo(expectedSize);
-    }
-
-    @Test
-    public void testBackup_forSameFile_producesNoNewChunks() throws Exception {
-        byte[] backupData = getRandomData(BACKUP_SIZE);
-        BackupEncrypter.Result result = runBackup(backupData, ImmutableList.of());
-
-        BackupEncrypter.Result incrementalResult = runBackup(backupData, result.getAllChunks());
-
-        assertThat(incrementalResult.getNewChunks()).isEmpty();
-    }
-
-    @Test
-    public void testBackup_onlyUpdatesChangedChunks() throws Exception {
-        byte[] backupData = getRandomData(BACKUP_SIZE);
-        BackupEncrypter.Result result = runBackup(backupData, ImmutableList.of());
-
-        // Let's update the 2nd and 5th chunk
-        backupData[positionOfChunk(result, 1)]++;
-        backupData[positionOfChunk(result, 4)]++;
-        BackupEncrypter.Result incrementalResult = runBackup(backupData, result.getAllChunks());
-
-        assertThat(incrementalResult.getNewChunks()).hasSize(2);
-    }
-
-    @Test
-    public void testBackup_doesNotIncludeUpdatedChunksInNewListing() throws Exception {
-        byte[] backupData = getRandomData(BACKUP_SIZE);
-        BackupEncrypter.Result result = runBackup(backupData, ImmutableList.of());
-
-        // Let's update the 2nd and 5th chunk
-        backupData[positionOfChunk(result, 1)]++;
-        backupData[positionOfChunk(result, 4)]++;
-        BackupEncrypter.Result incrementalResult = runBackup(backupData, result.getAllChunks());
-
-        List<EncryptedChunk> newChunks = incrementalResult.getNewChunks();
-        List<ChunkHash> chunkListing = result.getAllChunks();
-        assertThat(newChunks).doesNotContain(chunkListing.get(1));
-        assertThat(newChunks).doesNotContain(chunkListing.get(4));
-    }
-
-    @Test
-    public void testBackup_includesUnchangedChunksInNewListing() throws Exception {
-        byte[] backupData = getRandomData(BACKUP_SIZE);
-        BackupEncrypter.Result result = runBackup(backupData, ImmutableList.of());
-
-        // Let's update the 2nd and 5th chunk
-        backupData[positionOfChunk(result, 1)]++;
-        backupData[positionOfChunk(result, 4)]++;
-        BackupEncrypter.Result incrementalResult = runBackup(backupData, result.getAllChunks());
-
-        HashSet<ChunkHash> chunksPresentInIncremental =
-                new HashSet<>(incrementalResult.getAllChunks());
-        chunksPresentInIncremental.removeAll(result.getAllChunks());
-
-        assertThat(chunksPresentInIncremental).hasSize(2);
-    }
-
-    @Test
-    public void testBackup_forSameData_createsSameDigest() throws Exception {
-        byte[] backupData = getRandomData(SMALL_BACKUP_SIZE);
-
-        BackupEncrypter.Result result = runBackup(backupData, ImmutableList.of());
-        BackupEncrypter.Result result2 = runBackup(backupData, ImmutableList.of());
-        assertThat(result.getDigest()).isEqualTo(result2.getDigest());
-    }
-
-    @Test
-    public void testBackup_forDifferentData_createsDifferentDigest() throws Exception {
-        byte[] backup1Data = getRandomData(SMALL_BACKUP_SIZE);
-        byte[] backup2Data = getRandomData(SMALL_BACKUP_SIZE);
-
-        BackupEncrypter.Result result = runBackup(backup1Data, ImmutableList.of());
-        BackupEncrypter.Result result2 = runBackup(backup2Data, ImmutableList.of());
-        assertThat(result.getDigest()).isNotEqualTo(result2.getDigest());
-    }
-
-    @Test
-    public void testBackup_createsDigestOf32Bytes() throws Exception {
-        assertThat(runBackup(getRandomData(SMALL_BACKUP_SIZE), ImmutableList.of()).getDigest())
-                .hasLength(MESSAGE_DIGEST_SIZE_IN_BYTES);
-    }
-
-    private byte[] getRandomData(int size) throws Exception {
-        RandomInputStream randomInputStream = new RandomInputStream(mRandom, size);
-        byte[] backupData = new byte[size];
-        randomInputStream.read(backupData);
-        return backupData;
-    }
-
-    private BackupEncrypter.Result runBackup(int backupSize) throws Exception {
-        RandomInputStream dataStream = new RandomInputStream(mRandom, backupSize);
-        BackupStreamEncrypter task =
-                new BackupStreamEncrypter(
-                        dataStream, MIN_CHUNK_SIZE, MAX_CHUNK_SIZE, AVERAGE_CHUNK_SIZE);
-        return task.backup(mSecretKey, mSalt, ImmutableSet.of());
-    }
-
-    private BackupEncrypter.Result runBackup(byte[] data, List<ChunkHash> existingChunks)
-            throws Exception {
-        ByteArrayInputStream dataStream = new ByteArrayInputStream(data);
-        BackupStreamEncrypter task =
-                new BackupStreamEncrypter(
-                        dataStream, MIN_CHUNK_SIZE, MAX_CHUNK_SIZE, AVERAGE_CHUNK_SIZE);
-        return task.backup(mSecretKey, mSalt, ImmutableSet.copyOf(existingChunks));
-    }
-
-    /** Returns a {@link HashMap} of the chunks, indexed by the SHA-256 Mac key. */
-    private static HashMap<ChunkHash, EncryptedChunk> chunksIndexedByKey(
-            List<EncryptedChunk> chunks) {
-        HashMap<ChunkHash, EncryptedChunk> chunksByKey = new HashMap<>();
-        for (EncryptedChunk chunk : chunks) {
-            chunksByKey.put(chunk.key(), chunk);
-        }
-        return chunksByKey;
-    }
-
-    /**
-     * Returns the start position of the chunk in the plaintext backup data.
-     *
-     * @param result The result from a backup.
-     * @param index The index of the chunk in question.
-     * @return the start position.
-     */
-    private static int positionOfChunk(BackupEncrypter.Result result, int index) {
-        HashMap<ChunkHash, EncryptedChunk> byKey = chunksIndexedByKey(result.getNewChunks());
-        List<ChunkHash> listing = result.getAllChunks();
-
-        int position = 0;
-        for (int i = 0; i < index - 1; i++) {
-            EncryptedChunk chunk = byKey.get(listing.get(i));
-            position += chunk.encryptedBytes().length - BYTES_OVERHEAD_PER_CHUNK;
-        }
-
-        return position;
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/ClearCryptoStateTaskTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/ClearCryptoStateTaskTest.java
deleted file mode 100644
index 81bfce1..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/ClearCryptoStateTaskTest.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.tasks;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.spy;
-
-import android.content.Context;
-import android.platform.test.annotations.Presubmit;
-
-import androidx.test.core.app.ApplicationProvider;
-
-import com.android.server.backup.encryption.CryptoSettings;
-import com.android.server.backup.encryption.chunking.ProtoStore;
-import com.android.server.backup.encryption.protos.nano.ChunksMetadataProto.ChunkListing;
-import com.android.server.backup.encryption.protos.nano.KeyValueListingProto.KeyValueListing;
-import com.android.server.backup.encryption.storage.BackupEncryptionDb;
-import com.android.server.backup.encryption.storage.TertiaryKey;
-import com.android.server.backup.encryption.storage.TertiaryKeysTable;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-
-@RunWith(RobolectricTestRunner.class)
-@Presubmit
-public class ClearCryptoStateTaskTest {
-    private static final String TEST_PACKAGE_NAME = "com.android.example";
-
-    private ClearCryptoStateTask mClearCryptoStateTask;
-    private CryptoSettings mCryptoSettings;
-    private Context mApplication;
-
-    @Before
-    public void setUp() {
-        mApplication = ApplicationProvider.getApplicationContext();
-        mCryptoSettings = spy(CryptoSettings.getInstanceForTesting(mApplication));
-        mClearCryptoStateTask = new ClearCryptoStateTask(mApplication, mCryptoSettings);
-    }
-
-    @Test
-    public void run_clearsChunkListingProtoState() throws Exception {
-        String packageName = TEST_PACKAGE_NAME;
-        ChunkListing chunkListing = new ChunkListing();
-        ProtoStore.createChunkListingStore(mApplication).saveProto(packageName, chunkListing);
-
-        mClearCryptoStateTask.run();
-
-        assertThat(
-                        ProtoStore.createChunkListingStore(mApplication)
-                                .loadProto(packageName)
-                                .isPresent())
-                .isFalse();
-    }
-
-    @Test
-    public void run_clearsKeyValueProtoState() throws Exception {
-        String packageName = TEST_PACKAGE_NAME;
-        KeyValueListing keyValueListing = new KeyValueListing();
-        ProtoStore.createKeyValueListingStore(mApplication).saveProto(packageName, keyValueListing);
-
-        mClearCryptoStateTask.run();
-
-        assertThat(
-                        ProtoStore.createKeyValueListingStore(mApplication)
-                                .loadProto(packageName)
-                                .isPresent())
-                .isFalse();
-    }
-
-    @Test
-    public void run_clearsTertiaryKeysTable() throws Exception {
-        String secondaryKeyAlias = "bob";
-        TertiaryKeysTable tertiaryKeysTable =
-                BackupEncryptionDb.newInstance(mApplication).getTertiaryKeysTable();
-        tertiaryKeysTable.addKey(
-                new TertiaryKey(
-                        secondaryKeyAlias, "packageName", /*wrappedKeyBytes=*/ new byte[0]));
-
-        mClearCryptoStateTask.run();
-
-        assertThat(tertiaryKeysTable.getAllKeys(secondaryKeyAlias)).isEmpty();
-    }
-
-    @Test
-    public void run_clearsSettings() {
-        mCryptoSettings.setSecondaryLastRotated(100001);
-
-        mClearCryptoStateTask.run();
-
-        assertThat(mCryptoSettings.getSecondaryLastRotated().isPresent()).isFalse();
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedBackupTaskTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedBackupTaskTest.java
deleted file mode 100644
index 23d6e34..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedBackupTaskTest.java
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.tasks;
-
-import static com.android.server.backup.encryption.protos.nano.ChunksMetadataProto.AES_256_GCM;
-import static com.android.server.backup.encryption.protos.nano.ChunksMetadataProto.CHUNK_ORDERING_TYPE_UNSPECIFIED;
-import static com.android.server.backup.encryption.protos.nano.ChunksMetadataProto.SHA_256;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.testng.Assert.assertThrows;
-
-import android.platform.test.annotations.Presubmit;
-
-import com.android.server.backup.encryption.chunk.ChunkHash;
-import com.android.server.backup.encryption.chunking.BackupFileBuilder;
-import com.android.server.backup.encryption.chunking.EncryptedChunk;
-import com.android.server.backup.encryption.chunking.EncryptedChunkEncoder;
-import com.android.server.backup.encryption.chunking.LengthlessEncryptedChunkEncoder;
-import com.android.server.backup.encryption.client.CryptoBackupServer;
-import com.android.server.backup.encryption.keys.TertiaryKeyGenerator;
-import com.android.server.backup.encryption.protos.nano.ChunksMetadataProto;
-import com.android.server.backup.encryption.protos.nano.ChunksMetadataProto.ChunkListing;
-import com.android.server.backup.encryption.protos.nano.ChunksMetadataProto.ChunkOrdering;
-import com.android.server.backup.encryption.protos.nano.ChunksMetadataProto.ChunksMetadata;
-import com.android.server.backup.encryption.protos.nano.WrappedKeyProto.WrappedKey;
-import com.android.server.backup.encryption.tasks.BackupEncrypter.Result;
-import com.android.server.backup.testing.CryptoTestUtils;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.protobuf.nano.MessageNano;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-import org.robolectric.annotation.Implementation;
-import org.robolectric.annotation.Implements;
-
-import java.io.OutputStream;
-import java.security.SecureRandom;
-import java.util.Arrays;
-import java.util.concurrent.CancellationException;
-
-import javax.crypto.Cipher;
-import javax.crypto.SecretKey;
-import javax.crypto.spec.GCMParameterSpec;
-
-@Config(shadows = {EncryptedBackupTaskTest.ShadowBackupFileBuilder.class})
-@RunWith(RobolectricTestRunner.class)
-@Presubmit
-public class EncryptedBackupTaskTest {
-
-    private static final String CIPHER_ALGORITHM = "AES/GCM/NoPadding";
-    private static final int GCM_NONCE_LENGTH_BYTES = 12;
-    private static final int GCM_TAG_LENGTH_BYTES = 16;
-    private static final int BITS_PER_BYTE = 8;
-
-    private static final byte[] TEST_FINGERPRINT_MIXER_SALT =
-            Arrays.copyOf(new byte[] {22}, ChunkHash.HASH_LENGTH_BYTES);
-
-    private static final byte[] TEST_NONCE =
-            Arrays.copyOf(new byte[] {55}, EncryptedChunk.NONCE_LENGTH_BYTES);
-
-    private static final ChunkHash TEST_HASH_1 =
-            new ChunkHash(Arrays.copyOf(new byte[] {1}, ChunkHash.HASH_LENGTH_BYTES));
-    private static final ChunkHash TEST_HASH_2 =
-            new ChunkHash(Arrays.copyOf(new byte[] {2}, ChunkHash.HASH_LENGTH_BYTES));
-    private static final ChunkHash TEST_HASH_3 =
-            new ChunkHash(Arrays.copyOf(new byte[] {3}, ChunkHash.HASH_LENGTH_BYTES));
-
-    private static final EncryptedChunk TEST_CHUNK_1 =
-            EncryptedChunk.create(TEST_HASH_1, TEST_NONCE, new byte[] {1, 2, 3, 4, 5});
-    private static final EncryptedChunk TEST_CHUNK_2 =
-            EncryptedChunk.create(TEST_HASH_2, TEST_NONCE, new byte[] {6, 7, 8, 9, 10});
-    private static final EncryptedChunk TEST_CHUNK_3 =
-            EncryptedChunk.create(TEST_HASH_3, TEST_NONCE, new byte[] {11, 12, 13, 14, 15});
-
-    private static final byte[] TEST_CHECKSUM = Arrays.copyOf(new byte[] {10}, 258 / 8);
-    private static final String TEST_PACKAGE_NAME = "com.example.package";
-    private static final String TEST_OLD_DOCUMENT_ID = "old_doc_1";
-    private static final String TEST_NEW_DOCUMENT_ID = "new_doc_1";
-
-    @Captor private ArgumentCaptor<ChunksMetadata> mMetadataCaptor;
-
-    @Mock private CryptoBackupServer mCryptoBackupServer;
-    @Mock private BackupEncrypter mBackupEncrypter;
-    @Mock private BackupFileBuilder mBackupFileBuilder;
-
-    private ChunkListing mOldChunkListing;
-    private SecretKey mTertiaryKey;
-    private WrappedKey mWrappedTertiaryKey;
-    private EncryptedChunkEncoder mEncryptedChunkEncoder;
-    private EncryptedBackupTask mTask;
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        SecureRandom secureRandom = new SecureRandom();
-        mTertiaryKey = new TertiaryKeyGenerator(secureRandom).generate();
-        mWrappedTertiaryKey = new WrappedKey();
-
-        mEncryptedChunkEncoder = new LengthlessEncryptedChunkEncoder();
-
-        ShadowBackupFileBuilder.sInstance = mBackupFileBuilder;
-
-        mTask =
-                new EncryptedBackupTask(
-                        mCryptoBackupServer, secureRandom, TEST_PACKAGE_NAME, mBackupEncrypter);
-    }
-
-    @Test
-    public void performNonIncrementalBackup_performsBackup() throws Exception {
-        setUpWithoutExistingBackup();
-
-        // Chunk listing and ordering don't matter for this test.
-        when(mBackupFileBuilder.getNewChunkListing(any())).thenReturn(new ChunkListing());
-        when(mBackupFileBuilder.getNewChunkOrdering(TEST_CHECKSUM)).thenReturn(new ChunkOrdering());
-
-        when(mCryptoBackupServer.uploadNonIncrementalBackup(eq(TEST_PACKAGE_NAME), any(), any()))
-                .thenReturn(TEST_NEW_DOCUMENT_ID);
-
-        mTask.performNonIncrementalBackup(
-                mTertiaryKey, mWrappedTertiaryKey, TEST_FINGERPRINT_MIXER_SALT);
-
-        verify(mBackupFileBuilder)
-                .writeChunks(
-                        ImmutableList.of(TEST_HASH_1, TEST_HASH_2),
-                        ImmutableMap.of(TEST_HASH_1, TEST_CHUNK_1, TEST_HASH_2, TEST_CHUNK_2));
-        verify(mBackupFileBuilder).finish(any());
-        verify(mCryptoBackupServer)
-                .uploadNonIncrementalBackup(eq(TEST_PACKAGE_NAME), any(), eq(mWrappedTertiaryKey));
-    }
-
-    @Test
-    public void performIncrementalBackup_performsBackup() throws Exception {
-        setUpWithExistingBackup();
-
-        // Chunk listing and ordering don't matter for this test.
-        when(mBackupFileBuilder.getNewChunkListing(any())).thenReturn(new ChunkListing());
-        when(mBackupFileBuilder.getNewChunkOrdering(TEST_CHECKSUM)).thenReturn(new ChunkOrdering());
-
-        when(mCryptoBackupServer.uploadIncrementalBackup(
-                        eq(TEST_PACKAGE_NAME), eq(TEST_OLD_DOCUMENT_ID), any(), any()))
-                .thenReturn(TEST_NEW_DOCUMENT_ID);
-
-        mTask.performIncrementalBackup(mTertiaryKey, mWrappedTertiaryKey, mOldChunkListing);
-
-        verify(mBackupFileBuilder)
-                .writeChunks(
-                        ImmutableList.of(TEST_HASH_1, TEST_HASH_2, TEST_HASH_3),
-                        ImmutableMap.of(TEST_HASH_2, TEST_CHUNK_2));
-        verify(mBackupFileBuilder).finish(any());
-        verify(mCryptoBackupServer)
-                .uploadIncrementalBackup(
-                        eq(TEST_PACKAGE_NAME),
-                        eq(TEST_OLD_DOCUMENT_ID),
-                        any(),
-                        eq(mWrappedTertiaryKey));
-    }
-
-    @Test
-    public void performIncrementalBackup_returnsNewChunkListingWithDocId() throws Exception {
-        setUpWithExistingBackup();
-
-        ChunkListing chunkListingWithoutDocId =
-                CryptoTestUtils.newChunkListingWithoutDocId(
-                        TEST_FINGERPRINT_MIXER_SALT,
-                        AES_256_GCM,
-                        CHUNK_ORDERING_TYPE_UNSPECIFIED,
-                        createChunkProtoFor(TEST_HASH_1, TEST_CHUNK_1),
-                        createChunkProtoFor(TEST_HASH_2, TEST_CHUNK_2));
-        when(mBackupFileBuilder.getNewChunkListing(any())).thenReturn(chunkListingWithoutDocId);
-
-        // Chunk ordering doesn't matter for this test.
-        when(mBackupFileBuilder.getNewChunkOrdering(TEST_CHECKSUM)).thenReturn(new ChunkOrdering());
-
-        when(mCryptoBackupServer.uploadIncrementalBackup(
-                        eq(TEST_PACKAGE_NAME), eq(TEST_OLD_DOCUMENT_ID), any(), any()))
-                .thenReturn(TEST_NEW_DOCUMENT_ID);
-
-        ChunkListing actualChunkListing =
-                mTask.performIncrementalBackup(mTertiaryKey, mWrappedTertiaryKey, mOldChunkListing);
-
-        ChunkListing expectedChunkListing = CryptoTestUtils.clone(chunkListingWithoutDocId);
-        expectedChunkListing.documentId = TEST_NEW_DOCUMENT_ID;
-        assertChunkListingsAreEqual(actualChunkListing, expectedChunkListing);
-    }
-
-    @Test
-    public void performNonIncrementalBackup_returnsNewChunkListingWithDocId() throws Exception {
-        setUpWithoutExistingBackup();
-
-        ChunkListing chunkListingWithoutDocId =
-                CryptoTestUtils.newChunkListingWithoutDocId(
-                        TEST_FINGERPRINT_MIXER_SALT,
-                        AES_256_GCM,
-                        CHUNK_ORDERING_TYPE_UNSPECIFIED,
-                        createChunkProtoFor(TEST_HASH_1, TEST_CHUNK_1),
-                        createChunkProtoFor(TEST_HASH_2, TEST_CHUNK_2));
-        when(mBackupFileBuilder.getNewChunkListing(any())).thenReturn(chunkListingWithoutDocId);
-
-        // Chunk ordering doesn't matter for this test.
-        when(mBackupFileBuilder.getNewChunkOrdering(TEST_CHECKSUM)).thenReturn(new ChunkOrdering());
-
-        when(mCryptoBackupServer.uploadNonIncrementalBackup(eq(TEST_PACKAGE_NAME), any(), any()))
-                .thenReturn(TEST_NEW_DOCUMENT_ID);
-
-        ChunkListing actualChunkListing =
-                mTask.performNonIncrementalBackup(
-                        mTertiaryKey, mWrappedTertiaryKey, TEST_FINGERPRINT_MIXER_SALT);
-
-        ChunkListing expectedChunkListing = CryptoTestUtils.clone(chunkListingWithoutDocId);
-        expectedChunkListing.documentId = TEST_NEW_DOCUMENT_ID;
-        assertChunkListingsAreEqual(actualChunkListing, expectedChunkListing);
-    }
-
-    @Test
-    public void performNonIncrementalBackup_buildsCorrectChunkMetadata() throws Exception {
-        setUpWithoutExistingBackup();
-
-        // Chunk listing doesn't matter for this test.
-        when(mBackupFileBuilder.getNewChunkListing(any())).thenReturn(new ChunkListing());
-
-        ChunkOrdering expectedOrdering =
-                CryptoTestUtils.newChunkOrdering(new int[10], TEST_CHECKSUM);
-        when(mBackupFileBuilder.getNewChunkOrdering(TEST_CHECKSUM)).thenReturn(expectedOrdering);
-
-        when(mCryptoBackupServer.uploadNonIncrementalBackup(eq(TEST_PACKAGE_NAME), any(), any()))
-                .thenReturn(TEST_NEW_DOCUMENT_ID);
-
-        mTask.performNonIncrementalBackup(
-                mTertiaryKey, mWrappedTertiaryKey, TEST_FINGERPRINT_MIXER_SALT);
-
-        verify(mBackupFileBuilder).finish(mMetadataCaptor.capture());
-
-        ChunksMetadata actualMetadata = mMetadataCaptor.getValue();
-        assertThat(actualMetadata.checksumType).isEqualTo(SHA_256);
-        assertThat(actualMetadata.cipherType).isEqualTo(AES_256_GCM);
-
-        ChunkOrdering actualOrdering = decryptChunkOrdering(actualMetadata.chunkOrdering);
-        assertThat(actualOrdering.checksum).isEqualTo(TEST_CHECKSUM);
-        assertThat(actualOrdering.starts).isEqualTo(expectedOrdering.starts);
-    }
-
-    @Test
-    public void cancel_incrementalBackup_doesNotUploadOrSaveChunkListing() throws Exception {
-        setUpWithExistingBackup();
-
-        // Chunk listing and ordering don't matter for this test.
-        when(mBackupFileBuilder.getNewChunkListing(any())).thenReturn(new ChunkListing());
-        when(mBackupFileBuilder.getNewChunkOrdering(TEST_CHECKSUM)).thenReturn(new ChunkOrdering());
-
-        mTask.cancel();
-        assertThrows(
-                CancellationException.class,
-                () ->
-                        mTask.performIncrementalBackup(
-                                mTertiaryKey, mWrappedTertiaryKey, mOldChunkListing));
-
-        verify(mCryptoBackupServer, never()).uploadIncrementalBackup(any(), any(), any(), any());
-        verify(mCryptoBackupServer, never()).uploadNonIncrementalBackup(any(), any(), any());
-    }
-
-    @Test
-    public void cancel_nonIncrementalBackup_doesNotUploadOrSaveChunkListing() throws Exception {
-        setUpWithoutExistingBackup();
-
-        // Chunk listing and ordering don't matter for this test.
-        when(mBackupFileBuilder.getNewChunkListing(any())).thenReturn(new ChunkListing());
-        when(mBackupFileBuilder.getNewChunkOrdering(TEST_CHECKSUM)).thenReturn(new ChunkOrdering());
-
-        mTask.cancel();
-        assertThrows(
-                CancellationException.class,
-                () ->
-                        mTask.performNonIncrementalBackup(
-                                mTertiaryKey, mWrappedTertiaryKey, TEST_FINGERPRINT_MIXER_SALT));
-
-        verify(mCryptoBackupServer, never()).uploadIncrementalBackup(any(), any(), any(), any());
-        verify(mCryptoBackupServer, never()).uploadNonIncrementalBackup(any(), any(), any());
-    }
-
-    /** Sets up a backup of [CHUNK 1][CHUNK 2] with no existing data. */
-    private void setUpWithoutExistingBackup() throws Exception {
-        Result result =
-                new Result(
-                        ImmutableList.of(TEST_HASH_1, TEST_HASH_2),
-                        ImmutableList.of(TEST_CHUNK_1, TEST_CHUNK_2),
-                        TEST_CHECKSUM);
-        when(mBackupEncrypter.backup(any(), eq(TEST_FINGERPRINT_MIXER_SALT), eq(ImmutableSet.of())))
-                .thenReturn(result);
-    }
-
-    /**
-     * Sets up a backup of [CHUNK 1][CHUNK 2][CHUNK 3] where the previous backup contained [CHUNK
-     * 1][CHUNK 3].
-     */
-    private void setUpWithExistingBackup() throws Exception {
-        mOldChunkListing =
-                CryptoTestUtils.newChunkListing(
-                        TEST_OLD_DOCUMENT_ID,
-                        TEST_FINGERPRINT_MIXER_SALT,
-                        AES_256_GCM,
-                        CHUNK_ORDERING_TYPE_UNSPECIFIED,
-                        createChunkProtoFor(TEST_HASH_1, TEST_CHUNK_1),
-                        createChunkProtoFor(TEST_HASH_3, TEST_CHUNK_3));
-
-        Result result =
-                new Result(
-                        ImmutableList.of(TEST_HASH_1, TEST_HASH_2, TEST_HASH_3),
-                        ImmutableList.of(TEST_CHUNK_2),
-                        TEST_CHECKSUM);
-        when(mBackupEncrypter.backup(
-                        any(),
-                        eq(TEST_FINGERPRINT_MIXER_SALT),
-                        eq(ImmutableSet.of(TEST_HASH_1, TEST_HASH_3))))
-                .thenReturn(result);
-    }
-
-    private ChunksMetadataProto.Chunk createChunkProtoFor(
-            ChunkHash chunkHash, EncryptedChunk encryptedChunk) {
-        return CryptoTestUtils.newChunk(
-                chunkHash, mEncryptedChunkEncoder.getEncodedLengthOfChunk(encryptedChunk));
-    }
-
-    private ChunkOrdering decryptChunkOrdering(byte[] encryptedOrdering) throws Exception {
-        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
-        cipher.init(
-                Cipher.DECRYPT_MODE,
-                mTertiaryKey,
-                new GCMParameterSpec(
-                        GCM_TAG_LENGTH_BYTES * BITS_PER_BYTE,
-                        encryptedOrdering,
-                        /*offset=*/ 0,
-                        GCM_NONCE_LENGTH_BYTES));
-        byte[] decrypted =
-                cipher.doFinal(
-                        encryptedOrdering,
-                        GCM_NONCE_LENGTH_BYTES,
-                        encryptedOrdering.length - GCM_NONCE_LENGTH_BYTES);
-        return ChunkOrdering.parseFrom(decrypted);
-    }
-
-    // This method is needed because nano protobuf generated classes dont implmenent
-    // .equals
-    private void assertChunkListingsAreEqual(ChunkListing a, ChunkListing b) {
-        byte[] aBytes = MessageNano.toByteArray(a);
-        byte[] bBytes = MessageNano.toByteArray(b);
-
-        assertThat(aBytes).isEqualTo(bBytes);
-    }
-
-    @Implements(BackupFileBuilder.class)
-    public static class ShadowBackupFileBuilder {
-
-        private static BackupFileBuilder sInstance;
-
-        @Implementation
-        public static BackupFileBuilder createForNonIncremental(OutputStream outputStream) {
-            return sInstance;
-        }
-
-        @Implementation
-        public static BackupFileBuilder createForIncremental(
-                OutputStream outputStream, ChunkListing oldChunkListing) {
-            return sInstance;
-        }
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedFullBackupDataProcessorTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedFullBackupDataProcessorTest.java
deleted file mode 100644
index 675d03f..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedFullBackupDataProcessorTest.java
+++ /dev/null
@@ -1,387 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.tasks;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.testng.Assert.assertThrows;
-
-import android.annotation.Nullable;
-import android.app.backup.BackupTransport;
-import android.platform.test.annotations.Presubmit;
-
-import androidx.test.core.app.ApplicationProvider;
-
-import com.android.server.backup.encryption.FullBackupDataProcessor;
-import com.android.server.backup.encryption.chunking.ProtoStore;
-import com.android.server.backup.encryption.client.CryptoBackupServer;
-import com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKey;
-import com.android.server.backup.encryption.keys.TertiaryKeyManager;
-import com.android.server.backup.encryption.protos.nano.ChunksMetadataProto;
-import com.android.server.backup.encryption.testing.QueuingNonAutomaticExecutorService;
-
-import com.google.common.io.ByteStreams;
-import com.google.common.primitives.Bytes;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-import org.robolectric.annotation.Implementation;
-import org.robolectric.annotation.Implements;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.GeneralSecurityException;
-import java.security.SecureRandom;
-
-import javax.crypto.spec.SecretKeySpec;
-
-@RunWith(RobolectricTestRunner.class)
-@Presubmit
-@Config(
-        shadows = {
-            EncryptedFullBackupDataProcessorTest.ShadowEncryptedFullBackupTask.class,
-        })
-public class EncryptedFullBackupDataProcessorTest {
-
-    private static final String KEY_GENERATOR_ALGORITHM = "AES";
-
-    private static final String TEST_PACKAGE = "com.example.app1";
-    private static final byte[] TEST_DATA_1 = {1, 2, 3, 4};
-    private static final byte[] TEST_DATA_2 = {5, 6, 7, 8};
-
-    private final RecoverableKeyStoreSecondaryKey mTestSecondaryKey =
-            new RecoverableKeyStoreSecondaryKey(
-                    /*alias=*/ "test_key",
-                    new SecretKeySpec(
-                            new byte[] {
-                                1, 2, 3,
-                            },
-                            KEY_GENERATOR_ALGORITHM));
-
-    private QueuingNonAutomaticExecutorService mExecutorService;
-    private FullBackupDataProcessor mFullBackupDataProcessor;
-    @Mock private FullBackupDataProcessor.FullBackupCallbacks mFullBackupCallbacks;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-
-        mExecutorService = new QueuingNonAutomaticExecutorService();
-        mFullBackupDataProcessor =
-                new EncryptedFullBackupDataProcessor(
-                        ApplicationProvider.getApplicationContext(),
-                        mExecutorService,
-                        mock(CryptoBackupServer.class),
-                        new SecureRandom(),
-                        mTestSecondaryKey,
-                        TEST_PACKAGE);
-    }
-
-    @After
-    public void tearDown() {
-        ShadowEncryptedFullBackupTask.reset();
-    }
-
-    @Test
-    public void initiate_callTwice_throws() throws Exception {
-        mFullBackupDataProcessor.initiate(new ByteArrayInputStream(new byte[10]));
-
-        assertThrows(
-                IllegalStateException.class,
-                () -> mFullBackupDataProcessor.initiate(new ByteArrayInputStream(new byte[10])));
-    }
-
-    @Test
-    public void pushData_writesDataToTask() throws Exception {
-        byte[] inputData = Bytes.concat(TEST_DATA_1, TEST_DATA_2);
-
-        mFullBackupDataProcessor.initiate(new ByteArrayInputStream(inputData));
-        mFullBackupDataProcessor.start();
-        mFullBackupDataProcessor.pushData(TEST_DATA_1.length);
-        mFullBackupDataProcessor.pushData(TEST_DATA_2.length);
-        finishBackupTask();
-        mFullBackupDataProcessor.finish();
-
-        byte[] result = ByteStreams.toByteArray(ShadowEncryptedFullBackupTask.sInputStream);
-        assertThat(result).isEqualTo(Bytes.concat(TEST_DATA_1, TEST_DATA_2));
-    }
-
-    @Test
-    public void pushData_noError_returnsOk() throws Exception {
-        mFullBackupDataProcessor.initiate(new ByteArrayInputStream(TEST_DATA_1));
-        mFullBackupDataProcessor.start();
-        int result = mFullBackupDataProcessor.pushData(TEST_DATA_1.length);
-        finishBackupTask();
-        mFullBackupDataProcessor.finish();
-
-        assertThat(result).isEqualTo(BackupTransport.TRANSPORT_OK);
-    }
-
-    @Test
-    public void pushData_ioExceptionOnCopy_returnsError() throws Exception {
-        mFullBackupDataProcessor.initiate(new ByteArrayInputStream(TEST_DATA_1));
-        mFullBackupDataProcessor.start();
-
-        // Close the stream so there's an IO error when the processor tries to write to it.
-        ShadowEncryptedFullBackupTask.sInputStream.close();
-        int result = mFullBackupDataProcessor.pushData(TEST_DATA_1.length);
-
-        finishBackupTask();
-        mFullBackupDataProcessor.finish();
-
-        assertThat(result).isEqualTo(BackupTransport.TRANSPORT_ERROR);
-    }
-
-    @Test
-    public void pushData_exceptionDuringUpload_returnsError() throws Exception {
-        byte[] inputData = Bytes.concat(TEST_DATA_1, TEST_DATA_2);
-
-        mFullBackupDataProcessor.initiate(new ByteArrayInputStream(inputData));
-        mFullBackupDataProcessor.start();
-        mFullBackupDataProcessor.pushData(TEST_DATA_1.length);
-        finishBackupTaskWithException(new IOException("Test exception"));
-        int result = mFullBackupDataProcessor.pushData(TEST_DATA_2.length);
-
-        assertThat(result).isEqualTo(BackupTransport.TRANSPORT_ERROR);
-    }
-
-    @Test
-    public void pushData_quotaExceptionDuringUpload_doesNotLogAndReturnsQuotaExceeded()
-            throws Exception {
-        mFullBackupDataProcessor.attachCallbacks(mFullBackupCallbacks);
-        byte[] inputData = Bytes.concat(TEST_DATA_1, TEST_DATA_2);
-
-        mFullBackupDataProcessor.initiate(new ByteArrayInputStream(inputData));
-        mFullBackupDataProcessor.start();
-        mFullBackupDataProcessor.pushData(TEST_DATA_1.length);
-        finishBackupTaskWithException(new SizeQuotaExceededException());
-        int result = mFullBackupDataProcessor.pushData(TEST_DATA_2.length);
-
-        assertThat(result).isEqualTo(BackupTransport.TRANSPORT_QUOTA_EXCEEDED);
-
-        verify(mFullBackupCallbacks, never()).onSuccess();
-        verify(mFullBackupCallbacks, never())
-                .onTransferFailed(); // FullBackupSession will handle this.
-    }
-
-    @Test
-    public void pushData_unexpectedEncryptedBackup_logs() throws Exception {
-        byte[] inputData = Bytes.concat(TEST_DATA_1, TEST_DATA_2);
-
-        mFullBackupDataProcessor.initiate(new ByteArrayInputStream(inputData));
-        mFullBackupDataProcessor.start();
-        mFullBackupDataProcessor.pushData(TEST_DATA_1.length);
-        finishBackupTaskWithException(new GeneralSecurityException());
-        int result = mFullBackupDataProcessor.pushData(TEST_DATA_2.length);
-
-        assertThat(result).isEqualTo(BackupTransport.TRANSPORT_ERROR);
-    }
-
-    @Test
-    public void pushData_permanentExceptionDuringUpload_callsErrorCallback() throws Exception {
-        mFullBackupDataProcessor.attachCallbacks(mFullBackupCallbacks);
-        byte[] inputData = Bytes.concat(TEST_DATA_1, TEST_DATA_2);
-
-        mFullBackupDataProcessor.initiate(new ByteArrayInputStream(inputData));
-        mFullBackupDataProcessor.start();
-        mFullBackupDataProcessor.pushData(TEST_DATA_1.length);
-        finishBackupTaskWithException(new IOException());
-        mFullBackupDataProcessor.pushData(TEST_DATA_2.length);
-
-        verify(mFullBackupCallbacks, never()).onSuccess();
-        verify(mFullBackupCallbacks).onTransferFailed();
-    }
-
-    @Test
-    public void pushData_beforeInitiate_throws() {
-        assertThrows(
-                IllegalStateException.class,
-                () -> mFullBackupDataProcessor.pushData(/*numBytes=*/ 10));
-    }
-
-    @Test
-    public void cancel_cancelsTask() throws Exception {
-        mFullBackupDataProcessor.initiate(new ByteArrayInputStream(TEST_DATA_1));
-        mFullBackupDataProcessor.start();
-        mFullBackupDataProcessor.pushData(TEST_DATA_1.length);
-        mFullBackupDataProcessor.cancel();
-
-        assertThat(ShadowEncryptedFullBackupTask.sCancelled).isTrue();
-    }
-
-    @Test
-    public void cancel_beforeInitiate_throws() {
-        assertThrows(IllegalStateException.class, () -> mFullBackupDataProcessor.cancel());
-    }
-
-    @Test
-    public void finish_noException_returnsTransportOk() throws Exception {
-        mFullBackupDataProcessor.initiate(new ByteArrayInputStream(TEST_DATA_1));
-        mFullBackupDataProcessor.start();
-        mFullBackupDataProcessor.pushData(TEST_DATA_1.length);
-        finishBackupTask();
-        int result = mFullBackupDataProcessor.finish();
-
-        assertThat(result).isEqualTo(BackupTransport.TRANSPORT_OK);
-    }
-
-    @Test
-    public void finish_exceptionDuringUpload_returnsTransportError() throws Exception {
-        mFullBackupDataProcessor.initiate(new ByteArrayInputStream(TEST_DATA_1));
-        mFullBackupDataProcessor.start();
-        mFullBackupDataProcessor.pushData(TEST_DATA_1.length);
-        finishBackupTaskWithException(new IOException("Test exception"));
-        int result = mFullBackupDataProcessor.finish();
-
-        assertThat(result).isEqualTo(BackupTransport.TRANSPORT_ERROR);
-    }
-
-    @Test
-    public void finish_successfulBackup_callsSuccessCallback() throws Exception {
-        mFullBackupDataProcessor.attachCallbacks(mFullBackupCallbacks);
-
-        mFullBackupDataProcessor.initiate(new ByteArrayInputStream(TEST_DATA_1));
-        mFullBackupDataProcessor.start();
-        mFullBackupDataProcessor.pushData(TEST_DATA_1.length);
-        finishBackupTask();
-        mFullBackupDataProcessor.finish();
-
-        verify(mFullBackupCallbacks).onSuccess();
-        verify(mFullBackupCallbacks, never()).onTransferFailed();
-    }
-
-    @Test
-    public void finish_backupFailedWithPermanentError_callsErrorCallback() throws Exception {
-        mFullBackupDataProcessor.attachCallbacks(mFullBackupCallbacks);
-
-        mFullBackupDataProcessor.initiate(new ByteArrayInputStream(TEST_DATA_1));
-        mFullBackupDataProcessor.start();
-        mFullBackupDataProcessor.pushData(TEST_DATA_1.length);
-        finishBackupTaskWithException(new IOException());
-        mFullBackupDataProcessor.finish();
-
-        verify(mFullBackupCallbacks, never()).onSuccess();
-        verify(mFullBackupCallbacks).onTransferFailed();
-    }
-
-    @Test
-    public void finish_backupFailedWithQuotaException_doesNotCallbackAndReturnsQuotaExceeded()
-            throws Exception {
-        mFullBackupDataProcessor.attachCallbacks(mFullBackupCallbacks);
-
-        mFullBackupDataProcessor.initiate(new ByteArrayInputStream(TEST_DATA_1));
-        mFullBackupDataProcessor.start();
-        mFullBackupDataProcessor.pushData(TEST_DATA_1.length);
-        finishBackupTaskWithException(new SizeQuotaExceededException());
-        int result = mFullBackupDataProcessor.finish();
-
-        assertThat(result).isEqualTo(BackupTransport.TRANSPORT_QUOTA_EXCEEDED);
-        verify(mFullBackupCallbacks, never()).onSuccess();
-        verify(mFullBackupCallbacks, never())
-                .onTransferFailed(); // FullBackupSession will handle this.
-    }
-
-    @Test
-    public void finish_beforeInitiate_throws() {
-        assertThrows(IllegalStateException.class, () -> mFullBackupDataProcessor.finish());
-    }
-
-    @Test
-    public void handleCheckSizeRejectionZeroBytes_cancelsTask() throws Exception {
-        mFullBackupDataProcessor.initiate(new ByteArrayInputStream(new byte[10]));
-        mFullBackupDataProcessor.start();
-        mFullBackupDataProcessor.handleCheckSizeRejectionZeroBytes();
-
-        assertThat(ShadowEncryptedFullBackupTask.sCancelled).isTrue();
-    }
-
-    @Test
-    public void handleCheckSizeRejectionQuotaExceeded_cancelsTask() throws Exception {
-        mFullBackupDataProcessor.initiate(new ByteArrayInputStream(TEST_DATA_1));
-        mFullBackupDataProcessor.start();
-        mFullBackupDataProcessor.pushData(TEST_DATA_1.length);
-        mFullBackupDataProcessor.handleCheckSizeRejectionQuotaExceeded();
-
-        assertThat(ShadowEncryptedFullBackupTask.sCancelled).isTrue();
-    }
-
-    @Test
-    public void handleSendBytesQuotaExceeded_cancelsTask() throws Exception {
-        mFullBackupDataProcessor.initiate(new ByteArrayInputStream(TEST_DATA_1));
-        mFullBackupDataProcessor.start();
-        mFullBackupDataProcessor.pushData(TEST_DATA_1.length);
-        mFullBackupDataProcessor.handleSendBytesQuotaExceeded();
-
-        assertThat(ShadowEncryptedFullBackupTask.sCancelled).isTrue();
-    }
-
-    private void finishBackupTask() {
-        mExecutorService.runNext();
-    }
-
-    private void finishBackupTaskWithException(Exception exception) {
-        ShadowEncryptedFullBackupTask.sOnCallException = exception;
-        finishBackupTask();
-    }
-
-    @Implements(EncryptedFullBackupTask.class)
-    public static class ShadowEncryptedFullBackupTask {
-
-        private static InputStream sInputStream;
-        @Nullable private static Exception sOnCallException;
-        private static boolean sCancelled;
-
-        public void __constructor__(
-                ProtoStore<ChunksMetadataProto.ChunkListing> chunkListingStore,
-                TertiaryKeyManager tertiaryKeyManager,
-                EncryptedBackupTask task,
-                InputStream inputStream,
-                String packageName,
-                SecureRandom secureRandom) {
-            sInputStream = inputStream;
-        }
-
-        @Implementation
-        public Void call() throws Exception {
-            if (sOnCallException != null) {
-                throw sOnCallException;
-            }
-
-            return null;
-        }
-
-        @Implementation
-        public void cancel() {
-            sCancelled = true;
-        }
-
-        public static void reset() {
-            sOnCallException = null;
-            sCancelled = false;
-        }
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedFullBackupTaskTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedFullBackupTaskTest.java
deleted file mode 100644
index bfc5d0d..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedFullBackupTaskTest.java
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.tasks;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.testng.Assert.assertThrows;
-
-import com.android.server.backup.encryption.chunk.ChunkHash;
-import com.android.server.backup.encryption.chunking.ProtoStore;
-import com.android.server.backup.encryption.chunking.cdc.FingerprintMixer;
-import com.android.server.backup.encryption.keys.TertiaryKeyManager;
-import com.android.server.backup.encryption.protos.nano.ChunksMetadataProto;
-import com.android.server.backup.encryption.protos.nano.ChunksMetadataProto.ChunkListing;
-import com.android.server.backup.encryption.protos.nano.WrappedKeyProto.WrappedKey;
-import com.android.server.backup.testing.CryptoTestUtils;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.GeneralSecurityException;
-import java.security.SecureRandom;
-import java.util.Arrays;
-import java.util.Optional;
-
-import javax.crypto.SecretKey;
-
-@Config(shadows = {EncryptedBackupTaskTest.ShadowBackupFileBuilder.class})
-@RunWith(RobolectricTestRunner.class)
-public class EncryptedFullBackupTaskTest {
-    private static final String TEST_PACKAGE_NAME = "com.example.package";
-    private static final byte[] TEST_EXISTING_FINGERPRINT_MIXER_SALT =
-            Arrays.copyOf(new byte[] {11}, ChunkHash.HASH_LENGTH_BYTES);
-    private static final byte[] TEST_GENERATED_FINGERPRINT_MIXER_SALT =
-            Arrays.copyOf(new byte[] {22}, ChunkHash.HASH_LENGTH_BYTES);
-    private static final ChunkHash TEST_CHUNK_HASH_1 =
-            new ChunkHash(Arrays.copyOf(new byte[] {1}, ChunkHash.HASH_LENGTH_BYTES));
-    private static final ChunkHash TEST_CHUNK_HASH_2 =
-            new ChunkHash(Arrays.copyOf(new byte[] {2}, ChunkHash.HASH_LENGTH_BYTES));
-    private static final int TEST_CHUNK_LENGTH_1 = 20;
-    private static final int TEST_CHUNK_LENGTH_2 = 40;
-
-    @Mock private ProtoStore<ChunkListing> mChunkListingStore;
-    @Mock private TertiaryKeyManager mTertiaryKeyManager;
-    @Mock private InputStream mInputStream;
-    @Mock private EncryptedBackupTask mEncryptedBackupTask;
-    @Mock private SecretKey mTertiaryKey;
-    @Mock private SecureRandom mSecureRandom;
-
-    private EncryptedFullBackupTask mTask;
-    private ChunkListing mOldChunkListing;
-    private ChunkListing mNewChunkListing;
-    private WrappedKey mWrappedTertiaryKey;
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        mWrappedTertiaryKey = new WrappedKey();
-        when(mTertiaryKeyManager.getKey()).thenReturn(mTertiaryKey);
-        when(mTertiaryKeyManager.getWrappedKey()).thenReturn(mWrappedTertiaryKey);
-
-        mOldChunkListing =
-                CryptoTestUtils.newChunkListing(
-                        /* docId */ null,
-                        TEST_EXISTING_FINGERPRINT_MIXER_SALT,
-                        ChunksMetadataProto.AES_256_GCM,
-                        ChunksMetadataProto.CHUNK_ORDERING_TYPE_UNSPECIFIED,
-                        CryptoTestUtils.newChunk(TEST_CHUNK_HASH_1.getHash(), TEST_CHUNK_LENGTH_1));
-        mNewChunkListing =
-                CryptoTestUtils.newChunkListing(
-                        /* docId */ null,
-                        /* fingerprintSalt */ null,
-                        ChunksMetadataProto.AES_256_GCM,
-                        ChunksMetadataProto.CHUNK_ORDERING_TYPE_UNSPECIFIED,
-                        CryptoTestUtils.newChunk(TEST_CHUNK_HASH_1.getHash(), TEST_CHUNK_LENGTH_1),
-                        CryptoTestUtils.newChunk(TEST_CHUNK_HASH_2.getHash(), TEST_CHUNK_LENGTH_2));
-        when(mEncryptedBackupTask.performNonIncrementalBackup(any(), any(), any()))
-                .thenReturn(mNewChunkListing);
-        when(mEncryptedBackupTask.performIncrementalBackup(any(), any(), any()))
-                .thenReturn(mNewChunkListing);
-        when(mChunkListingStore.loadProto(TEST_PACKAGE_NAME)).thenReturn(Optional.empty());
-
-        doAnswer(invocation -> {
-            byte[] byteArray = (byte[]) invocation.getArguments()[0];
-            System.arraycopy(
-                    TEST_GENERATED_FINGERPRINT_MIXER_SALT,
-                    /* srcPos */ 0,
-                    byteArray,
-                    /* destPos */ 0,
-                    FingerprintMixer.SALT_LENGTH_BYTES);
-            return null;
-        })
-                .when(mSecureRandom)
-                .nextBytes(any(byte[].class));
-
-        mTask =
-                new EncryptedFullBackupTask(
-                        mChunkListingStore,
-                        mTertiaryKeyManager,
-                        mEncryptedBackupTask,
-                        mInputStream,
-                        TEST_PACKAGE_NAME,
-                        mSecureRandom);
-    }
-
-    @Test
-    public void call_existingChunkListingButTertiaryKeyRotated_performsNonIncrementalBackup()
-            throws Exception {
-        when(mTertiaryKeyManager.wasKeyRotated()).thenReturn(true);
-        when(mChunkListingStore.loadProto(TEST_PACKAGE_NAME))
-                .thenReturn(Optional.of(mOldChunkListing));
-
-        mTask.call();
-
-        verify(mEncryptedBackupTask)
-                .performNonIncrementalBackup(
-                        eq(mTertiaryKey),
-                        eq(mWrappedTertiaryKey),
-                        eq(TEST_GENERATED_FINGERPRINT_MIXER_SALT));
-    }
-
-    @Test
-    public void call_noExistingChunkListing_performsNonIncrementalBackup() throws Exception {
-        when(mChunkListingStore.loadProto(TEST_PACKAGE_NAME)).thenReturn(Optional.empty());
-        mTask.call();
-        verify(mEncryptedBackupTask)
-                .performNonIncrementalBackup(
-                        eq(mTertiaryKey),
-                        eq(mWrappedTertiaryKey),
-                        eq(TEST_GENERATED_FINGERPRINT_MIXER_SALT));
-    }
-
-    @Test
-    public void call_existingChunkListing_performsIncrementalBackup() throws Exception {
-        when(mChunkListingStore.loadProto(TEST_PACKAGE_NAME))
-                .thenReturn(Optional.of(mOldChunkListing));
-        mTask.call();
-        verify(mEncryptedBackupTask)
-                .performIncrementalBackup(
-                        eq(mTertiaryKey), eq(mWrappedTertiaryKey), eq(mOldChunkListing));
-    }
-
-    @Test
-    public void
-            call_existingChunkListingWithNoFingerprintMixerSalt_doesntSetSaltBeforeIncBackup()
-                    throws Exception {
-        mOldChunkListing.fingerprintMixerSalt = new byte[0];
-        when(mChunkListingStore.loadProto(TEST_PACKAGE_NAME))
-                .thenReturn(Optional.of(mOldChunkListing));
-
-        mTask.call();
-
-        verify(mEncryptedBackupTask)
-                .performIncrementalBackup(
-                        eq(mTertiaryKey), eq(mWrappedTertiaryKey), eq(mOldChunkListing));
-    }
-
-    @Test
-    public void call_noExistingChunkListing_storesNewChunkListing() throws Exception {
-        when(mChunkListingStore.loadProto(TEST_PACKAGE_NAME)).thenReturn(Optional.empty());
-        mTask.call();
-        verify(mChunkListingStore).saveProto(TEST_PACKAGE_NAME, mNewChunkListing);
-    }
-
-    @Test
-    public void call_existingChunkListing_storesNewChunkListing() throws Exception {
-        when(mChunkListingStore.loadProto(TEST_PACKAGE_NAME))
-                .thenReturn(Optional.of(mOldChunkListing));
-        mTask.call();
-        verify(mChunkListingStore).saveProto(TEST_PACKAGE_NAME, mNewChunkListing);
-    }
-
-    @Test
-    public void call_exceptionDuringBackup_doesNotSaveNewChunkListing() throws Exception {
-        when(mChunkListingStore.loadProto(TEST_PACKAGE_NAME)).thenReturn(Optional.empty());
-        when(mEncryptedBackupTask.performNonIncrementalBackup(any(), any(), any()))
-                .thenThrow(GeneralSecurityException.class);
-
-        assertThrows(Exception.class, () -> mTask.call());
-
-        assertThat(mChunkListingStore.loadProto(TEST_PACKAGE_NAME).isPresent()).isFalse();
-    }
-
-    @Test
-    public void call_incrementalThrowsPermanentException_clearsState() throws Exception {
-        when(mChunkListingStore.loadProto(TEST_PACKAGE_NAME))
-                .thenReturn(Optional.of(mOldChunkListing));
-        when(mEncryptedBackupTask.performIncrementalBackup(any(), any(), any()))
-                .thenThrow(IOException.class);
-
-        assertThrows(IOException.class, () -> mTask.call());
-
-        verify(mChunkListingStore).deleteProto(TEST_PACKAGE_NAME);
-    }
-
-    @Test
-    public void call_closesInputStream() throws Exception {
-        mTask.call();
-        verify(mInputStream).close();
-    }
-
-    @Test
-    public void cancel_cancelsTask() throws Exception {
-        mTask.cancel();
-        verify(mEncryptedBackupTask).cancel();
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedFullRestoreTaskTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedFullRestoreTaskTest.java
deleted file mode 100644
index 0affacd..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedFullRestoreTaskTest.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.tasks;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doAnswer;
-
-import static java.util.stream.Collectors.toList;
-
-import com.android.server.backup.encryption.FullRestoreDownloader;
-
-import com.google.common.io.Files;
-import com.google.common.primitives.Bytes;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
-
-@RunWith(RobolectricTestRunner.class)
-public class EncryptedFullRestoreTaskTest {
-    private static final int TEST_BUFFER_SIZE = 10;
-    private static final byte[] TEST_ENCRYPTED_DATA = {1, 2, 3, 4, 5, 6};
-    private static final byte[] TEST_DECRYPTED_DATA = fakeDecrypt(TEST_ENCRYPTED_DATA);
-
-    @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder();
-
-    @Mock private BackupFileDecryptorTask mDecryptorTask;
-
-    private File mFolder;
-    private FakeFullRestoreDownloader mFullRestorePackageWrapper;
-    private EncryptedFullRestoreTask mTask;
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        mFolder = temporaryFolder.newFolder();
-        mFullRestorePackageWrapper = new FakeFullRestoreDownloader(TEST_ENCRYPTED_DATA);
-
-        doAnswer(
-            invocation -> {
-                File source = invocation.getArgument(0);
-                DecryptedChunkOutput target = invocation.getArgument(1);
-                byte[] decrypted = fakeDecrypt(Files.toByteArray(source));
-                target.open();
-                target.processChunk(decrypted, decrypted.length);
-                target.close();
-                return null;
-            })
-                .when(mDecryptorTask)
-                .decryptFile(any(), any());
-
-        mTask = new EncryptedFullRestoreTask(mFolder, mFullRestorePackageWrapper, mDecryptorTask);
-    }
-
-    @Test
-    public void readNextChunk_downloadsAndDecryptsBackup() throws Exception {
-        ByteArrayOutputStream decryptedOutput = new ByteArrayOutputStream();
-
-        byte[] buffer = new byte[TEST_BUFFER_SIZE];
-        int bytesRead = mTask.readNextChunk(buffer);
-        while (bytesRead != -1) {
-            decryptedOutput.write(buffer, 0, bytesRead);
-            bytesRead = mTask.readNextChunk(buffer);
-        }
-
-        assertThat(decryptedOutput.toByteArray()).isEqualTo(TEST_DECRYPTED_DATA);
-    }
-
-    @Test
-    public void finish_deletesTemporaryFiles() throws Exception {
-        mTask.readNextChunk(new byte[10]);
-        mTask.finish(FullRestoreDownloader.FinishType.UNKNOWN_FINISH);
-
-        assertThat(mFolder.listFiles()).isEmpty();
-    }
-
-    /** Fake package wrapper which returns data from a byte array. */
-    private static class FakeFullRestoreDownloader extends FullRestoreDownloader {
-        private final ByteArrayInputStream mData;
-
-        FakeFullRestoreDownloader(byte[] data) {
-            // We override all methods of the superclass, so it does not require any collaborators.
-            super();
-            mData = new ByteArrayInputStream(data);
-        }
-
-        @Override
-        public int readNextChunk(byte[] buffer) throws IOException {
-            return mData.read(buffer);
-        }
-
-        @Override
-        public void finish(FinishType finishType) {
-            // Nothing to do.
-        }
-    }
-
-    /** Fake decrypts a byte array by subtracting 1 from each byte. */
-    private static byte[] fakeDecrypt(byte[] input) {
-        return Bytes.toArray(Bytes.asList(input).stream().map(b -> b + 1).collect(toList()));
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedKvBackupTaskTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedKvBackupTaskTest.java
deleted file mode 100644
index 222b882..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedKvBackupTaskTest.java
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.tasks;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertThrows;
-
-import android.app.Application;
-import android.util.Pair;
-
-import androidx.test.core.app.ApplicationProvider;
-
-import com.android.server.backup.encryption.chunk.ChunkHash;
-import com.android.server.backup.encryption.chunking.ProtoStore;
-import com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKey;
-import com.android.server.backup.encryption.keys.TertiaryKeyManager;
-import com.android.server.backup.encryption.kv.KeyValueListingBuilder;
-import com.android.server.backup.encryption.protos.nano.ChunksMetadataProto;
-import com.android.server.backup.encryption.protos.nano.KeyValueListingProto;
-import com.android.server.backup.encryption.protos.nano.WrappedKeyProto;
-import com.android.server.backup.testing.CryptoTestUtils;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import javax.crypto.SecretKey;
-
-
-@RunWith(RobolectricTestRunner.class)
-public class EncryptedKvBackupTaskTest {
-    private static final boolean INCREMENTAL = true;
-    private static final boolean NON_INCREMENTAL = false;
-
-    private static final String TEST_PACKAGE_1 = "com.example.app1";
-    private static final String TEST_KEY_1 = "key_1";
-    private static final String TEST_KEY_2 = "key_2";
-    private static final ChunkHash TEST_HASH_1 =
-            new ChunkHash(Arrays.copyOf(new byte[] {1}, ChunkHash.HASH_LENGTH_BYTES));
-    private static final ChunkHash TEST_HASH_2 =
-            new ChunkHash(Arrays.copyOf(new byte[] {2}, ChunkHash.HASH_LENGTH_BYTES));
-    private static final int TEST_LENGTH_1 = 200;
-    private static final int TEST_LENGTH_2 = 300;
-
-    @Rule public TemporaryFolder mTemporaryFolder = new TemporaryFolder();
-
-    @Captor private ArgumentCaptor<ChunksMetadataProto.ChunkListing> mChunkListingCaptor;
-
-    @Mock private TertiaryKeyManager mTertiaryKeyManager;
-    @Mock private RecoverableKeyStoreSecondaryKey mSecondaryKey;
-    @Mock private ProtoStore<KeyValueListingProto.KeyValueListing> mKeyValueListingStore;
-    @Mock private ProtoStore<ChunksMetadataProto.ChunkListing> mChunkListingStore;
-    @Mock private KvBackupEncrypter mKvBackupEncrypter;
-    @Mock private EncryptedBackupTask mEncryptedBackupTask;
-    @Mock private SecretKey mTertiaryKey;
-
-    private WrappedKeyProto.WrappedKey mWrappedTertiaryKey;
-    private KeyValueListingProto.KeyValueListing mNewKeyValueListing;
-    private ChunksMetadataProto.ChunkListing mNewChunkListing;
-    private EncryptedKvBackupTask mTask;
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        Application application = ApplicationProvider.getApplicationContext();
-        mKeyValueListingStore = ProtoStore.createKeyValueListingStore(application);
-        mChunkListingStore = ProtoStore.createChunkListingStore(application);
-
-        mWrappedTertiaryKey = new WrappedKeyProto.WrappedKey();
-
-        when(mTertiaryKeyManager.wasKeyRotated()).thenReturn(false);
-        when(mTertiaryKeyManager.getKey()).thenReturn(mTertiaryKey);
-        when(mTertiaryKeyManager.getWrappedKey()).thenReturn(mWrappedTertiaryKey);
-
-        mNewKeyValueListing =
-                createKeyValueListing(
-                        CryptoTestUtils.mapOf(
-                                new Pair<>(TEST_KEY_1, TEST_HASH_1),
-                                new Pair<>(TEST_KEY_2, TEST_HASH_2)));
-        mNewChunkListing =
-                createChunkListing(
-                        CryptoTestUtils.mapOf(
-                                new Pair<>(TEST_HASH_1, TEST_LENGTH_1),
-                                new Pair<>(TEST_HASH_2, TEST_LENGTH_2)));
-        when(mKvBackupEncrypter.getNewKeyValueListing()).thenReturn(mNewKeyValueListing);
-        when(mEncryptedBackupTask.performIncrementalBackup(
-                        eq(mTertiaryKey), eq(mWrappedTertiaryKey), any()))
-                .thenReturn(mNewChunkListing);
-        when(mEncryptedBackupTask.performNonIncrementalBackup(
-                        eq(mTertiaryKey), eq(mWrappedTertiaryKey), any()))
-                .thenReturn(mNewChunkListing);
-
-        mTask =
-                new EncryptedKvBackupTask(
-                        mTertiaryKeyManager,
-                        mKeyValueListingStore,
-                        mSecondaryKey,
-                        mChunkListingStore,
-                        mKvBackupEncrypter,
-                        mEncryptedBackupTask,
-                        TEST_PACKAGE_1);
-    }
-
-    @Test
-    public void testPerformBackup_rotationRequired_deletesListings() throws Exception {
-        mKeyValueListingStore.saveProto(
-                TEST_PACKAGE_1,
-                createKeyValueListing(CryptoTestUtils.mapOf(new Pair<>(TEST_KEY_1, TEST_HASH_1))));
-        mChunkListingStore.saveProto(
-                TEST_PACKAGE_1,
-                createChunkListing(CryptoTestUtils.mapOf(new Pair<>(TEST_HASH_1, TEST_LENGTH_1))));
-
-        when(mTertiaryKeyManager.wasKeyRotated()).thenReturn(true);
-        // Throw an IOException so it aborts before saving the new listings.
-        when(mEncryptedBackupTask.performNonIncrementalBackup(any(), any(), any()))
-                .thenThrow(IOException.class);
-
-        assertThrows(IOException.class, () -> mTask.performBackup(NON_INCREMENTAL));
-
-        assertFalse(mKeyValueListingStore.loadProto(TEST_PACKAGE_1).isPresent());
-        assertFalse(mChunkListingStore.loadProto(TEST_PACKAGE_1).isPresent());
-    }
-
-    @Test
-    public void testPerformBackup_rotationRequiredButIncremental_throws() throws Exception {
-        mKeyValueListingStore.saveProto(
-                TEST_PACKAGE_1,
-                createKeyValueListing(CryptoTestUtils.mapOf(new Pair<>(TEST_KEY_1, TEST_HASH_1))));
-        mChunkListingStore.saveProto(
-                TEST_PACKAGE_1,
-                createChunkListing(CryptoTestUtils.mapOf(new Pair<>(TEST_HASH_1, TEST_LENGTH_1))));
-
-        when(mTertiaryKeyManager.wasKeyRotated()).thenReturn(true);
-
-        assertThrows(NonIncrementalBackupRequiredException.class,
-                () -> mTask.performBackup(INCREMENTAL));
-    }
-
-    @Test
-    public void testPerformBackup_rotationRequiredAndNonIncremental_performsNonIncrementalBackup()
-            throws Exception {
-        mKeyValueListingStore.saveProto(
-                TEST_PACKAGE_1,
-                createKeyValueListing(CryptoTestUtils.mapOf(new Pair<>(TEST_KEY_1, TEST_HASH_1))));
-        mChunkListingStore.saveProto(
-                TEST_PACKAGE_1,
-                createChunkListing(CryptoTestUtils.mapOf(new Pair<>(TEST_HASH_1, TEST_LENGTH_1))));
-
-        when(mTertiaryKeyManager.wasKeyRotated()).thenReturn(true);
-
-        mTask.performBackup(NON_INCREMENTAL);
-
-        verify(mEncryptedBackupTask)
-                .performNonIncrementalBackup(eq(mTertiaryKey), eq(mWrappedTertiaryKey), any());
-    }
-
-    @Test
-    public void testPerformBackup_existingStateButNonIncremental_deletesListings() throws Exception {
-        mKeyValueListingStore.saveProto(
-                TEST_PACKAGE_1,
-                createKeyValueListing(CryptoTestUtils.mapOf(new Pair<>(TEST_KEY_1, TEST_HASH_1))));
-        mChunkListingStore.saveProto(
-                TEST_PACKAGE_1,
-                createChunkListing(CryptoTestUtils.mapOf(new Pair<>(TEST_HASH_1, TEST_LENGTH_1))));
-
-        // Throw an IOException so it aborts before saving the new listings.
-        when(mEncryptedBackupTask.performNonIncrementalBackup(any(), any(), any()))
-                .thenThrow(IOException.class);
-
-        assertThrows(IOException.class, () -> mTask.performBackup(NON_INCREMENTAL));
-
-        assertFalse(mKeyValueListingStore.loadProto(TEST_PACKAGE_1).isPresent());
-        assertFalse(mChunkListingStore.loadProto(TEST_PACKAGE_1).isPresent());
-    }
-
-    @Test
-    public void testPerformBackup_keyValueListingMissing_deletesChunkListingAndPerformsNonIncremental()
-            throws Exception {
-        mChunkListingStore.saveProto(
-                TEST_PACKAGE_1,
-                createChunkListing(CryptoTestUtils.mapOf(new Pair<>(TEST_HASH_1, TEST_LENGTH_1))));
-
-        // Throw an IOException so it aborts before saving the new listings.
-        when(mEncryptedBackupTask.performNonIncrementalBackup(any(), any(), any()))
-                .thenThrow(IOException.class);
-
-        assertThrows(IOException.class, () -> mTask.performBackup(NON_INCREMENTAL));
-
-        verify(mEncryptedBackupTask).performNonIncrementalBackup(any(), any(), any());
-        assertFalse(mKeyValueListingStore.loadProto(TEST_PACKAGE_1).isPresent());
-        assertFalse(mChunkListingStore.loadProto(TEST_PACKAGE_1).isPresent());
-    }
-
-    @Test
-    public void testPerformBackup_chunkListingMissing_deletesKeyValueListingAndPerformsNonIncremental()
-            throws Exception {
-        mKeyValueListingStore.saveProto(
-                TEST_PACKAGE_1,
-                createKeyValueListing(CryptoTestUtils.mapOf(new Pair<>(TEST_KEY_1, TEST_HASH_1))));
-
-        // Throw an IOException so it aborts before saving the new listings.
-        when(mEncryptedBackupTask.performNonIncrementalBackup(any(), any(), any()))
-                .thenThrow(IOException.class);
-
-        assertThrows(IOException.class, () -> mTask.performBackup(NON_INCREMENTAL));
-
-        verify(mEncryptedBackupTask).performNonIncrementalBackup(any(), any(), any());
-        assertFalse(mKeyValueListingStore.loadProto(TEST_PACKAGE_1).isPresent());
-        assertFalse(mChunkListingStore.loadProto(TEST_PACKAGE_1).isPresent());
-    }
-
-    @Test
-    public void testPerformBackup_existingStateAndIncremental_performsIncrementalBackup()
-            throws Exception {
-        mKeyValueListingStore.saveProto(
-                TEST_PACKAGE_1,
-                createKeyValueListing(CryptoTestUtils.mapOf(new Pair<>(TEST_KEY_1, TEST_HASH_1))));
-        ChunksMetadataProto.ChunkListing oldChunkListing =
-                createChunkListing(CryptoTestUtils.mapOf(new Pair<>(TEST_HASH_1, TEST_LENGTH_1)));
-        mChunkListingStore.saveProto(TEST_PACKAGE_1, oldChunkListing);
-
-        mTask.performBackup(INCREMENTAL);
-
-        verify(mEncryptedBackupTask)
-                .performIncrementalBackup(
-                        eq(mTertiaryKey), eq(mWrappedTertiaryKey), mChunkListingCaptor.capture());
-        assertChunkListingsEqual(mChunkListingCaptor.getValue(), oldChunkListing);
-    }
-
-    @Test
-    public void testPerformBackup_noExistingStateAndNonIncremental_performsNonIncrementalBackup()
-            throws Exception {
-        mTask.performBackup(NON_INCREMENTAL);
-
-        verify(mEncryptedBackupTask)
-                .performNonIncrementalBackup(eq(mTertiaryKey), eq(mWrappedTertiaryKey), eq(null));
-    }
-
-    @Test
-    public void testPerformBackup_incremental_savesNewListings() throws Exception {
-        mKeyValueListingStore.saveProto(
-                TEST_PACKAGE_1,
-                createKeyValueListing(CryptoTestUtils.mapOf(new Pair<>(TEST_KEY_1, TEST_HASH_1))));
-        mChunkListingStore.saveProto(
-                TEST_PACKAGE_1,
-                createChunkListing(CryptoTestUtils.mapOf(new Pair<>(TEST_HASH_1, TEST_LENGTH_1))));
-
-        mTask.performBackup(INCREMENTAL);
-
-        KeyValueListingProto.KeyValueListing actualKeyValueListing =
-                mKeyValueListingStore.loadProto(TEST_PACKAGE_1).get();
-        ChunksMetadataProto.ChunkListing actualChunkListing =
-                mChunkListingStore.loadProto(TEST_PACKAGE_1).get();
-        assertKeyValueListingsEqual(actualKeyValueListing, mNewKeyValueListing);
-        assertChunkListingsEqual(actualChunkListing, mNewChunkListing);
-    }
-
-    @Test
-    public void testPerformBackup_nonIncremental_savesNewListings() throws Exception {
-        mTask.performBackup(NON_INCREMENTAL);
-
-        KeyValueListingProto.KeyValueListing actualKeyValueListing =
-                mKeyValueListingStore.loadProto(TEST_PACKAGE_1).get();
-        ChunksMetadataProto.ChunkListing actualChunkListing =
-                mChunkListingStore.loadProto(TEST_PACKAGE_1).get();
-        assertKeyValueListingsEqual(actualKeyValueListing, mNewKeyValueListing);
-        assertChunkListingsEqual(actualChunkListing, mNewChunkListing);
-    }
-
-    private static KeyValueListingProto.KeyValueListing createKeyValueListing(
-            Map<String, ChunkHash> pairs) {
-        return new KeyValueListingBuilder().addAll(pairs).build();
-    }
-
-    private static ChunksMetadataProto.ChunkListing createChunkListing(
-            Map<ChunkHash, Integer> chunks) {
-        ChunksMetadataProto.Chunk[] listingChunks = new ChunksMetadataProto.Chunk[chunks.size()];
-        int chunksAdded = 0;
-        for (Entry<ChunkHash, Integer> entry : chunks.entrySet()) {
-            listingChunks[chunksAdded] = CryptoTestUtils.newChunk(entry.getKey(), entry.getValue());
-            chunksAdded++;
-        }
-        return CryptoTestUtils.newChunkListingWithoutDocId(
-                /* fingerprintSalt */ new byte[0],
-                ChunksMetadataProto.AES_256_GCM,
-                ChunksMetadataProto.CHUNK_ORDERING_TYPE_UNSPECIFIED,
-                listingChunks);
-    }
-
-    private static void assertKeyValueListingsEqual(
-            KeyValueListingProto.KeyValueListing actual,
-            KeyValueListingProto.KeyValueListing expected) {
-        KeyValueListingProto.KeyValueEntry[] actualEntries = actual.entries;
-        KeyValueListingProto.KeyValueEntry[] expectedEntries = expected.entries;
-        assertThat(actualEntries.length).isEqualTo(expectedEntries.length);
-        for (int i = 0; i < actualEntries.length; i++) {
-            assertWithMessage("entry " + i)
-                    .that(actualEntries[i].key)
-                    .isEqualTo(expectedEntries[i].key);
-            assertWithMessage("entry " + i)
-                    .that(actualEntries[i].hash)
-                    .isEqualTo(expectedEntries[i].hash);
-        }
-    }
-
-    private static void assertChunkListingsEqual(
-            ChunksMetadataProto.ChunkListing actual, ChunksMetadataProto.ChunkListing expected) {
-        ChunksMetadataProto.Chunk[] actualChunks = actual.chunks;
-        ChunksMetadataProto.Chunk[] expectedChunks = expected.chunks;
-        assertThat(actualChunks.length).isEqualTo(expectedChunks.length);
-        for (int i = 0; i < actualChunks.length; i++) {
-            assertWithMessage("chunk " + i)
-                    .that(actualChunks[i].hash)
-                    .isEqualTo(expectedChunks[i].hash);
-            assertWithMessage("chunk " + i)
-                    .that(actualChunks[i].length)
-                    .isEqualTo(expectedChunks[i].length);
-        }
-        assertThat(actual.cipherType).isEqualTo(expected.cipherType);
-        assertThat(actual.documentId)
-                .isEqualTo(expected.documentId == null ? "" : expected.documentId);
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedKvRestoreTaskTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedKvRestoreTaskTest.java
deleted file mode 100644
index 6666d95..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedKvRestoreTaskTest.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.tasks;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.when;
-import static org.testng.Assert.assertThrows;
-
-import android.os.ParcelFileDescriptor;
-
-import com.android.server.backup.encryption.chunk.ChunkHash;
-import com.android.server.backup.encryption.chunking.ChunkHasher;
-import com.android.server.backup.testing.CryptoTestUtils;
-import com.android.server.testing.shadows.DataEntity;
-import com.android.server.testing.shadows.ShadowBackupDataOutput;
-
-import com.google.protobuf.nano.MessageNano;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-@Config(shadows = {ShadowBackupDataOutput.class})
-@RunWith(RobolectricTestRunner.class)
-public class EncryptedKvRestoreTaskTest {
-    private static final String TEST_KEY_1 = "test_key_1";
-    private static final String TEST_KEY_2 = "test_key_2";
-    private static final String TEST_KEY_3 = "test_key_3";
-    private static final byte[] TEST_VALUE_1 = {1, 2, 3};
-    private static final byte[] TEST_VALUE_2 = {4, 5, 6};
-    private static final byte[] TEST_VALUE_3 = {20, 25, 30, 35};
-
-    @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder();
-
-    private File temporaryDirectory;
-
-    @Mock private ParcelFileDescriptor mParcelFileDescriptor;
-    @Mock private ChunkHasher mChunkHasher;
-    @Mock private FullRestoreToFileTask mFullRestoreToFileTask;
-    @Mock private BackupFileDecryptorTask mBackupFileDecryptorTask;
-
-    private EncryptedKvRestoreTask task;
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        when(mChunkHasher.computeHash(any()))
-                .thenAnswer(invocation -> fakeHash(invocation.getArgument(0)));
-        doAnswer(invocation -> writeTestPairsToFile(invocation.getArgument(0)))
-                .when(mFullRestoreToFileTask)
-                .restoreToFile(any());
-        doAnswer(
-                        invocation ->
-                                readPairsFromFile(
-                                        invocation.getArgument(0), invocation.getArgument(1)))
-                .when(mBackupFileDecryptorTask)
-                .decryptFile(any(), any());
-
-        temporaryDirectory = temporaryFolder.newFolder();
-        task =
-                new EncryptedKvRestoreTask(
-                        temporaryDirectory,
-                        mChunkHasher,
-                        mFullRestoreToFileTask,
-                        mBackupFileDecryptorTask);
-    }
-
-    @Test
-    public void testGetRestoreData_writesPairsToOutputInOrder() throws Exception {
-        task.getRestoreData(mParcelFileDescriptor);
-
-        assertThat(ShadowBackupDataOutput.getEntities())
-                .containsExactly(
-                        new DataEntity(TEST_KEY_1, TEST_VALUE_1),
-                        new DataEntity(TEST_KEY_2, TEST_VALUE_2),
-                        new DataEntity(TEST_KEY_3, TEST_VALUE_3))
-                .inOrder();
-    }
-
-    @Test
-    public void testGetRestoreData_exceptionDuringDecryption_throws() throws Exception {
-        doThrow(IOException.class).when(mBackupFileDecryptorTask).decryptFile(any(), any());
-        assertThrows(IOException.class, () -> task.getRestoreData(mParcelFileDescriptor));
-    }
-
-    @Test
-    public void testGetRestoreData_exceptionDuringDownload_throws() throws Exception {
-        doThrow(IOException.class).when(mFullRestoreToFileTask).restoreToFile(any());
-        assertThrows(IOException.class, () -> task.getRestoreData(mParcelFileDescriptor));
-    }
-
-    @Test
-    public void testGetRestoreData_exceptionDuringDecryption_deletesTemporaryFiles() throws Exception {
-        doThrow(InvalidKeyException.class).when(mBackupFileDecryptorTask).decryptFile(any(), any());
-        assertThrows(InvalidKeyException.class, () -> task.getRestoreData(mParcelFileDescriptor));
-        assertThat(temporaryDirectory.listFiles()).isEmpty();
-    }
-
-    @Test
-    public void testGetRestoreData_exceptionDuringDownload_deletesTemporaryFiles() throws Exception {
-        doThrow(IOException.class).when(mFullRestoreToFileTask).restoreToFile(any());
-        assertThrows(IOException.class, () -> task.getRestoreData(mParcelFileDescriptor));
-        assertThat(temporaryDirectory.listFiles()).isEmpty();
-    }
-
-    private static Void writeTestPairsToFile(File file) throws IOException {
-        // Write the pairs out of order to check the task sorts them.
-        Set<byte[]> pairs =
-                new HashSet<>(
-                        Arrays.asList(
-                                createPair(TEST_KEY_1, TEST_VALUE_1),
-                                createPair(TEST_KEY_3, TEST_VALUE_3),
-                                createPair(TEST_KEY_2, TEST_VALUE_2)));
-
-        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file))) {
-            oos.writeObject(pairs);
-        }
-        return null;
-    }
-
-    private static Void readPairsFromFile(File file, DecryptedChunkOutput decryptedChunkOutput)
-            throws IOException, ClassNotFoundException, InvalidKeyException,
-                    NoSuchAlgorithmException {
-        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
-                DecryptedChunkOutput output = decryptedChunkOutput.open()) {
-            Set<byte[]> pairs = readPairs(ois);
-            for (byte[] pair : pairs) {
-                output.processChunk(pair, pair.length);
-            }
-        }
-
-        return null;
-    }
-
-    private static byte[] createPair(String key, byte[] value) {
-        return MessageNano.toByteArray(CryptoTestUtils.newPair(key, value));
-    }
-
-    @SuppressWarnings("unchecked") // deserialization.
-    private static Set<byte[]> readPairs(ObjectInputStream ois)
-            throws IOException, ClassNotFoundException {
-        return (Set<byte[]>) ois.readObject();
-    }
-
-    private static ChunkHash fakeHash(byte[] data) {
-        return new ChunkHash(Arrays.copyOf(data, ChunkHash.HASH_LENGTH_BYTES));
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/FullRestoreToFileTaskTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/FullRestoreToFileTaskTest.java
deleted file mode 100644
index de8b734..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/FullRestoreToFileTaskTest.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.tasks;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.testng.Assert.assertThrows;
-
-import android.platform.test.annotations.Presubmit;
-
-import com.android.server.backup.encryption.FullRestoreDownloader;
-import com.android.server.backup.encryption.FullRestoreDownloader.FinishType;
-
-import com.google.common.io.Files;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.IOException;
-import java.util.Random;
-
-@RunWith(RobolectricTestRunner.class)
-@Presubmit
-public class FullRestoreToFileTaskTest {
-    private static final int TEST_RANDOM_SEED = 34;
-    private static final int TEST_MAX_CHUNK_SIZE_BYTES = 5;
-    private static final int TEST_DATA_LENGTH_BYTES = TEST_MAX_CHUNK_SIZE_BYTES * 20;
-
-    @Rule public TemporaryFolder mTemporaryFolder = new TemporaryFolder();
-
-    private byte[] mTestData;
-    private File mTargetFile;
-    private FakeFullRestoreDownloader mFakeFullRestoreDownloader;
-    @Mock private FullRestoreDownloader mMockFullRestoreDownloader;
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        mTargetFile = mTemporaryFolder.newFile();
-
-        mTestData = new byte[TEST_DATA_LENGTH_BYTES];
-        new Random(TEST_RANDOM_SEED).nextBytes(mTestData);
-        mFakeFullRestoreDownloader = new FakeFullRestoreDownloader(mTestData);
-    }
-
-    private FullRestoreToFileTask createTaskWithFakeDownloader() {
-        return new FullRestoreToFileTask(mFakeFullRestoreDownloader, TEST_MAX_CHUNK_SIZE_BYTES);
-    }
-
-    private FullRestoreToFileTask createTaskWithMockDownloader() {
-        return new FullRestoreToFileTask(mMockFullRestoreDownloader, TEST_MAX_CHUNK_SIZE_BYTES);
-    }
-
-    @Test
-    public void restoreToFile_readsDataAndWritesToFile() throws Exception {
-        FullRestoreToFileTask task = createTaskWithFakeDownloader();
-        task.restoreToFile(mTargetFile);
-        assertThat(Files.toByteArray(mTargetFile)).isEqualTo(mTestData);
-    }
-
-    @Test
-    public void restoreToFile_noErrors_closesDownloaderWithFinished() throws Exception {
-        FullRestoreToFileTask task = createTaskWithMockDownloader();
-        when(mMockFullRestoreDownloader.readNextChunk(any())).thenReturn(-1);
-
-        task.restoreToFile(mTargetFile);
-
-        verify(mMockFullRestoreDownloader).finish(FinishType.FINISHED);
-    }
-
-    @Test
-    public void restoreToFile_ioException_closesDownloaderWithTransferFailure() throws Exception {
-        FullRestoreToFileTask task = createTaskWithMockDownloader();
-        when(mMockFullRestoreDownloader.readNextChunk(any())).thenThrow(IOException.class);
-
-        assertThrows(IOException.class, () -> task.restoreToFile(mTargetFile));
-
-        verify(mMockFullRestoreDownloader).finish(FinishType.TRANSFER_FAILURE);
-    }
-
-    /** Fake package wrapper which returns data from a byte array. */
-    private static class FakeFullRestoreDownloader extends FullRestoreDownloader {
-
-        private final ByteArrayInputStream mData;
-
-        FakeFullRestoreDownloader(byte[] data) {
-            // We override all methods of the superclass, so it does not require any collaborators.
-            super();
-            this.mData = new ByteArrayInputStream(data);
-        }
-
-        @Override
-        public int readNextChunk(byte[] buffer) throws IOException {
-            return mData.read(buffer);
-        }
-
-        @Override
-        public void finish(FinishType finishType) {
-            // Do nothing.
-        }
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/InitializeRecoverableSecondaryKeyTaskTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/InitializeRecoverableSecondaryKeyTaskTest.java
deleted file mode 100644
index 4a7ae03..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/InitializeRecoverableSecondaryKeyTaskTest.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.tasks;
-
-import static android.security.keystore.recovery.RecoveryController.RECOVERY_STATUS_PERMANENT_FAILURE;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.when;
-import static org.testng.Assert.assertThrows;
-
-import android.app.Application;
-import android.security.keystore.recovery.RecoveryController;
-
-import androidx.test.core.app.ApplicationProvider;
-
-import com.android.server.backup.encryption.CryptoSettings;
-import com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKey;
-import com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKeyManager;
-import com.android.server.testing.fakes.FakeCryptoBackupServer;
-import com.android.server.testing.shadows.ShadowRecoveryController;
-
-import java.security.InvalidKeyException;
-import java.security.SecureRandom;
-import java.util.Optional;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-@Config(shadows = {ShadowRecoveryController.class})
-@RunWith(RobolectricTestRunner.class)
-public class InitializeRecoverableSecondaryKeyTaskTest {
-    @Mock private CryptoSettings mMockCryptoSettings;
-
-    private Application mApplication;
-    private InitializeRecoverableSecondaryKeyTask mTask;
-    private CryptoSettings mCryptoSettings;
-    private FakeCryptoBackupServer mFakeCryptoBackupServer;
-    private RecoverableKeyStoreSecondaryKeyManager mSecondaryKeyManager;
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-        ShadowRecoveryController.reset();
-
-        mApplication = ApplicationProvider.getApplicationContext();
-        mFakeCryptoBackupServer = new FakeCryptoBackupServer();
-        mCryptoSettings = CryptoSettings.getInstanceForTesting(mApplication);
-        mSecondaryKeyManager =
-                new RecoverableKeyStoreSecondaryKeyManager(
-                        RecoveryController.getInstance(mApplication), new SecureRandom());
-
-        mTask =
-                new InitializeRecoverableSecondaryKeyTask(
-                        mApplication, mCryptoSettings, mSecondaryKeyManager, mFakeCryptoBackupServer);
-    }
-
-    @Test
-    public void testRun_generatesNewKeyInRecoveryController() throws Exception {
-        RecoverableKeyStoreSecondaryKey key = mTask.run();
-
-        assertThat(RecoveryController.getInstance(mApplication).getAliases())
-                .contains(key.getAlias());
-    }
-
-    @Test
-    public void testRun_setsAliasOnServer() throws Exception {
-        RecoverableKeyStoreSecondaryKey key = mTask.run();
-
-        assertThat(mFakeCryptoBackupServer.getActiveSecondaryKeyAlias().get())
-                .isEqualTo(key.getAlias());
-    }
-
-    @Test
-    public void testRun_setsAliasInSettings() throws Exception {
-        RecoverableKeyStoreSecondaryKey key = mTask.run();
-
-        assertThat(mCryptoSettings.getActiveSecondaryKeyAlias().get()).isEqualTo(key.getAlias());
-    }
-
-    @Test
-    public void testRun_initializesSettings() throws Exception {
-        mTask.run();
-
-        assertThat(mCryptoSettings.getIsInitialized()).isTrue();
-    }
-
-    @Test
-    public void testRun_initializeSettingsFails_throws() throws Exception {
-        useMockCryptoSettings();
-        doThrow(IllegalArgumentException.class)
-                .when(mMockCryptoSettings)
-                .initializeWithKeyAlias(any());
-
-
-        assertThrows(IllegalArgumentException.class, () -> mTask.run());
-    }
-
-    @Test
-    public void testRun_doesNotGenerateANewKeyIfOneIsAvailable() throws Exception {
-        RecoverableKeyStoreSecondaryKey key1 = mTask.run();
-        RecoverableKeyStoreSecondaryKey key2 = mTask.run();
-
-        assertThat(key1.getAlias()).isEqualTo(key2.getAlias());
-        assertThat(key2.getSecretKey()).isEqualTo(key2.getSecretKey());
-    }
-
-    @Test
-    public void testRun_existingKeyButDestroyed_throws() throws Exception {
-        RecoverableKeyStoreSecondaryKey key = mTask.run();
-        ShadowRecoveryController.setRecoveryStatus(
-                key.getAlias(), RECOVERY_STATUS_PERMANENT_FAILURE);
-
-        assertThrows(InvalidKeyException.class, () -> mTask.run());
-    }
-
-    @Test
-    public void testRun_settingsInitializedButNotSecondaryKeyAlias_throws() {
-        useMockCryptoSettings();
-        when(mMockCryptoSettings.getIsInitialized()).thenReturn(true);
-        when(mMockCryptoSettings.getActiveSecondaryKeyAlias()).thenReturn(Optional.empty());
-
-        assertThrows(InvalidKeyException.class, () -> mTask.run());
-    }
-
-    @Test
-    public void testRun_keyAliasSetButNotInStore_throws() {
-        useMockCryptoSettings();
-        when(mMockCryptoSettings.getIsInitialized()).thenReturn(true);
-        when(mMockCryptoSettings.getActiveSecondaryKeyAlias())
-                .thenReturn(Optional.of("missingAlias"));
-
-        assertThrows(InvalidKeyException.class, () -> mTask.run());
-    }
-
-    private void useMockCryptoSettings() {
-        mTask =
-                new InitializeRecoverableSecondaryKeyTask(
-                        mApplication,
-                        mMockCryptoSettings,
-                        mSecondaryKeyManager,
-                        mFakeCryptoBackupServer);
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/KvBackupEncrypterTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/KvBackupEncrypterTest.java
deleted file mode 100644
index ccfbfa4..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/KvBackupEncrypterTest.java
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.tasks;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.testng.Assert.assertThrows;
-
-import android.app.backup.BackupDataInput;
-import android.platform.test.annotations.Presubmit;
-import android.util.Pair;
-
-import com.android.server.backup.encryption.chunk.ChunkHash;
-import com.android.server.backup.encryption.chunking.ChunkHasher;
-import com.android.server.backup.encryption.chunking.EncryptedChunk;
-import com.android.server.backup.encryption.kv.KeyValueListingBuilder;
-import com.android.server.backup.encryption.protos.nano.KeyValueListingProto.KeyValueListing;
-import com.android.server.backup.encryption.protos.nano.KeyValuePairProto.KeyValuePair;
-import com.android.server.backup.encryption.tasks.BackupEncrypter.Result;
-import com.android.server.testing.shadows.DataEntity;
-import com.android.server.testing.shadows.ShadowBackupDataInput;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Ordering;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-import java.security.MessageDigest;
-import java.util.Arrays;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import javax.crypto.Cipher;
-import javax.crypto.SecretKey;
-import javax.crypto.spec.GCMParameterSpec;
-import javax.crypto.spec.SecretKeySpec;
-
-@RunWith(RobolectricTestRunner.class)
-@Presubmit
-@Config(shadows = {ShadowBackupDataInput.class})
-public class KvBackupEncrypterTest {
-    private static final String KEY_ALGORITHM = "AES";
-    private static final String CIPHER_ALGORITHM = "AES/GCM/NoPadding";
-    private static final int GCM_TAG_LENGTH_BYTES = 16;
-
-    private static final byte[] TEST_TERTIARY_KEY = Arrays.copyOf(new byte[0], 256 / Byte.SIZE);
-    private static final String TEST_KEY_1 = "test_key_1";
-    private static final String TEST_KEY_2 = "test_key_2";
-    private static final String TEST_KEY_3 = "test_key_3";
-    private static final byte[] TEST_VALUE_1 = {10, 11, 12};
-    private static final byte[] TEST_VALUE_2 = {13, 14, 15};
-    private static final byte[] TEST_VALUE_2B = {13, 14, 15, 16};
-    private static final byte[] TEST_VALUE_3 = {16, 17, 18};
-
-    private SecretKey mSecretKey;
-    private ChunkHasher mChunkHasher;
-
-    @Before
-    public void setUp() {
-        mSecretKey = new SecretKeySpec(TEST_TERTIARY_KEY, KEY_ALGORITHM);
-        mChunkHasher = new ChunkHasher(mSecretKey);
-
-        ShadowBackupDataInput.reset();
-    }
-
-    private KvBackupEncrypter createEncrypter(KeyValueListing keyValueListing) {
-        KvBackupEncrypter encrypter = new KvBackupEncrypter(new BackupDataInput(null));
-        encrypter.setOldKeyValueListing(keyValueListing);
-        return encrypter;
-    }
-
-    @Test
-    public void backup_noExistingBackup_encryptsAllPairs() throws Exception {
-        ShadowBackupDataInput.addEntity(TEST_KEY_1, TEST_VALUE_1);
-        ShadowBackupDataInput.addEntity(TEST_KEY_2, TEST_VALUE_2);
-
-        KeyValueListing emptyKeyValueListing = new KeyValueListingBuilder().build();
-        ImmutableSet<ChunkHash> emptyExistingChunks = ImmutableSet.of();
-        KvBackupEncrypter encrypter = createEncrypter(emptyKeyValueListing);
-
-        Result result =
-                encrypter.backup(
-                        mSecretKey, /*unusedFingerprintMixerSalt=*/ null, emptyExistingChunks);
-
-        assertThat(result.getAllChunks()).hasSize(2);
-        EncryptedChunk chunk1 = result.getNewChunks().get(0);
-        EncryptedChunk chunk2 = result.getNewChunks().get(1);
-        assertThat(chunk1.key()).isEqualTo(getChunkHash(TEST_KEY_1, TEST_VALUE_1));
-        KeyValuePair pair1 = decryptChunk(chunk1);
-        assertThat(pair1.key).isEqualTo(TEST_KEY_1);
-        assertThat(pair1.value).isEqualTo(TEST_VALUE_1);
-        assertThat(chunk2.key()).isEqualTo(getChunkHash(TEST_KEY_2, TEST_VALUE_2));
-        KeyValuePair pair2 = decryptChunk(chunk2);
-        assertThat(pair2.key).isEqualTo(TEST_KEY_2);
-        assertThat(pair2.value).isEqualTo(TEST_VALUE_2);
-    }
-
-    @Test
-    public void backup_existingBackup_encryptsNewAndUpdatedPairs() throws Exception {
-        Pair<KeyValueListing, Set<ChunkHash>> initialResult = runInitialBackupOfPairs1And2();
-
-        // Update key 2 and add the new key 3.
-        ShadowBackupDataInput.reset();
-        ShadowBackupDataInput.addEntity(TEST_KEY_2, TEST_VALUE_2B);
-        ShadowBackupDataInput.addEntity(TEST_KEY_3, TEST_VALUE_3);
-
-        KvBackupEncrypter encrypter = createEncrypter(initialResult.first);
-        BackupEncrypter.Result secondResult =
-                encrypter.backup(
-                        mSecretKey, /*unusedFingerprintMixerSalt=*/ null, initialResult.second);
-
-        assertThat(secondResult.getAllChunks()).hasSize(3);
-        assertThat(secondResult.getNewChunks()).hasSize(2);
-        EncryptedChunk newChunk2 = secondResult.getNewChunks().get(0);
-        EncryptedChunk newChunk3 = secondResult.getNewChunks().get(1);
-        assertThat(newChunk2.key()).isEqualTo(getChunkHash(TEST_KEY_2, TEST_VALUE_2B));
-        assertThat(decryptChunk(newChunk2).value).isEqualTo(TEST_VALUE_2B);
-        assertThat(newChunk3.key()).isEqualTo(getChunkHash(TEST_KEY_3, TEST_VALUE_3));
-        assertThat(decryptChunk(newChunk3).value).isEqualTo(TEST_VALUE_3);
-    }
-
-    @Test
-    public void backup_allChunksContainsHashesOfAllChunks() throws Exception {
-        Pair<KeyValueListing, Set<ChunkHash>> initialResult = runInitialBackupOfPairs1And2();
-
-        ShadowBackupDataInput.reset();
-        ShadowBackupDataInput.addEntity(TEST_KEY_3, TEST_VALUE_3);
-
-        KvBackupEncrypter encrypter = createEncrypter(initialResult.first);
-        BackupEncrypter.Result secondResult =
-                encrypter.backup(
-                        mSecretKey, /*unusedFingerprintMixerSalt=*/ null, initialResult.second);
-
-        assertThat(secondResult.getAllChunks())
-                .containsExactly(
-                        getChunkHash(TEST_KEY_1, TEST_VALUE_1),
-                        getChunkHash(TEST_KEY_2, TEST_VALUE_2),
-                        getChunkHash(TEST_KEY_3, TEST_VALUE_3));
-    }
-
-    @Test
-    public void backup_negativeSize_deletesKeyFromExistingBackup() throws Exception {
-        Pair<KeyValueListing, Set<ChunkHash>> initialResult = runInitialBackupOfPairs1And2();
-
-        ShadowBackupDataInput.reset();
-        ShadowBackupDataInput.addEntity(new DataEntity(TEST_KEY_2));
-
-        KvBackupEncrypter encrypter = createEncrypter(initialResult.first);
-        Result secondResult =
-                encrypter.backup(
-                        mSecretKey, /*unusedFingerprintMixerSalt=*/ null, initialResult.second);
-
-        assertThat(secondResult.getAllChunks())
-                .containsExactly(getChunkHash(TEST_KEY_1, TEST_VALUE_1));
-        assertThat(secondResult.getNewChunks()).isEmpty();
-    }
-
-    @Test
-    public void backup_returnsMessageDigestOverChunkHashes() throws Exception {
-        Pair<KeyValueListing, Set<ChunkHash>> initialResult = runInitialBackupOfPairs1And2();
-
-        ShadowBackupDataInput.reset();
-        ShadowBackupDataInput.addEntity(TEST_KEY_3, TEST_VALUE_3);
-
-        KvBackupEncrypter encrypter = createEncrypter(initialResult.first);
-        Result secondResult =
-                encrypter.backup(
-                        mSecretKey, /*unusedFingerprintMixerSalt=*/ null, initialResult.second);
-
-        MessageDigest messageDigest =
-                MessageDigest.getInstance(BackupEncrypter.MESSAGE_DIGEST_ALGORITHM);
-        ImmutableList<ChunkHash> sortedHashes =
-                Ordering.natural()
-                        .immutableSortedCopy(
-                                ImmutableList.of(
-                                        getChunkHash(TEST_KEY_1, TEST_VALUE_1),
-                                        getChunkHash(TEST_KEY_2, TEST_VALUE_2),
-                                        getChunkHash(TEST_KEY_3, TEST_VALUE_3)));
-        messageDigest.update(sortedHashes.get(0).getHash());
-        messageDigest.update(sortedHashes.get(1).getHash());
-        messageDigest.update(sortedHashes.get(2).getHash());
-        assertThat(secondResult.getDigest()).isEqualTo(messageDigest.digest());
-    }
-
-    @Test
-    public void getNewKeyValueListing_noExistingBackup_returnsCorrectListing() throws Exception {
-        KeyValueListing keyValueListing = runInitialBackupOfPairs1And2().first;
-
-        assertThat(keyValueListing.entries.length).isEqualTo(2);
-        assertThat(keyValueListing.entries[0].key).isEqualTo(TEST_KEY_1);
-        assertThat(keyValueListing.entries[0].hash)
-                .isEqualTo(getChunkHash(TEST_KEY_1, TEST_VALUE_1).getHash());
-        assertThat(keyValueListing.entries[1].key).isEqualTo(TEST_KEY_2);
-        assertThat(keyValueListing.entries[1].hash)
-                .isEqualTo(getChunkHash(TEST_KEY_2, TEST_VALUE_2).getHash());
-    }
-
-    @Test
-    public void getNewKeyValueListing_existingBackup_returnsCorrectListing() throws Exception {
-        Pair<KeyValueListing, Set<ChunkHash>> initialResult = runInitialBackupOfPairs1And2();
-
-        ShadowBackupDataInput.reset();
-        ShadowBackupDataInput.addEntity(TEST_KEY_2, TEST_VALUE_2B);
-        ShadowBackupDataInput.addEntity(TEST_KEY_3, TEST_VALUE_3);
-
-        KvBackupEncrypter encrypter = createEncrypter(initialResult.first);
-        encrypter.backup(mSecretKey, /*unusedFingerprintMixerSalt=*/ null, initialResult.second);
-
-        ImmutableMap<String, ChunkHash> keyValueListing =
-                listingToMap(encrypter.getNewKeyValueListing());
-        assertThat(keyValueListing).hasSize(3);
-        assertThat(keyValueListing)
-                .containsEntry(TEST_KEY_1, getChunkHash(TEST_KEY_1, TEST_VALUE_1));
-        assertThat(keyValueListing)
-                .containsEntry(TEST_KEY_2, getChunkHash(TEST_KEY_2, TEST_VALUE_2B));
-        assertThat(keyValueListing)
-                .containsEntry(TEST_KEY_3, getChunkHash(TEST_KEY_3, TEST_VALUE_3));
-    }
-
-    @Test
-    public void getNewKeyValueChunkListing_beforeBackup_throws() throws Exception {
-        KvBackupEncrypter encrypter = createEncrypter(new KeyValueListing());
-        assertThrows(IllegalStateException.class, encrypter::getNewKeyValueListing);
-    }
-
-    private ImmutableMap<String, ChunkHash> listingToMap(KeyValueListing listing) {
-        // We can't use the ImmutableMap collector directly because it isn't supported in Android
-        // guava.
-        return ImmutableMap.copyOf(
-                Arrays.stream(listing.entries)
-                        .collect(
-                                Collectors.toMap(
-                                        entry -> entry.key, entry -> new ChunkHash(entry.hash))));
-    }
-
-    private Pair<KeyValueListing, Set<ChunkHash>> runInitialBackupOfPairs1And2() throws Exception {
-        ShadowBackupDataInput.addEntity(TEST_KEY_1, TEST_VALUE_1);
-        ShadowBackupDataInput.addEntity(TEST_KEY_2, TEST_VALUE_2);
-
-        KeyValueListing initialKeyValueListing = new KeyValueListingBuilder().build();
-        ImmutableSet<ChunkHash> initialExistingChunks = ImmutableSet.of();
-        KvBackupEncrypter encrypter = createEncrypter(initialKeyValueListing);
-        Result firstResult =
-                encrypter.backup(
-                        mSecretKey, /*unusedFingerprintMixerSalt=*/ null, initialExistingChunks);
-
-        return Pair.create(
-                encrypter.getNewKeyValueListing(), ImmutableSet.copyOf(firstResult.getAllChunks()));
-    }
-
-    private ChunkHash getChunkHash(String key, byte[] value) throws Exception {
-        KeyValuePair pair = new KeyValuePair();
-        pair.key = key;
-        pair.value = Arrays.copyOf(value, value.length);
-        return mChunkHasher.computeHash(KeyValuePair.toByteArray(pair));
-    }
-
-    private KeyValuePair decryptChunk(EncryptedChunk encryptedChunk) throws Exception {
-        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
-        cipher.init(
-                Cipher.DECRYPT_MODE,
-                mSecretKey,
-                new GCMParameterSpec(GCM_TAG_LENGTH_BYTES * Byte.SIZE, encryptedChunk.nonce()));
-        byte[] decryptedBytes = cipher.doFinal(encryptedChunk.encryptedBytes());
-        return KeyValuePair.parseFrom(decryptedBytes);
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/RotateSecondaryKeyTaskTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/RotateSecondaryKeyTaskTest.java
deleted file mode 100644
index cda7317..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/RotateSecondaryKeyTaskTest.java
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.tasks;
-
-import static com.android.server.backup.testing.CryptoTestUtils.generateAesKey;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.testng.Assert.assertFalse;
-
-import android.app.Application;
-import android.platform.test.annotations.Presubmit;
-import android.security.keystore.recovery.RecoveryController;
-
-import androidx.test.core.app.ApplicationProvider;
-
-import com.android.server.backup.encryption.CryptoSettings;
-import com.android.server.backup.encryption.keys.KeyWrapUtils;
-import com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKey;
-import com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKeyManager;
-import com.android.server.backup.encryption.keys.TertiaryKeyStore;
-import com.android.server.backup.encryption.protos.nano.WrappedKeyProto;
-import com.android.server.testing.fakes.FakeCryptoBackupServer;
-import com.android.server.testing.shadows.ShadowRecoveryController;
-
-import java.security.SecureRandom;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.crypto.SecretKey;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-@RunWith(RobolectricTestRunner.class)
-@Presubmit
-@Config(shadows = {ShadowRecoveryController.class, ShadowRecoveryController.class})
-public class RotateSecondaryKeyTaskTest {
-    private static final String APP_1 = "app1";
-    private static final String APP_2 = "app2";
-    private static final String APP_3 = "app3";
-
-    private static final String CURRENT_SECONDARY_KEY_ALIAS =
-            "recoverablekey.alias/d524796bd07de3c2225c63d434eff698";
-    private static final String NEXT_SECONDARY_KEY_ALIAS =
-            "recoverablekey.alias/6c6d198a7f12e662b6bc45f4849db170";
-
-    private Application mApplication;
-    private RotateSecondaryKeyTask mTask;
-    private RecoveryController mRecoveryController;
-    private FakeCryptoBackupServer mBackupServer;
-    private CryptoSettings mCryptoSettings;
-    private Map<String, SecretKey> mTertiaryKeysByPackageName;
-    private RecoverableKeyStoreSecondaryKeyManager mRecoverableSecondaryKeyManager;
-
-    @Before
-    public void setUp() throws Exception {
-        mApplication = ApplicationProvider.getApplicationContext();
-
-        mTertiaryKeysByPackageName = new HashMap<>();
-        mTertiaryKeysByPackageName.put(APP_1, generateAesKey());
-        mTertiaryKeysByPackageName.put(APP_2, generateAesKey());
-        mTertiaryKeysByPackageName.put(APP_3, generateAesKey());
-
-        mRecoveryController = RecoveryController.getInstance(mApplication);
-        mRecoverableSecondaryKeyManager =
-                new RecoverableKeyStoreSecondaryKeyManager(
-                        RecoveryController.getInstance(mApplication), new SecureRandom());
-        mBackupServer = new FakeCryptoBackupServer();
-        mCryptoSettings = CryptoSettings.getInstanceForTesting(mApplication);
-        addNextSecondaryKeyToRecoveryController();
-        mCryptoSettings.setNextSecondaryAlias(NEXT_SECONDARY_KEY_ALIAS);
-
-        mTask =
-                new RotateSecondaryKeyTask(
-                        mApplication,
-                        mRecoverableSecondaryKeyManager,
-                        mBackupServer,
-                        mCryptoSettings,
-                        mRecoveryController);
-
-        ShadowRecoveryController.reset();
-    }
-
-    @Test
-    public void run_failsIfThereIsNoActiveSecondaryKey() throws Exception {
-        setNextKeyRecoveryStatus(RecoveryController.RECOVERY_STATUS_SYNCED);
-        addCurrentSecondaryKeyToRecoveryController();
-        mBackupServer.setActiveSecondaryKeyAlias(
-                CURRENT_SECONDARY_KEY_ALIAS, Collections.emptyMap());
-
-        mTask.run();
-
-        assertFalse(mCryptoSettings.getActiveSecondaryKeyAlias().isPresent());
-    }
-
-    @Test
-    public void run_failsIfActiveSecondaryIsNotInRecoveryController() throws Exception {
-        setNextKeyRecoveryStatus(RecoveryController.RECOVERY_STATUS_SYNCED);
-        // Have to add it first as otherwise CryptoSettings throws an exception when trying to set
-        // it
-        addCurrentSecondaryKeyToRecoveryController();
-        mCryptoSettings.setActiveSecondaryKeyAlias(CURRENT_SECONDARY_KEY_ALIAS);
-        mBackupServer.setActiveSecondaryKeyAlias(
-                CURRENT_SECONDARY_KEY_ALIAS, Collections.emptyMap());
-
-        mTask.run();
-
-        assertThat(mCryptoSettings.getActiveSecondaryKeyAlias().get())
-                .isEqualTo(CURRENT_SECONDARY_KEY_ALIAS);
-    }
-
-    @Test
-    public void run_doesNothingIfFlagIsDisabled() throws Exception {
-        setNextKeyRecoveryStatus(RecoveryController.RECOVERY_STATUS_SYNCED);
-        addCurrentSecondaryKeyToRecoveryController();
-        mCryptoSettings.setActiveSecondaryKeyAlias(CURRENT_SECONDARY_KEY_ALIAS);
-        mBackupServer.setActiveSecondaryKeyAlias(
-                CURRENT_SECONDARY_KEY_ALIAS, Collections.emptyMap());
-        addWrappedTertiaries();
-
-        mTask.run();
-
-        assertThat(mCryptoSettings.getActiveSecondaryKeyAlias().get())
-                .isEqualTo(CURRENT_SECONDARY_KEY_ALIAS);
-    }
-
-    @Test
-    public void run_setsActiveSecondary() throws Exception {
-        addNextSecondaryKeyToRecoveryController();
-        setNextKeyRecoveryStatus(RecoveryController.RECOVERY_STATUS_SYNCED);
-        addCurrentSecondaryKeyToRecoveryController();
-        mCryptoSettings.setActiveSecondaryKeyAlias(CURRENT_SECONDARY_KEY_ALIAS);
-        mBackupServer.setActiveSecondaryKeyAlias(
-                CURRENT_SECONDARY_KEY_ALIAS, Collections.emptyMap());
-        addWrappedTertiaries();
-
-        mTask.run();
-
-        assertThat(mBackupServer.getActiveSecondaryKeyAlias().get())
-                .isEqualTo(NEXT_SECONDARY_KEY_ALIAS);
-    }
-
-    @Test
-    public void run_rewrapsExistingTertiaryKeys() throws Exception {
-        addNextSecondaryKeyToRecoveryController();
-        setNextKeyRecoveryStatus(RecoveryController.RECOVERY_STATUS_SYNCED);
-        addCurrentSecondaryKeyToRecoveryController();
-        mCryptoSettings.setActiveSecondaryKeyAlias(CURRENT_SECONDARY_KEY_ALIAS);
-        mBackupServer.setActiveSecondaryKeyAlias(
-                CURRENT_SECONDARY_KEY_ALIAS, Collections.emptyMap());
-        addWrappedTertiaries();
-
-        mTask.run();
-
-        Map<String, WrappedKeyProto.WrappedKey> rewrappedKeys =
-                mBackupServer.getAllTertiaryKeys(NEXT_SECONDARY_KEY_ALIAS);
-        SecretKey secondaryKey = (SecretKey) mRecoveryController.getKey(NEXT_SECONDARY_KEY_ALIAS);
-        for (String packageName : mTertiaryKeysByPackageName.keySet()) {
-            WrappedKeyProto.WrappedKey rewrappedKey = rewrappedKeys.get(packageName);
-            assertThat(KeyWrapUtils.unwrap(secondaryKey, rewrappedKey))
-                    .isEqualTo(mTertiaryKeysByPackageName.get(packageName));
-        }
-    }
-
-    @Test
-    public void run_persistsRewrappedKeysToDisk() throws Exception {
-        addNextSecondaryKeyToRecoveryController();
-        setNextKeyRecoveryStatus(RecoveryController.RECOVERY_STATUS_SYNCED);
-        addCurrentSecondaryKeyToRecoveryController();
-        mCryptoSettings.setActiveSecondaryKeyAlias(CURRENT_SECONDARY_KEY_ALIAS);
-        mBackupServer.setActiveSecondaryKeyAlias(
-                CURRENT_SECONDARY_KEY_ALIAS, Collections.emptyMap());
-        addWrappedTertiaries();
-
-        mTask.run();
-
-        RecoverableKeyStoreSecondaryKey secondaryKey = getRecoverableKey(NEXT_SECONDARY_KEY_ALIAS);
-        Map<String, SecretKey> keys =
-                TertiaryKeyStore.newInstance(mApplication, secondaryKey).getAll();
-        for (String packageName : mTertiaryKeysByPackageName.keySet()) {
-            SecretKey tertiaryKey = mTertiaryKeysByPackageName.get(packageName);
-            SecretKey newlyWrappedKey = keys.get(packageName);
-            assertThat(tertiaryKey.getEncoded()).isEqualTo(newlyWrappedKey.getEncoded());
-        }
-    }
-
-    @Test
-    public void run_stillSetsActiveSecondaryIfNoTertiaries() throws Exception {
-        addNextSecondaryKeyToRecoveryController();
-        setNextKeyRecoveryStatus(RecoveryController.RECOVERY_STATUS_SYNCED);
-        addCurrentSecondaryKeyToRecoveryController();
-        mCryptoSettings.setActiveSecondaryKeyAlias(CURRENT_SECONDARY_KEY_ALIAS);
-        mBackupServer.setActiveSecondaryKeyAlias(
-                CURRENT_SECONDARY_KEY_ALIAS, Collections.emptyMap());
-
-        mTask.run();
-
-        assertThat(mBackupServer.getActiveSecondaryKeyAlias().get())
-                .isEqualTo(NEXT_SECONDARY_KEY_ALIAS);
-    }
-
-    @Test
-    public void run_setsActiveSecondaryKeyAliasInSettings() throws Exception {
-        addNextSecondaryKeyToRecoveryController();
-        setNextKeyRecoveryStatus(RecoveryController.RECOVERY_STATUS_SYNCED);
-        addCurrentSecondaryKeyToRecoveryController();
-        mCryptoSettings.setActiveSecondaryKeyAlias(CURRENT_SECONDARY_KEY_ALIAS);
-        mBackupServer.setActiveSecondaryKeyAlias(
-                CURRENT_SECONDARY_KEY_ALIAS, Collections.emptyMap());
-
-        mTask.run();
-
-        assertThat(mCryptoSettings.getActiveSecondaryKeyAlias().get())
-                .isEqualTo(NEXT_SECONDARY_KEY_ALIAS);
-    }
-
-    @Test
-    public void run_removesNextSecondaryKeyAliasInSettings() throws Exception {
-        addNextSecondaryKeyToRecoveryController();
-        setNextKeyRecoveryStatus(RecoveryController.RECOVERY_STATUS_SYNCED);
-        addCurrentSecondaryKeyToRecoveryController();
-        mCryptoSettings.setActiveSecondaryKeyAlias(CURRENT_SECONDARY_KEY_ALIAS);
-        mBackupServer.setActiveSecondaryKeyAlias(
-                CURRENT_SECONDARY_KEY_ALIAS, Collections.emptyMap());
-
-        mTask.run();
-
-        assertFalse(mCryptoSettings.getNextSecondaryKeyAlias().isPresent());
-    }
-
-    @Test
-    public void run_deletesOldKeyFromRecoverableKeyStoreLoader() throws Exception {
-        addNextSecondaryKeyToRecoveryController();
-        setNextKeyRecoveryStatus(RecoveryController.RECOVERY_STATUS_SYNCED);
-        addCurrentSecondaryKeyToRecoveryController();
-        mCryptoSettings.setActiveSecondaryKeyAlias(CURRENT_SECONDARY_KEY_ALIAS);
-        mBackupServer.setActiveSecondaryKeyAlias(
-                CURRENT_SECONDARY_KEY_ALIAS, Collections.emptyMap());
-
-        mTask.run();
-
-        assertThat(mRecoveryController.getKey(CURRENT_SECONDARY_KEY_ALIAS)).isNull();
-    }
-
-    @Test
-    public void run_doesNotRotateIfNoNextAlias() throws Exception {
-        addCurrentSecondaryKeyToRecoveryController();
-        mCryptoSettings.setActiveSecondaryKeyAlias(CURRENT_SECONDARY_KEY_ALIAS);
-        mBackupServer.setActiveSecondaryKeyAlias(
-                CURRENT_SECONDARY_KEY_ALIAS, Collections.emptyMap());
-        mCryptoSettings.removeNextSecondaryKeyAlias();
-
-        mTask.run();
-
-        assertThat(mCryptoSettings.getActiveSecondaryKeyAlias().get())
-                .isEqualTo(CURRENT_SECONDARY_KEY_ALIAS);
-        assertFalse(mCryptoSettings.getNextSecondaryKeyAlias().isPresent());
-    }
-
-    @Test
-    public void run_doesNotRotateIfKeyIsNotSyncedYet() throws Exception {
-        addNextSecondaryKeyToRecoveryController();
-        setNextKeyRecoveryStatus(RecoveryController.RECOVERY_STATUS_SYNC_IN_PROGRESS);
-        addCurrentSecondaryKeyToRecoveryController();
-        mCryptoSettings.setActiveSecondaryKeyAlias(CURRENT_SECONDARY_KEY_ALIAS);
-        mBackupServer.setActiveSecondaryKeyAlias(
-                CURRENT_SECONDARY_KEY_ALIAS, Collections.emptyMap());
-
-        mTask.run();
-
-        assertThat(mCryptoSettings.getActiveSecondaryKeyAlias().get())
-                .isEqualTo(CURRENT_SECONDARY_KEY_ALIAS);
-    }
-
-    @Test
-    public void run_doesNotClearNextKeyIfSyncIsJustPending() throws Exception {
-        addNextSecondaryKeyToRecoveryController();
-        setNextKeyRecoveryStatus(RecoveryController.RECOVERY_STATUS_SYNC_IN_PROGRESS);
-        addCurrentSecondaryKeyToRecoveryController();
-        mCryptoSettings.setActiveSecondaryKeyAlias(CURRENT_SECONDARY_KEY_ALIAS);
-        mBackupServer.setActiveSecondaryKeyAlias(
-                CURRENT_SECONDARY_KEY_ALIAS, Collections.emptyMap());
-
-        mTask.run();
-
-        assertThat(mCryptoSettings.getNextSecondaryKeyAlias().get())
-                .isEqualTo(NEXT_SECONDARY_KEY_ALIAS);
-    }
-
-    @Test
-    public void run_doesNotRotateIfPermanentFailure() throws Exception {
-        addNextSecondaryKeyToRecoveryController();
-        setNextKeyRecoveryStatus(RecoveryController.RECOVERY_STATUS_PERMANENT_FAILURE);
-        addCurrentSecondaryKeyToRecoveryController();
-        mCryptoSettings.setActiveSecondaryKeyAlias(CURRENT_SECONDARY_KEY_ALIAS);
-        mBackupServer.setActiveSecondaryKeyAlias(
-                CURRENT_SECONDARY_KEY_ALIAS, Collections.emptyMap());
-
-        mTask.run();
-
-        assertThat(mCryptoSettings.getActiveSecondaryKeyAlias().get())
-                .isEqualTo(CURRENT_SECONDARY_KEY_ALIAS);
-    }
-
-    @Test
-    public void run_removesNextKeyIfPermanentFailure() throws Exception {
-        addNextSecondaryKeyToRecoveryController();
-        setNextKeyRecoveryStatus(RecoveryController.RECOVERY_STATUS_PERMANENT_FAILURE);
-        addCurrentSecondaryKeyToRecoveryController();
-        mCryptoSettings.setActiveSecondaryKeyAlias(CURRENT_SECONDARY_KEY_ALIAS);
-        mBackupServer.setActiveSecondaryKeyAlias(
-                CURRENT_SECONDARY_KEY_ALIAS, Collections.emptyMap());
-
-        mTask.run();
-
-        assertFalse(mCryptoSettings.getNextSecondaryKeyAlias().isPresent());
-    }
-
-    private void setNextKeyRecoveryStatus(int status) throws Exception {
-        mRecoveryController.setRecoveryStatus(NEXT_SECONDARY_KEY_ALIAS, status);
-    }
-
-    private void addCurrentSecondaryKeyToRecoveryController() throws Exception {
-        mRecoveryController.generateKey(CURRENT_SECONDARY_KEY_ALIAS);
-    }
-
-    private void addNextSecondaryKeyToRecoveryController() throws Exception {
-        mRecoveryController.generateKey(NEXT_SECONDARY_KEY_ALIAS);
-    }
-
-    private void addWrappedTertiaries() throws Exception {
-        TertiaryKeyStore tertiaryKeyStore =
-                TertiaryKeyStore.newInstance(
-                        mApplication, getRecoverableKey(CURRENT_SECONDARY_KEY_ALIAS));
-
-        for (String packageName : mTertiaryKeysByPackageName.keySet()) {
-            tertiaryKeyStore.save(packageName, mTertiaryKeysByPackageName.get(packageName));
-        }
-    }
-
-    private RecoverableKeyStoreSecondaryKey getRecoverableKey(String alias) throws Exception {
-        return mRecoverableSecondaryKeyManager.get(alias).get();
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/StartSecondaryKeyRotationTaskTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/StartSecondaryKeyRotationTaskTest.java
deleted file mode 100644
index 4ac4fa8..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/StartSecondaryKeyRotationTaskTest.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.tasks;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.platform.test.annotations.Presubmit;
-import android.security.keystore.recovery.RecoveryController;
-
-import com.android.server.backup.encryption.CryptoSettings;
-import com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKey;
-import com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKeyManager;
-import com.android.server.testing.shadows.ShadowRecoveryController;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-import java.security.SecureRandom;
-
-@RunWith(RobolectricTestRunner.class)
-@Config(shadows = {ShadowRecoveryController.class})
-@Presubmit
-public class StartSecondaryKeyRotationTaskTest {
-
-    private CryptoSettings mCryptoSettings;
-    private RecoverableKeyStoreSecondaryKeyManager mSecondaryKeyManager;
-    private StartSecondaryKeyRotationTask mStartSecondaryKeyRotationTask;
-
-    @Before
-    public void setUp() throws Exception {
-        mSecondaryKeyManager =
-                new RecoverableKeyStoreSecondaryKeyManager(
-                        RecoveryController.getInstance(RuntimeEnvironment.application),
-                        new SecureRandom());
-        mCryptoSettings = CryptoSettings.getInstanceForTesting(RuntimeEnvironment.application);
-        mStartSecondaryKeyRotationTask =
-                new StartSecondaryKeyRotationTask(mCryptoSettings, mSecondaryKeyManager);
-
-        ShadowRecoveryController.reset();
-    }
-
-    @Test
-    public void run_doesNothingIfNoActiveSecondaryExists() {
-        mStartSecondaryKeyRotationTask.run();
-
-        assertThat(mCryptoSettings.getNextSecondaryKeyAlias().isPresent()).isFalse();
-    }
-
-    @Test
-    public void run_doesNotRemoveExistingNextSecondaryKeyIfItIsAlreadyActive() throws Exception {
-        generateAnActiveKey();
-        String activeAlias = mCryptoSettings.getActiveSecondaryKeyAlias().get();
-        mCryptoSettings.setNextSecondaryAlias(activeAlias);
-
-        mStartSecondaryKeyRotationTask.run();
-
-        assertThat(mSecondaryKeyManager.get(activeAlias).isPresent()).isTrue();
-    }
-
-    @Test
-    public void run_doesRemoveExistingNextSecondaryKeyIfItIsNotYetActive() throws Exception {
-        generateAnActiveKey();
-        RecoverableKeyStoreSecondaryKey nextKey = mSecondaryKeyManager.generate();
-        String nextAlias = nextKey.getAlias();
-        mCryptoSettings.setNextSecondaryAlias(nextAlias);
-
-        mStartSecondaryKeyRotationTask.run();
-
-        assertThat(mSecondaryKeyManager.get(nextAlias).isPresent()).isFalse();
-    }
-
-    @Test
-    public void run_generatesANewNextSecondaryKey() throws Exception {
-        generateAnActiveKey();
-
-        mStartSecondaryKeyRotationTask.run();
-
-        assertThat(mCryptoSettings.getNextSecondaryKeyAlias().isPresent()).isTrue();
-    }
-
-    @Test
-    public void run_generatesANewKeyThatExistsInKeyStore() throws Exception {
-        generateAnActiveKey();
-
-        mStartSecondaryKeyRotationTask.run();
-
-        String nextAlias = mCryptoSettings.getNextSecondaryKeyAlias().get();
-        assertThat(mSecondaryKeyManager.get(nextAlias).isPresent()).isTrue();
-    }
-
-    private void generateAnActiveKey() throws Exception {
-        RecoverableKeyStoreSecondaryKey secondaryKey = mSecondaryKeyManager.generate();
-        mCryptoSettings.setActiveSecondaryKeyAlias(secondaryKey.getAlias());
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/testing/DiffScriptProcessor.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/testing/DiffScriptProcessor.java
deleted file mode 100644
index 7e97924..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/testing/DiffScriptProcessor.java
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.testing;
-
-import static com.android.internal.util.Preconditions.checkArgument;
-
-import static java.nio.charset.StandardCharsets.UTF_8;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.RandomAccessFile;
-import java.util.Locale;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.Scanner;
-import java.util.regex.Pattern;
-
-/**
- * To be used as part of a fake backup server. Processes a Scotty diff script.
- *
- * <p>A Scotty diff script consists of an ASCII line denoting a command, optionally followed by a
- * range of bytes. Command format is either
- *
- * <ul>
- *   <li>A single 64-bit integer, followed by a new line: this denotes that the given number of
- *       bytes are to follow in the stream. These bytes should be written directly to the new file.
- *   <li>Two 64-bit integers, separated by a hyphen, followed by a new line: this says that the
- *       given range of bytes from the original file ought to be copied into the new file.
- * </ul>
- */
-public class DiffScriptProcessor {
-
-    private static final int COPY_BUFFER_SIZE = 1024;
-
-    private static final String READ_MODE = "r";
-    private static final Pattern VALID_COMMAND_PATTERN = Pattern.compile("^\\d+(-\\d+)?$");
-
-    private final File mInput;
-    private final File mOutput;
-    private final long mInputLength;
-
-    /**
-     * A new instance, with {@code input} as previous file, and {@code output} as new file.
-     *
-     * @param input Previous file from which ranges of bytes are to be copied. This file should be
-     *     immutable.
-     * @param output Output file, to which the new data should be written.
-     * @throws IllegalArgumentException if input does not exist.
-     */
-    public DiffScriptProcessor(File input, File output) {
-        checkArgument(input.exists(), "input file did not exist.");
-        mInput = input;
-        mInputLength = input.length();
-        mOutput = Objects.requireNonNull(output);
-    }
-
-    public void process(InputStream diffScript) throws IOException, MalformedDiffScriptException {
-        RandomAccessFile randomAccessInput = new RandomAccessFile(mInput, READ_MODE);
-
-        try (FileOutputStream outputStream = new FileOutputStream(mOutput)) {
-            while (true) {
-                Optional<String> commandString = readCommand(diffScript);
-                if (!commandString.isPresent()) {
-                    return;
-                }
-                Command command = Command.parse(commandString.get());
-
-                if (command.mIsRange) {
-                    checkFileRange(command.mCount, command.mLimit);
-                    copyRange(randomAccessInput, outputStream, command.mCount, command.mLimit);
-                } else {
-                    long bytesCopied = copyBytes(diffScript, outputStream, command.mCount);
-                    if (bytesCopied < command.mCount) {
-                        throw new MalformedDiffScriptException(
-                                String.format(
-                                        Locale.US,
-                                        "Command to copy %d bytes from diff script, but only %d"
-                                            + " bytes available",
-                                        command.mCount,
-                                        bytesCopied));
-                    }
-                    if (diffScript.read() != '\n') {
-                        throw new MalformedDiffScriptException("Expected new line after bytes.");
-                    }
-                }
-            }
-        }
-    }
-
-    private void checkFileRange(long start, long end) throws MalformedDiffScriptException {
-        if (end < start) {
-            throw new MalformedDiffScriptException(
-                    String.format(
-                            Locale.US,
-                            "Command to copy %d-%d bytes from original file, but %2$d < %1$d.",
-                            start,
-                            end));
-        }
-
-        if (end >= mInputLength) {
-            throw new MalformedDiffScriptException(
-                    String.format(
-                            Locale.US,
-                            "Command to copy %d-%d bytes from original file, but file is only %d"
-                                + " bytes long.",
-                            start,
-                            end,
-                            mInputLength));
-        }
-    }
-
-    /**
-     * Reads a command from the input stream.
-     *
-     * @param inputStream The input.
-     * @return Optional of command, or empty if EOF.
-     */
-    private static Optional<String> readCommand(InputStream inputStream) throws IOException {
-        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
-
-        int b;
-        while (!isEndOfCommand(b = inputStream.read())) {
-            byteArrayOutputStream.write(b);
-        }
-
-        byte[] bytes = byteArrayOutputStream.toByteArray();
-        if (bytes.length == 0) {
-            return Optional.empty();
-        } else {
-            return Optional.of(new String(bytes, UTF_8));
-        }
-    }
-
-    /**
-     * If the given output from {@link InputStream#read()} is the end of a command - i.e., a new
-     * line or the EOF.
-     *
-     * @param b The byte or -1.
-     * @return {@code true} if ends the command.
-     */
-    private static boolean isEndOfCommand(int b) {
-        return b == -1 || b == '\n';
-    }
-
-    /**
-     * Copies {@code n} bytes from {@code inputStream} to {@code outputStream}.
-     *
-     * @return The number of bytes copied.
-     * @throws IOException if there was a problem reading or writing.
-     */
-    private static long copyBytes(InputStream inputStream, OutputStream outputStream, long n)
-            throws IOException {
-        byte[] buffer = new byte[COPY_BUFFER_SIZE];
-        long copied = 0;
-        while (n - copied > COPY_BUFFER_SIZE) {
-            long read = copyBlock(inputStream, outputStream, buffer, COPY_BUFFER_SIZE);
-            if (read <= 0) {
-                return copied;
-            }
-        }
-        while (n - copied > 0) {
-            copied += copyBlock(inputStream, outputStream, buffer, (int) (n - copied));
-        }
-        return copied;
-    }
-
-    private static long copyBlock(
-            InputStream inputStream, OutputStream outputStream, byte[] buffer, int size)
-            throws IOException {
-        int read = inputStream.read(buffer, 0, size);
-        outputStream.write(buffer, 0, read);
-        return read;
-    }
-
-    /**
-     * Copies the given range of bytes from the input file to the output stream.
-     *
-     * @param input The input file.
-     * @param output The output stream.
-     * @param start Start position in the input file.
-     * @param end End position in the output file (inclusive).
-     * @throws IOException if there was a problem reading or writing.
-     */
-    private static void copyRange(RandomAccessFile input, OutputStream output, long start, long end)
-            throws IOException {
-        input.seek(start);
-
-        // Inefficient but obviously correct. If tests become slow, optimize.
-        for (; start <= end; start++) {
-            output.write(input.read());
-        }
-    }
-
-    /** Error thrown for a malformed diff script. */
-    public static class MalformedDiffScriptException extends Exception {
-        public MalformedDiffScriptException(String message) {
-            super(message);
-        }
-    }
-
-    /**
-     * A command telling the processor either to insert n bytes, which follow, or copy n-m bytes
-     * from the original file.
-     */
-    private static class Command {
-        private final long mCount;
-        private final long mLimit;
-        private final boolean mIsRange;
-
-        private Command(long count, long limit, boolean isRange) {
-            mCount = count;
-            mLimit = limit;
-            mIsRange = isRange;
-        }
-
-        /**
-         * Attempts to parse the command string into a usable structure.
-         *
-         * @param command The command string, without a new line at the end.
-         * @throws MalformedDiffScriptException if the command is not a valid diff script command.
-         * @return The parsed command.
-         */
-        private static Command parse(String command) throws MalformedDiffScriptException {
-            if (!VALID_COMMAND_PATTERN.matcher(command).matches()) {
-                throw new MalformedDiffScriptException("Bad command: " + command);
-            }
-
-            Scanner commandScanner = new Scanner(command);
-            commandScanner.useDelimiter("-");
-            long n = commandScanner.nextLong();
-            if (!commandScanner.hasNextLong()) {
-                return new Command(n, 0L, /*isRange=*/ false);
-            }
-            long m = commandScanner.nextLong();
-            return new Command(n, m, /*isRange=*/ true);
-        }
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/testing/QueuingNonAutomaticExecutorService.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/testing/QueuingNonAutomaticExecutorService.java
deleted file mode 100644
index 9d2272e..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/testing/QueuingNonAutomaticExecutorService.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.encryption.testing;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.AbstractExecutorService;
-import java.util.concurrent.TimeUnit;
-
-/**
- * ExecutorService which needs to be stepped through the jobs in its' queue.
- *
- * <p>This is a deliberately simple implementation because it's only used in testing. The queued
- * jobs are run on the main thread to eliminate any race condition bugs.
- */
-public class QueuingNonAutomaticExecutorService extends AbstractExecutorService {
-
-    private List<Runnable> mWaitingJobs = new ArrayList<>();
-    private int mWaitingJobCount = 0;
-
-    @Override
-    public void shutdown() {
-        mWaitingJobCount = mWaitingJobs.size();
-        mWaitingJobs = null; // This will force an error if jobs are submitted after shutdown
-    }
-
-    @Override
-    public List<Runnable> shutdownNow() {
-        List<Runnable> queuedJobs = mWaitingJobs;
-        shutdown();
-        return queuedJobs;
-    }
-
-    @Override
-    public boolean isShutdown() {
-        return mWaitingJobs == null;
-    }
-
-    @Override
-    public boolean isTerminated() {
-        return mWaitingJobs == null && mWaitingJobCount == 0;
-    }
-
-    @Override
-    public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
-        long expiry = System.currentTimeMillis() + unit.toMillis(timeout);
-        for (Runnable job : mWaitingJobs) {
-            if (System.currentTimeMillis() > expiry) {
-                return false;
-            }
-
-            job.run();
-        }
-        return true;
-    }
-
-    @Override
-    public void execute(Runnable command) {
-        mWaitingJobs.add(command);
-    }
-
-    public void runNext() {
-        if (mWaitingJobs.isEmpty()) {
-            throw new IllegalStateException("Attempted to run jobs on an empty paused executor");
-        }
-
-        mWaitingJobs.remove(0).run();
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/testing/RandomInputStream.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/testing/RandomInputStream.java
deleted file mode 100644
index 998da0b..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/testing/RandomInputStream.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2019 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.backup.testing;
-
-import static com.android.internal.util.Preconditions.checkArgument;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Random;
-
-/** {@link InputStream} that generates random bytes up to a given length. For testing purposes. */
-public class RandomInputStream extends InputStream {
-    private static final int BYTE_MAX_VALUE = 255;
-
-    private final Random mRandom;
-    private final int mSizeBytes;
-    private int mBytesRead;
-
-    /**
-     * A new instance, generating {@code sizeBytes} from {@code random} as a source.
-     *
-     * @param random Source of random bytes.
-     * @param sizeBytes The number of bytes to generate before closing the stream.
-     */
-    public RandomInputStream(Random random, int sizeBytes) {
-        mRandom = random;
-        mSizeBytes = sizeBytes;
-        mBytesRead = 0;
-    }
-
-    @Override
-    public int read() throws IOException {
-        if (isFinished()) {
-            return -1;
-        }
-        mBytesRead++;
-        return mRandom.nextInt(BYTE_MAX_VALUE);
-    }
-
-    @Override
-    public int read(byte[] b, int off, int len) throws IOException {
-        checkArgument(off + len <= b.length);
-        if (isFinished()) {
-            return -1;
-        }
-        int length = Math.min(len, mSizeBytes - mBytesRead);
-        int end = off + length;
-
-        for (int i = off; i < end; ) {
-            for (int rnd = mRandom.nextInt(), n = Math.min(end - i, Integer.SIZE / Byte.SIZE);
-                    n-- > 0;
-                    rnd >>= Byte.SIZE) {
-                b[i++] = (byte) rnd;
-            }
-        }
-
-        mBytesRead += length;
-        return length;
-    }
-
-    private boolean isFinished() {
-        return mBytesRead >= mSizeBytes;
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/testing/CryptoTestUtils.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/testing/CryptoTestUtils.java
deleted file mode 100644
index b0c02ba..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/testing/CryptoTestUtils.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2018 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.backup.testing;
-
-import android.util.Pair;
-
-import com.android.server.backup.encryption.chunk.ChunkHash;
-import com.android.server.backup.encryption.protos.nano.ChunksMetadataProto;
-import com.android.server.backup.encryption.protos.nano.KeyValuePairProto;
-
-import java.nio.charset.Charset;
-import java.security.NoSuchAlgorithmException;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Random;
-
-import javax.crypto.KeyGenerator;
-import javax.crypto.SecretKey;
-
-/** Helpers for crypto code tests. */
-public class CryptoTestUtils {
-    private static final String KEY_ALGORITHM = "AES";
-    private static final int KEY_SIZE_BITS = 256;
-
-    private CryptoTestUtils() {}
-
-    public static SecretKey generateAesKey() throws NoSuchAlgorithmException {
-        KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_ALGORITHM);
-        keyGenerator.init(KEY_SIZE_BITS);
-        return keyGenerator.generateKey();
-    }
-
-    /** Generates a byte array of size {@code n} containing random bytes. */
-    public static byte[] generateRandomBytes(int n) {
-        byte[] bytes = new byte[n];
-        Random random = new Random();
-        random.nextBytes(bytes);
-        return bytes;
-    }
-
-    public static ChunksMetadataProto.Chunk newChunk(ChunkHash hash, int length) {
-        return newChunk(hash.getHash(), length);
-    }
-
-    public static ChunksMetadataProto.Chunk newChunk(byte[] hash, int length) {
-        ChunksMetadataProto.Chunk newChunk = new ChunksMetadataProto.Chunk();
-        newChunk.hash = Arrays.copyOf(hash, hash.length);
-        newChunk.length = length;
-        return newChunk;
-    }
-
-    public static ChunksMetadataProto.ChunkListing newChunkListing(
-            String docId,
-            byte[] fingerprintSalt,
-            int cipherType,
-            int orderingType,
-            ChunksMetadataProto.Chunk... chunks) {
-        ChunksMetadataProto.ChunkListing chunkListing =
-                newChunkListingWithoutDocId(fingerprintSalt, cipherType, orderingType, chunks);
-        chunkListing.documentId = docId;
-        return chunkListing;
-    }
-
-    public static ChunksMetadataProto.ChunkListing newChunkListingWithoutDocId(
-            byte[] fingerprintSalt,
-            int cipherType,
-            int orderingType,
-            ChunksMetadataProto.Chunk... chunks) {
-        ChunksMetadataProto.ChunkListing chunkListing = new ChunksMetadataProto.ChunkListing();
-        chunkListing.fingerprintMixerSalt =
-                fingerprintSalt == null
-                        ? null
-                        : Arrays.copyOf(fingerprintSalt, fingerprintSalt.length);
-        chunkListing.cipherType = cipherType;
-        chunkListing.chunkOrderingType = orderingType;
-        chunkListing.chunks = chunks;
-        return chunkListing;
-    }
-
-    public static ChunksMetadataProto.ChunkOrdering newChunkOrdering(
-            int[] starts, byte[] checksum) {
-        ChunksMetadataProto.ChunkOrdering chunkOrdering = new ChunksMetadataProto.ChunkOrdering();
-        chunkOrdering.starts = starts == null ? null : Arrays.copyOf(starts, starts.length);
-        chunkOrdering.checksum =
-                checksum == null ? checksum : Arrays.copyOf(checksum, checksum.length);
-        return chunkOrdering;
-    }
-
-    public static ChunksMetadataProto.ChunksMetadata newChunksMetadata(
-            int cipherType, int checksumType, int chunkOrderingType, byte[] chunkOrdering) {
-        ChunksMetadataProto.ChunksMetadata metadata = new ChunksMetadataProto.ChunksMetadata();
-        metadata.cipherType = cipherType;
-        metadata.checksumType = checksumType;
-        metadata.chunkOrdering = Arrays.copyOf(chunkOrdering, chunkOrdering.length);
-        metadata.chunkOrderingType = chunkOrderingType;
-        return metadata;
-    }
-
-    public static KeyValuePairProto.KeyValuePair newPair(String key, String value) {
-        return newPair(key, value.getBytes(Charset.forName("UTF-8")));
-    }
-
-    public static KeyValuePairProto.KeyValuePair newPair(String key, byte[] value) {
-        KeyValuePairProto.KeyValuePair newPair = new KeyValuePairProto.KeyValuePair();
-        newPair.key = key;
-        newPair.value = value;
-        return newPair;
-    }
-
-    public static ChunksMetadataProto.ChunkListing clone(
-            ChunksMetadataProto.ChunkListing original) {
-        ChunksMetadataProto.Chunk[] clonedChunks;
-        if (original.chunks == null) {
-            clonedChunks = null;
-        } else {
-            clonedChunks = new ChunksMetadataProto.Chunk[original.chunks.length];
-            for (int i = 0; i < original.chunks.length; i++) {
-                clonedChunks[i] = clone(original.chunks[i]);
-            }
-        }
-
-        return newChunkListing(
-                original.documentId,
-                original.fingerprintMixerSalt,
-                original.cipherType,
-                original.chunkOrderingType,
-                clonedChunks);
-    }
-
-    public static ChunksMetadataProto.Chunk clone(ChunksMetadataProto.Chunk original) {
-        return newChunk(original.hash, original.length);
-    }
-
-    public static ChunksMetadataProto.ChunksMetadata clone(
-            ChunksMetadataProto.ChunksMetadata original) {
-        ChunksMetadataProto.ChunksMetadata cloneMetadata = new ChunksMetadataProto.ChunksMetadata();
-        cloneMetadata.chunkOrderingType = original.chunkOrderingType;
-        cloneMetadata.chunkOrdering =
-                original.chunkOrdering == null
-                        ? null
-                        : Arrays.copyOf(original.chunkOrdering, original.chunkOrdering.length);
-        cloneMetadata.checksumType = original.checksumType;
-        cloneMetadata.cipherType = original.cipherType;
-        return cloneMetadata;
-    }
-
-    public static ChunksMetadataProto.ChunkOrdering clone(
-            ChunksMetadataProto.ChunkOrdering original) {
-        ChunksMetadataProto.ChunkOrdering clone = new ChunksMetadataProto.ChunkOrdering();
-        clone.starts = Arrays.copyOf(original.starts, original.starts.length);
-        clone.checksum = Arrays.copyOf(original.checksum, original.checksum.length);
-        return clone;
-    }
-
-    public static <K, V> Map<K, V> mapOf(Pair<K, V>... pairs) {
-        Map<K, V> map = new HashMap<>();
-        for (Pair<K, V> pair : pairs) {
-            map.put(pair.first, pair.second);
-        }
-        return map;
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/testing/TestFileUtils.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/testing/TestFileUtils.java
deleted file mode 100644
index e5d73ba..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/testing/TestFileUtils.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-import com.google.common.io.ByteStreams;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-
-/** Utility methods for use in tests */
-public class TestFileUtils {
-    /** Read the contents of a file into a byte array */
-    public static byte[] toByteArray(File file) throws IOException {
-        try (FileInputStream fis = new FileInputStream(file)) {
-            return ByteStreams.toByteArray(fis);
-        }
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/testing/fakes/FakeCryptoBackupServer.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/testing/fakes/FakeCryptoBackupServer.java
deleted file mode 100644
index 3329060..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/testing/fakes/FakeCryptoBackupServer.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2018 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.testing.fakes;
-
-import android.annotation.Nullable;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.server.backup.encryption.client.CryptoBackupServer;
-import com.android.server.backup.encryption.client.UnexpectedActiveSecondaryOnServerException;
-import com.android.server.backup.encryption.protos.nano.WrappedKeyProto;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Optional;
-
-/** Fake {@link CryptoBackupServer}, for tests. Stores tertiary keys in memory. */
-public class FakeCryptoBackupServer implements CryptoBackupServer {
-    @GuardedBy("this")
-    @Nullable
-    private String mActiveSecondaryKeyAlias;
-
-    // Secondary key alias -> (package name -> tertiary key)
-    @GuardedBy("this")
-    private Map<String, Map<String, WrappedKeyProto.WrappedKey>> mWrappedKeyStore = new HashMap<>();
-
-    @Override
-    public String uploadIncrementalBackup(
-            String packageName,
-            String oldDocId,
-            byte[] diffScript,
-            WrappedKeyProto.WrappedKey tertiaryKey) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String uploadNonIncrementalBackup(
-            String packageName, byte[] data, WrappedKeyProto.WrappedKey tertiaryKey) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public synchronized void setActiveSecondaryKeyAlias(
-            String keyAlias, Map<String, WrappedKeyProto.WrappedKey> tertiaryKeys) {
-        mActiveSecondaryKeyAlias = keyAlias;
-
-        mWrappedKeyStore.putIfAbsent(keyAlias, new HashMap<>());
-        Map<String, WrappedKeyProto.WrappedKey> keyStore = mWrappedKeyStore.get(keyAlias);
-
-        for (String packageName : tertiaryKeys.keySet()) {
-            keyStore.put(packageName, tertiaryKeys.get(packageName));
-        }
-    }
-
-    public synchronized Optional<String> getActiveSecondaryKeyAlias() {
-        return Optional.ofNullable(mActiveSecondaryKeyAlias);
-    }
-
-    public synchronized Map<String, WrappedKeyProto.WrappedKey> getAllTertiaryKeys(
-            String secondaryKeyAlias) throws UnexpectedActiveSecondaryOnServerException {
-        if (!secondaryKeyAlias.equals(mActiveSecondaryKeyAlias)) {
-            throw new UnexpectedActiveSecondaryOnServerException(
-                    String.format(
-                            Locale.US,
-                            "Requested tertiary keys wrapped with %s but %s was active secondary.",
-                            secondaryKeyAlias,
-                            mActiveSecondaryKeyAlias));
-        }
-
-        if (!mWrappedKeyStore.containsKey(secondaryKeyAlias)) {
-            return Collections.emptyMap();
-        }
-        return new HashMap<>(mWrappedKeyStore.get(secondaryKeyAlias));
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/testing/fakes/FakeCryptoBackupServerTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/testing/fakes/FakeCryptoBackupServerTest.java
deleted file mode 100644
index 4cd8333b..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/testing/fakes/FakeCryptoBackupServerTest.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2019 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.testing.fakes;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertThrows;
-
-import android.util.Pair;
-
-import com.android.server.backup.encryption.client.UnexpectedActiveSecondaryOnServerException;
-import com.android.server.backup.encryption.protos.nano.WrappedKeyProto;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.nio.charset.Charset;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-public class FakeCryptoBackupServerTest {
-    private static final String PACKAGE_NAME_1 = "package1";
-    private static final String PACKAGE_NAME_2 = "package2";
-    private static final String PACKAGE_NAME_3 = "package3";
-    private static final WrappedKeyProto.WrappedKey PACKAGE_KEY_1 = createWrappedKey("key1");
-    private static final WrappedKeyProto.WrappedKey PACKAGE_KEY_2 = createWrappedKey("key2");
-    private static final WrappedKeyProto.WrappedKey PACKAGE_KEY_3 = createWrappedKey("key3");
-
-    private FakeCryptoBackupServer mServer;
-
-    @Before
-    public void setUp() {
-        mServer = new FakeCryptoBackupServer();
-    }
-
-    @Test
-    public void getActiveSecondaryKeyAlias_isInitiallyAbsent() throws Exception {
-        assertFalse(mServer.getActiveSecondaryKeyAlias().isPresent());
-    }
-
-    @Test
-    public void setActiveSecondaryKeyAlias_setsTheKeyAlias() throws Exception {
-        String keyAlias = "test";
-        mServer.setActiveSecondaryKeyAlias(keyAlias, Collections.emptyMap());
-        assertThat(mServer.getActiveSecondaryKeyAlias().get()).isEqualTo(keyAlias);
-    }
-
-    @Test
-    public void getAllTertiaryKeys_returnsWrappedKeys() throws Exception {
-        Map<String, WrappedKeyProto.WrappedKey> entries =
-                createKeyMap(
-                        new Pair<>(PACKAGE_NAME_1, PACKAGE_KEY_1),
-                        new Pair<>(PACKAGE_NAME_2, PACKAGE_KEY_2));
-        String secondaryKeyAlias = "doge";
-        mServer.setActiveSecondaryKeyAlias(secondaryKeyAlias, entries);
-
-        assertThat(mServer.getAllTertiaryKeys(secondaryKeyAlias)).containsExactlyEntriesIn(entries);
-    }
-
-    @Test
-    public void addTertiaryKeys_updatesExistingSet() throws Exception {
-        String keyId = "karlin";
-        WrappedKeyProto.WrappedKey replacementKey = createWrappedKey("some replacement bytes");
-
-        mServer.setActiveSecondaryKeyAlias(
-                keyId,
-                createKeyMap(
-                        new Pair<>(PACKAGE_NAME_1, PACKAGE_KEY_1),
-                        new Pair<>(PACKAGE_NAME_2, PACKAGE_KEY_2)));
-
-        mServer.setActiveSecondaryKeyAlias(
-                keyId,
-                createKeyMap(
-                        new Pair<>(PACKAGE_NAME_1, replacementKey),
-                        new Pair<>(PACKAGE_NAME_3, PACKAGE_KEY_3)));
-
-        assertThat(mServer.getAllTertiaryKeys(keyId))
-                .containsExactlyEntriesIn(
-                        createKeyMap(
-                                new Pair<>(PACKAGE_NAME_1, replacementKey),
-                                new Pair<>(PACKAGE_NAME_2, PACKAGE_KEY_2),
-                                new Pair<>(PACKAGE_NAME_3, PACKAGE_KEY_3)));
-    }
-
-    @Test
-    public void getAllTertiaryKeys_throwsForUnknownSecondaryKeyAlias() throws Exception {
-        assertThrows(
-                UnexpectedActiveSecondaryOnServerException.class,
-                () -> mServer.getAllTertiaryKeys("unknown"));
-    }
-
-    @Test
-    public void uploadIncrementalBackup_throwsUnsupportedOperationException() {
-        assertThrows(
-                UnsupportedOperationException.class,
-                () ->
-                        mServer.uploadIncrementalBackup(
-                                PACKAGE_NAME_1,
-                                "docid",
-                                new byte[0],
-                                new WrappedKeyProto.WrappedKey()));
-    }
-
-    @Test
-    public void uploadNonIncrementalBackup_throwsUnsupportedOperationException() {
-        assertThrows(
-                UnsupportedOperationException.class,
-                () ->
-                        mServer.uploadNonIncrementalBackup(
-                                PACKAGE_NAME_1, new byte[0], new WrappedKeyProto.WrappedKey()));
-    }
-
-    private static WrappedKeyProto.WrappedKey createWrappedKey(String data) {
-        WrappedKeyProto.WrappedKey wrappedKey = new WrappedKeyProto.WrappedKey();
-        wrappedKey.key = data.getBytes(Charset.forName("UTF-8"));
-        return wrappedKey;
-    }
-
-    private Map<String, WrappedKeyProto.WrappedKey> createKeyMap(
-            Pair<String, WrappedKeyProto.WrappedKey>... pairs) {
-        Map<String, WrappedKeyProto.WrappedKey> map = new HashMap<>();
-        for (Pair<String, WrappedKeyProto.WrappedKey> pair : pairs) {
-            map.put(pair.first, pair.second);
-        }
-        return map;
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/testing/shadows/DataEntity.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/testing/shadows/DataEntity.java
deleted file mode 100644
index 06f4859..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/testing/shadows/DataEntity.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2019 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.testing.shadows;
-
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.Objects;
-
-/**
- * Represents a key value pair in {@link ShadowBackupDataInput} and {@link ShadowBackupDataOutput}.
- */
-public class DataEntity {
-    public final String mKey;
-    public final byte[] mValue;
-    public final int mSize;
-
-    /**
-     * Constructs a pair with a string value. The value will be converted to a byte array in {@link
-     * StandardCharsets#UTF_8}.
-     */
-    public DataEntity(String key, String value) {
-        this.mKey = Objects.requireNonNull(key);
-        this.mValue = value.getBytes(StandardCharsets.UTF_8);
-        mSize = this.mValue.length;
-    }
-
-    /**
-     * Constructs a new entity with the given key but a negative size. This represents a deleted
-     * pair.
-     */
-    public DataEntity(String key) {
-        this.mKey = Objects.requireNonNull(key);
-        mSize = -1;
-        mValue = null;
-    }
-
-    /** Constructs a new entity where the size of the value is the entire array. */
-    public DataEntity(String key, byte[] value) {
-        this(key, value, value.length);
-    }
-
-    /**
-     * Constructs a new entity.
-     *
-     * @param key the key of the pair
-     * @param data the value to associate with the key
-     * @param size the length of the value in bytes
-     */
-    public DataEntity(String key, byte[] data, int size) {
-        this.mKey = Objects.requireNonNull(key);
-        this.mSize = size;
-        mValue = new byte[size];
-        for (int i = 0; i < size; i++) {
-            mValue[i] = data[i];
-        }
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (o == null || getClass() != o.getClass()) {
-            return false;
-        }
-
-        DataEntity that = (DataEntity) o;
-
-        if (mSize != that.mSize) {
-            return false;
-        }
-        if (!mKey.equals(that.mKey)) {
-            return false;
-        }
-        return Arrays.equals(mValue, that.mValue);
-    }
-
-    @Override
-    public int hashCode() {
-        int result = mKey.hashCode();
-        result = 31 * result + Arrays.hashCode(mValue);
-        result = 31 * result + mSize;
-        return result;
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/testing/shadows/ShadowBackupDataInput.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/testing/shadows/ShadowBackupDataInput.java
deleted file mode 100644
index 7ac6ec4..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/testing/shadows/ShadowBackupDataInput.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2019 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.testing.shadows;
-
-import static com.google.common.base.Preconditions.checkState;
-
-import android.annotation.Nullable;
-import android.app.backup.BackupDataInput;
-
-import org.robolectric.annotation.Implementation;
-import org.robolectric.annotation.Implements;
-
-import java.io.ByteArrayInputStream;
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-/** Shadow for BackupDataInput. */
-@Implements(BackupDataInput.class)
-public class ShadowBackupDataInput {
-    private static final List<DataEntity> ENTITIES = new ArrayList<>();
-    @Nullable private static IOException sReadNextHeaderException;
-
-    @Nullable private ByteArrayInputStream mCurrentEntityInputStream;
-    private int mCurrentEntity = -1;
-
-    /** Resets the shadow, clearing any entities or exception. */
-    public static void reset() {
-        ENTITIES.clear();
-        sReadNextHeaderException = null;
-    }
-
-    /** Sets the exception which the input will throw for any call to {@link #readNextHeader}. */
-    public static void setReadNextHeaderException(@Nullable IOException readNextHeaderException) {
-        ShadowBackupDataInput.sReadNextHeaderException = readNextHeaderException;
-    }
-
-    /** Adds the given entity to the input. */
-    public static void addEntity(DataEntity e) {
-        ENTITIES.add(e);
-    }
-
-    /** Adds an entity to the input with the given key and value. */
-    public static void addEntity(String key, byte[] value) {
-        ENTITIES.add(new DataEntity(key, value, value.length));
-    }
-
-    public void __constructor__(FileDescriptor fd) {}
-
-    @Implementation
-    public boolean readNextHeader() throws IOException {
-        if (sReadNextHeaderException != null) {
-            throw sReadNextHeaderException;
-        }
-
-        mCurrentEntity++;
-
-        if (mCurrentEntity >= ENTITIES.size()) {
-            return false;
-        }
-
-        byte[] value = ENTITIES.get(mCurrentEntity).mValue;
-        if (value == null) {
-            mCurrentEntityInputStream = new ByteArrayInputStream(new byte[0]);
-        } else {
-            mCurrentEntityInputStream = new ByteArrayInputStream(value);
-        }
-        return true;
-    }
-
-    @Implementation
-    public String getKey() {
-        return ENTITIES.get(mCurrentEntity).mKey;
-    }
-
-    @Implementation
-    public int getDataSize() {
-        return ENTITIES.get(mCurrentEntity).mSize;
-    }
-
-    @Implementation
-    public void skipEntityData() {
-        // Do nothing.
-    }
-
-    @Implementation
-    public int readEntityData(byte[] data, int offset, int size) {
-        checkState(mCurrentEntityInputStream != null, "Must call readNextHeader() first");
-        return mCurrentEntityInputStream.read(data, offset, size);
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/testing/shadows/ShadowBackupDataOutput.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/testing/shadows/ShadowBackupDataOutput.java
deleted file mode 100644
index 2302e55..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/testing/shadows/ShadowBackupDataOutput.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2019 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.testing.shadows;
-
-import android.app.backup.BackupDataOutput;
-
-import java.io.FileDescriptor;
-import java.util.ArrayList;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Set;
-
-import org.junit.Assert;
-import org.robolectric.annotation.Implementation;
-import org.robolectric.annotation.Implements;
-
-/** Shadow for BackupDataOutput. */
-@Implements(BackupDataOutput.class)
-public class ShadowBackupDataOutput {
-    private static final List<DataEntity> ENTRIES = new ArrayList<>();
-
-    private String mCurrentKey;
-    private int mDataSize;
-
-    public static void reset() {
-        ENTRIES.clear();
-    }
-
-    public static Set<DataEntity> getEntities() {
-        return new LinkedHashSet<>(ENTRIES);
-    }
-
-    public void __constructor__(FileDescriptor fd) {}
-
-    public void __constructor__(FileDescriptor fd, long quota) {}
-
-    public void __constructor__(FileDescriptor fd, long quota, int transportFlags) {}
-
-    @Implementation
-    public int writeEntityHeader(String key, int size) {
-        mCurrentKey = key;
-        mDataSize = size;
-        return 0;
-    }
-
-    @Implementation
-    public int writeEntityData(byte[] data, int size) {
-        Assert.assertEquals("ShadowBackupDataOutput expects size = mDataSize", size, mDataSize);
-        ENTRIES.add(new DataEntity(mCurrentKey, data, mDataSize));
-        return 0;
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/testing/shadows/ShadowInternalRecoveryServiceException.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/testing/shadows/ShadowInternalRecoveryServiceException.java
deleted file mode 100644
index 9c06d81..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/testing/shadows/ShadowInternalRecoveryServiceException.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2018 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.testing.shadows;
-
-import android.security.keystore.recovery.InternalRecoveryServiceException;
-
-import org.robolectric.annotation.Implementation;
-import org.robolectric.annotation.Implements;
-
-/** Shadow {@link InternalRecoveryServiceException}. */
-@Implements(InternalRecoveryServiceException.class)
-public class ShadowInternalRecoveryServiceException {
-    private String mMessage;
-
-    @Implementation
-    public void __constructor__(String message) {
-        mMessage = message;
-    }
-
-    @Implementation
-    public void __constructor__(String message, Throwable cause) {
-        mMessage = message;
-    }
-
-    @Implementation
-    public String getMessage() {
-        return mMessage;
-    }
-}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/testing/shadows/ShadowRecoveryController.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/testing/shadows/ShadowRecoveryController.java
deleted file mode 100644
index 7dad8a4..0000000
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/testing/shadows/ShadowRecoveryController.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2018 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.testing.shadows;
-
-import android.content.Context;
-import android.security.keystore.recovery.InternalRecoveryServiceException;
-import android.security.keystore.recovery.LockScreenRequiredException;
-import android.security.keystore.recovery.RecoveryController;
-
-import com.google.common.collect.ImmutableList;
-
-import org.robolectric.annotation.Implementation;
-import org.robolectric.annotation.Implements;
-import org.robolectric.annotation.Resetter;
-
-import java.lang.reflect.Constructor;
-import java.security.Key;
-import java.security.NoSuchAlgorithmException;
-import java.security.UnrecoverableKeyException;
-import java.util.HashMap;
-import java.util.List;
-
-import javax.crypto.KeyGenerator;
-
-/**
- * Shadow of {@link RecoveryController}.
- *
- * <p>Instead of generating keys via the {@link RecoveryController}, this shadow generates them in
- * memory.
- */
-@Implements(RecoveryController.class)
-public class ShadowRecoveryController {
-    private static final String KEY_GENERATOR_ALGORITHM = "AES";
-    private static final int KEY_SIZE_BITS = 256;
-
-    private static boolean sIsSupported = true;
-    private static boolean sThrowsInternalError = false;
-    private static HashMap<String, Key> sKeysByAlias = new HashMap<>();
-    private static HashMap<String, Integer> sKeyStatusesByAlias = new HashMap<>();
-
-    @Implementation
-    public void __constructor__() {
-        // do not throw
-    }
-
-    @Implementation
-    public static RecoveryController getInstance(Context context) {
-        // Call non-public constructor.
-        try {
-            Constructor<RecoveryController> constructor = RecoveryController.class.getConstructor();
-            return constructor.newInstance();
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    @Implementation
-    public static boolean isRecoverableKeyStoreEnabled(Context context) {
-        return sIsSupported;
-    }
-
-    @Implementation
-    public Key generateKey(String alias)
-            throws InternalRecoveryServiceException, LockScreenRequiredException {
-        maybeThrowError();
-        KeyGenerator keyGenerator;
-        try {
-            keyGenerator = KeyGenerator.getInstance(KEY_GENERATOR_ALGORITHM);
-        } catch (NoSuchAlgorithmException e) {
-            // Should never happen
-            throw new RuntimeException(e);
-        }
-
-        keyGenerator.init(KEY_SIZE_BITS);
-        Key key = keyGenerator.generateKey();
-        sKeysByAlias.put(alias, key);
-        sKeyStatusesByAlias.put(alias, RecoveryController.RECOVERY_STATUS_SYNC_IN_PROGRESS);
-        return key;
-    }
-
-    @Implementation
-    public Key getKey(String alias)
-            throws InternalRecoveryServiceException, UnrecoverableKeyException {
-        return sKeysByAlias.get(alias);
-    }
-
-    @Implementation
-    public void removeKey(String alias) throws InternalRecoveryServiceException {
-        sKeyStatusesByAlias.remove(alias);
-        sKeysByAlias.remove(alias);
-    }
-
-    @Implementation
-    public int getRecoveryStatus(String alias) throws InternalRecoveryServiceException {
-        maybeThrowError();
-        return sKeyStatusesByAlias.getOrDefault(
-                alias, RecoveryController.RECOVERY_STATUS_PERMANENT_FAILURE);
-    }
-
-    @Implementation
-    public List<String> getAliases() throws InternalRecoveryServiceException {
-        return ImmutableList.copyOf(sKeyStatusesByAlias.keySet());
-    }
-
-    private static void maybeThrowError() throws InternalRecoveryServiceException {
-        if (sThrowsInternalError) {
-            throw new InternalRecoveryServiceException("test error");
-        }
-    }
-
-    /** Sets the recovery status of the key with {@code alias} to {@code status}. */
-    public static void setRecoveryStatus(String alias, int status) {
-        sKeyStatusesByAlias.put(alias, status);
-    }
-
-    /** Sets all existing keys to being synced. */
-    public static void syncAllKeys() {
-        for (String alias : sKeysByAlias.keySet()) {
-            sKeyStatusesByAlias.put(alias, RecoveryController.RECOVERY_STATUS_SYNCED);
-        }
-    }
-
-    public static void setThrowsInternalError(boolean throwsInternalError) {
-        ShadowRecoveryController.sThrowsInternalError = throwsInternalError;
-    }
-
-    public static void setIsSupported(boolean isSupported) {
-        ShadowRecoveryController.sIsSupported = isSupported;
-    }
-
-    @Resetter
-    public static void reset() {
-        sIsSupported = true;
-        sThrowsInternalError = false;
-        sKeysByAlias.clear();
-        sKeyStatusesByAlias.clear();
-    }
-}
diff --git a/packages/BackupEncryption/test/unittest/Android.bp b/packages/BackupEncryption/test/unittest/Android.bp
deleted file mode 100644
index f005170..0000000
--- a/packages/BackupEncryption/test/unittest/Android.bp
+++ /dev/null
@@ -1,31 +0,0 @@
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "frameworks_base_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["frameworks_base_license"],
-}
-
-android_test {
-    name: "BackupEncryptionUnitTests",
-    srcs: ["src/**/*.java"],
-    static_libs: [
-        "androidx.test.runner",
-        "androidx.test.rules",
-        "mockito-target-minus-junit4",
-        "platform-test-annotations",
-        "truth-prebuilt",
-        "testables",
-        "testng",
-    ],
-    libs: [
-        "android.test.mock",
-        "android.test.base",
-        "android.test.runner",
-        "BackupEncryption",
-    ],
-    test_suites: ["device-tests"],
-    instrumentation_for: "BackupEncryption",
-    certificate: "platform",
-}
diff --git a/packages/BackupEncryption/test/unittest/AndroidManifest.xml b/packages/BackupEncryption/test/unittest/AndroidManifest.xml
deleted file mode 100644
index 39ac8aa3..0000000
--- a/packages/BackupEncryption/test/unittest/AndroidManifest.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.server.backup.encryption.unittests"
-          android:sharedUserId="android.uid.system" >
-    <application android:testOnly="true">
-        <uses-library android:name="android.test.runner" />
-    </application>
-    <instrumentation
-        android:name="androidx.test.runner.AndroidJUnitRunner"
-        android:targetPackage="com.android.server.backup.encryption"
-        android:label="Backup Encryption Unit Tests" />
-</manifest>
\ No newline at end of file
diff --git a/packages/BackupEncryption/test/unittest/AndroidTest.xml b/packages/BackupEncryption/test/unittest/AndroidTest.xml
deleted file mode 100644
index c9c812a..0000000
--- a/packages/BackupEncryption/test/unittest/AndroidTest.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2019 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.
-  -->
-<configuration description="Runs Backup Encryption Unit Tests.">
-    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
-        <option name="cleanup-apks" value="true" />
-        <option name="install-arg" value="-t" />
-        <option name="test-file-name" value="BackupEncryptionUnitTests.apk" />
-    </target_preparer>
-
-    <option name="test-tag" value="BackupEncryptionUnitTests" />
-    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="com.android.server.backup.encryption.unittests" />
-        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
-    </test>
-</configuration>
diff --git a/services/Android.bp b/services/Android.bp
index 637c4ee..76a1484 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -88,7 +88,6 @@
         ":services.appwidget-sources",
         ":services.autofill-sources",
         ":services.backup-sources",
-        ":backuplib-sources",
         ":services.companion-sources",
         ":services.contentcapture-sources",
         ":services.contentsuggestions-sources",