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 70ab98c86cda3..9a0553d7aa0c7 100644 --- a/services/core/java/com/android/server/integrity/model/AtomicFormula.java +++ b/services/core/java/com/android/server/integrity/model/AtomicFormula.java @@ -46,12 +46,12 @@ public abstract class AtomicFormula implements Formula { @IntDef( value = { - PACKAGE_NAME, - APP_CERTIFICATE, - INSTALLER_NAME, - INSTALLER_CERTIFICATE, - VERSION_CODE, - PRE_INSTALLED, + PACKAGE_NAME, + APP_CERTIFICATE, + INSTALLER_NAME, + INSTALLER_CERTIFICATE, + VERSION_CODE, + PRE_INSTALLED, }) @Retention(RetentionPolicy.SOURCE) public @interface Key {} @@ -60,11 +60,47 @@ public abstract class AtomicFormula implements Formula { @Retention(RetentionPolicy.SOURCE) public @interface Operator {} + /** + * Package name of the app. + * + *
Can only be used in {@link StringAtomicFormula}. + */ public static final int PACKAGE_NAME = 0; + + /** + * SHA-256 of the app certificate of the app. + * + *
Can only be used in {@link StringAtomicFormula}. + */ public static final int APP_CERTIFICATE = 1; + + /** + * Package name of the installer. Will be empty string if installed by the system (e.g., adb). + * + *
Can only be used in {@link StringAtomicFormula}. + */ public static final int INSTALLER_NAME = 2; + + /** + * SHA-256 of the cert of the installer. Will be empty string if installed by the system (e.g., + * adb). + * + *
Can only be used in {@link StringAtomicFormula}. + */ public static final int INSTALLER_CERTIFICATE = 3; + + /** + * Version code of the app. + * + *
Can only be used in {@link IntAtomicFormula}. + */ public static final int VERSION_CODE = 4; + + /** + * If the app is pre-installed on the device. + * + *
Can only be used in {@link BooleanAtomicFormula}. + */ public static final int PRE_INSTALLED = 5; public static final int EQ = 0; @@ -91,7 +127,7 @@ public abstract class AtomicFormula implements Formula { * specified by {@code key} is of the correct relationship to {@code value} as specified by * {@code operator}. * - * @throws IllegalArgumentException if {@code key} is not {@link #VERSION_CODE} + * @throws IllegalArgumentException if {@code key} cannot be used with integer value */ public IntAtomicFormula(@Key int key, @Operator int operator, int value) { super(key); @@ -142,6 +178,11 @@ public abstract class AtomicFormula implements Formula { } } + @Override + public int getTag() { + return Formula.INT_ATOMIC_FORMULA_TAG; + } + @Override public String toString() { return String.format( @@ -157,7 +198,9 @@ public abstract class AtomicFormula implements Formula { return false; } IntAtomicFormula that = (IntAtomicFormula) o; - return getKey() == that.getKey() && mValue == that.mValue; + return getKey() == that.getKey() + && mValue == that.mValue + && mOperator == that.mOperator; } @Override @@ -206,8 +249,7 @@ public abstract class AtomicFormula implements Formula { *
This formula will hold if and only if the corresponding information of an install * specified by {@code key} equals {@code value}. * - * @throws IllegalArgumentException if {@code key} is not one of {@link #PACKAGE_NAME}, - * {@link #APP_CERTIFICATE}, {@link #INSTALLER_NAME} and {@link #INSTALLER_CERTIFICATE} + * @throws IllegalArgumentException if {@code key} cannot be used with string value */ public StringAtomicFormula(@Key int key, @NonNull String value) { super(key); @@ -246,6 +288,11 @@ public abstract class AtomicFormula implements Formula { return metadataValue.equals(mValue); } + @Override + public int getTag() { + return Formula.STRING_ATOMIC_FORMULA_TAG; + } + @Override public String toString() { return String.format("(%s %s %s)", keyToString(getKey()), operatorToString(EQ), mValue); @@ -279,6 +326,7 @@ public abstract class AtomicFormula implements Formula { dest.writeStringNoHelper(mValue); } + @NonNull public String getValue() { return mValue; } @@ -310,7 +358,7 @@ public abstract class AtomicFormula implements Formula { *
This formula will hold if and only if the corresponding information of an install
* specified by {@code key} equals {@code value}.
*
- * @throws IllegalArgumentException if {@code key} is not {@link #PRE_INSTALLED}
+ * @throws IllegalArgumentException if {@code key} cannot be used with boolean value
*/
public BooleanAtomicFormula(@Key int key, boolean value) {
super(key);
@@ -346,6 +394,11 @@ public abstract class AtomicFormula implements Formula {
return metadataValue == mValue;
}
+ @Override
+ public int getTag() {
+ return Formula.BOOLEAN_ATOMIC_FORMULA_TAG;
+ }
+
@Override
public String toString() {
return String.format("(%s %s %s)", keyToString(getKey()), operatorToString(EQ), mValue);
@@ -398,7 +451,7 @@ public abstract class AtomicFormula implements Formula {
return mKey;
}
- String keyToString(int key) {
+ static String keyToString(int key) {
switch (key) {
case PACKAGE_NAME:
return "PACKAGE_NAME";
@@ -417,7 +470,7 @@ public abstract class AtomicFormula implements Formula {
}
}
- String operatorToString(int op) {
+ static String operatorToString(int op) {
switch (op) {
case EQ:
return "EQ";
diff --git a/services/core/java/com/android/server/integrity/model/Formula.java b/services/core/java/com/android/server/integrity/model/Formula.java
index 852ece536f313..67698277800f5 100644
--- a/services/core/java/com/android/server/integrity/model/Formula.java
+++ b/services/core/java/com/android/server/integrity/model/Formula.java
@@ -16,6 +16,7 @@
package com.android.server.integrity.model;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.os.Parcel;
@@ -26,6 +27,9 @@ import com.android.server.integrity.model.AtomicFormula.BooleanAtomicFormula;
import com.android.server.integrity.model.AtomicFormula.IntAtomicFormula;
import com.android.server.integrity.model.AtomicFormula.StringAtomicFormula;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
/**
* Represents a rule logic/content.
*
@@ -34,6 +38,15 @@ import com.android.server.integrity.model.AtomicFormula.StringAtomicFormula;
@SystemApi
@VisibleForTesting
public interface Formula {
+ @IntDef(
+ value = {
+ OPEN_FORMULA_TAG,
+ STRING_ATOMIC_FORMULA_TAG,
+ INT_ATOMIC_FORMULA_TAG,
+ BOOLEAN_ATOMIC_FORMULA_TAG
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Tag {}
int OPEN_FORMULA_TAG = 0;
int STRING_ATOMIC_FORMULA_TAG = 1;
@@ -46,6 +59,9 @@ public interface Formula {
*/
boolean isSatisfied(@NonNull AppInstallMetadata appInstallMetadata);
+ /** Returns the tag that identifies the current class. */
+ @Tag int getTag();
+
/**
* Write a {@link Formula} to {@link android.os.Parcel}.
*
@@ -55,21 +71,8 @@ public interface Formula {
* @throws IllegalArgumentException if {@link Formula} is not a recognized subclass
*/
static void writeToParcel(@NonNull Formula formula, @NonNull Parcel dest, int flags) {
- if (formula instanceof OpenFormula) {
- dest.writeInt(OPEN_FORMULA_TAG);
- ((OpenFormula) formula).writeToParcel(dest, flags);
- } else if (formula instanceof StringAtomicFormula) {
- dest.writeInt(STRING_ATOMIC_FORMULA_TAG);
- ((StringAtomicFormula) formula).writeToParcel(dest, flags);
- } else if (formula instanceof IntAtomicFormula) {
- dest.writeInt(INT_ATOMIC_FORMULA_TAG);
- ((IntAtomicFormula) formula).writeToParcel(dest, flags);
- } else if (formula instanceof BooleanAtomicFormula) {
- dest.writeInt(BOOLEAN_ATOMIC_FORMULA_TAG);
- ((BooleanAtomicFormula) formula).writeToParcel(dest, flags);
- } else {
- throw new IllegalArgumentException("Unrecognized class " + formula.getClass());
- }
+ dest.writeInt(formula.getTag());
+ ((Parcelable) formula).writeToParcel(dest, flags);
}
/**
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 f29706adeebbc..7a3600f7a4fef 100644
--- a/services/core/java/com/android/server/integrity/model/OpenFormula.java
+++ b/services/core/java/com/android/server/integrity/model/OpenFormula.java
@@ -63,7 +63,7 @@ public final class OpenFormula implements Formula, Parcelable {
public static final int NOT = 2;
private final @Connector int mConnector;
- private final List