Merge changes Ic4587c5b,Ib7118228,I3411a0fb

* changes:
  Include isHashedValue in rule structure
  Support optional rule attributes in XML parser
  Add rule component validations
diff --git a/services/core/java/com/android/server/integrity/model/AtomicFormula.java b/services/core/java/com/android/server/integrity/model/AtomicFormula.java
index 9a0553d..a16f6b9 100644
--- a/services/core/java/com/android/server/integrity/model/AtomicFormula.java
+++ b/services/core/java/com/android/server/integrity/model/AtomicFormula.java
@@ -112,6 +112,7 @@
     private final @Key int mKey;
 
     public AtomicFormula(@Key int key) {
+        checkArgument(isValidKey(key), String.format("Unknown key: %d", key));
         mKey = key;
     }
 
@@ -134,6 +135,8 @@
             checkArgument(
                     key == VERSION_CODE,
                     String.format("Key %s cannot be used with IntAtomicFormula", keyToString(key)));
+            checkArgument(isValidOperator(operator),
+                    String.format("Unknown operator: %d", operator));
             mOperator = operator;
             mValue = value;
         }
@@ -237,11 +240,21 @@
                             "Unexpected key in IntAtomicFormula" + getKey());
             }
         }
+
+        private static boolean isValidOperator(int operator) {
+            return operator == EQ
+                    || operator == LT
+                    || operator == LE
+                    || operator == GT
+                    || operator == GE;
+        }
     }
 
     /** An {@link AtomicFormula} with a key and string value. */
     public static final class StringAtomicFormula extends AtomicFormula implements Parcelable {
         private final String mValue;
+        // Indicates whether the value is the actual value or the hashed value.
+        private final boolean mIsHashedValue;
 
         /**
          * Constructs a new {@link StringAtomicFormula}.
@@ -251,8 +264,9 @@
          *
          * @throws IllegalArgumentException if {@code key} cannot be used with string value
          */
-        public StringAtomicFormula(@Key int key, @NonNull String value) {
+        public StringAtomicFormula(@Key int key, @NonNull String value, boolean isHashedValue) {
             super(key);
+            mIsHashedValue = isHashedValue;
             checkArgument(
                     key == PACKAGE_NAME
                             || key == APP_CERTIFICATE
@@ -266,6 +280,7 @@
         StringAtomicFormula(Parcel in) {
             super(in.readInt());
             mValue = in.readStringNoHelper();
+            mIsHashedValue = in.readByte() != 0;
         }
 
         @NonNull
@@ -324,6 +339,7 @@
         public void writeToParcel(@NonNull Parcel dest, int flags) {
             dest.writeInt(getKey());
             dest.writeStringNoHelper(mValue);
+            dest.writeByte((byte) (mIsHashedValue ? 1 : 0));
         }
 
         @NonNull
@@ -331,6 +347,10 @@
             return mValue;
         }
 
+        public boolean getIsHashedValue() {
+            return mIsHashedValue;
+        }
+
         private String getMetadataValueByKey(AppInstallMetadata appInstallMetadata) {
             switch (getKey()) {
                 case PACKAGE_NAME:
@@ -486,4 +506,13 @@
                 throw new IllegalArgumentException("Unknown operator " + op);
         }
     }
+
+    private static boolean isValidKey(int key) {
+        return key == PACKAGE_NAME
+                || key == APP_CERTIFICATE
+                || key == VERSION_CODE
+                || key == INSTALLER_NAME
+                || key == INSTALLER_CERTIFICATE
+                || key == PRE_INSTALLED;
+    }
 }
diff --git a/services/core/java/com/android/server/integrity/model/OpenFormula.java b/services/core/java/com/android/server/integrity/model/OpenFormula.java
index 7a3600f..f7ea920 100644
--- a/services/core/java/com/android/server/integrity/model/OpenFormula.java
+++ b/services/core/java/com/android/server/integrity/model/OpenFormula.java
@@ -86,6 +86,8 @@
      *     for that operator (at least 2 for {@link #AND} and {@link #OR}, 1 for {@link #NOT}).
      */
     public OpenFormula(@Connector int connector, @NonNull List<Formula> formulas) {
+        checkArgument(isValidConnector(connector),
+                String.format("Unknown connector: %d", connector));
         validateFormulas(connector, formulas);
         this.mConnector = connector;
         this.mFormulas = Collections.unmodifiableList(formulas);
@@ -213,4 +215,10 @@
                 throw new IllegalArgumentException("Unknown connector " + connector);
         }
     }
+
+    private static boolean isValidConnector(int connector) {
+        return connector == AND
+                || connector == OR
+                || connector == NOT;
+    }
 }
diff --git a/services/core/java/com/android/server/integrity/model/Rule.java b/services/core/java/com/android/server/integrity/model/Rule.java
index f87e4e8..3ad8762 100644
--- a/services/core/java/com/android/server/integrity/model/Rule.java
+++ b/services/core/java/com/android/server/integrity/model/Rule.java
@@ -16,6 +16,7 @@
 
 package com.android.server.integrity.model;
 
+import static com.android.internal.util.Preconditions.checkArgument;
 import static com.android.internal.util.Preconditions.checkNotNull;
 
 import android.annotation.IntDef;
@@ -62,6 +63,7 @@
     private final @Effect int mEffect;
 
     public Rule(@NonNull Formula formula, @Effect int effect) {
+        checkArgument(isValidEffect(effect), String.format("Unknown effect: %d", effect));
         this.mFormula = checkNotNull(formula);
         this.mEffect = effect;
     }
@@ -137,4 +139,9 @@
                 throw new IllegalArgumentException("Unknown effect " + effect);
         }
     }
