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

Commit 5f7bd9b8 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Output the identified index maps into the indexing file."

parents 3c429ff1 2935a21b
Loading
Loading
Loading
Loading
+8 −8
Original line number Diff line number Diff line
@@ -44,12 +44,9 @@ import java.util.Optional;
public class IntegrityFileManager {
    private static final String TAG = "IntegrityFileManager";

    // TODO: this is a prototype implementation of this class. Thus no tests are included.
    //  Implementing rule indexing will likely overhaul this class and more tests should be included
    //  then.

    private static final String METADATA_FILE = "metadata";
    private static final String RULES_FILE = "rules";
    private static final String INDEXING_FILE = "indexing";
    private static final Object RULES_LOCK = new Object();

    private static IntegrityFileManager sInstance = null;
@@ -125,9 +122,12 @@ public class IntegrityFileManager {
            // We don't consider this fatal so we continue execution.
        }

        try (FileOutputStream fileOutputStream =
                new FileOutputStream(new File(mStagingDir, RULES_FILE))) {
            mRuleSerializer.serialize(rules, Optional.empty(), fileOutputStream);
        try (FileOutputStream ruleFileOutputStream =
                     new FileOutputStream(new File(mStagingDir, RULES_FILE));
             FileOutputStream indexingFileOutputStream =
                     new FileOutputStream(new File(mStagingDir, INDEXING_FILE))) {
            mRuleSerializer.serialize(
                    rules, Optional.empty(), ruleFileOutputStream, indexingFileOutputStream);
        }

        switchStagingRulesDir();
+2 −2
Original line number Diff line number Diff line
@@ -27,7 +27,7 @@ import java.io.OutputStream;
 */
public class ByteTrackedOutputStream {

    private static long sWrittenBytesCount;
    private static int sWrittenBytesCount;
    private static OutputStream sOutputStream;

    public ByteTrackedOutputStream(OutputStream outputStream) {
@@ -47,7 +47,7 @@ public class ByteTrackedOutputStream {
    /**
     * Returns the total number of bytes written into the output stream at the requested time.
     */
    public long getWrittenBytesCount() {
    public int getWrittenBytesCount() {
        return sWrittenBytesCount;
    }
}
+61 −22
Original line number Diff line number Diff line
@@ -52,20 +52,21 @@ import java.util.TreeMap;
/** A helper class to serialize rules from the {@link Rule} model to Binary representation. */
public class RuleBinarySerializer implements RuleSerializer {

    // The parsing time seems acceptable for 100 rules based on the tests in go/ic-rule-file-format.
    private static final int INDEXING_BLOCK_SIZE = 100;
    // The parsing time seems acceptable for this block size based on the tests in
    // go/ic-rule-file-format.
    public static final int INDEXING_BLOCK_SIZE = 100;

    private static final String START_INDEXING_KEY = "START_KEY";
    private static final String END_INDEXING_KEY = "END_KEY";
    public static final String START_INDEXING_KEY = "START_KEY";
    public static final String END_INDEXING_KEY = "END_KEY";

    // Get the byte representation for a list of rules.
    @Override
    public byte[] serialize(List<Rule> rules, Optional<Integer> formatVersion)
            throws RuleSerializeException {
        try {
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            serialize(rules, formatVersion, byteArrayOutputStream);
            return byteArrayOutputStream.toByteArray();
            ByteArrayOutputStream rulesOutputStream = new ByteArrayOutputStream();
            serialize(rules, formatVersion, rulesOutputStream, new ByteArrayOutputStream());
            return rulesOutputStream.toByteArray();
        } catch (Exception e) {
            throw new RuleSerializeException(e.getMessage(), e);
        }
@@ -74,27 +75,38 @@ public class RuleBinarySerializer implements RuleSerializer {
    // 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 originalOutputStream)
            List<Rule> rules,
            Optional<Integer> formatVersion,
            OutputStream rulesFileOutputStream,
            OutputStream indexingFileOutputStream)
            throws RuleSerializeException {
        try {
            // Determine the indexing groups and the order of the rules within each indexed group.
            Map<Integer, TreeMap<String, List<Rule>>> indexedRules =
                    RuleIndexingDetailsIdentifier.splitRulesIntoIndexBuckets(rules);

            ByteTrackedOutputStream outputStream =
                    new ByteTrackedOutputStream(originalOutputStream);
            ByteTrackedOutputStream ruleFileByteTrackedOutputStream =
                    new ByteTrackedOutputStream(rulesFileOutputStream);

            serializeRuleFileMetadata(formatVersion, outputStream);
            serializeRuleFileMetadata(formatVersion, ruleFileByteTrackedOutputStream);

            Map<String, Long> packageNameIndexes =
                    serializeRuleList(indexedRules.get(PACKAGE_NAME_INDEXED), outputStream);
            Map<String, Long> appCertificateIndexes =
                    serializeRuleList(indexedRules.get(APP_CERTIFICATE_INDEXED), outputStream);
            Map<String, Long> unindexedRulesIndex =
                    serializeRuleList(indexedRules.get(NOT_INDEXED), outputStream);
            Map<String, Integer> packageNameIndexes =
                    serializeRuleList(indexedRules.get(PACKAGE_NAME_INDEXED),
                            ruleFileByteTrackedOutputStream);
            indexingFileOutputStream.write(
                    serializeIndexes(packageNameIndexes, /* isIndexed= */true));

            // TODO(b/145493956): Write these indexes into a index file provided by integrity file
            //  manager.
            Map<String, Integer> appCertificateIndexes =
                    serializeRuleList(indexedRules.get(APP_CERTIFICATE_INDEXED),
                            ruleFileByteTrackedOutputStream);
            indexingFileOutputStream.write(
                    serializeIndexes(appCertificateIndexes, /* isIndexed= */true));

            Map<String, Integer> unindexedRulesIndexes =
                    serializeRuleList(indexedRules.get(NOT_INDEXED),
                            ruleFileByteTrackedOutputStream);
            indexingFileOutputStream.write(
                    serializeIndexes(unindexedRulesIndexes, /* isIndexed= */false));
        } catch (Exception e) {
            throw new RuleSerializeException(e.getMessage(), e);
        }
@@ -109,15 +121,15 @@ public class RuleBinarySerializer implements RuleSerializer {
        outputStream.write(bitOutputStream.toByteArray());
    }

    private Map<String, Long> serializeRuleList(TreeMap<String, List<Rule>> rulesMap,
    private Map<String, Integer> serializeRuleList(TreeMap<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();
        Map<String, Long> indexMapping = new TreeMap();
        long indexTracker = 0;
        Map<String, Integer> indexMapping = new TreeMap();
        int indexTracker = 0;

        indexMapping.put(START_INDEXING_KEY, outputStream.getWrittenBytesCount());
        for (Map.Entry<String, List<Rule>> entry : rulesMap.entrySet()) {
@@ -210,6 +222,33 @@ public class RuleBinarySerializer implements RuleSerializer {
        }
    }

    private byte[] serializeIndexes(Map<String, Integer> indexes, boolean isIndexed) {
        BitOutputStream bitOutputStream = new BitOutputStream();

        // 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);

        return bitOutputStream.toByteArray();
    }

    private void serializeStringValue(
            String value, boolean isHashedValue, BitOutputStream bitOutputStream) {
        if (value == null) {
+6 −2
Original line number Diff line number Diff line
@@ -26,10 +26,14 @@ import java.util.Optional;
public interface RuleSerializer {

    /** Serialize rules to an output stream */
    void serialize(List<Rule> rules, Optional<Integer> formatVersion, OutputStream outputStream)
    void serialize(
            List<Rule> rules,
            Optional<Integer> formatVersion,
            OutputStream ruleFileOutputStream,
            OutputStream indexingFileOutputStream)
            throws RuleSerializeException;

    /** Serialize rules to a ByteArray. */
    byte[] serialize(List<Rule> rule, Optional<Integer> formatVersion)
    byte[] serialize(List<Rule> rules, Optional<Integer> formatVersion)
            throws RuleSerializeException;
}
+6 −1
Original line number Diff line number Diff line
@@ -56,12 +56,17 @@ public class RuleXmlSerializer implements RuleSerializer {

    @Override
    public void serialize(
            List<Rule> rules, Optional<Integer> formatVersion, OutputStream outputStream)
            List<Rule> rules,
            Optional<Integer> formatVersion,
            OutputStream outputStream,
            OutputStream indexingOutputStream)
            throws RuleSerializeException {
        try {
            XmlSerializer xmlSerializer = Xml.newSerializer();
            xmlSerializer.setOutput(outputStream, StandardCharsets.UTF_8.name());
            serializeRules(rules, xmlSerializer);

            // TODO(b/145493956): Implement the indexing logic.
        } catch (Exception e) {
            throw new RuleSerializeException(e.getMessage(), e);
        }
Loading