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

Commit c153d2f7 authored by Khaled Abdelmohsen's avatar Khaled Abdelmohsen Committed by Android (Google) Code Review
Browse files

Merge changes I29f71b34,I15a16bbb

* changes:
  Use minified tag names for rule XML
  Implement XML serializing for rule
parents f39ec862 6d77f949
Loading
Loading
Loading
Loading
+13 −13
Original line number Diff line number Diff line
@@ -41,15 +41,15 @@ public final class RuleXmlParser implements RuleParser {
    public static final String TAG = "RuleXmlParser";

    // TODO: Use XML attributes
    private static final String RULE_LIST_TAG = "RuleList";
    private static final String RULE_TAG = "Rule";
    private static final String OPEN_FORMULA_TAG = "OpenFormula";
    private static final String ATOMIC_FORMULA_TAG = "AtomicFormula";
    private static final String EFFECT_TAG = "Effect";
    private static final String KEY_TAG = "Key";
    private static final String OPERATOR_TAG = "Operator";
    private static final String VALUE_TAG = "Value";
    private static final String CONNECTOR_TAG = "Connector";
    private static final String RULE_LIST_TAG = "RL";
    private static final String RULE_TAG = "R";
    private static final String OPEN_FORMULA_TAG = "OF";
    private static final String ATOMIC_FORMULA_TAG = "AF";
    private static final String EFFECT_TAG = "E";
    private static final String KEY_TAG = "K";
    private static final String OPERATOR_TAG = "O";
    private static final String VALUE_TAG = "V";
    private static final String CONNECTOR_TAG = "C";

    @Override
    public List<Rule> parse(String ruleText) throws RuleParseException {
@@ -80,16 +80,16 @@ public final class RuleXmlParser implements RuleParser {
        // Skipping the first event type, which is always {@link XmlPullParser.START_DOCUMENT}
        parser.next();

        // Processing the first tag; which should always be a <RuleList> tag.
        // Processing the first tag; which should always be a RuleList <RL> tag.
        String nodeName = parser.getName();
        // Validating that the XML is starting with a <RuleList> tag.
        // Validating that the XML is starting with a RuleList <RL> tag.
        // Note: This is the only breaking validation to run against XML files in the platform.
        // All rules inside are assumed to be validated at the server. If a rule is found to be
        // corrupt in the XML, it will be skipped to the next rule.
        if (!nodeName.equals(RULE_LIST_TAG)) {
            throw new RuntimeException(
                    String.format("Rules must start with <RuleList> tag. Found: %s at %s", nodeName,
                            parser.getPositionDescription()));
                    String.format("Rules must start with RuleList <RL> tag. Found: %s at %s",
                            nodeName, parser.getPositionDescription()));
        }

        int eventType;
+3 −2
Original line number Diff line number Diff line
@@ -19,17 +19,18 @@ package com.android.server.integrity.serializer;
import com.android.server.integrity.model.Rule;

import java.io.OutputStream;
import java.util.List;

/** A helper class to serialize rules from the {@link Rule} model to Xml representation. */
public class RuleBinarySerializer implements RuleSerializer {

    @Override
    public void serialize(Rule rule, OutputStream outputStream) {
    public void serialize(List<Rule> rules, OutputStream outputStream) {
        // TODO: Implement stream serializer.
    }

    @Override
    public String serialize(Rule rule) {
    public String serialize(List<Rule> rules) {
        // TODO: Implement text serializer.
        return null;
    }
+32 −0
Original line number Diff line number Diff line
/*
 * 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);
    }
}
+5 −4
Original line number Diff line number Diff line
@@ -19,13 +19,14 @@ package com.android.server.integrity.serializer;
import com.android.server.integrity.model.Rule;

import java.io.OutputStream;
import java.util.List;

/** A helper class to serialize rules from the {@link Rule} model. */
public interface RuleSerializer {

    /** Serialize a rule to an output stream */
    void serialize(Rule rule, OutputStream outputStream);
    /** Serialize rules to an output stream */
    void serialize(List<Rule> rules, OutputStream outputStream) throws RuleSerializeException;

    /** Serialize a rule to a string. */
    String serialize(Rule rule);
    /** Serialize rules to a string. */
    String serialize(List<Rule> rule) throws RuleSerializeException;
}
+127 −6
Original line number Diff line number Diff line
@@ -16,21 +16,142 @@

package com.android.server.integrity.serializer;

import android.util.Xml;

import com.android.server.integrity.model.AtomicFormula;
import com.android.server.integrity.model.Formula;
import com.android.server.integrity.model.OpenFormula;
import com.android.server.integrity.model.Rule;

import org.xmlpull.v1.XmlSerializer;

import java.io.IOException;
import java.io.OutputStream;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.util.List;

/** A helper class to serialize rules from the {@link Rule} model to Xml representation. */
/**
 * A helper class to serialize rules from the {@link Rule} model to Xml representation.
 */
public class RuleXmlSerializer implements RuleSerializer {

    public static final String TAG = "RuleXmlSerializer";
    private static final String NAMESPACE = "";

    private static final String RULE_LIST_TAG = "RL";
    private static final String RULE_TAG = "R";
    private static final String OPEN_FORMULA_TAG = "OF";
    private static final String ATOMIC_FORMULA_TAG = "AF";
    private static final String EFFECT_TAG = "E";
    private static final String KEY_TAG = "K";
    private static final String OPERATOR_TAG = "O";
    private static final String VALUE_TAG = "V";
    private static final String CONNECTOR_TAG = "C";

    @Override
    public void serialize(Rule rule, OutputStream outputStream) {
        // TODO: Implement stream serializer.
    public void serialize(List<Rule> rules, OutputStream outputStream)
            throws RuleSerializeException {
        try {
            XmlSerializer xmlSerializer = Xml.newSerializer();
            xmlSerializer.setOutput(outputStream, StandardCharsets.UTF_8.name());
            serializeRules(rules, xmlSerializer);
        } catch (Exception e) {
            throw new RuleSerializeException(e.getMessage(), e);
        }
    }

    @Override
    public String serialize(Rule rule) {
        // TODO: Implement text serializer.
        return null;
    public String serialize(List<Rule> rules) throws RuleSerializeException {
        try {
            XmlSerializer xmlSerializer = Xml.newSerializer();
            StringWriter writer = new StringWriter();
            xmlSerializer.setOutput(writer);
            serializeRules(rules, xmlSerializer);
            return writer.toString();
        } catch (Exception e) {
            throw new RuleSerializeException(e.getMessage(), e);
        }
    }

    private void serializeRules(List<Rule> rules, XmlSerializer xmlSerializer) throws IOException {
        xmlSerializer.startTag(NAMESPACE, RULE_LIST_TAG);
        for (Rule rule : rules) {
            serialize(rule, xmlSerializer);
        }
        xmlSerializer.endTag(NAMESPACE, RULE_LIST_TAG);
        xmlSerializer.endDocument();
    }

    private void serialize(Rule rule, XmlSerializer xmlSerializer) throws IOException {
        if (rule == null) {
            return;
        }
        xmlSerializer.startTag(NAMESPACE, RULE_TAG);
        serializeFormula(rule.getFormula(), xmlSerializer);
        serializeValue(EFFECT_TAG, String.valueOf(rule.getEffect()), xmlSerializer);
        xmlSerializer.endTag(NAMESPACE, RULE_TAG);
    }

    private void serializeFormula(Formula formula, XmlSerializer xmlSerializer) throws IOException {
        if (formula instanceof AtomicFormula) {
            serializeAtomicFormula((AtomicFormula) formula, xmlSerializer);
        } else if (formula instanceof OpenFormula) {
            serializeOpenFormula((OpenFormula) formula, xmlSerializer);
        } else {
            throw new IllegalArgumentException(
                    String.format("Invalid formula type: %s", formula.getClass()));
        }
    }

    private void serializeOpenFormula(OpenFormula openFormula, XmlSerializer xmlSerializer)
            throws IOException {
        if (openFormula == null) {
            return;
        }
        xmlSerializer.startTag(NAMESPACE, OPEN_FORMULA_TAG);
        serializeValue(CONNECTOR_TAG, String.valueOf(openFormula.getConnector()), xmlSerializer);
        for (Formula formula : openFormula.getFormulas()) {
            serializeFormula(formula, xmlSerializer);
        }
        xmlSerializer.endTag(NAMESPACE, OPEN_FORMULA_TAG);
    }

    private void serializeAtomicFormula(AtomicFormula atomicFormula, XmlSerializer xmlSerializer)
            throws IOException {
        if (atomicFormula == null) {
            return;
        }
        xmlSerializer.startTag(NAMESPACE, ATOMIC_FORMULA_TAG);
        serializeValue(KEY_TAG, String.valueOf(atomicFormula.getKey()), xmlSerializer);
        if (atomicFormula instanceof AtomicFormula.StringAtomicFormula) {
            serializeValue(VALUE_TAG,
                    ((AtomicFormula.StringAtomicFormula) atomicFormula).getValue(), xmlSerializer);
        } else if (atomicFormula instanceof AtomicFormula.IntAtomicFormula) {
            serializeValue(OPERATOR_TAG,
                    String.valueOf(((AtomicFormula.IntAtomicFormula) atomicFormula).getOperator()),
                    xmlSerializer);
            serializeValue(VALUE_TAG,
                    String.valueOf(((AtomicFormula.IntAtomicFormula) atomicFormula).getValue()),
                    xmlSerializer);
        } else if (atomicFormula instanceof AtomicFormula.BooleanAtomicFormula) {
            serializeValue(VALUE_TAG,
                    String.valueOf(((AtomicFormula.BooleanAtomicFormula) atomicFormula).getValue()),
                    xmlSerializer);
        } else {
            throw new IllegalArgumentException(
                    String.format("Invalid atomic formula type: %s", atomicFormula.getClass()));
        }
        xmlSerializer.endTag(NAMESPACE, ATOMIC_FORMULA_TAG);
    }

    private void serializeValue(String tag, String value, XmlSerializer xmlSerializer)
            throws IOException {
        if (value == null) {
            return;
        }
        xmlSerializer.startTag(NAMESPACE, tag);
        xmlSerializer.text(value);
        xmlSerializer.endTag(NAMESPACE, tag);
    }
}
Loading