+
+    private static boolean isValidEffect(int effect) {
+        return effect == DENY
+                || effect == FORCE_ALLOW;
+    }
 }
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 11a3979..1508c27 100644
--- a/services/core/java/com/android/server/integrity/parser/RuleXmlParser.java
+++ b/services/core/java/com/android/server/integrity/parser/RuleXmlParser.java
@@ -32,6 +32,7 @@
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Optional;
 
 /**
  * A helper class to parse rules into the {@link Rule} model from Xml representation.
@@ -50,6 +51,7 @@
     private static final String OPERATOR_ATTRIBUTE = "O";
     private static final String VALUE_ATTRIBUTE = "V";
     private static final String CONNECTOR_ATTRIBUTE = "C";
+    private static final String IS_HASHED_VALUE_ATTRIBUTE = "H";
 
     @Override
     public List<Rule> parse(String ruleText) throws RuleParseException {
@@ -106,7 +108,7 @@
 
     private static Rule parseRule(XmlPullParser parser) throws IOException, XmlPullParserException {
         Formula formula = null;
-        @Rule.Effect int effect = Integer.parseInt(extractAttributeValue(parser, EFFECT_ATTRIBUTE));
+        int effect = Integer.parseInt(extractAttributeValue(parser, EFFECT_ATTRIBUTE).orElse("-1"));
 
         int eventType;
         while ((eventType = parser.next()) != XmlPullParser.END_DOCUMENT) {
@@ -139,8 +141,8 @@
 
     private static Formula parseOpenFormula(XmlPullParser parser)
             throws IOException, XmlPullParserException {
-        @OpenFormula.Connector int connector = Integer.parseInt(
-                extractAttributeValue(parser, CONNECTOR_ATTRIBUTE));
+        int connector = Integer.parseInt(
+                extractAttributeValue(parser, CONNECTOR_ATTRIBUTE).orElse("-1"));
         List<Formula> formulas = new ArrayList<>();
 
         int eventType;
@@ -174,10 +176,12 @@
 
     private static Formula parseAtomicFormula(XmlPullParser parser)
             throws IOException, XmlPullParserException {
-        @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 key = Integer.parseInt(extractAttributeValue(parser, KEY_ATTRIBUTE).orElse("-1"));
+        int operator = Integer.parseInt(
+                extractAttributeValue(parser, OPERATOR_ATTRIBUTE).orElse("-1"));
+        String value = extractAttributeValue(parser, VALUE_ATTRIBUTE).orElse(null);
+        String isHashedValue = extractAttributeValue(parser, IS_HASHED_VALUE_ATTRIBUTE).orElse(
+                null);
 
         int eventType;
         while ((eventType = parser.next()) != XmlPullParser.END_DOCUMENT) {
@@ -185,17 +189,18 @@
                 break;
             }
         }
-        return constructAtomicFormulaBasedOnKey(key, operator, value);
+        return constructAtomicFormulaBasedOnKey(key, operator, value, isHashedValue);
     }
 
     private static Formula constructAtomicFormulaBasedOnKey(@AtomicFormula.Key int key,
-            @AtomicFormula.Operator int operator, String value) {
+            @AtomicFormula.Operator int operator, String value, String isHashedValue) {
         switch (key) {
             case AtomicFormula.PACKAGE_NAME:
             case AtomicFormula.INSTALLER_NAME:
             case AtomicFormula.APP_CERTIFICATE:
             case AtomicFormula.INSTALLER_CERTIFICATE:
-                return new AtomicFormula.StringAtomicFormula(key, value);
+                return new AtomicFormula.StringAtomicFormula(key, value,
+                        Boolean.parseBoolean(isHashedValue));
             case AtomicFormula.PRE_INSTALLED:
                 return new AtomicFormula.BooleanAtomicFormula(key, Boolean.parseBoolean(value));
             case AtomicFormula.VERSION_CODE:
@@ -205,11 +210,7 @@
         }
     }
 
-    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));
-        }
-        return attributeValue;
+    private static Optional<String> extractAttributeValue(XmlPullParser parser, String attribute) {
+        return Optional.ofNullable(parser.getAttributeValue(NAMESPACE, attribute));
     }
 }
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 1f22afb..f2ba756 100644
--- a/services/core/java/com/android/server/integrity/serializer/RuleXmlSerializer.java
+++ b/services/core/java/com/android/server/integrity/serializer/RuleXmlSerializer.java
@@ -48,6 +48,7 @@
     private static final String OPERATOR_ATTRIBUTE = "O";
     private static final String VALUE_ATTRIBUTE = "V";
     private static final String CONNECTOR_ATTRIBUTE = "C";
+    private static final String IS_HASHED_VALUE_ATTRIBUTE = "H";
 
     @Override
     public void serialize(List<Rule> rules, OutputStream outputStream)
@@ -129,6 +130,10 @@
         if (atomicFormula instanceof AtomicFormula.StringAtomicFormula) {
             serializeAttributeValue(VALUE_ATTRIBUTE,
                     ((AtomicFormula.StringAtomicFormula) atomicFormula).getValue(), xmlSerializer);
+            serializeAttributeValue(IS_HASHED_VALUE_ATTRIBUTE,
+                    String.valueOf(
+                            ((AtomicFormula.StringAtomicFormula) atomicFormula).getIsHashedValue()),
+                    xmlSerializer);
         } else if (atomicFormula instanceof AtomicFormula.IntAtomicFormula) {
             serializeAttributeValue(OPERATOR_ATTRIBUTE,
                     String.valueOf(((AtomicFormula.IntAtomicFormula) atomicFormula).getOperator()),
diff --git a/services/tests/servicestests/src/com/android/server/integrity/engine/RuleEvaluatorTest.java b/services/tests/servicestests/src/com/android/server/integrity/engine/RuleEvaluatorTest.java
index e52aca3..d6773d4 100644
--- a/services/tests/servicestests/src/com/android/server/integrity/engine/RuleEvaluatorTest.java
+++ b/services/tests/servicestests/src/com/android/server/integrity/engine/RuleEvaluatorTest.java
@@ -63,7 +63,8 @@
     public void testEvaluateRules_noMatchedRules_allow() {
         Rule rule1 =
                 new Rule(
-                        new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_2),
+                        new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_2,
+                                /* isHashedValue= */ false),
                         Rule.DENY);
 
         IntegrityCheckResult result =
