summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Khaled Abdelmohsen <khelmy@google.com> 2019-11-20 07:30:11 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2019-11-20 07:30:11 +0000
commit8489a8d702af610a226427362e2225c17909e1a7 (patch)
treed41547cb964eaec28fb62a51fdc87884069beb52
parent5bf4530d3ea159debcd923576a97a2f015c58f16 (diff)
parentb05d706787c4c55c1f8497d7517e693f3caaa810 (diff)
Merge "Use attributes for rule XML"
-rw-r--r--services/core/java/com/android/server/integrity/parser/RuleXmlParser.java68
-rw-r--r--services/core/java/com/android/server/integrity/serializer/RuleXmlSerializer.java33
-rw-r--r--services/tests/servicestests/src/com/android/server/integrity/parser/RuleXmlParserTest.java366
-rw-r--r--services/tests/servicestests/src/com/android/server/integrity/serializer/RuleXmlSerializerTest.java159
4 files changed, 335 insertions, 291 deletions
diff --git a/services/core/java/com/android/server/integrity/parser/RuleXmlParser.java b/services/core/java/com/android/server/integrity/parser/RuleXmlParser.java
index 23d0b40f08f6..11a397948b14 100644
--- a/services/core/java/com/android/server/integrity/parser/RuleXmlParser.java
+++ b/services/core/java/com/android/server/integrity/parser/RuleXmlParser.java
@@ -40,16 +40,16 @@ public final class RuleXmlParser implements RuleParser {
public static final String TAG = "RuleXmlParser";
- // TODO: Use XML attributes
+ 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";
+ private static final String EFFECT_ATTRIBUTE = "E";
+ private static final String KEY_ATTRIBUTE = "K";
+ private static final String OPERATOR_ATTRIBUTE = "O";
+ private static final String VALUE_ATTRIBUTE = "V";
+ private static final String CONNECTOR_ATTRIBUTE = "C";
@Override
public List<Rule> parse(String ruleText) throws RuleParseException {
@@ -106,7 +106,7 @@ public final class RuleXmlParser implements RuleParser {
private static Rule parseRule(XmlPullParser parser) throws IOException, XmlPullParserException {
Formula formula = null;
- @Rule.Effect int effect = 0;
+ @Rule.Effect int effect = Integer.parseInt(extractAttributeValue(parser, EFFECT_ATTRIBUTE));
int eventType;
while ((eventType = parser.next()) != XmlPullParser.END_DOCUMENT) {
@@ -124,9 +124,6 @@ public final class RuleXmlParser implements RuleParser {
case ATOMIC_FORMULA_TAG:
formula = parseAtomicFormula(parser);
break;
- case EFFECT_TAG:
- effect = Integer.parseInt(extractValue(parser));
- break;
default:
throw new RuntimeException(
String.format("Found unexpected tag: %s", nodeName));
@@ -142,7 +139,8 @@ public final class RuleXmlParser implements RuleParser {
private static Formula parseOpenFormula(XmlPullParser parser)
throws IOException, XmlPullParserException {
- @OpenFormula.Connector int connector = 0;
+ @OpenFormula.Connector int connector = Integer.parseInt(
+ extractAttributeValue(parser, CONNECTOR_ATTRIBUTE));
List<Formula> formulas = new ArrayList<>();
int eventType;
@@ -155,9 +153,6 @@ public final class RuleXmlParser implements RuleParser {
if (eventType == XmlPullParser.START_TAG) {
switch (nodeName) {
- case CONNECTOR_TAG:
- connector = Integer.parseInt(extractValue(parser));
- break;
case ATOMIC_FORMULA_TAG:
formulas.add(parseAtomicFormula(parser));
break;
@@ -179,37 +174,16 @@ public final class RuleXmlParser implements RuleParser {
private static Formula parseAtomicFormula(XmlPullParser parser)
throws IOException, XmlPullParserException {
- @AtomicFormula.Key int key = 0;
- @AtomicFormula.Operator int operator = 0;
- String value = null;
+ @AtomicFormula.Key int key = Integer.parseInt(extractAttributeValue(parser, KEY_ATTRIBUTE));
+ @AtomicFormula.Operator int operator = Integer.parseInt(
+ extractAttributeValue(parser, OPERATOR_ATTRIBUTE));
+ String value = extractAttributeValue(parser, VALUE_ATTRIBUTE);
int eventType;
while ((eventType = parser.next()) != XmlPullParser.END_DOCUMENT) {
- String nodeName = parser.getName();
-
if (eventType == XmlPullParser.END_TAG && parser.getName().equals(ATOMIC_FORMULA_TAG)) {
break;
}
-
- if (eventType == XmlPullParser.START_TAG) {
- switch (nodeName) {
- case KEY_TAG:
- key = Integer.parseInt(extractValue(parser));
- break;
- case OPERATOR_TAG:
- operator = Integer.parseInt(extractValue(parser));
- break;
- case VALUE_TAG:
- value = extractValue(parser);
- break;
- default:
- throw new RuntimeException(
- String.format("Found unexpected tag: %s", nodeName));
- }
- } else {
- throw new RuntimeException(
- String.format("Found unexpected event type: %d", eventType));
- }
}
return constructAtomicFormulaBasedOnKey(key, operator, value);
}
@@ -231,17 +205,11 @@ public final class RuleXmlParser implements RuleParser {
}
}
- private static String extractValue(XmlPullParser parser)
- throws IOException, XmlPullParserException {
- String value;
- int eventType = parser.next();
- if (eventType == XmlPullParser.TEXT) {
- value = parser.getText();
- eventType = parser.next();
- if (eventType == XmlPullParser.END_TAG) {
- return value;
- }
+ private static String extractAttributeValue(XmlPullParser parser, String attribute) {
+ String attributeValue = parser.getAttributeValue(NAMESPACE, attribute);
+ if (attributeValue == null) {
+ throw new RuntimeException(String.format("Attribute not found: %s", attribute));
}
- throw new RuntimeException(String.format("Found unexpected event type: %d", eventType));
+ return attributeValue;
}
}
diff --git a/services/core/java/com/android/server/integrity/serializer/RuleXmlSerializer.java b/services/core/java/com/android/server/integrity/serializer/RuleXmlSerializer.java
index b0805fc488cb..1f22afb0e9bf 100644
--- a/services/core/java/com/android/server/integrity/serializer/RuleXmlSerializer.java
+++ b/services/core/java/com/android/server/integrity/serializer/RuleXmlSerializer.java
@@ -43,11 +43,11 @@ public class RuleXmlSerializer implements RuleSerializer {
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";
+ private static final String EFFECT_ATTRIBUTE = "E";
+ private static final String KEY_ATTRIBUTE = "K";
+ private static final String OPERATOR_ATTRIBUTE = "O";
+ private static final String VALUE_ATTRIBUTE = "V";
+ private static final String CONNECTOR_ATTRIBUTE = "C";
@Override
public void serialize(List<Rule> rules, OutputStream outputStream)
@@ -88,8 +88,8 @@ public class RuleXmlSerializer implements RuleSerializer {
return;
}
xmlSerializer.startTag(NAMESPACE, RULE_TAG);
+ serializeAttributeValue(EFFECT_ATTRIBUTE, String.valueOf(rule.getEffect()), xmlSerializer);
serializeFormula(rule.getFormula(), xmlSerializer);
- serializeValue(EFFECT_TAG, String.valueOf(rule.getEffect()), xmlSerializer);
xmlSerializer.endTag(NAMESPACE, RULE_TAG);
}
@@ -110,7 +110,8 @@ public class RuleXmlSerializer implements RuleSerializer {
return;
}
xmlSerializer.startTag(NAMESPACE, OPEN_FORMULA_TAG);
- serializeValue(CONNECTOR_TAG, String.valueOf(openFormula.getConnector()), xmlSerializer);
+ serializeAttributeValue(CONNECTOR_ATTRIBUTE, String.valueOf(openFormula.getConnector()),
+ xmlSerializer);
for (Formula formula : openFormula.getFormulas()) {
serializeFormula(formula, xmlSerializer);
}
@@ -123,19 +124,20 @@ public class RuleXmlSerializer implements RuleSerializer {
return;
}
xmlSerializer.startTag(NAMESPACE, ATOMIC_FORMULA_TAG);
- serializeValue(KEY_TAG, String.valueOf(atomicFormula.getKey()), xmlSerializer);
+ serializeAttributeValue(KEY_ATTRIBUTE, String.valueOf(atomicFormula.getKey()),
+ xmlSerializer);
if (atomicFormula instanceof AtomicFormula.StringAtomicFormula) {
- serializeValue(VALUE_TAG,
+ serializeAttributeValue(VALUE_ATTRIBUTE,
((AtomicFormula.StringAtomicFormula) atomicFormula).getValue(), xmlSerializer);
} else if (atomicFormula instanceof AtomicFormula.IntAtomicFormula) {
- serializeValue(OPERATOR_TAG,
+ serializeAttributeValue(OPERATOR_ATTRIBUTE,
String.valueOf(((AtomicFormula.IntAtomicFormula) atomicFormula).getOperator()),
xmlSerializer);
- serializeValue(VALUE_TAG,
+ serializeAttributeValue(VALUE_ATTRIBUTE,
String.valueOf(((AtomicFormula.IntAtomicFormula) atomicFormula).getValue()),
xmlSerializer);
} else if (atomicFormula instanceof AtomicFormula.BooleanAtomicFormula) {
- serializeValue(VALUE_TAG,
+ serializeAttributeValue(VALUE_ATTRIBUTE,
String.valueOf(((AtomicFormula.BooleanAtomicFormula) atomicFormula).getValue()),
xmlSerializer);
} else {
@@ -145,13 +147,12 @@ public class RuleXmlSerializer implements RuleSerializer {
xmlSerializer.endTag(NAMESPACE, ATOMIC_FORMULA_TAG);
}
- private void serializeValue(String tag, String value, XmlSerializer xmlSerializer)
+ private void serializeAttributeValue(String attribute, String value,
+ XmlSerializer xmlSerializer)
throws IOException {
if (value == null) {
return;
}
- xmlSerializer.startTag(NAMESPACE, tag);
- xmlSerializer.text(value);
- xmlSerializer.endTag(NAMESPACE, tag);
+ xmlSerializer.attribute(NAMESPACE, attribute, value);
}
}
diff --git a/services/tests/servicestests/src/com/android/server/integrity/parser/RuleXmlParserTest.java b/services/tests/servicestests/src/com/android/server/integrity/parser/RuleXmlParserTest.java
index 975689db5264..be6a31fa949e 100644
--- a/services/tests/servicestests/src/com/android/server/integrity/parser/RuleXmlParserTest.java
+++ b/services/tests/servicestests/src/com/android/server/integrity/parser/RuleXmlParserTest.java
@@ -32,24 +32,28 @@ import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
@RunWith(JUnit4.class)
public class RuleXmlParserTest {
@Test
public void testXmlStream_validOpenFormula() throws Exception {
+ Map<String, String> atomicFormulaAttrs = new HashMap<>();
+ atomicFormulaAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME));
+ atomicFormulaAttrs.put("O", String.valueOf(AtomicFormula.EQ));
+ atomicFormulaAttrs.put("V", "com.app.test");
String ruleXmlOpenFormula = "<RL>"
- + "<R>"
- + "<OF>"
- + "<C>" + OpenFormula.NOT + "</C>"
- + "<AF>"
- + "<K>" + AtomicFormula.PACKAGE_NAME + "</K>"
- + "<O>" + AtomicFormula.EQ + "</O>"
- + "<V>com.app.test</V>"
- + "</AF>"
+ + generateTagWithAttribute(/* tag= */ "R",
+ Collections.singletonMap("E", String.valueOf(Rule.DENY)),
+ /* closed= */ false)
+ + generateTagWithAttribute(/* tag= */ "OF",
+ Collections.singletonMap("C", String.valueOf(OpenFormula.NOT)),
+ /* closed= */ false)
+ + generateTagWithAttribute(/* tag= */ "AF", atomicFormulaAttrs, /* closed= */ true)
+ "</OF>"
- + "<E>" + Rule.DENY + "</E>"
+ "</R>"
+ "</RL>";
RuleParser xmlParser = new RuleXmlParser();
@@ -65,17 +69,19 @@ public class RuleXmlParserTest {
@Test
public void testXmlString_validOpenFormula_notConnector() throws Exception {
+ Map<String, String> packageNameAttrs = new HashMap<>();
+ packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME));
+ packageNameAttrs.put("O", String.valueOf(AtomicFormula.EQ));
+ packageNameAttrs.put("V", "com.app.test");
String ruleXmlOpenFormula = "<RL>"
- + "<R>"
- + "<OF>"
- + "<C>" + OpenFormula.NOT + "</C>"
- + "<AF>"
- + "<K>" + AtomicFormula.PACKAGE_NAME + "</K>"
- + "<O>" + AtomicFormula.EQ + "</O>"
- + "<V>com.app.test</V>"
- + "</AF>"
+ + generateTagWithAttribute(/* tag= */ "R",
+ Collections.singletonMap("E", String.valueOf(Rule.DENY)),
+ /* closed= */ false)
+ + generateTagWithAttribute(/* tag= */ "OF",
+ Collections.singletonMap("C", String.valueOf(OpenFormula.NOT)),
+ /* closed= */ false)
+ + generateTagWithAttribute(/* tag= */ "AF", packageNameAttrs, /* closed= */ true)
+ "</OF>"
- + "<E>" + Rule.DENY + "</E>"
+ "</R>"
+ "</RL>";
RuleParser xmlParser = new RuleXmlParser();
@@ -90,22 +96,24 @@ public class RuleXmlParserTest {
@Test
public void testXmlString_validOpenFormula_andConnector() throws Exception {
+ Map<String, String> packageNameAttrs = new HashMap<>();
+ packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME));
+ packageNameAttrs.put("O", String.valueOf(AtomicFormula.EQ));
+ packageNameAttrs.put("V", "com.app.test");
+ Map<String, String> appCertificateAttrs = new HashMap<>();
+ appCertificateAttrs.put("K", String.valueOf(AtomicFormula.APP_CERTIFICATE));
+ appCertificateAttrs.put("O", String.valueOf(AtomicFormula.EQ));
+ appCertificateAttrs.put("V", "test_cert");
String ruleXmlOpenFormula = "<RL>"
- + "<R>"
- + "<OF>"
- + "<C>" + OpenFormula.AND + "</C>"
- + "<AF>"
- + "<K>" + AtomicFormula.PACKAGE_NAME + "</K>"
- + "<O>" + AtomicFormula.EQ + "</O>"
- + "<V>com.app.test</V>"
- + "</AF>"
- + "<AF>"
- + "<K>" + AtomicFormula.APP_CERTIFICATE + "</K>"
- + "<O>" + AtomicFormula.EQ + "</O>"
- + "<V>test_cert</V>"
- + "</AF>"
+ + generateTagWithAttribute(/* tag= */ "R",
+ Collections.singletonMap("E", String.valueOf(Rule.DENY)),
+ /* closed= */ false)
+ + generateTagWithAttribute(/* tag= */ "OF",
+ Collections.singletonMap("C", String.valueOf(OpenFormula.AND)),
+ /* closed= */ false)
+ + generateTagWithAttribute(/* tag= */ "AF", packageNameAttrs, /* closed= */ true)
+ + generateTagWithAttribute(/* tag= */ "AF", appCertificateAttrs, /* closed= */ true)
+ "</OF>"
- + "<E>" + Rule.DENY + "</E>"
+ "</R>"
+ "</RL>";
RuleParser xmlParser = new RuleXmlParser();
@@ -121,22 +129,24 @@ public class RuleXmlParserTest {
@Test
public void testXmlString_validOpenFormula_orConnector() throws Exception {
+ Map<String, String> packageNameAttrs = new HashMap<>();
+ packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME));
+ packageNameAttrs.put("O", String.valueOf(AtomicFormula.EQ));
+ packageNameAttrs.put("V", "com.app.test");
+ Map<String, String> appCertificateAttrs = new HashMap<>();
+ appCertificateAttrs.put("K", String.valueOf(AtomicFormula.APP_CERTIFICATE));
+ appCertificateAttrs.put("O", String.valueOf(AtomicFormula.EQ));
+ appCertificateAttrs.put("V", "test_cert");
String ruleXmlOpenFormula = "<RL>"
- + "<R>"
- + "<OF>"
- + "<C>" + OpenFormula.OR + "</C>"
- + "<AF>"
- + "<K>" + AtomicFormula.PACKAGE_NAME + "</K>"
- + "<O>" + AtomicFormula.EQ + "</O>"
- + "<V>com.app.test</V>"
- + "</AF>"
- + "<AF>"
- + "<K>" + AtomicFormula.APP_CERTIFICATE + "</K>"
- + "<O>" + AtomicFormula.EQ + "</O>"
- + "<V>test_cert</V>"
- + "</AF>"
+ + generateTagWithAttribute(/* tag= */ "R",
+ Collections.singletonMap("E", String.valueOf(Rule.DENY)),
+ /* closed= */ false)
+ + generateTagWithAttribute(/* tag= */ "OF",
+ Collections.singletonMap("C", String.valueOf(OpenFormula.OR)),
+ /* closed= */ false)
+ + generateTagWithAttribute(/* tag= */ "AF", packageNameAttrs, /* closed= */ true)
+ + generateTagWithAttribute(/* tag= */ "AF", appCertificateAttrs, /* closed= */ true)
+ "</OF>"
- + "<E>" + Rule.DENY + "</E>"
+ "</R>"
+ "</RL>";
RuleParser xmlParser = new RuleXmlParser();
@@ -152,17 +162,19 @@ public class RuleXmlParserTest {
@Test
public void testXmlString_validOpenFormula_differentTagOrder() throws Exception {
+ Map<String, String> packageNameAttrs = new HashMap<>();
+ packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME));
+ packageNameAttrs.put("V", "com.app.test");
+ packageNameAttrs.put("O", String.valueOf(AtomicFormula.EQ));
String ruleXmlOpenFormula = "<RL>"
- + "<R>"
- + "<OF>"
- + "<AF>"
- + "<K>" + AtomicFormula.PACKAGE_NAME + "</K>"
- + "<O>" + AtomicFormula.EQ + "</O>"
- + "<V>com.app.test</V>"
- + "</AF>"
- + "<C>" + OpenFormula.NOT + "</C>"
+ + generateTagWithAttribute(/* tag= */ "R",
+ Collections.singletonMap("E", String.valueOf(Rule.DENY)),
+ /* closed= */ false)
+ + generateTagWithAttribute(/* tag= */ "OF",
+ Collections.singletonMap("C", String.valueOf(OpenFormula.NOT)),
+ /* closed= */ false)
+ + generateTagWithAttribute(/* tag= */ "AF", packageNameAttrs, /* closed= */ true)
+ "</OF>"
- + "<E>" + Rule.DENY + "</E>"
+ "</R>"
+ "</RL>";
RuleParser xmlParser = new RuleXmlParser();
@@ -177,22 +189,24 @@ public class RuleXmlParserTest {
@Test
public void testXmlString_invalidOpenFormula_invalidNumberOfFormulas() throws Exception {
+ Map<String, String> packageNameAttrs = new HashMap<>();
+ packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME));
+ packageNameAttrs.put("O", String.valueOf(AtomicFormula.EQ));
+ packageNameAttrs.put("V", "com.app.test");
+ Map<String, String> versionCodeAttrs = new HashMap<>();
+ versionCodeAttrs.put("K", String.valueOf(AtomicFormula.VERSION_CODE));
+ versionCodeAttrs.put("O", String.valueOf(AtomicFormula.EQ));
+ versionCodeAttrs.put("V", "1");
String ruleXmlOpenFormula = "<RL>"
- + "<R>"
- + "<OF>"
- + "<C>" + OpenFormula.NOT + "</C>"
- + "<AF>"
- + "<K>" + AtomicFormula.PACKAGE_NAME + "</K>"
- + "<O>" + AtomicFormula.EQ + "</O>"
- + "<V>com.app.test</V>"
- + "</AF>"
- + "<AF>"
- + "<K>" + AtomicFormula.VERSION_CODE + "</K>"
- + "<O>" + AtomicFormula.EQ + "</O>"
- + "<V>1</V>"
- + "</AF>"
+ + generateTagWithAttribute(/* tag= */ "R",
+ Collections.singletonMap("E", String.valueOf(Rule.DENY)),
+ /* closed= */ false)
+ + generateTagWithAttribute(/* tag= */ "OF",
+ Collections.singletonMap("C", String.valueOf(OpenFormula.NOT)),
+ /* closed= */ false)
+ + generateTagWithAttribute(/* tag= */ "AF", packageNameAttrs, /* closed= */ true)
+ + generateTagWithAttribute(/* tag= */ "AF", versionCodeAttrs, /* closed= */ true)
+ "</OF>"
- + "<E>" + Rule.DENY + "</E>"
+ "</R>"
+ "</RL>";
RuleParser xmlParser = new RuleXmlParser();
@@ -205,17 +219,19 @@ public class RuleXmlParserTest {
@Test
public void testXmlString_invalidOpenFormula_invalidOperator() throws Exception {
+ Map<String, String> packageNameAttrs = new HashMap<>();
+ packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME));
+ packageNameAttrs.put("O", "INVALID_OPERATOR");
+ packageNameAttrs.put("V", "com.app.test");
String ruleXmlOpenFormula = "<RL>"
- + "<R>"
- + "<OF>"
- + "<C>" + OpenFormula.NOT + "</C>"
- + "<AF>"
- + "<K>" + AtomicFormula.PACKAGE_NAME + "</K>"
- + "<O>INVALID_OPERATOR</O>"
- + "<V>com.app.test</V>"
- + "</AF>"
+ + generateTagWithAttribute(/* tag= */ "R",
+ Collections.singletonMap("E", String.valueOf(Rule.DENY)),
+ /* closed= */ false)
+ + generateTagWithAttribute(/* tag= */ "OF",
+ Collections.singletonMap("C", String.valueOf(OpenFormula.NOT)),
+ /* closed= */ false)
+ + generateTagWithAttribute(/* tag= */ "AF", packageNameAttrs, /* closed= */ true)
+ "</OF>"
- + "<E>" + Rule.DENY + "</E>"
+ "</R>"
+ "</RL>";
RuleParser xmlParser = new RuleXmlParser();
@@ -228,17 +244,19 @@ public class RuleXmlParserTest {
@Test
public void testXmlString_invalidOpenFormula_invalidEffect() throws Exception {
+ Map<String, String> packageNameAttrs = new HashMap<>();
+ packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME));
+ packageNameAttrs.put("O", String.valueOf(AtomicFormula.EQ));
+ packageNameAttrs.put("V", "com.app.test");
String ruleXmlOpenFormula = "<RL>"
- + "<R>"
- + "<OF>"
- + "<C>" + OpenFormula.NOT + "</C>"
- + "<AF>"
- + "<K>" + AtomicFormula.PACKAGE_NAME + "</K>"
- + "<O>" + AtomicFormula.EQ + "</O>"
- + "<V>com.app.test</V>"
- + "</AF>"
+ + generateTagWithAttribute(/* tag= */ "R",
+ Collections.singletonMap("E", "INVALID_EFFECT"),
+ /* closed= */ false)
+ + generateTagWithAttribute(/* tag= */ "OF",
+ Collections.singletonMap("C", String.valueOf(OpenFormula.NOT)),
+ /* closed= */ false)
+ + generateTagWithAttribute(/* tag= */ "AF", packageNameAttrs, /* closed= */ true)
+ "</OF>"
- + "<E>INVALID_EFFECT</E>"
+ "</R>"
+ "</RL>";
RuleParser xmlParser = new RuleXmlParser();
@@ -251,37 +269,41 @@ public class RuleXmlParserTest {
@Test
public void testXmlString_invalidOpenFormula_invalidTags() throws Exception {
+ Map<String, String> packageNameAttrs = new HashMap<>();
+ packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME));
+ packageNameAttrs.put("O", String.valueOf(AtomicFormula.EQ));
+ packageNameAttrs.put("V", "com.app.test");
String ruleXmlOpenFormula = "<RL>"
- + "<R>"
- + "<OF>"
- + "<InvalidConnector>" + OpenFormula.NOT + "</InvalidConnector>"
- + "<AF>"
- + "<K>" + AtomicFormula.PACKAGE_NAME + "</K>"
- + "<O>" + AtomicFormula.EQ + "</O>"
- + "<V>com.app.test</V>"
- + "</AF>"
+ + generateTagWithAttribute(/* tag= */ "R",
+ Collections.singletonMap("E", String.valueOf(Rule.DENY)),
+ /* closed= */ false)
+ + generateTagWithAttribute(/* tag= */ "OF",
+ Collections.singletonMap("C", String.valueOf(OpenFormula.NOT)),
+ /* closed= */ false)
+ + generateTagWithAttribute(/* tag= */ "InvalidAtomicFormula",
+ packageNameAttrs, /* closed= */ true)
+ "</OF>"
- + "<E>" + Rule.DENY + "</E>"
+ "</R>"
+ "</RL>";
RuleParser xmlParser = new RuleXmlParser();
assertExpectException(
RuleParseException.class,
- /* expectedExceptionMessageRegex */ "Found unexpected tag: InvalidConnector",
+ /* expectedExceptionMessageRegex */ "Found unexpected tag: InvalidAtomicFormula",
() -> xmlParser.parse(ruleXmlOpenFormula));
}
@Test
public void testXmlString_validAtomicFormula_stringValue() throws Exception {
+ Map<String, String> packageNameAttrs = new HashMap<>();
+ packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME));
+ packageNameAttrs.put("O", String.valueOf(AtomicFormula.EQ));
+ packageNameAttrs.put("V", "com.app.test");
String ruleXmlAtomicFormula = "<RL>"
- + "<R>"
- + "<AF>"
- + "<K>" + AtomicFormula.PACKAGE_NAME + "</K>"
- + "<O>" + AtomicFormula.EQ + "</O>"
- + "<V>com.app.test</V>"
- + "</AF>"
- + "<E>" + Rule.DENY + "</E>"
+ + generateTagWithAttribute(/* tag= */ "R",
+ Collections.singletonMap("E", String.valueOf(Rule.DENY)),
+ /* closed= */ false)
+ + generateTagWithAttribute(/* tag= */ "AF", packageNameAttrs, /* closed= */ true)
+ "</R>"
+ "</RL>";
RuleParser xmlParser = new RuleXmlParser();
@@ -296,14 +318,15 @@ public class RuleXmlParserTest {
@Test
public void testXmlString_validAtomicFormula_integerValue() throws Exception {
+ Map<String, String> versionCodeAttrs = new HashMap<>();
+ versionCodeAttrs.put("K", String.valueOf(AtomicFormula.VERSION_CODE));
+ versionCodeAttrs.put("O", String.valueOf(AtomicFormula.EQ));
+ versionCodeAttrs.put("V", "1");
String ruleXmlAtomicFormula = "<RL>"
- + "<R>"
- + "<AF>"
- + "<K>" + AtomicFormula.VERSION_CODE + "</K>"
- + "<O>" + AtomicFormula.EQ + "</O>"
- + "<V>1</V>"
- + "</AF>"
- + "<E>" + Rule.DENY + "</E>"
+ + generateTagWithAttribute(/* tag= */ "R",
+ Collections.singletonMap("E", String.valueOf(Rule.DENY)),
+ /* closed= */ false)
+ + generateTagWithAttribute(/* tag= */ "AF", versionCodeAttrs, /* closed= */ true)
+ "</R>"
+ "</RL>";
RuleParser xmlParser = new RuleXmlParser();
@@ -318,14 +341,15 @@ public class RuleXmlParserTest {
@Test
public void testXmlString_validAtomicFormula_booleanValue() throws Exception {
+ Map<String, String> preInstalledAttrs = new HashMap<>();
+ preInstalledAttrs.put("K", String.valueOf(AtomicFormula.PRE_INSTALLED));
+ preInstalledAttrs.put("O", String.valueOf(AtomicFormula.EQ));
+ preInstalledAttrs.put("V", "true");
String ruleXmlAtomicFormula = "<RL>"
- + "<R>"
- + "<AF>"
- + "<K>" + AtomicFormula.PRE_INSTALLED + "</K>"
- + "<O>" + AtomicFormula.EQ + "</O>"
- + "<V>true</V>"
- + "</AF>"
- + "<E>" + Rule.DENY + "</E>"
+ + generateTagWithAttribute(/* tag= */ "R",
+ Collections.singletonMap("E", String.valueOf(Rule.DENY)),
+ /* closed= */ false)
+ + generateTagWithAttribute(/* tag= */ "AF", preInstalledAttrs, /* closed= */ true)
+ "</R>"
+ "</RL>";
RuleParser xmlParser = new RuleXmlParser();
@@ -339,15 +363,16 @@ public class RuleXmlParserTest {
}
@Test
- public void testXmlString_validAtomicFormula_differentTagOrder() throws Exception {
+ public void testXmlString_validAtomicFormula_differentAttributeOrder() throws Exception {
+ Map<String, String> packageNameAttrs = new HashMap<>();
+ packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME));
+ packageNameAttrs.put("V", "com.app.test");
+ packageNameAttrs.put("O", String.valueOf(AtomicFormula.EQ));
String ruleXmlAtomicFormula = "<RL>"
- + "<R>"
- + "<AF>"
- + "<O>" + AtomicFormula.EQ + "</O>"
- + "<V>com.app.test</V>"
- + "<K>" + AtomicFormula.PACKAGE_NAME + "</K>"
- + "</AF>"
- + "<E>" + Rule.DENY + "</E>"
+ + generateTagWithAttribute(/* tag= */ "R",
+ Collections.singletonMap("E", String.valueOf(Rule.DENY)),
+ /* closed= */ false)
+ + generateTagWithAttribute(/* tag= */ "AF", packageNameAttrs, /* closed= */ true)
+ "</R>"
+ "</RL>";
RuleParser xmlParser = new RuleXmlParser();
@@ -361,35 +386,37 @@ public class RuleXmlParserTest {
}
@Test
- public void testXmlString_invalidAtomicFormula_invalidTags() throws Exception {
+ public void testXmlString_invalidAtomicFormula_invalidAttribute() throws Exception {
+ Map<String, String> packageNameAttrs = new HashMap<>();
+ packageNameAttrs.put("BadKey", String.valueOf(AtomicFormula.PACKAGE_NAME));
+ packageNameAttrs.put("O", String.valueOf(AtomicFormula.EQ));
+ packageNameAttrs.put("V", "com.app.test");
String ruleXmlAtomicFormula = "<RL>"
- + "<R>"
- + "<AF>"
- + "<BadKey>" + AtomicFormula.PACKAGE_NAME + "</BadKey>"
- + "<O>" + AtomicFormula.EQ + "</O>"
- + "<V>com.app.test</V>"
- + "</AF>"
- + "<E>" + Rule.DENY + "</E>"
+ + generateTagWithAttribute(/* tag= */ "R",
+ Collections.singletonMap("E", String.valueOf(Rule.DENY)),
+ /* closed= */ false)
+ + generateTagWithAttribute(/* tag= */ "AF", packageNameAttrs, /* closed= */ true)
+ "</R>"
+ "</RL>";
RuleParser xmlParser = new RuleXmlParser();
assertExpectException(
RuleParseException.class,
- /* expectedExceptionMessageRegex */ "Found unexpected tag: BadKey",
+ /* expectedExceptionMessageRegex */ "Attribute not found: K",
() -> xmlParser.parse(ruleXmlAtomicFormula));
}
@Test
public void testXmlString_invalidAtomicFormula() throws Exception {
+ Map<String, String> packageNameAttrs = new HashMap<>();
+ packageNameAttrs.put("K", String.valueOf(AtomicFormula.VERSION_CODE));
+ packageNameAttrs.put("O", String.valueOf(AtomicFormula.EQ));
+ packageNameAttrs.put("V", "com.app.test");
String ruleXmlAtomicFormula = "<RL>"
- + "<R>"
- + "<AF>"
- + "<K>" + AtomicFormula.VERSION_CODE + "</K>"
- + "<O>" + AtomicFormula.EQ + "</O>"
- + "<V>com.app.test</V>"
- + "</AF>"
- + "<E>" + Rule.DENY + "</E>"
+ + generateTagWithAttribute(/* tag= */ "R",
+ Collections.singletonMap("E", String.valueOf(Rule.DENY)),
+ /* closed= */ false)
+ + generateTagWithAttribute(/* tag= */ "AF", packageNameAttrs, /* closed= */ true)
+ "</R>"
+ "</RL>";
RuleParser xmlParser = new RuleXmlParser();
@@ -402,16 +429,18 @@ public class RuleXmlParserTest {
@Test
public void testXmlString_withNoRuleList() {
- String ruleXmlWithNoRuleList = "<R>"
- + "<OF>"
- + "<C>" + OpenFormula.NOT + "</C>"
- + "<AF>"
- + "<K>" + AtomicFormula.PACKAGE_NAME + "</K>"
- + "<O>" + AtomicFormula.EQ + "</O>"
- + "<V>com.app.test</V>"
- + "</AF>"
+ Map<String, String> atomicFormulaAttrs = new HashMap<>();
+ atomicFormulaAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME));
+ atomicFormulaAttrs.put("O", String.valueOf(AtomicFormula.EQ));
+ atomicFormulaAttrs.put("V", "com.app.test");
+ String ruleXmlWithNoRuleList = generateTagWithAttribute(/* tag= */ "R",
+ Collections.singletonMap("E", String.valueOf(Rule.DENY)),
+ /* closed= */ false)
+ + generateTagWithAttribute(/* tag= */ "OF",
+ Collections.singletonMap("C", String.valueOf(OpenFormula.NOT)),
+ /* closed= */ false)
+ + generateTagWithAttribute(/* tag= */ "AF", atomicFormulaAttrs, /* closed= */ true)
+ "</OF>"
- + "<E>" + Rule.DENY + "</E>"
+ "</R>";
RuleParser xmlParser = new RuleXmlParser();
@@ -423,16 +452,18 @@ public class RuleXmlParserTest {
@Test
public void testXmlStream_withNoRuleList() {
- String ruleXmlWithNoRuleList = "<R>"
- + "<OF>"
- + "<C>" + OpenFormula.NOT + "</C>"
- + "<AF>"
- + "<K>" + AtomicFormula.PACKAGE_NAME + "</K>"
- + "<O>" + AtomicFormula.EQ + "</O>"
- + "<V>com.app.test</V>"
- + "</AF>"
+ Map<String, String> atomicFormulaAttrs = new HashMap<>();
+ atomicFormulaAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME));
+ atomicFormulaAttrs.put("O", String.valueOf(AtomicFormula.EQ));
+ atomicFormulaAttrs.put("V", "com.app.test");
+ String ruleXmlWithNoRuleList = generateTagWithAttribute(/* tag= */ "R",
+ Collections.singletonMap("E", String.valueOf(Rule.DENY)),
+ /* closed= */ false)
+ + generateTagWithAttribute(/* tag= */ "OF",
+ Collections.singletonMap("C", String.valueOf(OpenFormula.NOT)),
+ /* closed= */ false)
+ + generateTagWithAttribute(/* tag= */ "AF", atomicFormulaAttrs, /* closed= */ true)
+ "</OF>"
- + "<E>" + Rule.DENY + "</E>"
+ "</R>";
InputStream inputStream = new ByteArrayInputStream(ruleXmlWithNoRuleList.getBytes());
RuleParser xmlParser = new RuleXmlParser();
@@ -442,4 +473,19 @@ public class RuleXmlParserTest {
/* expectedExceptionMessageRegex */ "Rules must start with RuleList <RL> tag",
() -> xmlParser.parse(inputStream));
}
+
+ private String generateTagWithAttribute(String tag, Map<String, String> attributeValues,
+ boolean closed) {
+ StringBuilder res = new StringBuilder("<");
+ res.append(tag);
+ for (String attribute : attributeValues.keySet()) {
+ res.append(" ");
+ res.append(attribute);
+ res.append("=\"");
+ res.append(attributeValues.get(attribute));
+ res.append("\"");
+ }
+ res.append(closed ? " />" : ">");
+ return res.toString();
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleXmlSerializerTest.java b/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleXmlSerializerTest.java
index 082fda82499a..a25627155950 100644
--- a/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleXmlSerializerTest.java
+++ b/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleXmlSerializerTest.java
@@ -36,6 +36,8 @@ import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
@RunWith(JUnit4.class)
public class RuleXmlSerializerTest {
@@ -58,13 +60,14 @@ public class RuleXmlSerializerTest {
new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.app.test"),
Rule.DENY);
RuleSerializer xmlSerializer = new RuleXmlSerializer();
+ Map<String, String> packageNameAttrs = new LinkedHashMap<>();
+ packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME));
+ packageNameAttrs.put("V", "com.app.test");
String expectedRules = "<RL>"
- + "<R>"
- + "<AF>"
- + "<K>" + AtomicFormula.PACKAGE_NAME + "</K>"
- + "<V>com.app.test</V>"
- + "</AF>"
- + "<E>" + Rule.DENY + "</E>"
+ + generateTagWithAttribute(/* tag= */ "R",
+ Collections.singletonMap("E", String.valueOf(Rule.DENY)),
+ /* closed= */ false)
+ + generateTagWithAttribute(/* tag= */ "AF", packageNameAttrs, /* closed= */ true)
+ "</R>"
+ "</RL>";
@@ -81,16 +84,18 @@ public class RuleXmlSerializerTest {
"com.app.test"))), Rule.DENY);
RuleSerializer xmlSerializer = new RuleXmlSerializer();
OutputStream outputStream = new ByteArrayOutputStream();
+ Map<String, String> packageNameAttrs = new LinkedHashMap<>();
+ packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME));
+ packageNameAttrs.put("V", "com.app.test");
String expectedRules = "<RL>"
- + "<R>"
- + "<OF>"
- + "<C>" + OpenFormula.NOT + "</C>"
- + "<AF>"
- + "<K>" + AtomicFormula.PACKAGE_NAME + "</K>"
- + "<V>com.app.test</V>"
- + "</AF>"
+ + generateTagWithAttribute(/* tag= */ "R",
+ Collections.singletonMap("E", String.valueOf(Rule.DENY)),
+ /* closed= */ false)
+ + generateTagWithAttribute(/* tag= */ "OF",
+ Collections.singletonMap("C", String.valueOf(OpenFormula.NOT)),
+ /* closed= */ false)
+ + generateTagWithAttribute(/* tag= */ "AF", packageNameAttrs, /* closed= */ true)
+ "</OF>"
- + "<E>" + Rule.DENY + "</E>"
+ "</R>"
+ "</RL>";
@@ -107,16 +112,18 @@ public class RuleXmlSerializerTest {
new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME,
"com.app.test"))), Rule.DENY);
RuleSerializer xmlSerializer = new RuleXmlSerializer();
+ Map<String, String> packageNameAttrs = new LinkedHashMap<>();
+ packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME));
+ packageNameAttrs.put("V", "com.app.test");
String expectedRules = "<RL>"
- + "<R>"
- + "<OF>"
- + "<C>" + OpenFormula.NOT + "</C>"
- + "<AF>"
- + "<K>" + AtomicFormula.PACKAGE_NAME + "</K>"
- + "<V>com.app.test</V>"
- + "</AF>"
+ + generateTagWithAttribute(/* tag= */ "R",
+ Collections.singletonMap("E", String.valueOf(Rule.DENY)),
+ /* closed= */ false)
+ + generateTagWithAttribute(/* tag= */ "OF",
+ Collections.singletonMap("C", String.valueOf(OpenFormula.NOT)),
+ /* closed= */ false)
+ + generateTagWithAttribute(/* tag= */ "AF", packageNameAttrs, /* closed= */ true)
+ "</OF>"
- + "<E>" + Rule.DENY + "</E>"
+ "</R>"
+ "</RL>";
@@ -133,20 +140,22 @@ public class RuleXmlSerializerTest {
new AtomicFormula.StringAtomicFormula(AtomicFormula.APP_CERTIFICATE,
"test_cert"))), Rule.DENY);
RuleSerializer xmlSerializer = new RuleXmlSerializer();
+ Map<String, String> packageNameAttrs = new LinkedHashMap<>();
+ packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME));
+ packageNameAttrs.put("V", "com.app.test");
+ Map<String, String> appCertificateAttrs = new LinkedHashMap<>();
+ appCertificateAttrs.put("K", String.valueOf(AtomicFormula.APP_CERTIFICATE));
+ appCertificateAttrs.put("V", "test_cert");
String expectedRules = "<RL>"
- + "<R>"
- + "<OF>"
- + "<C>" + OpenFormula.AND + "</C>"
- + "<AF>"
- + "<K>" + AtomicFormula.PACKAGE_NAME + "</K>"
- + "<V>com.app.test</V>"
- + "</AF>"
- + "<AF>"
- + "<K>" + AtomicFormula.APP_CERTIFICATE + "</K>"
- + "<V>test_cert</V>"
- + "</AF>"
+ + generateTagWithAttribute(/* tag= */ "R",
+ Collections.singletonMap("E", String.valueOf(Rule.DENY)),
+ /* closed= */ false)
+ + generateTagWithAttribute(/* tag= */ "OF",
+ Collections.singletonMap("C", String.valueOf(OpenFormula.AND)),
+ /* closed= */ false)
+ + generateTagWithAttribute(/* tag= */ "AF", packageNameAttrs, /* closed= */ true)
+ + generateTagWithAttribute(/* tag= */ "AF", appCertificateAttrs, /* closed= */ true)
+ "</OF>"
- + "<E>" + Rule.DENY + "</E>"
+ "</R>"
+ "</RL>";
@@ -163,20 +172,22 @@ public class RuleXmlSerializerTest {
new AtomicFormula.StringAtomicFormula(AtomicFormula.APP_CERTIFICATE,
"test_cert"))), Rule.DENY);
RuleSerializer xmlSerializer = new RuleXmlSerializer();
+ Map<String, String> packageNameAttrs = new LinkedHashMap<>();
+ packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME));
+ packageNameAttrs.put("V", "com.app.test");
+ Map<String, String> appCertificateAttrs = new LinkedHashMap<>();
+ appCertificateAttrs.put("K", String.valueOf(AtomicFormula.APP_CERTIFICATE));
+ appCertificateAttrs.put("V", "test_cert");
String expectedRules = "<RL>"
- + "<R>"
- + "<OF>"
- + "<C>" + OpenFormula.OR + "</C>"
- + "<AF>"
- + "<K>" + AtomicFormula.PACKAGE_NAME + "</K>"
- + "<V>com.app.test</V>"
- + "</AF>"
- + "<AF>"
- + "<K>" + AtomicFormula.APP_CERTIFICATE + "</K>"
- + "<V>test_cert</V>"
- + "</AF>"
+ + generateTagWithAttribute(/* tag= */ "R",
+ Collections.singletonMap("E", String.valueOf(Rule.DENY)),
+ /* closed= */ false)
+ + generateTagWithAttribute(/* tag= */ "OF",
+ Collections.singletonMap("C", String.valueOf(OpenFormula.OR)),
+ /* closed= */ false)
+ + generateTagWithAttribute(/* tag= */ "AF", packageNameAttrs, /* closed= */ true)
+ + generateTagWithAttribute(/* tag= */ "AF", appCertificateAttrs, /* closed= */ true)
+ "</OF>"
- + "<E>" + Rule.DENY + "</E>"
+ "</R>"
+ "</RL>";
@@ -191,13 +202,14 @@ public class RuleXmlSerializerTest {
new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.app.test"),
Rule.DENY);
RuleSerializer xmlSerializer = new RuleXmlSerializer();
+ Map<String, String> packageNameAttrs = new LinkedHashMap<>();
+ packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME));
+ packageNameAttrs.put("V", "com.app.test");
String expectedRules = "<RL>"
- + "<R>"
- + "<AF>"
- + "<K>" + AtomicFormula.PACKAGE_NAME + "</K>"
- + "<V>com.app.test</V>"
- + "</AF>"
- + "<E>" + Rule.DENY + "</E>"
+ + generateTagWithAttribute(/* tag= */ "R",
+ Collections.singletonMap("E", String.valueOf(Rule.DENY)),
+ /* closed= */ false)
+ + generateTagWithAttribute(/* tag= */ "AF", packageNameAttrs, /* closed= */ true)
+ "</R>"
+ "</RL>";
@@ -212,14 +224,15 @@ public class RuleXmlSerializerTest {
new AtomicFormula.IntAtomicFormula(AtomicFormula.VERSION_CODE, AtomicFormula.EQ, 1),
Rule.DENY);
RuleSerializer xmlSerializer = new RuleXmlSerializer();
+ Map<String, String> versionCodeAttrs = new LinkedHashMap<>();
+ versionCodeAttrs.put("K", String.valueOf(AtomicFormula.VERSION_CODE));
+ versionCodeAttrs.put("O", String.valueOf(AtomicFormula.EQ));
+ versionCodeAttrs.put("V", "1");
String expectedRules = "<RL>"
- + "<R>"
- + "<AF>"
- + "<K>" + AtomicFormula.VERSION_CODE + "</K>"
- + "<O>" + AtomicFormula.EQ + "</O>"
- + "<V>1</V>"
- + "</AF>"
- + "<E>" + Rule.DENY + "</E>"
+ + generateTagWithAttribute(/* tag= */ "R",
+ Collections.singletonMap("E", String.valueOf(Rule.DENY)),
+ /* closed= */ false)
+ + generateTagWithAttribute(/* tag= */ "AF", versionCodeAttrs, /* closed= */ true)
+ "</R>"
+ "</RL>";
@@ -234,13 +247,14 @@ public class RuleXmlSerializerTest {
new AtomicFormula.BooleanAtomicFormula(AtomicFormula.PRE_INSTALLED, true),
Rule.DENY);
RuleSerializer xmlSerializer = new RuleXmlSerializer();
+ Map<String, String> preInstalledAttrs = new LinkedHashMap<>();
+ preInstalledAttrs.put("K", String.valueOf(AtomicFormula.PRE_INSTALLED));
+ preInstalledAttrs.put("V", "true");
String expectedRules = "<RL>"
- + "<R>"
- + "<AF>"
- + "<K>" + AtomicFormula.PRE_INSTALLED + "</K>"
- + "<V>true</V>"
- + "</AF>"
- + "<E>" + Rule.DENY + "</E>"
+ + generateTagWithAttribute(/* tag= */ "R",
+ Collections.singletonMap("E", String.valueOf(Rule.DENY)),
+ /* closed= */ false)
+ + generateTagWithAttribute(/* tag= */ "AF", preInstalledAttrs, /* closed= */ true)
+ "</R>"
+ "</RL>";
@@ -261,6 +275,21 @@ public class RuleXmlSerializerTest {
() -> xmlSerializer.serialize(Collections.singletonList(rule)));
}
+ private String generateTagWithAttribute(String tag, Map<String, String> attributeValues,
+ boolean closed) {
+ StringBuilder res = new StringBuilder("<");
+ res.append(tag);
+ for (String attribute : attributeValues.keySet()) {
+ res.append(" ");
+ res.append(attribute);
+ res.append("=\"");
+ res.append(attributeValues.get(attribute));
+ res.append("\"");
+ }
+ res.append(closed ? " />" : ">");
+ return res.toString();
+ }
+
private Formula getInvalidFormula() {
return new Formula() {
@Override