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

Commit 2935a21b authored by Omer Nebil Yaveroglu's avatar Omer Nebil Yaveroglu
Browse files

Output the identified index maps into the indexing file.

Bug: 145493956
Test: atest FrameworksServicesTests:RuleBinarySerializerTest
Change-Id: I892cc01e1395bbd16734fe30be70748a82cd536e
parent 18813f70
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