@@ -76,11 +77,13 @@
     public void testEvaluateRules_oneMatch_deny() {
         Rule rule1 =
                 new Rule(
-                        new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_1),
+                        new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_1,
+                                /* isHashedValue= */ false),
                         Rule.DENY);
         Rule rule2 =
                 new Rule(
-                        new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_2),
+                        new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_2,
+                                /* isHashedValue= */ false),
                         Rule.DENY);
 
         IntegrityCheckResult result =
@@ -94,15 +97,18 @@
     public void testEvaluateRules_multipleMatches_deny() {
         Rule rule1 =
                 new Rule(
-                        new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_1),
+                        new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_1,
+                                /* isHashedValue= */ false),
                         Rule.DENY);
         OpenFormula openFormula2 =
                 new OpenFormula(
                         OpenFormula.AND,
                         Arrays.asList(
-                                new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_1),
+                                new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_1,
+                                        /* isHashedValue= */ false),
                                 new StringAtomicFormula(
-                                        AtomicFormula.APP_CERTIFICATE, APP_CERTIFICATE)));
+                                        AtomicFormula.APP_CERTIFICATE, APP_CERTIFICATE,
+                                        /* isHashedValue= */ false)));
         Rule rule2 = new Rule(openFormula2, Rule.DENY);
 
         IntegrityCheckResult result =
@@ -119,7 +125,8 @@
                         OpenFormula.NOT,
                         Collections.singletonList(
                                 new StringAtomicFormula(
-                                        AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_2)));
+                                        AtomicFormula.PACKAGE_NAME,
+                                        PACKAGE_NAME_2, /* isHashedValue= */ false)));
         Rule rule = new Rule(openFormula, Rule.DENY);
 
         IntegrityCheckResult result =
