diff --git a/services/core/java/com/android/server/integrity/parser/RuleMetadataParser.java b/services/core/java/com/android/server/integrity/parser/RuleMetadataParser.java
deleted file mode 100644
index e831e40..0000000
--- a/services/core/java/com/android/server/integrity/parser/RuleMetadataParser.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.integrity.parser;
-
-import android.annotation.Nullable;
-import android.util.Xml;
-
-import com.android.modules.utils.TypedXmlPullParser;
-import com.android.server.integrity.model.RuleMetadata;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-/** Helper class for parsing rule metadata. */
-public class RuleMetadataParser {
-
-    public static final String RULE_PROVIDER_TAG = "P";
-    public static final String VERSION_TAG = "V";
-
-    /** Parse the rule metadata from an input stream. */
-    @Nullable
-    public static RuleMetadata parse(InputStream inputStream)
-            throws XmlPullParserException, IOException {
-
-        String ruleProvider = "";
-        String version = "";
-
-        TypedXmlPullParser xmlPullParser = Xml.resolvePullParser(inputStream);
-
-        int eventType;
-        while ((eventType = xmlPullParser.next()) != XmlPullParser.END_DOCUMENT) {
-            if (eventType == XmlPullParser.START_TAG) {
-                String tag = xmlPullParser.getName();
-                switch (tag) {
-                    case RULE_PROVIDER_TAG:
-                        ruleProvider = xmlPullParser.nextText();
-                        break;
-                    case VERSION_TAG:
-                        version = xmlPullParser.nextText();
-                        break;
-                    default:
-                        throw new IllegalStateException("Unknown tag in metadata: " + tag);
-                }
-            }
-        }
-
-        return new RuleMetadata(ruleProvider, version);
-    }
-}
diff --git a/services/core/java/com/android/server/integrity/serializer/RuleBinarySerializer.java b/services/core/java/com/android/server/integrity/serializer/RuleBinarySerializer.java
deleted file mode 100644
index 8ba5870..0000000
--- a/services/core/java/com/android/server/integrity/serializer/RuleBinarySerializer.java
+++ /dev/null
@@ -1,324 +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.integrity.serializer;
-
-import static com.android.server.integrity.model.ComponentBitSize.ATOMIC_FORMULA_START;
-import static com.android.server.integrity.model.ComponentBitSize.COMPOUND_FORMULA_END;
-import static com.android.server.integrity.model.ComponentBitSize.COMPOUND_FORMULA_START;
-import static com.android.server.integrity.model.ComponentBitSize.CONNECTOR_BITS;
-import static com.android.server.integrity.model.ComponentBitSize.DEFAULT_FORMAT_VERSION;
-import static com.android.server.integrity.model.ComponentBitSize.EFFECT_BITS;
-import static com.android.server.integrity.model.ComponentBitSize.FORMAT_VERSION_BITS;
-import static com.android.server.integrity.model.ComponentBitSize.INSTALLER_ALLOWED_BY_MANIFEST_START;
-import static com.android.server.integrity.model.ComponentBitSize.KEY_BITS;
-import static com.android.server.integrity.model.ComponentBitSize.OPERATOR_BITS;
-import static com.android.server.integrity.model.ComponentBitSize.SEPARATOR_BITS;
-import static com.android.server.integrity.model.ComponentBitSize.VALUE_SIZE_BITS;
-import static com.android.server.integrity.model.IndexingFileConstants.END_INDEXING_KEY;
-import static com.android.server.integrity.model.IndexingFileConstants.INDEXING_BLOCK_SIZE;
-import static com.android.server.integrity.model.IndexingFileConstants.START_INDEXING_KEY;
-import static com.android.server.integrity.serializer.RuleIndexingDetails.APP_CERTIFICATE_INDEXED;
-import static com.android.server.integrity.serializer.RuleIndexingDetails.NOT_INDEXED;
-import static com.android.server.integrity.serializer.RuleIndexingDetails.PACKAGE_NAME_INDEXED;
-
-import android.content.integrity.AtomicFormula;
-import android.content.integrity.CompoundFormula;
-import android.content.integrity.InstallerAllowedByManifestFormula;
-import android.content.integrity.IntegrityFormula;
-import android.content.integrity.IntegrityUtils;
-import android.content.integrity.Rule;
-
-import com.android.internal.util.Preconditions;
-import com.android.server.integrity.model.BitOutputStream;
-import com.android.server.integrity.model.ByteTrackedOutputStream;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.nio.charset.StandardCharsets;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.stream.Collectors;
-
-/** A helper class to serialize rules from the {@link Rule} model to Binary representation. */
-public class RuleBinarySerializer implements RuleSerializer {
-    static final int TOTAL_RULE_SIZE_LIMIT = 200000;
-    static final int INDEXED_RULE_SIZE_LIMIT = 100000;
-    static final int NONINDEXED_RULE_SIZE_LIMIT = 1000;
-
-    // Get the byte representation for a list of rules.
-    @Override
-    public byte[] serialize(List<Rule> rules, Optional<Integer> formatVersion)
-            throws RuleSerializeException {
-        try {
-            ByteArrayOutputStream rulesOutputStream = new ByteArrayOutputStream();
-            serialize(rules, formatVersion, rulesOutputStream, new ByteArrayOutputStream());
-            return rulesOutputStream.toByteArray();
-        } catch (Exception e) {
-            throw new RuleSerializeException(e.getMessage(), e);
-        }
-    }
-
-    // Get the byte representation for a list of rules, and write them to an output stream.
-    @Override
-    public void serialize(
-            List<Rule> rules,
-            Optional<Integer> formatVersion,
-            OutputStream rulesFileOutputStream,
-            OutputStream indexingFileOutputStream)
-            throws RuleSerializeException {
-        try {
-            if (rules == null) {
-                throw new IllegalArgumentException("Null rules cannot be serialized.");
-            }
-
-            if (rules.size() > TOTAL_RULE_SIZE_LIMIT) {
-                throw new IllegalArgumentException("Too many rules provided: " + rules.size());
-            }
-
-            // Determine the indexing groups and the order of the rules within each indexed group.
-            Map<Integer, Map<String, List<Rule>>> indexedRules =
-                    RuleIndexingDetailsIdentifier.splitRulesIntoIndexBuckets(rules);
-
-            // Validate the rule blocks are not larger than expected limits.
-            verifySize(indexedRules.get(PACKAGE_NAME_INDEXED), INDEXED_RULE_SIZE_LIMIT);
-            verifySize(indexedRules.get(APP_CERTIFICATE_INDEXED), INDEXED_RULE_SIZE_LIMIT);
-            verifySize(indexedRules.get(NOT_INDEXED), NONINDEXED_RULE_SIZE_LIMIT);
-
-            // Serialize the rules.
-            ByteTrackedOutputStream ruleFileByteTrackedOutputStream =
-                    new ByteTrackedOutputStream(rulesFileOutputStream);
-            serializeRuleFileMetadata(formatVersion, ruleFileByteTrackedOutputStream);
-            LinkedHashMap<String, Integer> packageNameIndexes =
-                    serializeRuleList(
-                            indexedRules.get(PACKAGE_NAME_INDEXED),
-                            ruleFileByteTrackedOutputStream);
-            LinkedHashMap<String, Integer> appCertificateIndexes =
-                    serializeRuleList(
-                            indexedRules.get(APP_CERTIFICATE_INDEXED),
-                            ruleFileByteTrackedOutputStream);
-            LinkedHashMap<String, Integer> unindexedRulesIndexes =
-                    serializeRuleList(
-                            indexedRules.get(NOT_INDEXED), ruleFileByteTrackedOutputStream);
-
-            // Serialize their indexes.
-            BitOutputStream indexingBitOutputStream = new BitOutputStream(indexingFileOutputStream);
-            serializeIndexGroup(packageNameIndexes, indexingBitOutputStream, /* isIndexed= */ true);
-            serializeIndexGroup(
-                    appCertificateIndexes, indexingBitOutputStream, /* isIndexed= */ true);
-            serializeIndexGroup(
-                    unindexedRulesIndexes, indexingBitOutputStream, /* isIndexed= */ false);
-            indexingBitOutputStream.flush();
-        } catch (Exception e) {
-            throw new RuleSerializeException(e.getMessage(), e);
-        }
-    }
-
-    private void verifySize(Map<String, List<Rule>> ruleListMap, int ruleSizeLimit) {
-        int totalRuleCount =
-                ruleListMap.values().stream()
-                        .map(list -> list.size())
-                        .collect(Collectors.summingInt(Integer::intValue));
-        if (totalRuleCount > ruleSizeLimit) {
-            throw new IllegalArgumentException(
-                    "Too many rules provided in the indexing group. Provided "
-                            + totalRuleCount
-                            + " limit "
-                            + ruleSizeLimit);
-        }
-    }
-
-    private void serializeRuleFileMetadata(
-            Optional<Integer> formatVersion, ByteTrackedOutputStream outputStream)
-            throws IOException {
-        int formatVersionValue = formatVersion.orElse(DEFAULT_FORMAT_VERSION);
-
-        BitOutputStream bitOutputStream = new BitOutputStream(outputStream);
-        bitOutputStream.setNext(FORMAT_VERSION_BITS, formatVersionValue);
-        bitOutputStream.flush();
-    }
-
-    private LinkedHashMap<String, Integer> serializeRuleList(
-            Map<String, List<Rule>> rulesMap, ByteTrackedOutputStream outputStream)
-            throws IOException {
-        Preconditions.checkArgument(
-                rulesMap != null, "serializeRuleList should never be called with null rule list.");
-
-        BitOutputStream bitOutputStream = new BitOutputStream(outputStream);
-        LinkedHashMap<String, Integer> indexMapping = new LinkedHashMap();
-        indexMapping.put(START_INDEXING_KEY, outputStream.getWrittenBytesCount());
-
-        List<String> sortedKeys = rulesMap.keySet().stream().sorted().collect(Collectors.toList());
-        int indexTracker = 0;
-        for (String key : sortedKeys) {
-            if (indexTracker >= INDEXING_BLOCK_SIZE) {
-                indexMapping.put(key, outputStream.getWrittenBytesCount());
-                indexTracker = 0;
-            }
-
-            for (Rule rule : rulesMap.get(key)) {
-                serializeRule(rule, bitOutputStream);
-                bitOutputStream.flush();
-                indexTracker++;
-            }
-        }
-        indexMapping.put(END_INDEXING_KEY, outputStream.getWrittenBytesCount());
-
-        return indexMapping;
-    }
-
-    private void serializeRule(Rule rule, BitOutputStream bitOutputStream) throws IOException {
-        if (rule == null) {
-            throw new IllegalArgumentException("Null rule can not be serialized");
-        }
-
-        // Start with a '1' bit to mark the start of a rule.
-        bitOutputStream.setNext();
-
-        serializeFormula(rule.getFormula(), bitOutputStream);
-        bitOutputStream.setNext(EFFECT_BITS, rule.getEffect());
-
-        // End with a '1' bit to mark the end of a rule.
-        bitOutputStream.setNext();
-    }
-
-    private void serializeFormula(IntegrityFormula formula, BitOutputStream bitOutputStream)
-            throws IOException {
-        if (formula instanceof AtomicFormula) {
-            serializeAtomicFormula((AtomicFormula) formula, bitOutputStream);
-        } else if (formula instanceof CompoundFormula) {
-            serializeCompoundFormula((CompoundFormula) formula, bitOutputStream);
-        } else if (formula instanceof InstallerAllowedByManifestFormula) {
-            bitOutputStream.setNext(SEPARATOR_BITS, INSTALLER_ALLOWED_BY_MANIFEST_START);
-        } else {
-            throw new IllegalArgumentException(
-                    String.format("Invalid formula type: %s", formula.getClass()));
-        }
-    }
-
-    private void serializeCompoundFormula(
-            CompoundFormula compoundFormula, BitOutputStream bitOutputStream) throws IOException {
-        if (compoundFormula == null) {
-            throw new IllegalArgumentException("Null compound formula can not be serialized");
-        }
-
-        bitOutputStream.setNext(SEPARATOR_BITS, COMPOUND_FORMULA_START);
-        bitOutputStream.setNext(CONNECTOR_BITS, compoundFormula.getConnector());
-        for (IntegrityFormula formula : compoundFormula.getFormulas()) {
-            serializeFormula(formula, bitOutputStream);
-        }
-        bitOutputStream.setNext(SEPARATOR_BITS, COMPOUND_FORMULA_END);
-    }
-
-    private void serializeAtomicFormula(
-            AtomicFormula atomicFormula, BitOutputStream bitOutputStream) throws IOException {
-        if (atomicFormula == null) {
-            throw new IllegalArgumentException("Null atomic formula can not be serialized");
-        }
-
-        bitOutputStream.setNext(SEPARATOR_BITS, ATOMIC_FORMULA_START);
-        bitOutputStream.setNext(KEY_BITS, atomicFormula.getKey());
-        if (atomicFormula.getTag() == AtomicFormula.STRING_ATOMIC_FORMULA_TAG) {
-            AtomicFormula.StringAtomicFormula stringAtomicFormula =
-                    (AtomicFormula.StringAtomicFormula) atomicFormula;
-            bitOutputStream.setNext(OPERATOR_BITS, AtomicFormula.EQ);
-            serializeStringValue(
-                    stringAtomicFormula.getValue(),
-                    stringAtomicFormula.getIsHashedValue(),
-                    bitOutputStream);
-        } else if (atomicFormula.getTag() == AtomicFormula.LONG_ATOMIC_FORMULA_TAG) {
-            AtomicFormula.LongAtomicFormula longAtomicFormula =
-                    (AtomicFormula.LongAtomicFormula) atomicFormula;
-            bitOutputStream.setNext(OPERATOR_BITS, longAtomicFormula.getOperator());
-            // TODO(b/147880712): Temporary hack until we support long values in bitOutputStream
-            long value = longAtomicFormula.getValue();
-            serializeIntValue((int) (value >>> 32), bitOutputStream);
-            serializeIntValue((int) value, bitOutputStream);
-        } else if (atomicFormula.getTag() == AtomicFormula.BOOLEAN_ATOMIC_FORMULA_TAG) {
-            AtomicFormula.BooleanAtomicFormula booleanAtomicFormula =
-                    (AtomicFormula.BooleanAtomicFormula) atomicFormula;
-            bitOutputStream.setNext(OPERATOR_BITS, AtomicFormula.EQ);
-            serializeBooleanValue(booleanAtomicFormula.getValue(), bitOutputStream);
-        } else {
-            throw new IllegalArgumentException(
-                    String.format("Invalid atomic formula type: %s", atomicFormula.getClass()));
-        }
-    }
-
-    private void serializeIndexGroup(
-            LinkedHashMap<String, Integer> indexes,
-            BitOutputStream bitOutputStream,
-            boolean isIndexed)
-            throws IOException {
-        // Output the starting location of this indexing group.
-        serializeStringValue(START_INDEXING_KEY, /* isHashedValue= */ false, bitOutputStream);
-        serializeIntValue(indexes.get(START_INDEXING_KEY), bitOutputStream);
-
-        // If the group is indexed, output the locations of the indexes.
-        if (isIndexed) {
-            for (Map.Entry<String, Integer> entry : indexes.entrySet()) {
-                if (!entry.getKey().equals(START_INDEXING_KEY)
-                        && !entry.getKey().equals(END_INDEXING_KEY)) {
-                    serializeStringValue(
-                            entry.getKey(), /* isHashedValue= */ false, bitOutputStream);
-                    serializeIntValue(entry.getValue(), bitOutputStream);
-                }
-            }
-        }
-
-        // Output the end location of this indexing group.
-        serializeStringValue(END_INDEXING_KEY, /*isHashedValue= */ false, bitOutputStream);
-        serializeIntValue(indexes.get(END_INDEXING_KEY), bitOutputStream);
-    }
-
-    private void serializeStringValue(
-            String value, boolean isHashedValue, BitOutputStream bitOutputStream)
-            throws IOException {
-        if (value == null) {
-            throw new IllegalArgumentException("String value can not be null.");
-        }
-        byte[] valueBytes = getBytesForString(value, isHashedValue);
-
-        bitOutputStream.setNext(isHashedValue);
-        bitOutputStream.setNext(VALUE_SIZE_BITS, valueBytes.length);
-        for (byte valueByte : valueBytes) {
-            bitOutputStream.setNext(/* numOfBits= */ 8, valueByte);
-        }
-    }
-
-    private void serializeIntValue(int value, BitOutputStream bitOutputStream) throws IOException {
-        bitOutputStream.setNext(/* numOfBits= */ 32, value);
-    }
-
-    private void serializeBooleanValue(boolean value, BitOutputStream bitOutputStream)
-            throws IOException {
-        bitOutputStream.setNext(value);
-    }
-
-    // Get the byte array for a value.
-    // If the value is not hashed, use its byte array form directly.
-    // If the value is hashed, get the raw form decoding of the value. All hashed values are
-    // hex-encoded. Serialized values are in raw form.
-    private static byte[] getBytesForString(String value, boolean isHashedValue) {
-        if (!isHashedValue) {
-            return value.getBytes(StandardCharsets.UTF_8);
-        }
-        return IntegrityUtils.getBytesFromHexDigest(value);
-    }
-}
diff --git a/services/core/java/com/android/server/integrity/serializer/RuleIndexingDetails.java b/services/core/java/com/android/server/integrity/serializer/RuleIndexingDetails.java
deleted file mode 100644
index 2cbd4ede..0000000
--- a/services/core/java/com/android/server/integrity/serializer/RuleIndexingDetails.java
+++ /dev/null
@@ -1,69 +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.integrity.serializer;
-
-import android.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/** Holds the indexing type and indexing key of a given formula. */
-class RuleIndexingDetails {
-
-    static final int NOT_INDEXED = 0;
-    static final int PACKAGE_NAME_INDEXED = 1;
-    static final int APP_CERTIFICATE_INDEXED = 2;
-
-    static final String DEFAULT_RULE_KEY = "N/A";
-
-    /** Represents which indexed file the rule should be located. */
-    @IntDef(
-            value = {
-                    NOT_INDEXED,
-                    PACKAGE_NAME_INDEXED,
-                    APP_CERTIFICATE_INDEXED
-            })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface IndexType {
-    }
-
-    private @IndexType int mIndexType;
-    private String mRuleKey;
-
-    /** Constructor without a ruleKey for {@code NOT_INDEXED}. */
-    RuleIndexingDetails(@IndexType int indexType) {
-        this.mIndexType = indexType;
-        this.mRuleKey = DEFAULT_RULE_KEY;
-    }
-
-    /** Constructor with a ruleKey for indexed rules. */
-    RuleIndexingDetails(@IndexType int indexType, String ruleKey) {
-        this.mIndexType = indexType;
-        this.mRuleKey = ruleKey;
-    }
-
-    /** Returns the indexing type for the rule. */
-    @IndexType
-    public int getIndexType() {
-        return mIndexType;
-    }
-
-    /** Returns the identified rule key. */
-    public String getRuleKey() {
-        return mRuleKey;
-    }
-}
diff --git a/services/core/java/com/android/server/integrity/serializer/RuleIndexingDetailsIdentifier.java b/services/core/java/com/android/server/integrity/serializer/RuleIndexingDetailsIdentifier.java
deleted file mode 100644
index e723559..0000000
--- a/services/core/java/com/android/server/integrity/serializer/RuleIndexingDetailsIdentifier.java
+++ /dev/null
@@ -1,151 +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.integrity.serializer;
-
-import static com.android.server.integrity.serializer.RuleIndexingDetails.APP_CERTIFICATE_INDEXED;
-import static com.android.server.integrity.serializer.RuleIndexingDetails.NOT_INDEXED;
-import static com.android.server.integrity.serializer.RuleIndexingDetails.PACKAGE_NAME_INDEXED;
-
-import android.content.integrity.AtomicFormula;
-import android.content.integrity.CompoundFormula;
-import android.content.integrity.IntegrityFormula;
-import android.content.integrity.Rule;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-
-/** A helper class for identifying the indexing type and key of a given rule. */
-class RuleIndexingDetailsIdentifier {
-
-    /**
-     * Splits a given rule list into three indexing categories. Each rule category is returned as a
-     * TreeMap that is sorted by their indexing keys -- where keys correspond to package name for
-     * PACKAGE_NAME_INDEXED rules, app certificate for APP_CERTIFICATE_INDEXED rules and N/A for
-     * NOT_INDEXED rules.
-     */
-    public static Map<Integer, Map<String, List<Rule>>> splitRulesIntoIndexBuckets(
-            List<Rule> rules) {
-        if (rules == null) {
-            throw new IllegalArgumentException(
-                    "Index buckets cannot be created for null rule list.");
-        }
-
-        Map<Integer, Map<String, List<Rule>>> typeOrganizedRuleMap = new HashMap();
-        typeOrganizedRuleMap.put(NOT_INDEXED, new HashMap());
-        typeOrganizedRuleMap.put(PACKAGE_NAME_INDEXED, new HashMap<>());
-        typeOrganizedRuleMap.put(APP_CERTIFICATE_INDEXED, new HashMap<>());
-
-        // Split the rules into the appropriate indexed pattern. The Tree Maps help us to keep the
-        // entries sorted by their index key.
-        for (Rule rule : rules) {
-            RuleIndexingDetails indexingDetails;
-            try {
-                indexingDetails = getIndexingDetails(rule.getFormula());
-            } catch (Exception e) {
-                throw new IllegalArgumentException(
-                        String.format("Malformed rule identified. [%s]", rule.toString()));
-            }
-
-            int ruleIndexType = indexingDetails.getIndexType();
-            String ruleKey = indexingDetails.getRuleKey();
-
-            if (!typeOrganizedRuleMap.get(ruleIndexType).containsKey(ruleKey)) {
-                typeOrganizedRuleMap.get(ruleIndexType).put(ruleKey, new ArrayList());
-            }
-
-            typeOrganizedRuleMap.get(ruleIndexType).get(ruleKey).add(rule);
-        }
-
-        return typeOrganizedRuleMap;
-    }
-
-    private static RuleIndexingDetails getIndexingDetails(IntegrityFormula formula) {
-        switch (formula.getTag()) {
-            case IntegrityFormula.COMPOUND_FORMULA_TAG:
-                return getIndexingDetailsForCompoundFormula((CompoundFormula) formula);
-            case IntegrityFormula.STRING_ATOMIC_FORMULA_TAG:
-                return getIndexingDetailsForStringAtomicFormula(
-                        (AtomicFormula.StringAtomicFormula) formula);
-            case IntegrityFormula.LONG_ATOMIC_FORMULA_TAG:
-            case IntegrityFormula.INSTALLER_ALLOWED_BY_MANIFEST_FORMULA_TAG:
-            case IntegrityFormula.BOOLEAN_ATOMIC_FORMULA_TAG:
-                // Package name and app certificate related formulas are string atomic formulas.
-                return new RuleIndexingDetails(NOT_INDEXED);
-            default:
-                throw new IllegalArgumentException(
-                        String.format("Invalid formula tag type: %s", formula.getTag()));
-        }
-    }
-
-    private static RuleIndexingDetails getIndexingDetailsForCompoundFormula(
-            CompoundFormula compoundFormula) {
-        int connector = compoundFormula.getConnector();
-        List<IntegrityFormula> formulas = compoundFormula.getFormulas();
-
-        switch (connector) {
-            case CompoundFormula.AND:
-            case CompoundFormula.OR:
-                // If there is a package name related atomic rule, return package name indexed.
-                Optional<RuleIndexingDetails> packageNameRule =
-                        formulas.stream()
-                                .map(formula -> getIndexingDetails(formula))
-                                .filter(ruleIndexingDetails -> ruleIndexingDetails.getIndexType()
-                                        == PACKAGE_NAME_INDEXED)
-                                .findAny();
-                if (packageNameRule.isPresent()) {
-                    return packageNameRule.get();
-                }
-
-                // If there is an app certificate related atomic rule but no package name related
-                // atomic rule, return app certificate indexed.
-                Optional<RuleIndexingDetails> appCertificateRule =
-                        formulas.stream()
-                                .map(formula -> getIndexingDetails(formula))
-                                .filter(ruleIndexingDetails -> ruleIndexingDetails.getIndexType()
-                                        == APP_CERTIFICATE_INDEXED)
-                                .findAny();
-                if (appCertificateRule.isPresent()) {
-                    return appCertificateRule.get();
-                }
-
-                // Do not index when there is not package name or app certificate indexing.
-                return new RuleIndexingDetails(NOT_INDEXED);
-            default:
-                // Having a NOT operator in the indexing messes up the indexing; e.g., deny
-                // installation if app certificate is NOT X (should not be indexed with app cert
-                // X). We will not keep these rules indexed.
-                // Also any other type of unknown operators will not be indexed.
-                return new RuleIndexingDetails(NOT_INDEXED);
-        }
-    }
-
-    private static RuleIndexingDetails getIndexingDetailsForStringAtomicFormula(
-            AtomicFormula.StringAtomicFormula atomicFormula) {
-        switch (atomicFormula.getKey()) {
-            case AtomicFormula.PACKAGE_NAME:
-                return new RuleIndexingDetails(PACKAGE_NAME_INDEXED, atomicFormula.getValue());
-            case AtomicFormula.APP_CERTIFICATE:
-                return new RuleIndexingDetails(APP_CERTIFICATE_INDEXED, atomicFormula.getValue());
-            default:
-                return new RuleIndexingDetails(NOT_INDEXED);
-        }
-    }
-}
-
diff --git a/services/core/java/com/android/server/integrity/serializer/RuleMetadataSerializer.java b/services/core/java/com/android/server/integrity/serializer/RuleMetadataSerializer.java
deleted file mode 100644
index 022b4b8..0000000
--- a/services/core/java/com/android/server/integrity/serializer/RuleMetadataSerializer.java
+++ /dev/null
@@ -1,52 +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.integrity.serializer;
-
-import static com.android.server.integrity.parser.RuleMetadataParser.RULE_PROVIDER_TAG;
-import static com.android.server.integrity.parser.RuleMetadataParser.VERSION_TAG;
-
-import android.util.Xml;
-
-import com.android.modules.utils.TypedXmlSerializer;
-import com.android.server.integrity.model.RuleMetadata;
-
-import org.xmlpull.v1.XmlSerializer;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.nio.charset.StandardCharsets;
-
-/** Helper class for writing rule metadata. */
-public class RuleMetadataSerializer {
-    /** Serialize the rule metadata to an output stream. */
-    public static void serialize(RuleMetadata ruleMetadata, OutputStream outputStream)
-            throws IOException {
-        TypedXmlSerializer xmlSerializer = Xml.resolveSerializer(outputStream);
-
-        serializeTaggedValue(xmlSerializer, RULE_PROVIDER_TAG, ruleMetadata.getRuleProvider());
-        serializeTaggedValue(xmlSerializer, VERSION_TAG, ruleMetadata.getVersion());
-
-        xmlSerializer.endDocument();
-    }
-
-    private static void serializeTaggedValue(TypedXmlSerializer xmlSerializer, String tag,
-            String value) throws IOException {
-        xmlSerializer.startTag(/* namespace= */ null, tag);
-        xmlSerializer.text(value);
-        xmlSerializer.endTag(/* namespace= */ null, tag);
-    }
-}
diff --git a/services/core/java/com/android/server/integrity/serializer/RuleSerializeException.java b/services/core/java/com/android/server/integrity/serializer/RuleSerializeException.java
deleted file mode 100644
index 60cfc48..0000000
--- a/services/core/java/com/android/server/integrity/serializer/RuleSerializeException.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.integrity.serializer;
-
-import android.annotation.NonNull;
-
-/**
- * Thrown when rule serialization fails.
- */
-public class RuleSerializeException extends Exception {
-    public RuleSerializeException(@NonNull String message) {
-        super(message);
-    }
-
-    public RuleSerializeException(@NonNull String message, @NonNull Throwable cause) {
-        super(message, cause);
-    }
-}
diff --git a/services/core/java/com/android/server/integrity/serializer/RuleSerializer.java b/services/core/java/com/android/server/integrity/serializer/RuleSerializer.java
deleted file mode 100644
index 2941856..0000000
--- a/services/core/java/com/android/server/integrity/serializer/RuleSerializer.java
+++ /dev/null
@@ -1,39 +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.integrity.serializer;
-
-import android.content.integrity.Rule;
-
-import java.io.OutputStream;
-import java.util.List;
-import java.util.Optional;
-
-/** A helper class to serialize rules from the {@link Rule} model. */
-public interface RuleSerializer {
-
-    /** Serialize rules to an output stream */
-    void serialize(
-            List<Rule> rules,
-            Optional<Integer> formatVersion,
-            OutputStream ruleFileOutputStream,
-            OutputStream indexingFileOutputStream)
-            throws RuleSerializeException;
-
-    /** Serialize rules to a ByteArray. */
-    byte[] serialize(List<Rule> rules, Optional<Integer> formatVersion)
-            throws RuleSerializeException;
-}
diff --git a/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleBinarySerializerTest.java b/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleBinarySerializerTest.java
deleted file mode 100644
index 9ed2e88..0000000
--- a/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleBinarySerializerTest.java
+++ /dev/null
@@ -1,914 +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.integrity.serializer;
-
-import static com.android.server.integrity.model.ComponentBitSize.ATOMIC_FORMULA_START;
-import static com.android.server.integrity.model.ComponentBitSize.COMPOUND_FORMULA_END;
-import static com.android.server.integrity.model.ComponentBitSize.COMPOUND_FORMULA_START;
-import static com.android.server.integrity.model.ComponentBitSize.CONNECTOR_BITS;
-import static com.android.server.integrity.model.ComponentBitSize.DEFAULT_FORMAT_VERSION;
-import static com.android.server.integrity.model.ComponentBitSize.EFFECT_BITS;
-import static com.android.server.integrity.model.ComponentBitSize.FORMAT_VERSION_BITS;
-import static com.android.server.integrity.model.ComponentBitSize.KEY_BITS;
-import static com.android.server.integrity.model.ComponentBitSize.OPERATOR_BITS;
-import static com.android.server.integrity.model.ComponentBitSize.SEPARATOR_BITS;
-import static com.android.server.integrity.model.ComponentBitSize.VALUE_SIZE_BITS;
-import static com.android.server.integrity.model.IndexingFileConstants.END_INDEXING_KEY;
-import static com.android.server.integrity.model.IndexingFileConstants.INDEXING_BLOCK_SIZE;
-import static com.android.server.integrity.model.IndexingFileConstants.START_INDEXING_KEY;
-import static com.android.server.integrity.serializer.RuleBinarySerializer.INDEXED_RULE_SIZE_LIMIT;
-import static com.android.server.integrity.serializer.RuleBinarySerializer.NONINDEXED_RULE_SIZE_LIMIT;
-import static com.android.server.integrity.utils.TestUtils.getBits;
-import static com.android.server.integrity.utils.TestUtils.getBytes;
-import static com.android.server.integrity.utils.TestUtils.getValueBits;
-import static com.android.server.testutils.TestUtils.assertExpectException;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.integrity.AppInstallMetadata;
-import android.content.integrity.AtomicFormula;
-import android.content.integrity.CompoundFormula;
-import android.content.integrity.IntegrityFormula;
-import android.content.integrity.IntegrityUtils;
-import android.content.integrity.Rule;
-
-import androidx.annotation.NonNull;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-import java.io.ByteArrayOutputStream;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Optional;
-
-@RunWith(JUnit4.class)
-public class RuleBinarySerializerTest {
-
-    private static final String SAMPLE_INSTALLER_NAME = "com.test.installer";
-    private static final String SAMPLE_INSTALLER_CERT = "installer_cert";
-
-    private static final String COMPOUND_FORMULA_START_BITS =
-            getBits(COMPOUND_FORMULA_START, SEPARATOR_BITS);
-    private static final String COMPOUND_FORMULA_END_BITS =
-            getBits(COMPOUND_FORMULA_END, SEPARATOR_BITS);
-    private static final String ATOMIC_FORMULA_START_BITS =
-            getBits(ATOMIC_FORMULA_START, SEPARATOR_BITS);
-
-    private static final String NOT = getBits(CompoundFormula.NOT, CONNECTOR_BITS);
-    private static final String AND = getBits(CompoundFormula.AND, CONNECTOR_BITS);
-    private static final String OR = getBits(CompoundFormula.OR, CONNECTOR_BITS);
-
-    private static final String PACKAGE_NAME = getBits(AtomicFormula.PACKAGE_NAME, KEY_BITS);
-    private static final String APP_CERTIFICATE = getBits(AtomicFormula.APP_CERTIFICATE, KEY_BITS);
-    private static final String INSTALLER_NAME = getBits(AtomicFormula.INSTALLER_NAME, KEY_BITS);
-    private static final String INSTALLER_CERTIFICATE =
-            getBits(AtomicFormula.INSTALLER_CERTIFICATE, KEY_BITS);
-    private static final String VERSION_CODE = getBits(AtomicFormula.VERSION_CODE, KEY_BITS);
-    private static final String PRE_INSTALLED = getBits(AtomicFormula.PRE_INSTALLED, KEY_BITS);
-
-    private static final String EQ = getBits(AtomicFormula.EQ, OPERATOR_BITS);
-
-    private static final String IS_NOT_HASHED = "0";
-    private static final String IS_HASHED = "1";
-
-    private static final String DENY = getBits(Rule.DENY, EFFECT_BITS);
-
-    private static final String START_BIT = "1";
-    private static final String END_BIT = "1";
-
-    private static final byte[] DEFAULT_FORMAT_VERSION_BYTES =
-            getBytes(getBits(DEFAULT_FORMAT_VERSION, FORMAT_VERSION_BITS));
-
-    private static final String SERIALIZED_START_INDEXING_KEY =
-            IS_NOT_HASHED
-                    + getBits(START_INDEXING_KEY.length(), VALUE_SIZE_BITS)
-                    + getValueBits(START_INDEXING_KEY);
-    private static final String SERIALIZED_END_INDEXING_KEY =
-            IS_NOT_HASHED
-                    + getBits(END_INDEXING_KEY.length(), VALUE_SIZE_BITS)
-                    + getValueBits(END_INDEXING_KEY);
-
-    @Test
-    public void testBinaryString_serializeNullRules() {
-        RuleSerializer binarySerializer = new RuleBinarySerializer();
-
-        assertExpectException(
-                RuleSerializeException.class,
-                /* expectedExceptionMessageRegex= */ "Null rules cannot be serialized.",
-                () -> binarySerializer.serialize(null, /* formatVersion= */ Optional.empty()));
-    }
-
-    @Test
-    public void testBinaryString_emptyRules() throws Exception {
-        ByteArrayOutputStream ruleOutputStream = new ByteArrayOutputStream();
-        ByteArrayOutputStream indexingOutputStream = new ByteArrayOutputStream();
-        RuleSerializer binarySerializer = new RuleBinarySerializer();
-
-        binarySerializer.serialize(
-                Collections.emptyList(),
-                /* formatVersion= */ Optional.empty(),
-                ruleOutputStream,
-                indexingOutputStream);
-
-        ByteArrayOutputStream expectedRuleOutputStream = new ByteArrayOutputStream();
-        expectedRuleOutputStream.write(DEFAULT_FORMAT_VERSION_BYTES);
-        assertThat(ruleOutputStream.toByteArray())
-                .isEqualTo(expectedRuleOutputStream.toByteArray());
-
-        ByteArrayOutputStream expectedIndexingOutputStream = new ByteArrayOutputStream();
-        String serializedIndexingBytes =
-                SERIALIZED_START_INDEXING_KEY
-                        + getBits(DEFAULT_FORMAT_VERSION_BYTES.length, /* numOfBits= */ 32)
-                        + SERIALIZED_END_INDEXING_KEY
-                        + getBits(DEFAULT_FORMAT_VERSION_BYTES.length, /* numOfBits= */ 32);
-        byte[] expectedIndexingBytes =
-                getBytes(
-                        serializedIndexingBytes
-                                + serializedIndexingBytes
-                                + serializedIndexingBytes);
-        expectedIndexingOutputStream.write(expectedIndexingBytes);
-        assertThat(indexingOutputStream.toByteArray())
-                .isEqualTo(expectedIndexingOutputStream.toByteArray());
-    }
-
-    @Test
-    public void testBinaryStream_serializeValidCompoundFormula() throws Exception {
-        String packageName = "com.test.app";
-        Rule rule =
-                new Rule(
-                        new CompoundFormula(
-                                CompoundFormula.NOT,
-                                Collections.singletonList(
-                                        new AtomicFormula.StringAtomicFormula(
-                                                AtomicFormula.PACKAGE_NAME,
-                                                packageName,
-                                                /* isHashedValue= */ false))),
-                        Rule.DENY);
-
-        ByteArrayOutputStream ruleOutputStream = new ByteArrayOutputStream();
-        ByteArrayOutputStream indexingOutputStream = new ByteArrayOutputStream();
-        RuleSerializer binarySerializer = new RuleBinarySerializer();
-        binarySerializer.serialize(
-                Collections.singletonList(rule),
-                /* formatVersion= */ Optional.empty(),
-                ruleOutputStream,
-                indexingOutputStream);
-
-        String expectedBits =
-                START_BIT
-                        + COMPOUND_FORMULA_START_BITS
-                        + NOT
-                        + ATOMIC_FORMULA_START_BITS
-                        + PACKAGE_NAME
-                        + EQ
-                        + IS_NOT_HASHED
-                        + getBits(packageName.length(), VALUE_SIZE_BITS)
-                        + getValueBits(packageName)
-                        + COMPOUND_FORMULA_END_BITS
-                        + DENY
-                        + END_BIT;
-        ByteArrayOutputStream expectedRuleOutputStream = new ByteArrayOutputStream();
-        expectedRuleOutputStream.write(DEFAULT_FORMAT_VERSION_BYTES);
-        expectedRuleOutputStream.write(getBytes(expectedBits));
-        assertThat(ruleOutputStream.toByteArray())
-                .isEqualTo(expectedRuleOutputStream.toByteArray());
-
-        ByteArrayOutputStream expectedIndexingOutputStream = new ByteArrayOutputStream();
-        String expectedIndexingBitsForIndexed =
-                SERIALIZED_START_INDEXING_KEY
-                        + getBits(DEFAULT_FORMAT_VERSION_BYTES.length, /* numOfBits= */ 32)
-                        + SERIALIZED_END_INDEXING_KEY
-                        + getBits(DEFAULT_FORMAT_VERSION_BYTES.length, /* numOfBits= */ 32);
-        String expectedIndexingBitsForUnindexed =
-                SERIALIZED_START_INDEXING_KEY
-                        + getBits(DEFAULT_FORMAT_VERSION_BYTES.length, /* numOfBits= */ 32)
-                        + SERIALIZED_END_INDEXING_KEY
-                        + getBits(
-                                DEFAULT_FORMAT_VERSION_BYTES.length + getBytes(expectedBits).length,
-                                /* numOfBits= */ 32);
-        expectedIndexingOutputStream.write(
-                getBytes(
-                        expectedIndexingBitsForIndexed
-                                + expectedIndexingBitsForIndexed
-                                + expectedIndexingBitsForUnindexed));
-
-        assertThat(indexingOutputStream.toByteArray())
-                .isEqualTo(expectedIndexingOutputStream.toByteArray());
-    }
-
-    @Test
-    public void testBinaryString_serializeValidCompoundFormula_notConnector() throws Exception {
-        String packageName = "com.test.app";
-        Rule rule =
-                new Rule(
-                        new CompoundFormula(
-                                CompoundFormula.NOT,
-                                Collections.singletonList(
-                                        new AtomicFormula.StringAtomicFormula(
-                                                AtomicFormula.PACKAGE_NAME,
-                                                packageName,
-                                                /* isHashedValue= */ false))),
-                        Rule.DENY);
-        RuleSerializer binarySerializer = new RuleBinarySerializer();
-        String expectedBits =
-                START_BIT
-                        + COMPOUND_FORMULA_START_BITS
-                        + NOT
-                        + ATOMIC_FORMULA_START_BITS
-                        + PACKAGE_NAME
-                        + EQ
-                        + IS_NOT_HASHED
-                        + getBits(packageName.length(), VALUE_SIZE_BITS)
-                        + getValueBits(packageName)
-                        + COMPOUND_FORMULA_END_BITS
-                        + DENY
-                        + END_BIT;
-        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
-        byteArrayOutputStream.write(DEFAULT_FORMAT_VERSION_BYTES);
-        byteArrayOutputStream.write(getBytes(expectedBits));
-        byte[] expectedRules = byteArrayOutputStream.toByteArray();
-
-        byte[] actualRules =
-                binarySerializer.serialize(
-                        Collections.singletonList(rule), /* formatVersion= */ Optional.empty());
-
-        assertThat(actualRules).isEqualTo(expectedRules);
-    }
-
-    @Test
-    public void testBinaryString_serializeValidCompoundFormula_andConnector() throws Exception {
-        String packageName = "com.test.app";
-        String appCertificate = "test_cert";
-        Rule rule =
-                new Rule(
-                        new CompoundFormula(
-                                CompoundFormula.AND,
-                                Arrays.asList(
-                                        new AtomicFormula.StringAtomicFormula(
-                                                AtomicFormula.PACKAGE_NAME,
-                                                packageName,
-                                                /* isHashedValue= */ false),
-                                        new AtomicFormula.StringAtomicFormula(
-                                                AtomicFormula.APP_CERTIFICATE,
-                                                appCertificate,
-                                                /* isHashedValue= */ false))),
-                        Rule.DENY);
-        RuleSerializer binarySerializer = new RuleBinarySerializer();
-        String expectedBits =
-                START_BIT
-                        + COMPOUND_FORMULA_START_BITS
-                        + AND
-                        + ATOMIC_FORMULA_START_BITS
-                        + PACKAGE_NAME
-                        + EQ
-                        + IS_NOT_HASHED
-                        + getBits(packageName.length(), VALUE_SIZE_BITS)
-                        + getValueBits(packageName)
-                        + ATOMIC_FORMULA_START_BITS
-                        + APP_CERTIFICATE
-                        + EQ
-                        + IS_NOT_HASHED
-                        + getBits(appCertificate.length(), VALUE_SIZE_BITS)
-                        + getValueBits(appCertificate)
-                        + COMPOUND_FORMULA_END_BITS
-                        + DENY
-                        + END_BIT;
-        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
-        byteArrayOutputStream.write(DEFAULT_FORMAT_VERSION_BYTES);
-        byteArrayOutputStream.write(getBytes(expectedBits));
-        byte[] expectedRules = byteArrayOutputStream.toByteArray();
-
-        byte[] actualRules =
-                binarySerializer.serialize(
-                        Collections.singletonList(rule), /* formatVersion= */ Optional.empty());
-
-        assertThat(actualRules).isEqualTo(expectedRules);
-    }
-
-    @Test
-    public void testBinaryString_serializeValidCompoundFormula_orConnector() throws Exception {
-        String packageName = "com.test.app";
-        String appCertificate = "test_cert";
-        Rule rule =
-                new Rule(
-                        new CompoundFormula(
-                                CompoundFormula.OR,
-                                Arrays.asList(
-                                        new AtomicFormula.StringAtomicFormula(
-                                                AtomicFormula.PACKAGE_NAME,
-                                                packageName,
-                                                /* isHashedValue= */ false),
-                                        new AtomicFormula.StringAtomicFormula(
-                                                AtomicFormula.APP_CERTIFICATE,
-                                                appCertificate,
-                                                /* isHashedValue= */ false))),
-                        Rule.DENY);
-        RuleSerializer binarySerializer = new RuleBinarySerializer();
-        String expectedBits =
-                START_BIT
-                        + COMPOUND_FORMULA_START_BITS
-                        + OR
-                        + ATOMIC_FORMULA_START_BITS
-                        + PACKAGE_NAME
-                        + EQ
-                        + IS_NOT_HASHED
-                        + getBits(packageName.length(), VALUE_SIZE_BITS)
-                        + getValueBits(packageName)
-                        + ATOMIC_FORMULA_START_BITS
-                        + APP_CERTIFICATE
-                        + EQ
-                        + IS_NOT_HASHED
-                        + getBits(appCertificate.length(), VALUE_SIZE_BITS)
-                        + getValueBits(appCertificate)
-                        + COMPOUND_FORMULA_END_BITS
-                        + DENY
-                        + END_BIT;
-        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
-        byteArrayOutputStream.write(DEFAULT_FORMAT_VERSION_BYTES);
-        byteArrayOutputStream.write(getBytes(expectedBits));
-        byte[] expectedRules = byteArrayOutputStream.toByteArray();
-
-        byte[] actualRules =
-                binarySerializer.serialize(
-                        Collections.singletonList(rule), /* formatVersion= */ Optional.empty());
-
-        assertThat(actualRules).isEqualTo(expectedRules);
-    }
-
-    @Test
-    public void testBinaryString_serializeValidAtomicFormula_stringValue() throws Exception {
-        String packageName = "com.test.app";
-        Rule rule =
-                new Rule(
-                        new AtomicFormula.StringAtomicFormula(
-                                AtomicFormula.PACKAGE_NAME,
-                                packageName,
-                                /* isHashedValue= */ false),
-                        Rule.DENY);
-        RuleSerializer binarySerializer = new RuleBinarySerializer();
-        String expectedBits =
-                START_BIT
-                        + ATOMIC_FORMULA_START_BITS
-                        + PACKAGE_NAME
-                        + EQ
-                        + IS_NOT_HASHED
-                        + getBits(packageName.length(), VALUE_SIZE_BITS)
-                        + getValueBits(packageName)
-                        + DENY
-                        + END_BIT;
-        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
-        byteArrayOutputStream.write(DEFAULT_FORMAT_VERSION_BYTES);
-        byteArrayOutputStream.write(getBytes(expectedBits));
-        byte[] expectedRules = byteArrayOutputStream.toByteArray();
-
-        byte[] actualRules =
-                binarySerializer.serialize(
-                        Collections.singletonList(rule), /* formatVersion= */ Optional.empty());
-
-        assertThat(actualRules).isEqualTo(expectedRules);
-    }
-
-    @Test
-    public void testBinaryString_serializeValidAtomicFormula_hashedValue() throws Exception {
-        String appCertificate = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
-        Rule rule =
-                new Rule(
-                        new AtomicFormula.StringAtomicFormula(
-                                AtomicFormula.APP_CERTIFICATE,
-                                IntegrityUtils.getHexDigest(
-                                        appCertificate.getBytes(StandardCharsets.UTF_8)),
-                                /* isHashedValue= */ true),
-                        Rule.DENY);
-        RuleSerializer binarySerializer = new RuleBinarySerializer();
-        String expectedBits =
-                START_BIT
-                        + ATOMIC_FORMULA_START_BITS
-                        + APP_CERTIFICATE
-                        + EQ
-                        + IS_HASHED
-                        + getBits(appCertificate.length(), VALUE_SIZE_BITS)
-                        + getValueBits(appCertificate)
-                        + DENY
-                        + END_BIT;
-        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
-        byteArrayOutputStream.write(DEFAULT_FORMAT_VERSION_BYTES);
-        byteArrayOutputStream.write(getBytes(expectedBits));
-        byte[] expectedRules = byteArrayOutputStream.toByteArray();
-
-        byte[] actualRules =
-                binarySerializer.serialize(
-                        Collections.singletonList(rule), /* formatVersion= */ Optional.empty());
-
-        assertThat(actualRules).isEqualTo(expectedRules);
-    }
-
-    @Test
-    public void testBinaryString_serializeValidAtomicFormula_integerValue() throws Exception {
-        long versionCode = 1;
-        Rule rule =
-                new Rule(
-                        new AtomicFormula.LongAtomicFormula(
-                                AtomicFormula.VERSION_CODE, AtomicFormula.EQ, versionCode),
-                        Rule.DENY);
-        RuleSerializer binarySerializer = new RuleBinarySerializer();
-        String expectedBits =
-                START_BIT
-                        + ATOMIC_FORMULA_START_BITS
-                        + VERSION_CODE
-                        + EQ
-                        + getBits(versionCode, /* numOfBits= */ 64)
-                        + DENY
-                        + END_BIT;
-        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
-        byteArrayOutputStream.write(DEFAULT_FORMAT_VERSION_BYTES);
-        byteArrayOutputStream.write(getBytes(expectedBits));
-        byte[] expectedRules = byteArrayOutputStream.toByteArray();
-
-        byte[] actualRules =
-                binarySerializer.serialize(
-                        Collections.singletonList(rule), /* formatVersion= */ Optional.empty());
-
-        assertThat(actualRules).isEqualTo(expectedRules);
-    }
-
-    @Test
-    public void testBinaryString_serializeValidAtomicFormula_booleanValue() throws Exception {
-        String preInstalled = "1";
-        Rule rule =
-                new Rule(
-                        new AtomicFormula.BooleanAtomicFormula(AtomicFormula.PRE_INSTALLED, true),
-                        Rule.DENY);
-        RuleSerializer binarySerializer = new RuleBinarySerializer();
-        String expectedBits =
-                START_BIT
-                        + ATOMIC_FORMULA_START_BITS
-                        + PRE_INSTALLED
-                        + EQ
-                        + preInstalled
-                        + DENY
-                        + END_BIT;
-        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
-        byteArrayOutputStream.write(DEFAULT_FORMAT_VERSION_BYTES);
-        byteArrayOutputStream.write(getBytes(expectedBits));
-        byte[] expectedRules = byteArrayOutputStream.toByteArray();
-
-        byte[] actualRules =
-                binarySerializer.serialize(
-                        Collections.singletonList(rule), /* formatVersion= */ Optional.empty());
-
-        assertThat(actualRules).isEqualTo(expectedRules);
-    }
-
-    @Test
-    public void testBinaryString_serializeInvalidFormulaType() throws Exception {
-        IntegrityFormula invalidFormula = getInvalidFormula();
-        Rule rule = new Rule(invalidFormula, Rule.DENY);
-        RuleSerializer binarySerializer = new RuleBinarySerializer();
-
-        assertExpectException(
-                RuleSerializeException.class,
-                /* expectedExceptionMessageRegex= */ "Malformed rule identified.",
-                () ->
-                        binarySerializer.serialize(
-                                Collections.singletonList(rule),
-                                /* formatVersion= */ Optional.empty()));
-    }
-
-    @Test
-    public void testBinaryString_serializeFormatVersion() throws Exception {
-        int formatVersion = 1;
-        RuleSerializer binarySerializer = new RuleBinarySerializer();
-        String expectedBits = getBits(formatVersion, FORMAT_VERSION_BITS);
-        byte[] expectedRules = getBytes(expectedBits);
-
-        byte[] actualRules =
-                binarySerializer.serialize(
-                        Collections.emptyList(), /* formatVersion= */ Optional.of(formatVersion));
-
-        assertThat(actualRules).isEqualTo(expectedRules);
-    }
-
-    @Test
-    public void testBinaryString_verifyManyRulesAreIndexedCorrectly() throws Exception {
-        int ruleCount = 225;
-        String packagePrefix = "package.name.";
-        String appCertificatePrefix = "app.cert.";
-        String installerNamePrefix = "installer.";
-
-        // Create the rule set with 225 package name based rules, 225 app certificate indexed rules,
-        // and 225 non-indexed rules..
-        List<Rule> ruleList = new ArrayList();
-        for (int count = 0; count < ruleCount; count++) {
-            ruleList.add(
-                    getRuleWithPackageNameAndSampleInstallerName(
-                            String.format("%s%04d", packagePrefix, count)));
-        }
-        for (int count = 0; count < ruleCount; count++) {
-            ruleList.add(
-                    getRuleWithAppCertificateAndSampleInstallerName(
-                            String.format("%s%04d", appCertificatePrefix, count)));
-        }
-        for (int count = 0; count < ruleCount; count++) {
-            ruleList.add(
-                    getNonIndexedRuleWithInstallerName(
-                            String.format("%s%04d", installerNamePrefix, count)));
-        }
-
-        // Serialize the rules.
-        ByteArrayOutputStream ruleOutputStream = new ByteArrayOutputStream();
-        ByteArrayOutputStream indexingOutputStream = new ByteArrayOutputStream();
-        RuleSerializer binarySerializer = new RuleBinarySerializer();
-        binarySerializer.serialize(
-                ruleList,
-                /* formatVersion= */ Optional.empty(),
-                ruleOutputStream,
-                indexingOutputStream);
-
-        // Verify the rules file and index files.
-        ByteArrayOutputStream expectedOrderedRuleOutputStream = new ByteArrayOutputStream();
-        ByteArrayOutputStream expectedIndexingOutputStream = new ByteArrayOutputStream();
-
-        expectedOrderedRuleOutputStream.write(DEFAULT_FORMAT_VERSION_BYTES);
-        int totalBytesWritten = DEFAULT_FORMAT_VERSION_BYTES.length;
-
-        String expectedIndexingBytesForPackageNameIndexed =
-                SERIALIZED_START_INDEXING_KEY + getBits(totalBytesWritten, /* numOfBits= */ 32);
-        for (int count = 0; count < ruleCount; count++) {
-            String packageName = String.format("%s%04d", packagePrefix, count);
-            if (count > 0 && count % INDEXING_BLOCK_SIZE == 0) {
-                expectedIndexingBytesForPackageNameIndexed +=
-                        IS_NOT_HASHED
-                                + getBits(packageName.length(), VALUE_SIZE_BITS)
-                                + getValueBits(packageName)
-                                + getBits(totalBytesWritten, /* numOfBits= */ 32);
-            }
-
-            byte[] bytesForPackage =
-                    getBytes(
-                            getSerializedCompoundRuleWithPackageNameAndSampleInstallerName(
-                                    packageName));
-            expectedOrderedRuleOutputStream.write(bytesForPackage);
-            totalBytesWritten += bytesForPackage.length;
-        }
-        expectedIndexingBytesForPackageNameIndexed +=
-                SERIALIZED_END_INDEXING_KEY + getBits(totalBytesWritten, /* numOfBits= */ 32);
-
-        String expectedIndexingBytesForAppCertificateIndexed =
-                SERIALIZED_START_INDEXING_KEY + getBits(totalBytesWritten, /* numOfBits= */ 32);
-        for (int count = 0; count < ruleCount; count++) {
-            String appCertificate = String.format("%s%04d", appCertificatePrefix, count);
-            if (count > 0 && count % INDEXING_BLOCK_SIZE == 0) {
-                expectedIndexingBytesForAppCertificateIndexed +=
-                        IS_NOT_HASHED
-                                + getBits(appCertificate.length(), VALUE_SIZE_BITS)
-                                + getValueBits(appCertificate)
-                                + getBits(totalBytesWritten, /* numOfBits= */ 32);
-            }
-
-            byte[] bytesForPackage =
-                    getBytes(
-                            getSerializedCompoundRuleWithCertificateNameAndSampleInstallerName(
-                                    appCertificate));
-            expectedOrderedRuleOutputStream.write(bytesForPackage);
-            totalBytesWritten += bytesForPackage.length;
-        }
-        expectedIndexingBytesForAppCertificateIndexed +=
-                SERIALIZED_END_INDEXING_KEY + getBits(totalBytesWritten, /* numOfBits= */ 32);
-
-        String expectedIndexingBytesForUnindexed =
-                SERIALIZED_START_INDEXING_KEY + getBits(totalBytesWritten, /* numOfBits= */ 32);
-        for (int count = 0; count < ruleCount; count++) {
-            byte[] bytesForPackage =
-                    getBytes(
-                            getSerializedCompoundRuleWithInstallerNameAndInstallerCert(
-                                    String.format("%s%04d", installerNamePrefix, count)));
-            expectedOrderedRuleOutputStream.write(bytesForPackage);
-            totalBytesWritten += bytesForPackage.length;
-        }
-        expectedIndexingBytesForUnindexed +=
-                SERIALIZED_END_INDEXING_KEY + getBits(totalBytesWritten, /* numOfBits= */ 32);
-        expectedIndexingOutputStream.write(
-                getBytes(
-                        expectedIndexingBytesForPackageNameIndexed
-                                + expectedIndexingBytesForAppCertificateIndexed
-                                + expectedIndexingBytesForUnindexed));
-
-        assertThat(ruleOutputStream.toByteArray())
-                .isEqualTo(expectedOrderedRuleOutputStream.toByteArray());
-        assertThat(indexingOutputStream.toByteArray())
-                .isEqualTo(expectedIndexingOutputStream.toByteArray());
-    }
-
-    @Test
-    public void testBinaryString_totalRuleSizeLimitReached() {
-        int ruleCount = INDEXED_RULE_SIZE_LIMIT - 1;
-        String packagePrefix = "package.name.";
-        String appCertificatePrefix = "app.cert.";
-        String installerNamePrefix = "installer.";
-
-        // Create the rule set with more rules than the system can handle in total.
-        List<Rule> ruleList = new ArrayList();
-        for (int count = 0; count < ruleCount; count++) {
-            ruleList.add(
-                    getRuleWithPackageNameAndSampleInstallerName(
-                            String.format("%s%04d", packagePrefix, count)));
-        }
-        for (int count = 0; count < ruleCount; count++) {
-            ruleList.add(
-                    getRuleWithAppCertificateAndSampleInstallerName(
-                            String.format("%s%04d", appCertificatePrefix, count)));
-        }
-        for (int count = 0; count < NONINDEXED_RULE_SIZE_LIMIT - 1; count++) {
-            ruleList.add(
-                    getNonIndexedRuleWithInstallerName(
-                            String.format("%s%04d", installerNamePrefix, count)));
-        }
-
-        // Serialize the rules.
-        ByteArrayOutputStream ruleOutputStream = new ByteArrayOutputStream();
-        ByteArrayOutputStream indexingOutputStream = new ByteArrayOutputStream();
-        RuleSerializer binarySerializer = new RuleBinarySerializer();
-
-        assertExpectException(
-                RuleSerializeException.class,
-                "Too many rules provided",
-                () ->
-                        binarySerializer.serialize(
-                                ruleList,
-                                /* formatVersion= */ Optional.empty(),
-                                ruleOutputStream,
-                                indexingOutputStream));
-    }
-
-    @Test
-    public void testBinaryString_tooManyPackageNameIndexedRules() {
-        String packagePrefix = "package.name.";
-
-        // Create a rule set with too many package name indexed rules.
-        List<Rule> ruleList = new ArrayList();
-        for (int count = 0; count < INDEXED_RULE_SIZE_LIMIT + 1; count++) {
-            ruleList.add(
-                    getRuleWithPackageNameAndSampleInstallerName(
-                            String.format("%s%04d", packagePrefix, count)));
-        }
-
-        // Serialize the rules.
-        ByteArrayOutputStream ruleOutputStream = new ByteArrayOutputStream();
-        ByteArrayOutputStream indexingOutputStream = new ByteArrayOutputStream();
-        RuleSerializer binarySerializer = new RuleBinarySerializer();
-
-        assertExpectException(
-                RuleSerializeException.class,
-                "Too many rules provided in the indexing group.",
-                () ->
-                        binarySerializer.serialize(
-                                ruleList,
-                                /* formatVersion= */ Optional.empty(),
-                                ruleOutputStream,
-                                indexingOutputStream));
-    }
-
-    @Test
-    public void testBinaryString_tooManyAppCertificateIndexedRules() {
-        String appCertificatePrefix = "app.cert.";
-
-        // Create a rule set with too many app certificate indexed rules.
-        List<Rule> ruleList = new ArrayList();
-        for (int count = 0; count < INDEXED_RULE_SIZE_LIMIT + 1; count++) {
-            ruleList.add(
-                    getRuleWithAppCertificateAndSampleInstallerName(
-                            String.format("%s%04d", appCertificatePrefix, count)));
-        }
-
-        // Serialize the rules.
-        ByteArrayOutputStream ruleOutputStream = new ByteArrayOutputStream();
-        ByteArrayOutputStream indexingOutputStream = new ByteArrayOutputStream();
-        RuleSerializer binarySerializer = new RuleBinarySerializer();
-
-        assertExpectException(
-                RuleSerializeException.class,
-                "Too many rules provided in the indexing group.",
-                () ->
-                        binarySerializer.serialize(
-                                ruleList,
-                                /* formatVersion= */ Optional.empty(),
-                                ruleOutputStream,
-                                indexingOutputStream));
-    }
-
-    @Test
-    public void testBinaryString_tooManyNonIndexedRules() {
-        String installerNamePrefix = "installer.";
-
-        // Create a rule set with too many unindexed rules.
-        List<Rule> ruleList = new ArrayList();
-        for (int count = 0; count < NONINDEXED_RULE_SIZE_LIMIT + 1; count++) {
-            ruleList.add(
-                    getNonIndexedRuleWithInstallerName(
-                            String.format("%s%04d", installerNamePrefix, count)));
-        }
-
-        // Serialize the rules.
-        ByteArrayOutputStream ruleOutputStream = new ByteArrayOutputStream();
-        ByteArrayOutputStream indexingOutputStream = new ByteArrayOutputStream();
-        RuleSerializer binarySerializer = new RuleBinarySerializer();
-
-        assertExpectException(
-                RuleSerializeException.class,
-                "Too many rules provided in the indexing group.",
-                () ->
-                        binarySerializer.serialize(
-                                ruleList,
-                                /* formatVersion= */ Optional.empty(),
-                                ruleOutputStream,
-                                indexingOutputStream));
-    }
-
-    private Rule getRuleWithPackageNameAndSampleInstallerName(String packageName) {
-        return new Rule(
-                new CompoundFormula(
-                        CompoundFormula.AND,
-                        Arrays.asList(
-                                new AtomicFormula.StringAtomicFormula(
-                                        AtomicFormula.PACKAGE_NAME,
-                                        packageName,
-                                        /* isHashedValue= */ false),
-                                new AtomicFormula.StringAtomicFormula(
-                                        AtomicFormula.INSTALLER_NAME,
-                                        SAMPLE_INSTALLER_NAME,
-                                        /* isHashedValue= */ false))),
-                Rule.DENY);
-    }
-
-    private String getSerializedCompoundRuleWithPackageNameAndSampleInstallerName(
-            String packageName) {
-        return START_BIT
-                + COMPOUND_FORMULA_START_BITS
-                + AND
-                + ATOMIC_FORMULA_START_BITS
-                + PACKAGE_NAME
-                + EQ
-                + IS_NOT_HASHED
-                + getBits(packageName.length(), VALUE_SIZE_BITS)
-                + getValueBits(packageName)
-                + ATOMIC_FORMULA_START_BITS
-                + INSTALLER_NAME
-                + EQ
-                + IS_NOT_HASHED
-                + getBits(SAMPLE_INSTALLER_NAME.length(), VALUE_SIZE_BITS)
-                + getValueBits(SAMPLE_INSTALLER_NAME)
-                + COMPOUND_FORMULA_END_BITS
-                + DENY
-                + END_BIT;
-    }
-
-    private Rule getRuleWithAppCertificateAndSampleInstallerName(String certificate) {
-        return new Rule(
-                new CompoundFormula(
-                        CompoundFormula.AND,
-                        Arrays.asList(
-                                new AtomicFormula.StringAtomicFormula(
-                                        AtomicFormula.APP_CERTIFICATE,
-                                        certificate,
-                                        /* isHashedValue= */ false),
-                                new AtomicFormula.StringAtomicFormula(
-                                        AtomicFormula.INSTALLER_NAME,
-                                        SAMPLE_INSTALLER_NAME,
-                                        /* isHashedValue= */ false))),
-                Rule.DENY);
-    }
-
-    private String getSerializedCompoundRuleWithCertificateNameAndSampleInstallerName(
-            String appCertificate) {
-        return START_BIT
-                + COMPOUND_FORMULA_START_BITS
-                + AND
-                + ATOMIC_FORMULA_START_BITS
-                + APP_CERTIFICATE
-                + EQ
-                + IS_NOT_HASHED
-                + getBits(appCertificate.length(), VALUE_SIZE_BITS)
-                + getValueBits(appCertificate)
-                + ATOMIC_FORMULA_START_BITS
-                + INSTALLER_NAME
-                + EQ
-                + IS_NOT_HASHED
-                + getBits(SAMPLE_INSTALLER_NAME.length(), VALUE_SIZE_BITS)
-                + getValueBits(SAMPLE_INSTALLER_NAME)
-                + COMPOUND_FORMULA_END_BITS
-                + DENY
-                + END_BIT;
-    }
-
-    private Rule getNonIndexedRuleWithInstallerName(String installerName) {
-        return new Rule(
-                new CompoundFormula(
-                        CompoundFormula.AND,
-                        Arrays.asList(
-                                new AtomicFormula.StringAtomicFormula(
-                                        AtomicFormula.INSTALLER_NAME,
-                                        installerName,
-                                        /* isHashedValue= */ false),
-                                new AtomicFormula.StringAtomicFormula(
-                                        AtomicFormula.INSTALLER_CERTIFICATE,
-                                        SAMPLE_INSTALLER_CERT,
-                                        /* isHashedValue= */ false))),
-                Rule.DENY);
-    }
-
-    private String getSerializedCompoundRuleWithInstallerNameAndInstallerCert(
-            String installerName) {
-        return START_BIT
-                + COMPOUND_FORMULA_START_BITS
-                + AND
-                + ATOMIC_FORMULA_START_BITS
-                + INSTALLER_NAME
-                + EQ
-                + IS_NOT_HASHED
-                + getBits(installerName.length(), VALUE_SIZE_BITS)
-                + getValueBits(installerName)
-                + ATOMIC_FORMULA_START_BITS
-                + INSTALLER_CERTIFICATE
-                + EQ
-                + IS_NOT_HASHED
-                + getBits(SAMPLE_INSTALLER_CERT.length(), VALUE_SIZE_BITS)
-                + getValueBits(SAMPLE_INSTALLER_CERT)
-                + COMPOUND_FORMULA_END_BITS
-                + DENY
-                + END_BIT;
-    }
-
-    private static IntegrityFormula getInvalidFormula() {
-        return new AtomicFormula(0) {
-            @Override
-            public int getTag() {
-                return 0;
-            }
-
-            @Override
-            public boolean matches(AppInstallMetadata appInstallMetadata) {
-                return false;
-            }
-
-            @Override
-            public boolean isAppCertificateFormula() {
-                return false;
-            }
-
-            @Override
-            public boolean isAppCertificateLineageFormula() {
-                return false;
-            }
-
-            @Override
-            public boolean isInstallerFormula() {
-                return false;
-            }
-
-            @Override
-            public int hashCode() {
-                return super.hashCode();
-            }
-
-            @Override
-            public boolean equals(Object obj) {
-                return super.equals(obj);
-            }
-
-            @NonNull
-            @Override
-            protected Object clone() throws CloneNotSupportedException {
-                return super.clone();
-            }
-
-            @Override
-            public String toString() {
-                return super.toString();
-            }
-
-            @Override
-            protected void finalize() throws Throwable {
-                super.finalize();
-            }
-        };
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleIndexingDetailsIdentifierTest.java b/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleIndexingDetailsIdentifierTest.java
deleted file mode 100644
index 6dccdf5..0000000
--- a/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleIndexingDetailsIdentifierTest.java
+++ /dev/null
@@ -1,344 +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.integrity.serializer;
-
-import static com.android.server.integrity.serializer.RuleIndexingDetails.APP_CERTIFICATE_INDEXED;
-import static com.android.server.integrity.serializer.RuleIndexingDetails.NOT_INDEXED;
-import static com.android.server.integrity.serializer.RuleIndexingDetails.PACKAGE_NAME_INDEXED;
-import static com.android.server.integrity.serializer.RuleIndexingDetailsIdentifier.splitRulesIntoIndexBuckets;
-import static com.android.server.testutils.TestUtils.assertExpectException;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.integrity.AppInstallMetadata;
-import android.content.integrity.AtomicFormula;
-import android.content.integrity.CompoundFormula;
-import android.content.integrity.IntegrityFormula;
-import android.content.integrity.Rule;
-
-import androidx.annotation.NonNull;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-
-/** Unit tests for {@link RuleIndexingDetailsIdentifier}. */
-@RunWith(JUnit4.class)
-public class RuleIndexingDetailsIdentifierTest {
-
-    private static final String SAMPLE_APP_CERTIFICATE = "testcert";
-    private static final String SAMPLE_INSTALLER_NAME = "com.test.installer";
-    private static final String SAMPLE_INSTALLER_CERTIFICATE = "installercert";
-    private static final String SAMPLE_PACKAGE_NAME = "com.test.package";
-
-    private static final AtomicFormula ATOMIC_FORMULA_WITH_PACKAGE_NAME =
-            new AtomicFormula.StringAtomicFormula(
-                    AtomicFormula.PACKAGE_NAME,
-                    SAMPLE_PACKAGE_NAME,
-                    /* isHashedValue= */ false);
-    private static final AtomicFormula ATOMIC_FORMULA_WITH_APP_CERTIFICATE =
-            new AtomicFormula.StringAtomicFormula(
-                    AtomicFormula.APP_CERTIFICATE,
-                    SAMPLE_APP_CERTIFICATE,
-                    /* isHashedValue= */ false);
-    private static final AtomicFormula ATOMIC_FORMULA_WITH_INSTALLER_NAME =
-            new AtomicFormula.StringAtomicFormula(
-                    AtomicFormula.INSTALLER_NAME,
-                    SAMPLE_INSTALLER_NAME,
-                    /* isHashedValue= */ false);
-    private static final AtomicFormula ATOMIC_FORMULA_WITH_INSTALLER_CERTIFICATE =
-            new AtomicFormula.StringAtomicFormula(
-                    AtomicFormula.INSTALLER_CERTIFICATE,
-                    SAMPLE_INSTALLER_CERTIFICATE,
-                    /* isHashedValue= */ false);
-    private static final AtomicFormula ATOMIC_FORMULA_WITH_VERSION_CODE =
-            new AtomicFormula.LongAtomicFormula(AtomicFormula.VERSION_CODE,
-                    AtomicFormula.EQ, 12);
-    private static final AtomicFormula ATOMIC_FORMULA_WITH_ISPREINSTALLED =
-            new AtomicFormula.BooleanAtomicFormula(
-                    AtomicFormula.PRE_INSTALLED, /* booleanValue= */
-                    true);
-
-
-    private static final Rule RULE_WITH_PACKAGE_NAME =
-            new Rule(
-                    new CompoundFormula(
-                            CompoundFormula.AND,
-                            Arrays.asList(
-                                    ATOMIC_FORMULA_WITH_PACKAGE_NAME,
-                                    ATOMIC_FORMULA_WITH_INSTALLER_NAME)),
-                    Rule.DENY);
-    private static final Rule RULE_WITH_APP_CERTIFICATE =
-            new Rule(
-                    new CompoundFormula(
-                            CompoundFormula.AND,
-                            Arrays.asList(
-                                    ATOMIC_FORMULA_WITH_APP_CERTIFICATE,
-                                    ATOMIC_FORMULA_WITH_INSTALLER_NAME)),
-                    Rule.DENY);
-    private static final Rule RULE_WITH_INSTALLER_RESTRICTIONS =
-            new Rule(
-                    new CompoundFormula(
-                            CompoundFormula.AND,
-                            Arrays.asList(
-                                    ATOMIC_FORMULA_WITH_INSTALLER_NAME,
-                                    ATOMIC_FORMULA_WITH_INSTALLER_CERTIFICATE)),
-                    Rule.DENY);
-
-    private static final Rule RULE_WITH_NONSTRING_RESTRICTIONS =
-            new Rule(
-                    new CompoundFormula(
-                            CompoundFormula.AND,
-                            Arrays.asList(
-                                    ATOMIC_FORMULA_WITH_VERSION_CODE,
-                                    ATOMIC_FORMULA_WITH_ISPREINSTALLED)),
-                    Rule.DENY);
-    public static final int INVALID_FORMULA_TAG = -1;
-
-    @Test
-    public void getIndexType_nullRule() {
-        List<Rule> ruleList = null;
-
-        assertExpectException(
-                IllegalArgumentException.class,
-                /* expectedExceptionMessageRegex= */
-                "Index buckets cannot be created for null rule list.",
-                () -> splitRulesIntoIndexBuckets(ruleList));
-    }
-
-    @Test
-    public void getIndexType_invalidFormula() {
-        List<Rule> ruleList = new ArrayList();
-        ruleList.add(new Rule(getInvalidFormula(), Rule.DENY));
-
-        assertExpectException(
-                IllegalArgumentException.class,
-                /* expectedExceptionMessageRegex= */ "Malformed rule identified.",
-                () -> splitRulesIntoIndexBuckets(ruleList));
-    }
-
-    @Test
-    public void getIndexType_ruleContainingPackageNameFormula() {
-        List<Rule> ruleList = new ArrayList();
-        ruleList.add(RULE_WITH_PACKAGE_NAME);
-
-        Map<Integer, Map<String, List<Rule>>> result = splitRulesIntoIndexBuckets(ruleList);
-
-        // Verify the resulting map content.
-        assertThat(result.keySet())
-                .containsExactly(NOT_INDEXED, PACKAGE_NAME_INDEXED, APP_CERTIFICATE_INDEXED);
-        assertThat(result.get(NOT_INDEXED)).isEmpty();
-        assertThat(result.get(APP_CERTIFICATE_INDEXED)).isEmpty();
-        assertThat(result.get(PACKAGE_NAME_INDEXED).keySet()).containsExactly(SAMPLE_PACKAGE_NAME);
-        assertThat(result.get(PACKAGE_NAME_INDEXED).get(SAMPLE_PACKAGE_NAME))
-                .containsExactly(RULE_WITH_PACKAGE_NAME);
-    }
-
-    @Test
-    public void getIndexType_ruleContainingAppCertificateFormula() {
-        List<Rule> ruleList = new ArrayList();
-        ruleList.add(RULE_WITH_APP_CERTIFICATE);
-
-        Map<Integer, Map<String, List<Rule>>> result = splitRulesIntoIndexBuckets(ruleList);
-
-        assertThat(result.keySet())
-                .containsExactly(NOT_INDEXED, PACKAGE_NAME_INDEXED, APP_CERTIFICATE_INDEXED);
-        assertThat(result.get(NOT_INDEXED)).isEmpty();
-        assertThat(result.get(PACKAGE_NAME_INDEXED)).isEmpty();
-        assertThat(result.get(APP_CERTIFICATE_INDEXED).keySet())
-                .containsExactly(SAMPLE_APP_CERTIFICATE);
-        assertThat(result.get(APP_CERTIFICATE_INDEXED).get(SAMPLE_APP_CERTIFICATE))
-                .containsExactly(RULE_WITH_APP_CERTIFICATE);
-    }
-
-    @Test
-    public void getIndexType_ruleWithUnindexedCompoundFormula() {
-        List<Rule> ruleList = new ArrayList();
-        ruleList.add(RULE_WITH_INSTALLER_RESTRICTIONS);
-
-        Map<Integer, Map<String, List<Rule>>> result = splitRulesIntoIndexBuckets(ruleList);
-
-        assertThat(result.keySet())
-                .containsExactly(NOT_INDEXED, PACKAGE_NAME_INDEXED, APP_CERTIFICATE_INDEXED);
-        assertThat(result.get(PACKAGE_NAME_INDEXED)).isEmpty();
-        assertThat(result.get(APP_CERTIFICATE_INDEXED)).isEmpty();
-        assertThat(result.get(NOT_INDEXED).get("N/A"))
-                .containsExactly(RULE_WITH_INSTALLER_RESTRICTIONS);
-    }
-
-    @Test
-    public void getIndexType_ruleContainingCompoundFormulaWithIntAndBoolean() {
-        List<Rule> ruleList = new ArrayList();
-        ruleList.add(RULE_WITH_NONSTRING_RESTRICTIONS);
-
-        Map<Integer, Map<String, List<Rule>>> result = splitRulesIntoIndexBuckets(ruleList);
-
-        assertThat(result.keySet())
-                .containsExactly(NOT_INDEXED, PACKAGE_NAME_INDEXED, APP_CERTIFICATE_INDEXED);
-        assertThat(result.get(PACKAGE_NAME_INDEXED)).isEmpty();
-        assertThat(result.get(APP_CERTIFICATE_INDEXED)).isEmpty();
-        assertThat(result.get(NOT_INDEXED).get("N/A"))
-                .containsExactly(RULE_WITH_NONSTRING_RESTRICTIONS);
-    }
-
-    @Test
-    public void getIndexType_negatedRuleContainingPackageNameFormula() {
-        Rule negatedRule =
-                new Rule(
-                        new CompoundFormula(
-                                CompoundFormula.NOT,
-                                Arrays.asList(
-                                        new CompoundFormula(
-                                                CompoundFormula.AND,
-                                                Arrays.asList(
-                                                        ATOMIC_FORMULA_WITH_PACKAGE_NAME,
-                                                        ATOMIC_FORMULA_WITH_APP_CERTIFICATE)))),
-                        Rule.DENY);
-        List<Rule> ruleList = new ArrayList();
-        ruleList.add(negatedRule);
-
-        Map<Integer, Map<String, List<Rule>>> result = splitRulesIntoIndexBuckets(ruleList);
-
-        assertThat(result.keySet())
-                .containsExactly(NOT_INDEXED, PACKAGE_NAME_INDEXED, APP_CERTIFICATE_INDEXED);
-        assertThat(result.get(PACKAGE_NAME_INDEXED)).isEmpty();
-        assertThat(result.get(APP_CERTIFICATE_INDEXED)).isEmpty();
-        assertThat(result.get(NOT_INDEXED).get("N/A")).containsExactly(negatedRule);
-    }
-
-    @Test
-    public void getIndexType_allRulesTogetherSplitCorrectly() {
-        Rule packageNameRuleA = getRuleWithPackageName("aaa");
-        Rule packageNameRuleB = getRuleWithPackageName("bbb");
-        Rule packageNameRuleC = getRuleWithPackageName("ccc");
-        Rule certificateRule1 = getRuleWithAppCertificate("cert1");
-        Rule certificateRule2 = getRuleWithAppCertificate("cert2");
-        Rule certificateRule3 = getRuleWithAppCertificate("cert3");
-
-        List<Rule> ruleList = new ArrayList();
-        ruleList.add(packageNameRuleB);
-        ruleList.add(packageNameRuleC);
-        ruleList.add(packageNameRuleA);
-        ruleList.add(certificateRule3);
-        ruleList.add(certificateRule2);
-        ruleList.add(certificateRule1);
-        ruleList.add(RULE_WITH_INSTALLER_RESTRICTIONS);
-        ruleList.add(RULE_WITH_NONSTRING_RESTRICTIONS);
-
-        Map<Integer, Map<String, List<Rule>>> result = splitRulesIntoIndexBuckets(ruleList);
-
-        assertThat(result.keySet())
-                .containsExactly(NOT_INDEXED, PACKAGE_NAME_INDEXED, APP_CERTIFICATE_INDEXED);
-
-        // We check asserts this way to ensure ordering based on package name.
-        assertThat(result.get(PACKAGE_NAME_INDEXED).keySet()).containsExactly("aaa", "bbb", "ccc");
-
-        // We check asserts this way to ensure ordering based on app certificate.
-        assertThat(result.get(APP_CERTIFICATE_INDEXED).keySet()).containsExactly("cert1", "cert2",
-                "cert3");
-
-        assertThat(result.get(NOT_INDEXED).get("N/A"))
-                .containsExactly(RULE_WITH_INSTALLER_RESTRICTIONS,
-                        RULE_WITH_NONSTRING_RESTRICTIONS);
-    }
-
-    private Rule getRuleWithPackageName(String packageName) {
-        return new Rule(
-                new CompoundFormula(
-                        CompoundFormula.AND,
-                        Arrays.asList(
-                                new AtomicFormula.StringAtomicFormula(
-                                        AtomicFormula.PACKAGE_NAME,
-                                        packageName,
-                                        /* isHashedValue= */ false),
-                                ATOMIC_FORMULA_WITH_INSTALLER_NAME)),
-                Rule.DENY);
-    }
-
-    private Rule getRuleWithAppCertificate(String certificate) {
-        return new Rule(
-                new CompoundFormula(
-                        CompoundFormula.AND,
-                        Arrays.asList(
-                                new AtomicFormula.StringAtomicFormula(
-                                        AtomicFormula.APP_CERTIFICATE,
-                                        certificate,
-                                        /* isHashedValue= */ false),
-                                ATOMIC_FORMULA_WITH_INSTALLER_NAME)),
-                Rule.DENY);
-    }
-
-    private IntegrityFormula getInvalidFormula() {
-        return new AtomicFormula(0) {
-            @Override
-            public int getTag() {
-                return INVALID_FORMULA_TAG;
-            }
-
-            @Override
-            public boolean matches(AppInstallMetadata appInstallMetadata) {
-                return false;
-            }
-
-            @Override
-            public boolean isAppCertificateFormula() {
-                return false;
-            }
-
-            @Override
-            public boolean isAppCertificateLineageFormula() {
-                return false;
-            }
-
-            @Override
-            public boolean isInstallerFormula() {
-                return false;
-            }
-
-            @Override
-            public int hashCode() {
-                return super.hashCode();
-            }
-
-            @Override
-            public boolean equals(Object obj) {
-                return super.equals(obj);
-            }
-
-            @NonNull
-            @Override
-            protected Object clone() throws CloneNotSupportedException {
-                return super.clone();
-            }
-
-            @Override
-            public String toString() {
-                return super.toString();
-            }
-
-            @Override
-            protected void finalize() throws Throwable {
-                super.finalize();
-            }
-        };
-    }
-}