@@ -150,9 +157,11 @@
                 new OpenFormula(
                         OpenFormula.AND,
                         Arrays.asList(
-                                new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_1),
+                                new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_1,
+                                        /* isHashedValue= */ false),
                                 new StringAtomicFormula(
-                                        AtomicFormula.APP_CERTIFICATE, APP_CERTIFICATE)));
+                                        AtomicFormula.APP_CERTIFICATE, APP_CERTIFICATE,
+                                        /* isHashedValue= */ false)));
         Rule rule = new Rule(openFormula, Rule.DENY);
 
         IntegrityCheckResult result =
@@ -168,9 +177,11 @@
                 new OpenFormula(
                         OpenFormula.OR,
                         Arrays.asList(
-                                new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_1),
+                                new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_1,
+                                        /* isHashedValue= */ false),
                                 new StringAtomicFormula(
-                                        AtomicFormula.APP_CERTIFICATE, APP_CERTIFICATE)));
+                                        AtomicFormula.APP_CERTIFICATE, APP_CERTIFICATE,
+                                        /* isHashedValue= */ false)));
         Rule rule = new Rule(openFormula, Rule.DENY);
 
         IntegrityCheckResult result =
@@ -185,9 +196,11 @@
                 new OpenFormula(
                         OpenFormula.AND,
                         Arrays.asList(
-                                new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_2),
+                                new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_2,
+                                        /* isHashedValue= */ false),
                                 new StringAtomicFormula(
-                                        AtomicFormula.APP_CERTIFICATE, APP_CERTIFICATE)));
+                                        AtomicFormula.APP_CERTIFICATE, APP_CERTIFICATE,
+                                        /* isHashedValue= */ false)));
         OpenFormula openFormula =
                 new OpenFormula(OpenFormula.NOT, Collections.singletonList(openSubFormula));
         Rule rule = new Rule(openFormula, Rule.DENY);
@@ -202,15 +215,18 @@
     public void testEvaluateRules_forceAllow() {
         Rule rule1 =
                 new Rule(
-                        new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_1),
+                        new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_1,
+                                /* isHashedValue= */ false),
                         Rule.FORCE_ALLOW);
         OpenFormula openFormula2 =
                 new OpenFormula(
                         OpenFormula.AND,
                         Arrays.asList(
-                                new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_1),
+                                new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_1,
+                                        /* isHashedValue= */ false),
                                 new StringAtomicFormula(
-                                        AtomicFormula.APP_CERTIFICATE, APP_CERTIFICATE)));
+                                        AtomicFormula.APP_CERTIFICATE, APP_CERTIFICATE,
+                                        /* isHashedValue= */ false)));
         Rule rule2 = new Rule(openFormula2, Rule.DENY);
 
         IntegrityCheckResult result =
diff --git a/services/tests/servicestests/src/com/android/server/integrity/model/AtomicFormulaTest.java b/services/tests/servicestests/src/com/android/server/integrity/model/AtomicFormulaTest.java
index c8c5eca..988e18b 100644
--- a/services/tests/servicestests/src/com/android/server/integrity/model/AtomicFormulaTest.java
+++ b/services/tests/servicestests/src/com/android/server/integrity/model/AtomicFormulaTest.java
@@ -38,7 +38,8 @@
     @Test
     public void testValidAtomicFormula_stringValue() {
         StringAtomicFormula stringAtomicFormula =
-                new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.test.app");
+                new StringAtomicFormula(AtomicFormula.PACKAGE_NAME,
+                        "com.test.app", /* isHashedValue= */ false);
 
         assertEquals(AtomicFormula.PACKAGE_NAME, stringAtomicFormula.getKey());
     }
@@ -66,7 +67,8 @@
                 /* expectedExceptionMessageRegex */
                 String.format(
                         "Key VERSION_CODE cannot be used with StringAtomicFormula"),
-                () -> new StringAtomicFormula(AtomicFormula.VERSION_CODE, "test-value"));
+                () -> new StringAtomicFormula(AtomicFormula.VERSION_CODE, "test-value",
+                        /* isHashedValue= */ false));
     }
 
     @Test
@@ -92,7 +94,8 @@
     @Test
     public void testIsSatisfiable_string_true() {
         StringAtomicFormula stringAtomicFormula =
-                new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.test.app");
+                new StringAtomicFormula(AtomicFormula.PACKAGE_NAME,
+                        "com.test.app", /* isHashedValue= */ false);
         AppInstallMetadata appInstallMetadata =
                 getAppInstallMetadataBuilder().setPackageName("com.test.app").build();
 
@@ -102,7 +105,8 @@
     @Test
     public void testIsSatisfiable_string_false() {
         StringAtomicFormula stringAtomicFormula =
-                new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.test.app");
+                new StringAtomicFormula(AtomicFormula.PACKAGE_NAME,
+                        "com.test.app", /* isHashedValue= */ false);
         AppInstallMetadata appInstallMetadata =
                 getAppInstallMetadataBuilder().setPackageName("com.foo.bar").build();
 
@@ -231,7 +235,8 @@
 
     @Test
     public void testParcelUnparcel_string() {
-        StringAtomicFormula formula = new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "abc");
+        StringAtomicFormula formula = new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "abc",
+                /* isHashedValue= */ false);
         Parcel p = Parcel.obtain();
         formula.writeToParcel(p, 0);
         p.setDataPosition(0);
@@ -263,6 +268,22 @@
         assertEquals(formula, newFormula);
     }
 
+    @Test
+    public void testInvalidAtomicFormula_invalidKey() {
+        assertExpectException(
+                IllegalArgumentException.class,
+                /* expectedExceptionMessageRegex */ "Unknown key: -1",
+                () -> new IntAtomicFormula(/* key= */ -1, AtomicFormula.EQ, 0));
+    }
+
+    @Test
+    public void testInvalidAtomicFormula_invalidOperator() {
+        assertExpectException(
+                IllegalArgumentException.class,
+                /* expectedExceptionMessageRegex */ "Unknown operator: -1",
+                () -> new IntAtomicFormula(AtomicFormula.VERSION_CODE, /* operator= */ -1, 0));
+    }
+
     /** Returns a builder with all fields filled with some dummy data. */
     private AppInstallMetadata.Builder getAppInstallMetadataBuilder() {
         return new AppInstallMetadata.Builder()
diff --git a/services/tests/servicestests/src/com/android/server/integrity/model/OpenFormulaTest.java b/services/tests/servicestests/src/com/android/server/integrity/model/OpenFormulaTest.java
index ecabb527..b58ffd7 100644
--- a/services/tests/servicestests/src/com/android/server/integrity/model/OpenFormulaTest.java
+++ b/services/tests/servicestests/src/com/android/server/integrity/model/OpenFormulaTest.java
@@ -35,7 +35,8 @@
 public class OpenFormulaTest {
 
     private static final AtomicFormula ATOMIC_FORMULA_1 =
-            new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "test1");
+            new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "test1",
+                    /* isHashedValue= */ false);
     private static final AtomicFormula ATOMIC_FORMULA_2 =
             new AtomicFormula.IntAtomicFormula(AtomicFormula.VERSION_CODE, AtomicFormula.EQ, 1);
 
@@ -53,7 +54,7 @@
         assertExpectException(
                 IllegalArgumentException.class,
                 /* expectedExceptionMessageRegex */
-                String.format("Connector AND must have at least 2 formulas"),
+                "Connector AND must have at least 2 formulas",
                 () ->
                         new OpenFormula(
                                 OpenFormula.AND, Collections.singletonList(ATOMIC_FORMULA_1)));
@@ -64,7 +65,7 @@
         assertExpectException(
                 IllegalArgumentException.class,
                 /* expectedExceptionMessageRegex */
-                String.format("Connector NOT must have 1 formula only"),
+                "Connector NOT must have 1 formula only",
                 () ->
                         new OpenFormula(
                                 OpenFormula.NOT,
@@ -73,7 +74,8 @@
 
     @Test
     public void testIsSatisfiable_notFalse_true() {
-        OpenFormula openFormula = new OpenFormula(OpenFormula.NOT, Arrays.asList(ATOMIC_FORMULA_1));
+        OpenFormula openFormula = new OpenFormula(OpenFormula.NOT,
+                Collections.singletonList(ATOMIC_FORMULA_1));
         AppInstallMetadata appInstallMetadata =
                 getAppInstallMetadataBuilder().setPackageName("test2").build();
         // validate assumptions about the metadata
@@ -84,7 +86,8 @@
 
     @Test
     public void testIsSatisfiable_notTrue_false() {
-        OpenFormula openFormula = new OpenFormula(OpenFormula.NOT, Arrays.asList(ATOMIC_FORMULA_1));
+        OpenFormula openFormula = new OpenFormula(OpenFormula.NOT,
+                Collections.singletonList(ATOMIC_FORMULA_1));
         AppInstallMetadata appInstallMetadata =
                 getAppInstallMetadataBuilder().setPackageName("test1").build();
         // validate assumptions about the metadata
@@ -209,6 +212,15 @@
         assertEquals(formula, newFormula);
     }
 
+    @Test
+    public void testInvalidOpenFormula_invalidConnector() {
+        assertExpectException(
+                IllegalArgumentException.class,
+                /* expectedExceptionMessageRegex */ "Unknown connector: -1",
+                () -> new OpenFormula(/* connector= */ -1,
+                        Arrays.asList(ATOMIC_FORMULA_1, ATOMIC_FORMULA_2)));
+    }
+
     /** Returns a builder with all fields filled with some dummy data. */
     private AppInstallMetadata.Builder getAppInstallMetadataBuilder() {
         return new AppInstallMetadata.Builder()
diff --git a/services/tests/servicestests/src/com/android/server/integrity/model/RuleTest.java b/services/tests/servicestests/src/com/android/server/integrity/model/RuleTest.java
index e0c36fd..cad3928 100644
--- a/services/tests/servicestests/src/com/android/server/integrity/model/RuleTest.java
+++ b/services/tests/servicestests/src/com/android/server/integrity/model/RuleTest.java
@@ -36,9 +36,11 @@
     private static final String PACKAGE_NAME = "com.test.app";
     private static final String APP_CERTIFICATE = "test_cert";
     private static final Formula PACKAGE_NAME_ATOMIC_FORMULA =
-            new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME);
+            new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME,
+                    /* isHashedValue= */ false);
     private static final Formula APP_CERTIFICATE_ATOMIC_FORMULA =
-            new AtomicFormula.StringAtomicFormula(AtomicFormula.APP_CERTIFICATE, APP_CERTIFICATE);
+            new AtomicFormula.StringAtomicFormula(AtomicFormula.APP_CERTIFICATE, APP_CERTIFICATE,
+                    /* isHashedValue= */ false);
 
     @Test
     public void testValidRule() {
@@ -106,4 +108,12 @@
 
         assertEquals(newRule, rule);
     }
+
+    @Test
+    public void testInvalidRule_invalidEffect() {
+        assertExpectException(
+                IllegalArgumentException.class,
+                /* expectedExceptionMessageRegex */ "Unknown effect: -1",
+                () -> new Rule(PACKAGE_NAME_ATOMIC_FORMULA, /* effect= */ -1));
+    }
 }
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 be6a31f..7d71cd4c 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
@@ -43,7 +43,6 @@
     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>"
                 + generateTagWithAttribute(/* tag= */ "R",
@@ -59,7 +58,8 @@
         RuleParser xmlParser = new RuleXmlParser();
         InputStream inputStream = new ByteArrayInputStream(ruleXmlOpenFormula.getBytes());
         Rule expectedRule = new Rule(new OpenFormula(OpenFormula.NOT, Collections.singletonList(
-                new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.app.test"))),
+                new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.app.test",
+                        /* isHashedValue= */ false))),
                 Rule.DENY);
 
         List<Rule> rules = xmlParser.parse(inputStream);
@@ -71,7 +71,6 @@
     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>"
                 + generateTagWithAttribute(/* tag= */ "R",
@@ -86,7 +85,8 @@
                 + "</RL>";
         RuleParser xmlParser = new RuleXmlParser();
         Rule expectedRule = new Rule(new OpenFormula(OpenFormula.NOT, Collections.singletonList(
-                new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.app.test"))),
+                new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.app.test",
+                        /* isHashedValue= */ false))),
                 Rule.DENY);
 
         List<Rule> rules = xmlParser.parse(ruleXmlOpenFormula);
@@ -98,11 +98,9 @@
     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>"
                 + generateTagWithAttribute(/* tag= */ "R",
@@ -118,8 +116,10 @@
                 + "</RL>";
         RuleParser xmlParser = new RuleXmlParser();
         Rule expectedRule = new Rule(new OpenFormula(OpenFormula.AND, Arrays.asList(
-                new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.app.test"),
-                new AtomicFormula.StringAtomicFormula(AtomicFormula.APP_CERTIFICATE, "test_cert"))),
+                new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.app.test",
+                        /* isHashedValue= */ false),
+                new AtomicFormula.StringAtomicFormula(AtomicFormula.APP_CERTIFICATE, "test_cert",
+                        /* isHashedValue= */ false))),
                 Rule.DENY);
 
         List<Rule> rules = xmlParser.parse(ruleXmlOpenFormula);
@@ -131,11 +131,9 @@
     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>"
                 + generateTagWithAttribute(/* tag= */ "R",
@@ -151,8 +149,10 @@
                 + "</RL>";
         RuleParser xmlParser = new RuleXmlParser();
         Rule expectedRule = new Rule(new OpenFormula(OpenFormula.OR, Arrays.asList(
-                new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.app.test"),
-                new AtomicFormula.StringAtomicFormula(AtomicFormula.APP_CERTIFICATE, "test_cert"))),
+                new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.app.test",
+                        /* isHashedValue= */ false),
+                new AtomicFormula.StringAtomicFormula(AtomicFormula.APP_CERTIFICATE, "test_cert",
+                        /* isHashedValue= */ false))),
                 Rule.DENY);
 
         List<Rule> rules = xmlParser.parse(ruleXmlOpenFormula);
@@ -165,7 +165,6 @@
         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>"
                 + generateTagWithAttribute(/* tag= */ "R",
                     Collections.singletonMap("E", String.valueOf(Rule.DENY)),
@@ -179,7 +178,8 @@
                 + "</RL>";
         RuleParser xmlParser = new RuleXmlParser();
         Rule expectedRule = new Rule(new OpenFormula(OpenFormula.NOT, Collections.singletonList(
-                new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.app.test"))),
+                new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.app.test",
+                        /* isHashedValue= */ false))),
                 Rule.DENY);
 
         List<Rule> rules = xmlParser.parse(ruleXmlOpenFormula);
@@ -191,7 +191,6 @@
     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));
@@ -246,7 +245,6 @@
     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>"
                 + generateTagWithAttribute(/* tag= */ "R",
@@ -271,7 +269,6 @@
     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>"
                 + generateTagWithAttribute(/* tag= */ "R",
@@ -297,7 +294,6 @@
     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>"
                 + generateTagWithAttribute(/* tag= */ "R",
@@ -308,7 +304,8 @@
                 + "</RL>";
         RuleParser xmlParser = new RuleXmlParser();
         Rule expectedRule = new Rule(
-                new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.app.test"),
+                new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.app.test",
+                        /* isHashedValue= */ false),
                 Rule.DENY);
 
         List<Rule> rules = xmlParser.parse(ruleXmlAtomicFormula);
@@ -343,7 +340,6 @@
     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>"
                 + generateTagWithAttribute(/* tag= */ "R",
@@ -367,7 +363,6 @@
         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>"
                 + generateTagWithAttribute(/* tag= */ "R",
                     Collections.singletonMap("E", String.valueOf(Rule.DENY)),
@@ -377,7 +372,8 @@
                 + "</RL>";
         RuleParser xmlParser = new RuleXmlParser();
         Rule expectedRule = new Rule(
-                new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.app.test"),
+                new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.app.test",
+                        /* isHashedValue= */ false),
                 Rule.DENY);
 
         List<Rule> rules = xmlParser.parse(ruleXmlAtomicFormula);
@@ -389,7 +385,6 @@
     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>"
                 + generateTagWithAttribute(/* tag= */ "R",
@@ -402,11 +397,53 @@
 
         assertExpectException(
                 RuleParseException.class,
-                /* expectedExceptionMessageRegex */ "Attribute not found: K",
+                /* expectedExceptionMessageRegex */ "Found unexpected key: -1",
                 () -> xmlParser.parse(ruleXmlAtomicFormula));
     }
 
     @Test
+    public void testXmlString_invalidRule_invalidAttribute() throws Exception {
+        Map<String, String> packageNameAttrs = new HashMap<>();
+        packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME));
+        packageNameAttrs.put("V", "com.app.test");
+        String ruleXmlAtomicFormula = "<RL>"
+                + generateTagWithAttribute(/* tag= */ "R",
+                    Collections.singletonMap("BadEffect", String.valueOf(Rule.DENY)),
+                        /* closed= */ false)
+                + generateTagWithAttribute(/* tag= */ "AF", packageNameAttrs, /* closed= */ true)
+                + "</R>"
+                + "</RL>";
+        RuleParser xmlParser = new RuleXmlParser();
+        assertExpectException(
+                RuleParseException.class,
+                /* expectedExceptionMessageRegex */ "Unknown effect: -1",
+                () -> xmlParser.parse(ruleXmlAtomicFormula));
+    }
+
+    @Test
+    public void testXmlString_invalidOpenFormula_invalidAttribute() throws Exception {
+        Map<String, String> packageNameAttrs = new HashMap<>();
+        packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME));
+        packageNameAttrs.put("V", "com.app.test");
+        String ruleXmlOpenFormula = "<RL>"
+                + generateTagWithAttribute(/* tag= */ "R",
+                    Collections.singletonMap("E", String.valueOf(Rule.DENY)),
+                        /* closed= */ false)
+                + generateTagWithAttribute(/* tag= */ "OF",
+                    Collections.singletonMap("BadConnector", String.valueOf(OpenFormula.NOT)),
+                        /* closed= */ false)
+                + generateTagWithAttribute(/* tag= */ "AF", packageNameAttrs, /* closed= */ true)
+                + "</OF>"
+                + "</R>"
+                + "</RL>";
+        RuleParser xmlParser = new RuleXmlParser();
+        assertExpectException(
+                RuleParseException.class,
+                /* expectedExceptionMessageRegex */ "Unknown connector: -1",
+                () -> xmlParser.parse(ruleXmlOpenFormula));
+    }
+
+    @Test
     public void testXmlString_invalidAtomicFormula() throws Exception {
         Map<String, String> packageNameAttrs = new HashMap<>();
         packageNameAttrs.put("K", String.valueOf(AtomicFormula.VERSION_CODE));
@@ -431,7 +468,6 @@
     public void testXmlString_withNoRuleList() {
         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)),
@@ -454,7 +490,6 @@
     public void testXmlStream_withNoRuleList() {
         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)),
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 77886c8..7eac0b9 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
@@ -57,12 +57,14 @@
     public void testXmlString_serializeMultipleRules_oneEmpty() throws Exception {
         Rule rule1 = null;
         Rule rule2 = new Rule(
-                new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.app.test"),
+                new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.app.test",
+                        /* isHashedValue= */ false),
                 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");
+        packageNameAttrs.put("H", "false");
         String expectedRules = "<RL>"
                 + generateTagWithAttribute(/* tag= */ "R",
                     Collections.singletonMap("E", String.valueOf(Rule.DENY)),
@@ -81,12 +83,13 @@
         Rule rule = new Rule(new OpenFormula(OpenFormula.NOT,
                 Collections.singletonList(
                         new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME,
-                                "com.app.test"))), Rule.DENY);
+                                "com.app.test", /* isHashedValue= */ false))), 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");
+        packageNameAttrs.put("H", "false");
         String expectedRules = "<RL>"
                 + generateTagWithAttribute(/* tag= */ "R",
                     Collections.singletonMap("E", String.valueOf(Rule.DENY)),
@@ -110,11 +113,12 @@
         Rule rule = new Rule(new OpenFormula(OpenFormula.NOT,
                 Collections.singletonList(
                         new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME,
-                                "com.app.test"))), Rule.DENY);
+                                "com.app.test", /* isHashedValue= */ false))), 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");
+        packageNameAttrs.put("H", "false");
         String expectedRules = "<RL>"
                 + generateTagWithAttribute(/* tag= */ "R",
                     Collections.singletonMap("E", String.valueOf(Rule.DENY)),
@@ -136,16 +140,18 @@
     public void testXmlString_serializeValidOpenFormula_andConnector() throws Exception {
         Rule rule = new Rule(new OpenFormula(OpenFormula.AND,
                 Arrays.asList(new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME,
-                                "com.app.test"),
+                                "com.app.test", /* isHashedValue= */ false),
                         new AtomicFormula.StringAtomicFormula(AtomicFormula.APP_CERTIFICATE,
-                                "test_cert"))), Rule.DENY);
+                                "test_cert", /* isHashedValue= */ false))), 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");
+        packageNameAttrs.put("H", "false");
         Map<String, String> appCertificateAttrs = new LinkedHashMap<>();
         appCertificateAttrs.put("K", String.valueOf(AtomicFormula.APP_CERTIFICATE));
         appCertificateAttrs.put("V", "test_cert");
+        appCertificateAttrs.put("H", "false");
         String expectedRules = "<RL>"
                 + generateTagWithAttribute(/* tag= */ "R",
                     Collections.singletonMap("E", String.valueOf(Rule.DENY)),
@@ -168,16 +174,18 @@
     public void testXmlString_serializeValidOpenFormula_orConnector() throws Exception {
         Rule rule = new Rule(new OpenFormula(OpenFormula.OR,
                 Arrays.asList(new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME,
-                                "com.app.test"),
+                                "com.app.test", /* isHashedValue= */ false),
                         new AtomicFormula.StringAtomicFormula(AtomicFormula.APP_CERTIFICATE,
-                                "test_cert"))), Rule.DENY);
+                                "test_cert", /* isHashedValue= */ false))), 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");
+        packageNameAttrs.put("H", "false");
         Map<String, String> appCertificateAttrs = new LinkedHashMap<>();
         appCertificateAttrs.put("K", String.valueOf(AtomicFormula.APP_CERTIFICATE));
         appCertificateAttrs.put("V", "test_cert");
+        appCertificateAttrs.put("H", "false");
         String expectedRules = "<RL>"
                 + generateTagWithAttribute(/* tag= */ "R",
                     Collections.singletonMap("E", String.valueOf(Rule.DENY)),
@@ -199,12 +207,14 @@
     @Test
     public void testXmlString_serializeValidAtomicFormula_stringValue() throws Exception {
         Rule rule = new Rule(
-                new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.app.test"),
+                new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.app.test",
+                        /* isHashedValue= */ false),
                 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");
+        packageNameAttrs.put("H", "false");
         String expectedRules = "<RL>"
                 + generateTagWithAttribute(/* tag= */ "R",
                     Collections.singletonMap("E", String.valueOf(Rule.DENY)),