diff options
55 files changed, 1769 insertions, 562 deletions
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslConverter.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslConverter.java index 191f38d3df80..718d8987c13b 100644 --- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslConverter.java +++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslConverter.java @@ -62,13 +62,11 @@ public class AslConverter { XmlUtils.getSingleChildElement( document, XmlUtils.HR_TAG_APP_METADATA_BUNDLES, true); - return new AndroidSafetyLabelFactory() - .createFromHrElements(XmlUtils.listOf(appMetadataBundles)); + return new AndroidSafetyLabelFactory().createFromHrElement(appMetadataBundles); case ON_DEVICE: Element bundleEle = XmlUtils.getSingleChildElement(document, XmlUtils.OD_TAG_BUNDLE, true); - return new AndroidSafetyLabelFactory() - .createFromOdElements(XmlUtils.listOf(bundleEle)); + return new AndroidSafetyLabelFactory().createFromOdElement(bundleEle); default: throw new IllegalStateException("Unrecognized input format."); } @@ -91,14 +89,10 @@ public class AslConverter { switch (format) { case HUMAN_READABLE: - for (var child : asl.toHrDomElements(document)) { - document.appendChild(child); - } + document.appendChild(asl.toHrDomElement(document)); break; case ON_DEVICE: - for (var child : asl.toOdDomElements(document)) { - document.appendChild(child); - } + document.appendChild(asl.toOdDomElement(document)); break; default: throw new IllegalStateException("Unrecognized input format."); diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AndroidSafetyLabel.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AndroidSafetyLabel.java index 72140a17297c..8b2fd93df889 100644 --- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AndroidSafetyLabel.java +++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AndroidSafetyLabel.java @@ -21,8 +21,6 @@ import com.android.asllib.util.XmlUtils; import org.w3c.dom.Document; import org.w3c.dom.Element; -import java.util.List; - public class AndroidSafetyLabel implements AslMarshallable { private final Long mVersion; @@ -46,36 +44,34 @@ public class AndroidSafetyLabel implements AslMarshallable { } /** Creates an on-device DOM element from an {@link AndroidSafetyLabel} */ - @Override - public List<Element> toOdDomElements(Document doc) { + public Element toOdDomElement(Document doc) { Element aslEle = doc.createElement(XmlUtils.OD_TAG_BUNDLE); aslEle.appendChild(XmlUtils.createOdLongEle(doc, XmlUtils.OD_NAME_VERSION, mVersion)); if (mSafetyLabels != null) { - XmlUtils.appendChildren(aslEle, mSafetyLabels.toOdDomElements(doc)); + aslEle.appendChild(mSafetyLabels.toOdDomElement(doc)); } if (mSystemAppSafetyLabel != null) { - XmlUtils.appendChildren(aslEle, mSystemAppSafetyLabel.toOdDomElements(doc)); + aslEle.appendChild(mSystemAppSafetyLabel.toOdDomElement(doc)); } if (mTransparencyInfo != null) { - XmlUtils.appendChildren(aslEle, mTransparencyInfo.toOdDomElements(doc)); + aslEle.appendChild(mTransparencyInfo.toOdDomElement(doc)); } - return XmlUtils.listOf(aslEle); + return aslEle; } /** Creates the human-readable DOM elements from the AslMarshallable Java Object. */ - @Override - public List<Element> toHrDomElements(Document doc) { + public Element toHrDomElement(Document doc) { Element aslEle = doc.createElement(XmlUtils.HR_TAG_APP_METADATA_BUNDLES); aslEle.setAttribute(XmlUtils.HR_ATTR_VERSION, String.valueOf(mVersion)); if (mSafetyLabels != null) { - XmlUtils.appendChildren(aslEle, mSafetyLabels.toHrDomElements(doc)); + aslEle.appendChild(mSafetyLabels.toHrDomElement(doc)); } if (mSystemAppSafetyLabel != null) { - XmlUtils.appendChildren(aslEle, mSystemAppSafetyLabel.toHrDomElements(doc)); + aslEle.appendChild(mSystemAppSafetyLabel.toHrDomElement(doc)); } if (mTransparencyInfo != null) { - XmlUtils.appendChildren(aslEle, mTransparencyInfo.toHrDomElements(doc)); + aslEle.appendChild(mTransparencyInfo.toHrDomElement(doc)); } - return XmlUtils.listOf(aslEle); + return aslEle; } } diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AndroidSafetyLabelFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AndroidSafetyLabelFactory.java index c53cbbf99a46..b9eb2a35e63b 100644 --- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AndroidSafetyLabelFactory.java +++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AndroidSafetyLabelFactory.java @@ -21,65 +21,117 @@ import com.android.asllib.util.XmlUtils; import org.w3c.dom.Element; -import java.util.List; +import java.util.Map; +import java.util.Set; public class AndroidSafetyLabelFactory implements AslMarshallableFactory<AndroidSafetyLabel> { + private final Map<Long, Set<String>> mRecognizedHrAttrs = + Map.ofEntries(Map.entry(1L, Set.of(XmlUtils.HR_ATTR_VERSION))); + private final Map<Long, Set<String>> mRequiredHrAttrs = + Map.ofEntries(Map.entry(1L, Set.of(XmlUtils.HR_ATTR_VERSION))); + private final Map<Long, Set<String>> mRecognizedHrEles = + Map.ofEntries( + Map.entry( + 1L, + Set.of( + XmlUtils.HR_TAG_SYSTEM_APP_SAFETY_LABEL, + XmlUtils.HR_TAG_SAFETY_LABELS, + XmlUtils.HR_TAG_TRANSPARENCY_INFO))); + private final Map<Long, Set<String>> mRequiredHrEles = + Map.ofEntries( + Map.entry(1L, Set.of()), + Map.entry( + 2L, + Set.of( + XmlUtils.HR_TAG_SYSTEM_APP_SAFETY_LABEL, + XmlUtils.HR_TAG_TRANSPARENCY_INFO))); + private final Map<Long, Set<String>> mRecognizedOdEleNames = + Map.ofEntries( + Map.entry( + 1L, + Set.of( + XmlUtils.OD_NAME_VERSION, + XmlUtils.OD_NAME_SAFETY_LABELS, + XmlUtils.OD_NAME_SYSTEM_APP_SAFETY_LABEL, + XmlUtils.OD_NAME_TRANSPARENCY_INFO))); + private final Map<Long, Set<String>> mRequiredOdEleNames = + Map.ofEntries( + Map.entry(1L, Set.of(XmlUtils.OD_NAME_VERSION)), + Map.entry( + 2L, + Set.of( + XmlUtils.OD_NAME_VERSION, + XmlUtils.OD_NAME_SYSTEM_APP_SAFETY_LABEL, + XmlUtils.OD_NAME_TRANSPARENCY_INFO))); /** Creates an {@link AndroidSafetyLabel} from human-readable DOM element */ - @Override - public AndroidSafetyLabel createFromHrElements(List<Element> appMetadataBundles) + public AndroidSafetyLabel createFromHrElement(Element appMetadataBundlesEle) throws MalformedXmlException { - Element appMetadataBundlesEle = XmlUtils.getSingleElement(appMetadataBundles); long version = XmlUtils.tryGetVersion(appMetadataBundlesEle); + XmlUtils.throwIfExtraneousAttributes( + appMetadataBundlesEle, XmlUtils.getMostRecentVersion(mRecognizedHrAttrs, version)); + XmlUtils.throwIfExtraneousChildrenHr( + appMetadataBundlesEle, XmlUtils.getMostRecentVersion(mRecognizedHrEles, version)); Element safetyLabelsEle = XmlUtils.getSingleChildElement( - appMetadataBundlesEle, XmlUtils.HR_TAG_SAFETY_LABELS, false); + appMetadataBundlesEle, + XmlUtils.HR_TAG_SAFETY_LABELS, + XmlUtils.getMostRecentVersion(mRequiredHrEles, version)); SafetyLabels safetyLabels = - new SafetyLabelsFactory().createFromHrElements(XmlUtils.listOf(safetyLabelsEle)); + new SafetyLabelsFactory().createFromHrElement(safetyLabelsEle, version); Element systemAppSafetyLabelEle = XmlUtils.getSingleChildElement( - appMetadataBundlesEle, XmlUtils.HR_TAG_SYSTEM_APP_SAFETY_LABEL, false); + appMetadataBundlesEle, + XmlUtils.HR_TAG_SYSTEM_APP_SAFETY_LABEL, + XmlUtils.getMostRecentVersion(mRequiredHrEles, version)); SystemAppSafetyLabel systemAppSafetyLabel = new SystemAppSafetyLabelFactory() - .createFromHrElements(XmlUtils.listOf(systemAppSafetyLabelEle)); + .createFromHrElement(systemAppSafetyLabelEle, version); Element transparencyInfoEle = XmlUtils.getSingleChildElement( - appMetadataBundlesEle, XmlUtils.HR_TAG_TRANSPARENCY_INFO, false); + appMetadataBundlesEle, + XmlUtils.HR_TAG_TRANSPARENCY_INFO, + XmlUtils.getMostRecentVersion(mRequiredHrEles, version)); TransparencyInfo transparencyInfo = - new TransparencyInfoFactory() - .createFromHrElements(XmlUtils.listOf(transparencyInfoEle)); + new TransparencyInfoFactory().createFromHrElement(transparencyInfoEle, version); return new AndroidSafetyLabel( version, systemAppSafetyLabel, safetyLabels, transparencyInfo); } /** Creates an {@link AndroidSafetyLabel} from on-device DOM elements */ - @Override - public AndroidSafetyLabel createFromOdElements(List<Element> elements) - throws MalformedXmlException { - Element bundleEle = XmlUtils.getSingleElement(elements); + public AndroidSafetyLabel createFromOdElement(Element bundleEle) throws MalformedXmlException { Long version = XmlUtils.getOdLongEle(bundleEle, XmlUtils.OD_NAME_VERSION, true); + XmlUtils.throwIfExtraneousChildrenOd( + bundleEle, XmlUtils.getMostRecentVersion(mRecognizedOdEleNames, version)); Element safetyLabelsEle = - XmlUtils.getOdPbundleWithName(bundleEle, XmlUtils.OD_NAME_SAFETY_LABELS, false); + XmlUtils.getOdPbundleWithName( + bundleEle, + XmlUtils.OD_NAME_SAFETY_LABELS, + XmlUtils.getMostRecentVersion(mRequiredOdEleNames, version)); SafetyLabels safetyLabels = - new SafetyLabelsFactory().createFromOdElements(XmlUtils.listOf(safetyLabelsEle)); + new SafetyLabelsFactory().createFromOdElement(safetyLabelsEle, version); Element systemAppSafetyLabelEle = XmlUtils.getOdPbundleWithName( - bundleEle, XmlUtils.OD_NAME_SYSTEM_APP_SAFETY_LABEL, false); + bundleEle, + XmlUtils.OD_NAME_SYSTEM_APP_SAFETY_LABEL, + XmlUtils.getMostRecentVersion(mRequiredOdEleNames, version)); SystemAppSafetyLabel systemAppSafetyLabel = new SystemAppSafetyLabelFactory() - .createFromOdElements(XmlUtils.listOf(systemAppSafetyLabelEle)); + .createFromOdElement(systemAppSafetyLabelEle, version); Element transparencyInfoEle = - XmlUtils.getOdPbundleWithName(bundleEle, XmlUtils.OD_NAME_TRANSPARENCY_INFO, false); + XmlUtils.getOdPbundleWithName( + bundleEle, + XmlUtils.OD_NAME_TRANSPARENCY_INFO, + XmlUtils.getMostRecentVersion(mRequiredOdEleNames, version)); TransparencyInfo transparencyInfo = - new TransparencyInfoFactory() - .createFromOdElements(XmlUtils.listOf(transparencyInfoEle)); + new TransparencyInfoFactory().createFromOdElement(transparencyInfoEle, version); return new AndroidSafetyLabel( version, systemAppSafetyLabel, safetyLabels, transparencyInfo); diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AppInfo.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AppInfo.java index f39722589a96..d2557aec5f82 100644 --- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AppInfo.java +++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AppInfo.java @@ -25,36 +25,107 @@ import java.util.List; /** AppInfo representation */ public class AppInfo implements AslMarshallable { - private final Boolean mApsCompliant; + private final String mTitle; + private final String mDescription; + private final Boolean mContainsAds; + private final Boolean mObeyAps; + private final Boolean mAdsFingerprinting; + private final Boolean mSecurityFingerprinting; private final String mPrivacyPolicy; + private final List<String> mSecurityEndpoints; private final List<String> mFirstPartyEndpoints; private final List<String> mServiceProviderEndpoints; + private final String mCategory; + private final String mEmail; + private final String mWebsite; + + private final Boolean mApsCompliant; + private final String mDeveloperId; + private final String mApplicationId; + + // private final String mPrivacyPolicy; + // private final List<String> mFirstPartyEndpoints; + // private final List<String> mServiceProviderEndpoints; public AppInfo( - Boolean apsCompliant, + String title, + String description, + Boolean containsAds, + Boolean obeyAps, + Boolean adsFingerprinting, + Boolean securityFingerprinting, String privacyPolicy, + List<String> securityEndpoints, List<String> firstPartyEndpoints, - List<String> serviceProviderEndpoints) { - this.mApsCompliant = apsCompliant; + List<String> serviceProviderEndpoints, + String category, + String email, + String website, + Boolean apsCompliant, + String developerId, + String applicationId) { + this.mTitle = title; + this.mDescription = description; + this.mContainsAds = containsAds; + this.mObeyAps = obeyAps; + this.mAdsFingerprinting = adsFingerprinting; + this.mSecurityFingerprinting = securityFingerprinting; this.mPrivacyPolicy = privacyPolicy; + this.mSecurityEndpoints = securityEndpoints; this.mFirstPartyEndpoints = firstPartyEndpoints; this.mServiceProviderEndpoints = serviceProviderEndpoints; + this.mCategory = category; + this.mEmail = email; + this.mWebsite = website; + this.mApsCompliant = apsCompliant; + this.mDeveloperId = developerId; + this.mApplicationId = applicationId; } /** Creates an on-device DOM element from the {@link SafetyLabels}. */ - @Override - public List<Element> toOdDomElements(Document doc) { + public Element toOdDomElement(Document doc) { Element appInfoEle = XmlUtils.createPbundleEleWithName(doc, XmlUtils.OD_NAME_APP_INFO); - if (this.mApsCompliant != null) { + + if (this.mTitle != null) { + appInfoEle.appendChild(XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_TITLE, mTitle)); + } + if (this.mDescription != null) { + appInfoEle.appendChild( + XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_DESCRIPTION, mDescription)); + } + if (this.mContainsAds != null) { + appInfoEle.appendChild( + XmlUtils.createOdBooleanEle(doc, XmlUtils.OD_NAME_CONTAINS_ADS, mContainsAds)); + } + if (this.mObeyAps != null) { + appInfoEle.appendChild( + XmlUtils.createOdBooleanEle(doc, XmlUtils.OD_NAME_OBEY_APS, mObeyAps)); + } + if (this.mAdsFingerprinting != null) { appInfoEle.appendChild( XmlUtils.createOdBooleanEle( - doc, XmlUtils.OD_NAME_APS_COMPLIANT, mApsCompliant)); + doc, XmlUtils.OD_NAME_ADS_FINGERPRINTING, mAdsFingerprinting)); + } + if (this.mSecurityFingerprinting != null) { + appInfoEle.appendChild( + XmlUtils.createOdBooleanEle( + doc, + XmlUtils.OD_NAME_SECURITY_FINGERPRINTING, + mSecurityFingerprinting)); } if (this.mPrivacyPolicy != null) { appInfoEle.appendChild( XmlUtils.createOdStringEle( doc, XmlUtils.OD_NAME_PRIVACY_POLICY, mPrivacyPolicy)); } + if (this.mSecurityEndpoints != null) { + appInfoEle.appendChild( + XmlUtils.createOdArray( + doc, + XmlUtils.OD_TAG_STRING_ARRAY, + XmlUtils.OD_NAME_SECURITY_ENDPOINTS, + mSecurityEndpoints)); + } if (this.mFirstPartyEndpoints != null) { appInfoEle.appendChild( XmlUtils.createOdArray( @@ -71,27 +142,88 @@ public class AppInfo implements AslMarshallable { XmlUtils.OD_NAME_SERVICE_PROVIDER_ENDPOINTS, mServiceProviderEndpoints)); } - return XmlUtils.listOf(appInfoEle); + if (this.mCategory != null) { + appInfoEle.appendChild( + XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_CATEGORY, this.mCategory)); + } + if (this.mEmail != null) { + appInfoEle.appendChild( + XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_EMAIL, this.mEmail)); + } + if (this.mWebsite != null) { + appInfoEle.appendChild( + XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_WEBSITE, this.mWebsite)); + } + + if (this.mApsCompliant != null) { + appInfoEle.appendChild( + XmlUtils.createOdBooleanEle( + doc, XmlUtils.OD_NAME_APS_COMPLIANT, mApsCompliant)); + } + if (this.mDeveloperId != null) { + appInfoEle.appendChild( + XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_DEVELOPER_ID, mDeveloperId)); + } + if (this.mApplicationId != null) { + appInfoEle.appendChild( + XmlUtils.createOdStringEle( + doc, XmlUtils.OD_NAME_APPLICATION_ID, mApplicationId)); + } + return appInfoEle; } /** Creates the human-readable DOM elements from the AslMarshallable Java Object. */ - @Override - public List<Element> toHrDomElements(Document doc) { + public Element toHrDomElement(Document doc) { Element appInfoEle = doc.createElement(XmlUtils.HR_TAG_APP_INFO); - if (this.mApsCompliant != null) { + + if (this.mTitle != null) { + appInfoEle.setAttribute(XmlUtils.HR_ATTR_TITLE, this.mTitle); + } + if (this.mDescription != null) { + appInfoEle.setAttribute(XmlUtils.HR_ATTR_DESCRIPTION, this.mDescription); + } + if (this.mContainsAds != null) { appInfoEle.setAttribute( - XmlUtils.HR_ATTR_APS_COMPLIANT, String.valueOf(this.mApsCompliant)); + XmlUtils.HR_ATTR_CONTAINS_ADS, String.valueOf(this.mContainsAds)); + } + if (this.mObeyAps != null) { + appInfoEle.setAttribute(XmlUtils.HR_ATTR_OBEY_APS, String.valueOf(this.mObeyAps)); + } + if (this.mAdsFingerprinting != null) { + appInfoEle.setAttribute( + XmlUtils.HR_ATTR_ADS_FINGERPRINTING, String.valueOf(this.mAdsFingerprinting)); + } + if (this.mSecurityFingerprinting != null) { + appInfoEle.setAttribute( + XmlUtils.HR_ATTR_SECURITY_FINGERPRINTING, + String.valueOf(this.mSecurityFingerprinting)); } if (this.mPrivacyPolicy != null) { appInfoEle.setAttribute(XmlUtils.HR_ATTR_PRIVACY_POLICY, this.mPrivacyPolicy); } + if (this.mSecurityEndpoints != null) { + appInfoEle.setAttribute( + XmlUtils.HR_ATTR_SECURITY_ENDPOINTS, String.join("|", this.mSecurityEndpoints)); + } + if (this.mCategory != null) { + appInfoEle.setAttribute(XmlUtils.HR_ATTR_CATEGORY, this.mCategory); + } + if (this.mEmail != null) { + appInfoEle.setAttribute(XmlUtils.HR_ATTR_EMAIL, this.mEmail); + } + if (this.mWebsite != null) { + appInfoEle.setAttribute(XmlUtils.HR_ATTR_WEBSITE, this.mWebsite); + } + if (this.mApsCompliant != null) { + appInfoEle.setAttribute( + XmlUtils.HR_ATTR_APS_COMPLIANT, String.valueOf(this.mApsCompliant)); + } if (this.mFirstPartyEndpoints != null) { appInfoEle.appendChild( XmlUtils.createHrArray( doc, XmlUtils.HR_TAG_FIRST_PARTY_ENDPOINTS, mFirstPartyEndpoints)); } - if (this.mServiceProviderEndpoints != null) { appInfoEle.appendChild( XmlUtils.createHrArray( @@ -99,7 +231,13 @@ public class AppInfo implements AslMarshallable { XmlUtils.HR_TAG_SERVICE_PROVIDER_ENDPOINTS, mServiceProviderEndpoints)); } + if (this.mDeveloperId != null) { + appInfoEle.setAttribute(XmlUtils.HR_ATTR_DEVELOPER_ID, this.mDeveloperId); + } + if (this.mApplicationId != null) { + appInfoEle.setAttribute(XmlUtils.HR_ATTR_APPLICATION_ID, this.mApplicationId); + } - return XmlUtils.listOf(appInfoEle); + return appInfoEle; } } diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AppInfoFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AppInfoFactory.java index 6ad202765218..277a508ced57 100644 --- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AppInfoFactory.java +++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AppInfoFactory.java @@ -16,60 +16,233 @@ package com.android.asllib.marshallable; -import com.android.asllib.util.AslgenUtil; import com.android.asllib.util.MalformedXmlException; import com.android.asllib.util.XmlUtils; import org.w3c.dom.Element; import java.util.List; +import java.util.Map; +import java.util.Set; public class AppInfoFactory implements AslMarshallableFactory<AppInfo> { + // We don't need to support V1 for HR. + private final Map<Long, Set<String>> mRecognizedHrAttrs = + Map.ofEntries( + Map.entry( + 2L, + Set.of( + XmlUtils.HR_ATTR_APS_COMPLIANT, + XmlUtils.HR_ATTR_PRIVACY_POLICY, + XmlUtils.HR_ATTR_DEVELOPER_ID, + XmlUtils.HR_ATTR_APPLICATION_ID))); + private final Map<Long, Set<String>> mRequiredHrAttrs = + Map.ofEntries( + Map.entry( + 2L, + Set.of( + XmlUtils.HR_ATTR_APS_COMPLIANT, + XmlUtils.HR_ATTR_PRIVACY_POLICY, + XmlUtils.HR_ATTR_DEVELOPER_ID, + XmlUtils.HR_ATTR_APPLICATION_ID))); + private final Map<Long, Set<String>> mRecognizedHrEles = + Map.ofEntries( + Map.entry( + 2L, + Set.of( + XmlUtils.HR_TAG_FIRST_PARTY_ENDPOINTS, + XmlUtils.HR_TAG_SERVICE_PROVIDER_ENDPOINTS))); + private final Map<Long, Set<String>> mRequiredHrEles = + Map.ofEntries( + Map.entry( + 2L, + Set.of( + XmlUtils.HR_TAG_FIRST_PARTY_ENDPOINTS, + XmlUtils.HR_TAG_SERVICE_PROVIDER_ENDPOINTS))); + private final Map<Long, Set<String>> mRecognizedOdEleNames = + Map.ofEntries( + Map.entry( + 1L, + Set.of( + XmlUtils.OD_NAME_TITLE, + XmlUtils.OD_NAME_DESCRIPTION, + XmlUtils.OD_NAME_CONTAINS_ADS, + XmlUtils.OD_NAME_OBEY_APS, + XmlUtils.OD_NAME_ADS_FINGERPRINTING, + XmlUtils.OD_NAME_SECURITY_FINGERPRINTING, + XmlUtils.OD_NAME_PRIVACY_POLICY, + XmlUtils.OD_NAME_SECURITY_ENDPOINTS, + XmlUtils.OD_NAME_FIRST_PARTY_ENDPOINTS, + XmlUtils.OD_NAME_SERVICE_PROVIDER_ENDPOINTS, + XmlUtils.OD_NAME_CATEGORY, + XmlUtils.OD_NAME_EMAIL, + XmlUtils.OD_NAME_WEBSITE)), + Map.entry( + 2L, + Set.of( + XmlUtils.OD_NAME_APS_COMPLIANT, + XmlUtils.OD_NAME_PRIVACY_POLICY, + XmlUtils.OD_NAME_FIRST_PARTY_ENDPOINTS, + XmlUtils.OD_NAME_SERVICE_PROVIDER_ENDPOINTS, + XmlUtils.OD_NAME_DEVELOPER_ID, + XmlUtils.OD_NAME_APPLICATION_ID))); + private final Map<Long, Set<String>> mRequiredOdEles = + Map.ofEntries( + Map.entry( + 1L, + Set.of( + XmlUtils.OD_NAME_TITLE, + XmlUtils.OD_NAME_DESCRIPTION, + XmlUtils.OD_NAME_CONTAINS_ADS, + XmlUtils.OD_NAME_OBEY_APS, + XmlUtils.OD_NAME_ADS_FINGERPRINTING, + XmlUtils.OD_NAME_SECURITY_FINGERPRINTING, + XmlUtils.OD_NAME_PRIVACY_POLICY, + XmlUtils.OD_NAME_SECURITY_ENDPOINTS, + XmlUtils.OD_NAME_FIRST_PARTY_ENDPOINTS, + XmlUtils.OD_NAME_SERVICE_PROVIDER_ENDPOINTS, + XmlUtils.OD_NAME_CATEGORY)), + Map.entry( + 2L, + Set.of( + XmlUtils.OD_NAME_APS_COMPLIANT, + XmlUtils.OD_NAME_PRIVACY_POLICY, + XmlUtils.OD_NAME_FIRST_PARTY_ENDPOINTS, + XmlUtils.OD_NAME_SERVICE_PROVIDER_ENDPOINTS, + XmlUtils.OD_NAME_DEVELOPER_ID, + XmlUtils.OD_NAME_APPLICATION_ID))); /** Creates a {@link AppInfo} from the human-readable DOM element. */ - @Override - public AppInfo createFromHrElements(List<Element> elements) throws MalformedXmlException { - Element appInfoEle = XmlUtils.getSingleElement(elements); - if (appInfoEle == null) { - AslgenUtil.logI("No AppInfo found in hr format."); - return null; - } + public AppInfo createFromHrElement(Element appInfoEle, long version) + throws MalformedXmlException { + XmlUtils.throwIfExtraneousAttributes( + appInfoEle, XmlUtils.getMostRecentVersion(mRecognizedHrAttrs, version)); + XmlUtils.throwIfExtraneousChildrenHr( + appInfoEle, XmlUtils.getMostRecentVersion(mRecognizedHrEles, version)); - Boolean apsCompliant = - XmlUtils.getBoolAttr(appInfoEle, XmlUtils.HR_ATTR_APS_COMPLIANT, true); + var requiredHrAttrs = XmlUtils.getMostRecentVersion(mRequiredHrAttrs, version); + var requiredHrEles = XmlUtils.getMostRecentVersion(mRequiredHrEles, version); + + String title = XmlUtils.getStringAttr(appInfoEle, XmlUtils.HR_ATTR_TITLE, requiredHrAttrs); + String description = + XmlUtils.getStringAttr(appInfoEle, XmlUtils.HR_ATTR_DESCRIPTION, requiredHrAttrs); + Boolean containsAds = + XmlUtils.getBoolAttr(appInfoEle, XmlUtils.HR_ATTR_CONTAINS_ADS, requiredHrAttrs); + Boolean obeyAps = + XmlUtils.getBoolAttr(appInfoEle, XmlUtils.HR_ATTR_OBEY_APS, requiredHrAttrs); + Boolean adsFingerprinting = + XmlUtils.getBoolAttr( + appInfoEle, XmlUtils.HR_ATTR_ADS_FINGERPRINTING, requiredHrAttrs); + Boolean securityFingerprinting = + XmlUtils.getBoolAttr( + appInfoEle, XmlUtils.HR_ATTR_SECURITY_FINGERPRINTING, requiredHrAttrs); String privacyPolicy = - XmlUtils.getStringAttr(appInfoEle, XmlUtils.HR_ATTR_PRIVACY_POLICY, true); + XmlUtils.getStringAttr( + appInfoEle, XmlUtils.HR_ATTR_PRIVACY_POLICY, requiredHrAttrs); + List<String> securityEndpoints = + XmlUtils.getPipelineSplitAttr( + appInfoEle, XmlUtils.HR_ATTR_SECURITY_ENDPOINTS, requiredHrAttrs); + String category = + XmlUtils.getStringAttr(appInfoEle, XmlUtils.HR_ATTR_CATEGORY, requiredHrAttrs); + String email = XmlUtils.getStringAttr(appInfoEle, XmlUtils.HR_ATTR_EMAIL, requiredHrAttrs); + String website = + XmlUtils.getStringAttr(appInfoEle, XmlUtils.HR_ATTR_WEBSITE, requiredHrAttrs); + String developerId = + XmlUtils.getStringAttr(appInfoEle, XmlUtils.HR_ATTR_DEVELOPER_ID, requiredHrAttrs); + String applicationId = + XmlUtils.getStringAttr( + appInfoEle, XmlUtils.HR_ATTR_APPLICATION_ID, requiredHrAttrs); + + Boolean apsCompliant = + XmlUtils.getBoolAttr(appInfoEle, XmlUtils.HR_ATTR_APS_COMPLIANT, requiredHrAttrs); List<String> firstPartyEndpoints = XmlUtils.getHrItemsAsStrings( - appInfoEle, XmlUtils.HR_TAG_FIRST_PARTY_ENDPOINTS, true); + appInfoEle, XmlUtils.HR_TAG_FIRST_PARTY_ENDPOINTS, requiredHrEles); List<String> serviceProviderEndpoints = XmlUtils.getHrItemsAsStrings( - appInfoEle, XmlUtils.HR_TAG_SERVICE_PROVIDER_ENDPOINTS, true); + appInfoEle, XmlUtils.HR_TAG_SERVICE_PROVIDER_ENDPOINTS, requiredHrEles); return new AppInfo( - apsCompliant, privacyPolicy, firstPartyEndpoints, serviceProviderEndpoints); + title, + description, + containsAds, + obeyAps, + adsFingerprinting, + securityFingerprinting, + privacyPolicy, + securityEndpoints, + firstPartyEndpoints, + serviceProviderEndpoints, + category, + email, + website, + apsCompliant, + developerId, + applicationId); } /** Creates an {@link AslMarshallableFactory} from on-device DOM elements */ - @Override - public AppInfo createFromOdElements(List<Element> elements) throws MalformedXmlException { - Element appInfoEle = XmlUtils.getSingleElement(elements); - if (appInfoEle == null) { - AslgenUtil.logI("No AppInfo found in od format."); - return null; - } + public AppInfo createFromOdElement(Element appInfoEle, long version) + throws MalformedXmlException { + XmlUtils.throwIfExtraneousChildrenOd( + appInfoEle, XmlUtils.getMostRecentVersion(mRecognizedOdEleNames, version)); + var requiredOdEles = XmlUtils.getMostRecentVersion(mRequiredOdEles, version); - Boolean apsCompliant = - XmlUtils.getOdBoolEle(appInfoEle, XmlUtils.OD_NAME_APS_COMPLIANT, true); + String title = XmlUtils.getOdStringEle(appInfoEle, XmlUtils.OD_NAME_TITLE, requiredOdEles); + String description = + XmlUtils.getOdStringEle(appInfoEle, XmlUtils.OD_NAME_DESCRIPTION, requiredOdEles); + Boolean containsAds = + XmlUtils.getOdBoolEle(appInfoEle, XmlUtils.OD_NAME_CONTAINS_ADS, requiredOdEles); + Boolean obeyAps = + XmlUtils.getOdBoolEle(appInfoEle, XmlUtils.OD_NAME_OBEY_APS, requiredOdEles); + Boolean adsFingerprinting = + XmlUtils.getOdBoolEle( + appInfoEle, XmlUtils.OD_NAME_ADS_FINGERPRINTING, requiredOdEles); + Boolean securityFingerprinting = + XmlUtils.getOdBoolEle( + appInfoEle, XmlUtils.OD_NAME_SECURITY_FINGERPRINTING, requiredOdEles); String privacyPolicy = - XmlUtils.getOdStringEle(appInfoEle, XmlUtils.OD_NAME_PRIVACY_POLICY, true); + XmlUtils.getOdStringEle( + appInfoEle, XmlUtils.OD_NAME_PRIVACY_POLICY, requiredOdEles); + List<String> securityEndpoints = + XmlUtils.getOdStringArray( + appInfoEle, XmlUtils.OD_NAME_SECURITY_ENDPOINTS, requiredOdEles); + String category = + XmlUtils.getOdStringEle(appInfoEle, XmlUtils.OD_NAME_CATEGORY, requiredOdEles); + String email = XmlUtils.getOdStringEle(appInfoEle, XmlUtils.OD_NAME_EMAIL, requiredOdEles); + String website = + XmlUtils.getOdStringEle(appInfoEle, XmlUtils.OD_NAME_WEBSITE, requiredOdEles); + String developerId = + XmlUtils.getOdStringEle(appInfoEle, XmlUtils.OD_NAME_DEVELOPER_ID, requiredOdEles); + String applicationId = + XmlUtils.getOdStringEle( + appInfoEle, XmlUtils.OD_NAME_APPLICATION_ID, requiredOdEles); + + Boolean apsCompliant = + XmlUtils.getOdBoolEle(appInfoEle, XmlUtils.OD_NAME_APS_COMPLIANT, requiredOdEles); List<String> firstPartyEndpoints = - XmlUtils.getOdStringArray(appInfoEle, XmlUtils.OD_NAME_FIRST_PARTY_ENDPOINTS, true); + XmlUtils.getOdStringArray( + appInfoEle, XmlUtils.OD_NAME_FIRST_PARTY_ENDPOINTS, requiredOdEles); List<String> serviceProviderEndpoints = XmlUtils.getOdStringArray( - appInfoEle, XmlUtils.OD_NAME_SERVICE_PROVIDER_ENDPOINTS, true); + appInfoEle, XmlUtils.OD_NAME_SERVICE_PROVIDER_ENDPOINTS, requiredOdEles); return new AppInfo( - apsCompliant, privacyPolicy, firstPartyEndpoints, serviceProviderEndpoints); + title, + description, + containsAds, + obeyAps, + adsFingerprinting, + securityFingerprinting, + privacyPolicy, + securityEndpoints, + firstPartyEndpoints, + serviceProviderEndpoints, + category, + email, + website, + apsCompliant, + developerId, + applicationId); } } diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AslMarshallable.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AslMarshallable.java index 0a70e7d0d74b..b6c789dc5ec7 100644 --- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AslMarshallable.java +++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AslMarshallable.java @@ -16,16 +16,11 @@ package com.android.asllib.marshallable; -import org.w3c.dom.Document; -import org.w3c.dom.Element; - -import java.util.List; - public interface AslMarshallable { /** Creates the on-device DOM elements from the AslMarshallable Java Object. */ - List<Element> toOdDomElements(Document doc); + // List<Element> toOdDomElements(Document doc); /** Creates the human-readable DOM elements from the AslMarshallable Java Object. */ - List<Element> toHrDomElements(Document doc); + // List<Element> toHrDomElements(Document doc); } diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AslMarshallableFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AslMarshallableFactory.java index 39582900f3a0..67f106948e79 100644 --- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AslMarshallableFactory.java +++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AslMarshallableFactory.java @@ -16,17 +16,11 @@ package com.android.asllib.marshallable; -import com.android.asllib.util.MalformedXmlException; - -import org.w3c.dom.Element; - -import java.util.List; - public interface AslMarshallableFactory<T extends AslMarshallable> { /** Creates an {@link AslMarshallableFactory} from human-readable DOM elements */ - T createFromHrElements(List<Element> elements) throws MalformedXmlException; + // T createFromHrElements(List<Element> elements) throws MalformedXmlException; /** Creates an {@link AslMarshallableFactory} from on-device DOM elements */ - T createFromOdElements(List<Element> elements) throws MalformedXmlException; + // T createFromOdElements(List<Element> elements) throws MalformedXmlException; } diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataCategory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataCategory.java index c16d18b34360..501f170ad317 100644 --- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataCategory.java +++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataCategory.java @@ -57,18 +57,16 @@ public class DataCategory implements AslMarshallable { } /** Creates on-device DOM element(s) from the {@link DataCategory}. */ - @Override - public List<Element> toOdDomElements(Document doc) { + public Element toOdDomElement(Document doc) { Element dataCategoryEle = XmlUtils.createPbundleEleWithName(doc, this.getCategoryName()); for (DataType dataType : mDataTypes.values()) { - XmlUtils.appendChildren(dataCategoryEle, dataType.toOdDomElements(doc)); + dataCategoryEle.appendChild(dataType.toOdDomElement(doc)); } - return XmlUtils.listOf(dataCategoryEle); + return dataCategoryEle; } /** Creates the human-readable DOM elements from the AslMarshallable Java Object. */ - @Override - public List<Element> toHrDomElements(Document doc) { + public List<Element> toHrDomElement(Document doc) { throw new IllegalStateException( "Turning DataCategory or DataType into human-readable DOM elements requires" + " visibility into parent elements. The logic resides in DataLabels."); diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataCategoryFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataCategoryFactory.java index 724416285acd..fb84e508ff7f 100644 --- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataCategoryFactory.java +++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataCategoryFactory.java @@ -23,13 +23,11 @@ import com.android.asllib.util.XmlUtils; import org.w3c.dom.Element; import java.util.LinkedHashMap; -import java.util.List; import java.util.Map; public class DataCategoryFactory { /** Creates an {@link AslMarshallableFactory} from on-device DOM elements */ - public DataCategory createFromOdElements(List<Element> elements) throws MalformedXmlException { - Element dataCategoryEle = XmlUtils.getSingleElement(elements); + public DataCategory createFromOdElement(Element dataCategoryEle) throws MalformedXmlException { Map<String, DataType> dataTypeMap = new LinkedHashMap<String, DataType>(); String categoryName = dataCategoryEle.getAttribute(XmlUtils.OD_ATTR_NAME); var odDataTypes = XmlUtils.asElementList(dataCategoryEle.getChildNodes()); @@ -45,9 +43,7 @@ public class DataCategoryFactory { "Unrecognized data type name %s for category %s", dataTypeName, categoryName)); } - dataTypeMap.put( - dataTypeName, - new DataTypeFactory().createFromOdElements(XmlUtils.listOf(odDataTypeEle))); + dataTypeMap.put(dataTypeName, new DataTypeFactory().createFromOdElement(odDataTypeEle)); } return new DataCategory(categoryName, dataTypeMap); diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataLabels.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataLabels.java index 3c93c88cd060..2cf7c82fdb3e 100644 --- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataLabels.java +++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataLabels.java @@ -22,7 +22,6 @@ import com.android.asllib.util.XmlUtils; import org.w3c.dom.Document; import org.w3c.dom.Element; -import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -57,20 +56,18 @@ public class DataLabels implements AslMarshallable { } /** Gets the on-device DOM element for the {@link DataLabels}. */ - @Override - public List<Element> toOdDomElements(Document doc) { + public Element toOdDomElement(Document doc) { Element dataLabelsEle = XmlUtils.createPbundleEleWithName(doc, XmlUtils.OD_NAME_DATA_LABELS); maybeAppendDataUsages(doc, dataLabelsEle, mDataCollected, XmlUtils.OD_NAME_DATA_COLLECTED); maybeAppendDataUsages(doc, dataLabelsEle, mDataShared, XmlUtils.OD_NAME_DATA_SHARED); - return XmlUtils.listOf(dataLabelsEle); + return dataLabelsEle; } /** Creates the human-readable DOM elements from the AslMarshallable Java Object. */ - @Override - public List<Element> toHrDomElements(Document doc) { + public Element toHrDomElement(Document doc) { Element dataLabelsEle = doc.createElement(XmlUtils.HR_TAG_DATA_LABELS); maybeAppendHrDataUsages( doc, dataLabelsEle, mDataCollected, XmlUtils.HR_TAG_DATA_COLLECTED, false); @@ -78,7 +75,7 @@ public class DataLabels implements AslMarshallable { doc, dataLabelsEle, mDataCollected, XmlUtils.HR_TAG_DATA_COLLECTED_EPHEMERAL, true); maybeAppendHrDataUsages( doc, dataLabelsEle, mDataShared, XmlUtils.HR_TAG_DATA_SHARED, false); - return XmlUtils.listOf(dataLabelsEle); + return dataLabelsEle; } private void maybeAppendDataUsages( @@ -96,7 +93,7 @@ public class DataLabels implements AslMarshallable { DataCategory dataCategory = dataCategoriesMap.get(dataCategoryName); for (String dataTypeName : dataCategory.getDataTypes().keySet()) { DataType dataType = dataCategory.getDataTypes().get(dataTypeName); - XmlUtils.appendChildren(dataCategoryEle, dataType.toOdDomElements(doc)); + dataCategoryEle.appendChild(dataType.toOdDomElement(doc)); } dataUsageEle.appendChild(dataCategoryEle); } diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataLabelsFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataLabelsFactory.java index c4d88761835a..b1cf3ea0d39a 100644 --- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataLabelsFactory.java +++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataLabelsFactory.java @@ -31,9 +31,7 @@ import java.util.Map; public class DataLabelsFactory implements AslMarshallableFactory<DataLabels> { /** Creates a {@link DataLabels} from the human-readable DOM element. */ - @Override - public DataLabels createFromHrElements(List<Element> elements) throws MalformedXmlException { - Element ele = XmlUtils.getSingleElement(elements); + public DataLabels createFromHrElement(Element ele) throws MalformedXmlException { if (ele == null) { AslgenUtil.logI("Found no DataLabels in hr format."); return null; @@ -83,9 +81,7 @@ public class DataLabelsFactory implements AslMarshallableFactory<DataLabels> { } /** Creates an {@link AslMarshallableFactory} from on-device DOM elements */ - @Override - public DataLabels createFromOdElements(List<Element> elements) throws MalformedXmlException { - Element dataLabelsEle = XmlUtils.getSingleElement(elements); + public DataLabels createFromOdElement(Element dataLabelsEle) throws MalformedXmlException { if (dataLabelsEle == null) { AslgenUtil.logI("Found no DataLabels in od format."); return null; @@ -111,7 +107,7 @@ public class DataLabelsFactory implements AslMarshallableFactory<DataLabels> { for (Element dataCategoryEle : dataCategoryEles) { String dataCategoryName = dataCategoryEle.getAttribute(XmlUtils.OD_ATTR_NAME); DataCategory dataCategory = - new DataCategoryFactory().createFromOdElements(List.of(dataCategoryEle)); + new DataCategoryFactory().createFromOdElement(dataCategoryEle); dataCategoryMap.put(dataCategoryName, dataCategory); } return dataCategoryMap; diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataType.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataType.java index 284a4b804435..83bb61144efa 100644 --- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataType.java +++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataType.java @@ -172,8 +172,8 @@ public class DataType implements AslMarshallable { return mEphemeral; } - @Override - public List<Element> toOdDomElements(Document doc) { + /** Gets the on-device dom element */ + public Element toOdDomElement(Document doc) { Element dataTypeEle = XmlUtils.createPbundleEleWithName(doc, this.getDataTypeName()); if (!this.getPurposes().isEmpty()) { dataTypeEle.appendChild( @@ -197,11 +197,10 @@ public class DataType implements AslMarshallable { this.getIsSharingOptional(), XmlUtils.OD_NAME_IS_SHARING_OPTIONAL); maybeAddBoolToOdElement(doc, dataTypeEle, this.getEphemeral(), XmlUtils.OD_NAME_EPHEMERAL); - return XmlUtils.listOf(dataTypeEle); + return dataTypeEle; } /** Creates the human-readable DOM elements from the AslMarshallable Java Object. */ - @Override public List<Element> toHrDomElements(Document doc) { throw new IllegalStateException( "Turning DataCategory or DataType into human-readable DOM elements requires" diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataTypeFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataTypeFactory.java index a5559d801349..96a58fa34707 100644 --- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataTypeFactory.java +++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataTypeFactory.java @@ -64,8 +64,7 @@ public class DataTypeFactory { } /** Creates an {@link AslMarshallableFactory} from on-device DOM elements */ - public DataType createFromOdElements(List<Element> elements) throws MalformedXmlException { - Element odDataTypeEle = XmlUtils.getSingleElement(elements); + public DataType createFromOdElement(Element odDataTypeEle) throws MalformedXmlException { String dataTypeName = odDataTypeEle.getAttribute(XmlUtils.OD_ATTR_NAME); List<Integer> purposeInts = XmlUtils.getOdIntArray(odDataTypeEle, XmlUtils.OD_NAME_PURPOSES, true); diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DeveloperInfo.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DeveloperInfo.java new file mode 100644 index 000000000000..96a64dc29526 --- /dev/null +++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DeveloperInfo.java @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.asllib.marshallable; + +import com.android.asllib.util.XmlUtils; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +/** DeveloperInfo representation */ +public class DeveloperInfo implements AslMarshallable { + public enum DeveloperRelationship { + OEM(0), + ODM(1), + SOC(2), + OTA(3), + CARRIER(4), + AOSP(5), + OTHER(6); + + private final int mValue; + + DeveloperRelationship(int value) { + this.mValue = value; + } + + /** Get the int value associated with the DeveloperRelationship. */ + public int getValue() { + return mValue; + } + + /** Get the DeveloperRelationship associated with the int value. */ + public static DeveloperInfo.DeveloperRelationship forValue(int value) { + for (DeveloperInfo.DeveloperRelationship e : values()) { + if (e.getValue() == value) { + return e; + } + } + throw new IllegalArgumentException("No DeveloperRelationship enum for value: " + value); + } + + /** Get the DeveloperRelationship associated with the human-readable String. */ + public static DeveloperInfo.DeveloperRelationship forString(String s) { + for (DeveloperInfo.DeveloperRelationship e : values()) { + if (e.toString().equals(s)) { + return e; + } + } + throw new IllegalArgumentException("No DeveloperRelationship enum for str: " + s); + } + + /** Human-readable String representation of DeveloperRelationship. */ + public String toString() { + return this.name().toLowerCase(); + } + } + + private final String mName; + private final String mEmail; + private final String mAddress; + private final String mCountryRegion; + private final DeveloperRelationship mDeveloperRelationship; + private final String mWebsite; + private final String mAppDeveloperRegistryId; + + public DeveloperInfo( + String name, + String email, + String address, + String countryRegion, + DeveloperRelationship developerRelationship, + String website, + String appDeveloperRegistryId) { + this.mName = name; + this.mEmail = email; + this.mAddress = address; + this.mCountryRegion = countryRegion; + this.mDeveloperRelationship = developerRelationship; + this.mWebsite = website; + this.mAppDeveloperRegistryId = appDeveloperRegistryId; + } + + /** Creates an on-device DOM element from the {@link SafetyLabels}. */ + public Element toOdDomElement(Document doc) { + Element developerInfoEle = + XmlUtils.createPbundleEleWithName(doc, XmlUtils.OD_NAME_DEVELOPER_INFO); + if (mName != null) { + developerInfoEle.appendChild( + XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_NAME, mName)); + } + if (mEmail != null) { + developerInfoEle.appendChild( + XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_EMAIL, mEmail)); + } + if (mAddress != null) { + developerInfoEle.appendChild( + XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_ADDRESS, mAddress)); + } + if (mCountryRegion != null) { + developerInfoEle.appendChild( + XmlUtils.createOdStringEle( + doc, XmlUtils.OD_NAME_COUNTRY_REGION, mCountryRegion)); + } + if (mDeveloperRelationship != null) { + developerInfoEle.appendChild( + XmlUtils.createOdLongEle( + doc, + XmlUtils.OD_NAME_DEVELOPER_RELATIONSHIP, + mDeveloperRelationship.getValue())); + } + if (mWebsite != null) { + developerInfoEle.appendChild( + XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_WEBSITE, mWebsite)); + } + if (mAppDeveloperRegistryId != null) { + developerInfoEle.appendChild( + XmlUtils.createOdStringEle( + doc, + XmlUtils.OD_NAME_APP_DEVELOPER_REGISTRY_ID, + mAppDeveloperRegistryId)); + } + return developerInfoEle; + } + + /** Creates the human-readable DOM elements from the AslMarshallable Java Object. */ + public Element toHrDomElement(Document doc) { + Element developerInfoEle = doc.createElement(XmlUtils.HR_TAG_DEVELOPER_INFO); + if (mName != null) { + developerInfoEle.setAttribute(XmlUtils.HR_ATTR_NAME, mName); + } + if (mEmail != null) { + developerInfoEle.setAttribute(XmlUtils.HR_ATTR_EMAIL, mEmail); + } + if (mAddress != null) { + developerInfoEle.setAttribute(XmlUtils.HR_ATTR_ADDRESS, mAddress); + } + if (mCountryRegion != null) { + developerInfoEle.setAttribute(XmlUtils.HR_ATTR_COUNTRY_REGION, mCountryRegion); + } + if (mDeveloperRelationship != null) { + developerInfoEle.setAttribute( + XmlUtils.HR_ATTR_DEVELOPER_RELATIONSHIP, mDeveloperRelationship.toString()); + } + if (mWebsite != null) { + developerInfoEle.setAttribute(XmlUtils.HR_ATTR_WEBSITE, mWebsite); + } + if (mAppDeveloperRegistryId != null) { + developerInfoEle.setAttribute( + XmlUtils.HR_ATTR_APP_DEVELOPER_REGISTRY_ID, mAppDeveloperRegistryId); + } + return developerInfoEle; + } +} diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DeveloperInfoFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DeveloperInfoFactory.java new file mode 100644 index 000000000000..e82a53a53b25 --- /dev/null +++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DeveloperInfoFactory.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.asllib.marshallable; + +import com.android.asllib.util.AslgenUtil; +import com.android.asllib.util.MalformedXmlException; +import com.android.asllib.util.XmlUtils; + +import org.w3c.dom.Element; + +public class DeveloperInfoFactory implements AslMarshallableFactory<DeveloperInfo> { + /** Creates a {@link DeveloperInfo} from the human-readable DOM element. */ + public DeveloperInfo createFromHrElement(Element developerInfoEle) + throws MalformedXmlException { + if (developerInfoEle == null) { + AslgenUtil.logI("No DeveloperInfo found in hr format."); + return null; + } + String name = XmlUtils.getStringAttr(developerInfoEle, XmlUtils.HR_ATTR_NAME, true); + String email = XmlUtils.getStringAttr(developerInfoEle, XmlUtils.HR_ATTR_EMAIL, true); + String address = XmlUtils.getStringAttr(developerInfoEle, XmlUtils.HR_ATTR_ADDRESS, true); + String countryRegion = + XmlUtils.getStringAttr(developerInfoEle, XmlUtils.HR_ATTR_COUNTRY_REGION, true); + DeveloperInfo.DeveloperRelationship developerRelationship = + DeveloperInfo.DeveloperRelationship.forString( + XmlUtils.getStringAttr( + developerInfoEle, XmlUtils.HR_ATTR_DEVELOPER_RELATIONSHIP, true)); + String website = XmlUtils.getStringAttr(developerInfoEle, XmlUtils.HR_ATTR_WEBSITE, false); + String appDeveloperRegistryId = + XmlUtils.getStringAttr( + developerInfoEle, XmlUtils.HR_ATTR_APP_DEVELOPER_REGISTRY_ID, false); + return new DeveloperInfo( + name, + email, + address, + countryRegion, + developerRelationship, + website, + appDeveloperRegistryId); + } + + /** Creates an {@link AslMarshallableFactory} from on-device DOM elements */ + public DeveloperInfo createFromOdElement(Element developerInfoEle) + throws MalformedXmlException { + if (developerInfoEle == null) { + AslgenUtil.logI("No DeveloperInfo found in od format."); + return null; + } + String name = XmlUtils.getOdStringEle(developerInfoEle, XmlUtils.OD_NAME_NAME, true); + String email = XmlUtils.getOdStringEle(developerInfoEle, XmlUtils.OD_NAME_EMAIL, true); + String address = XmlUtils.getOdStringEle(developerInfoEle, XmlUtils.OD_NAME_ADDRESS, true); + String countryRegion = + XmlUtils.getOdStringEle(developerInfoEle, XmlUtils.OD_NAME_COUNTRY_REGION, true); + DeveloperInfo.DeveloperRelationship developerRelationship = + DeveloperInfo.DeveloperRelationship.forValue( + (int) + (long) + XmlUtils.getOdLongEle( + developerInfoEle, + XmlUtils.OD_NAME_DEVELOPER_RELATIONSHIP, + true)); + String website = XmlUtils.getOdStringEle(developerInfoEle, XmlUtils.OD_NAME_WEBSITE, false); + String appDeveloperRegistryId = + XmlUtils.getOdStringEle( + developerInfoEle, XmlUtils.OD_NAME_APP_DEVELOPER_REGISTRY_ID, false); + return new DeveloperInfo( + name, + email, + address, + countryRegion, + developerRelationship, + website, + appDeveloperRegistryId); + } +} diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SafetyLabels.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SafetyLabels.java index 2a4e130981af..1a83c02de3e4 100644 --- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SafetyLabels.java +++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SafetyLabels.java @@ -21,40 +21,50 @@ import com.android.asllib.util.XmlUtils; import org.w3c.dom.Document; import org.w3c.dom.Element; -import java.util.List; - /** Safety Label representation containing zero or more {@link DataCategory} for data shared */ public class SafetyLabels implements AslMarshallable { private final DataLabels mDataLabels; + private final SecurityLabels mSecurityLabels; + private final ThirdPartyVerification mThirdPartyVerification; - public SafetyLabels(DataLabels dataLabels) { + public SafetyLabels( + DataLabels dataLabels, + SecurityLabels securityLabels, + ThirdPartyVerification thirdPartyVerification) { this.mDataLabels = dataLabels; - } - - /** Returns the data label for the safety label */ - public DataLabels getDataLabel() { - return mDataLabels; + this.mSecurityLabels = securityLabels; + this.mThirdPartyVerification = thirdPartyVerification; } /** Creates an on-device DOM element from the {@link SafetyLabels}. */ - @Override - public List<Element> toOdDomElements(Document doc) { + public Element toOdDomElement(Document doc) { Element safetyLabelsEle = XmlUtils.createPbundleEleWithName(doc, XmlUtils.OD_NAME_SAFETY_LABELS); if (mDataLabels != null) { - XmlUtils.appendChildren(safetyLabelsEle, mDataLabels.toOdDomElements(doc)); + safetyLabelsEle.appendChild(mDataLabels.toOdDomElement(doc)); + } + if (mSecurityLabels != null) { + safetyLabelsEle.appendChild(mSecurityLabels.toOdDomElement(doc)); } - return XmlUtils.listOf(safetyLabelsEle); + if (mThirdPartyVerification != null) { + safetyLabelsEle.appendChild(mThirdPartyVerification.toOdDomElement(doc)); + } + return safetyLabelsEle; } /** Creates the human-readable DOM elements from the AslMarshallable Java Object. */ - @Override - public List<Element> toHrDomElements(Document doc) { + public Element toHrDomElement(Document doc) { Element safetyLabelsEle = doc.createElement(XmlUtils.HR_TAG_SAFETY_LABELS); if (mDataLabels != null) { - XmlUtils.appendChildren(safetyLabelsEle, mDataLabels.toHrDomElements(doc)); + safetyLabelsEle.appendChild(mDataLabels.toHrDomElement(doc)); + } + if (mSecurityLabels != null) { + safetyLabelsEle.appendChild(mSecurityLabels.toHrDomElement(doc)); + } + if (mThirdPartyVerification != null) { + safetyLabelsEle.appendChild(mThirdPartyVerification.toHrDomElement(doc)); } - return XmlUtils.listOf(safetyLabelsEle); + return safetyLabelsEle; } } diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SafetyLabelsFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SafetyLabelsFactory.java index 2738337b7080..35804d9351b4 100644 --- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SafetyLabelsFactory.java +++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SafetyLabelsFactory.java @@ -16,54 +16,109 @@ package com.android.asllib.marshallable; -import com.android.asllib.util.AslgenUtil; import com.android.asllib.util.MalformedXmlException; import com.android.asllib.util.XmlUtils; import org.w3c.dom.Element; -import java.util.List; +import java.util.Map; +import java.util.Set; public class SafetyLabelsFactory implements AslMarshallableFactory<SafetyLabels> { + private final Map<Long, Set<String>> mRecognizedHrAttrs = + Map.ofEntries(Map.entry(1L, Set.of())); + private final Map<Long, Set<String>> mRequiredHrAttrs = Map.ofEntries(Map.entry(1L, Set.of())); + private final Map<Long, Set<String>> mRecognizedHrEles = + Map.ofEntries( + Map.entry( + 1L, + Set.of( + XmlUtils.HR_TAG_DATA_LABELS, + XmlUtils.HR_TAG_SECURITY_LABELS, + XmlUtils.HR_TAG_THIRD_PARTY_VERIFICATION)), + Map.entry(2L, Set.of(XmlUtils.HR_TAG_DATA_LABELS))); + private final Map<Long, Set<String>> mRequiredHrEles = Map.ofEntries(Map.entry(1L, Set.of())); + private final Map<Long, Set<String>> mRecognizedOdEleNames = + Map.ofEntries( + Map.entry( + 1L, + Set.of( + XmlUtils.OD_NAME_DATA_LABELS, + XmlUtils.OD_NAME_SECURITY_LABELS, + XmlUtils.OD_NAME_THIRD_PARTY_VERIFICATION)), + Map.entry(2L, Set.of(XmlUtils.OD_NAME_DATA_LABELS))); + private final Map<Long, Set<String>> mRequiredOdEles = Map.ofEntries(Map.entry(1L, Set.of())); /** Creates a {@link SafetyLabels} from the human-readable DOM element. */ - @Override - public SafetyLabels createFromHrElements(List<Element> elements) throws MalformedXmlException { - Element safetyLabelsEle = XmlUtils.getSingleElement(elements); + public SafetyLabels createFromHrElement(Element safetyLabelsEle, long version) + throws MalformedXmlException { if (safetyLabelsEle == null) { - AslgenUtil.logI("No SafetyLabels found in hr format."); return null; } + XmlUtils.throwIfExtraneousAttributes( + safetyLabelsEle, XmlUtils.getMostRecentVersion(mRecognizedHrAttrs, version)); + XmlUtils.throwIfExtraneousChildrenHr( + safetyLabelsEle, XmlUtils.getMostRecentVersion(mRecognizedHrEles, version)); + + var requiredHrEles = XmlUtils.getMostRecentVersion(mRequiredHrEles, version); + DataLabels dataLabels = new DataLabelsFactory() - .createFromHrElements( - XmlUtils.listOf( - XmlUtils.getSingleChildElement( - safetyLabelsEle, - XmlUtils.HR_TAG_DATA_LABELS, - false))); - return new SafetyLabels(dataLabels); + .createFromHrElement( + XmlUtils.getSingleChildElement( + safetyLabelsEle, + XmlUtils.HR_TAG_DATA_LABELS, + requiredHrEles)); + SecurityLabels securityLabels = + new SecurityLabelsFactory() + .createFromHrElement( + XmlUtils.getSingleChildElement( + safetyLabelsEle, + XmlUtils.HR_TAG_SECURITY_LABELS, + requiredHrEles)); + ThirdPartyVerification thirdPartyVerification = + new ThirdPartyVerificationFactory() + .createFromHrElement( + XmlUtils.getSingleChildElement( + safetyLabelsEle, + XmlUtils.HR_TAG_THIRD_PARTY_VERIFICATION, + requiredHrEles)); + return new SafetyLabels(dataLabels, securityLabels, thirdPartyVerification); } /** Creates an {@link AslMarshallableFactory} from on-device DOM elements */ - @Override - public SafetyLabels createFromOdElements(List<Element> elements) throws MalformedXmlException { - Element safetyLabelsEle = XmlUtils.getSingleElement(elements); + public SafetyLabels createFromOdElement(Element safetyLabelsEle, long version) + throws MalformedXmlException { if (safetyLabelsEle == null) { - AslgenUtil.logI("No SafetyLabels found in od format."); return null; } + XmlUtils.throwIfExtraneousChildrenOd( + safetyLabelsEle, XmlUtils.getMostRecentVersion(mRecognizedOdEleNames, version)); + var requiredOdEles = XmlUtils.getMostRecentVersion(mRequiredOdEles, version); + DataLabels dataLabels = new DataLabelsFactory() - .createFromOdElements( - XmlUtils.listOf( - XmlUtils.getOdPbundleWithName( - safetyLabelsEle, - XmlUtils.OD_NAME_DATA_LABELS, - false))); - - return new SafetyLabels(dataLabels); + .createFromOdElement( + XmlUtils.getOdPbundleWithName( + safetyLabelsEle, + XmlUtils.OD_NAME_DATA_LABELS, + requiredOdEles)); + SecurityLabels securityLabels = + new SecurityLabelsFactory() + .createFromOdElement( + XmlUtils.getOdPbundleWithName( + safetyLabelsEle, + XmlUtils.OD_NAME_SECURITY_LABELS, + requiredOdEles)); + ThirdPartyVerification thirdPartyVerification = + new ThirdPartyVerificationFactory() + .createFromOdElement( + XmlUtils.getOdPbundleWithName( + safetyLabelsEle, + XmlUtils.OD_NAME_THIRD_PARTY_VERIFICATION, + requiredOdEles)); + return new SafetyLabels(dataLabels, securityLabels, thirdPartyVerification); } } diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SecurityLabels.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SecurityLabels.java index 48643ba0e3ab..ccb84451c96f 100644 --- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SecurityLabels.java +++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SecurityLabels.java @@ -21,8 +21,6 @@ import com.android.asllib.util.XmlUtils; import org.w3c.dom.Document; import org.w3c.dom.Element; -import java.util.List; - /** Security Labels representation */ public class SecurityLabels implements AslMarshallable { @@ -35,8 +33,7 @@ public class SecurityLabels implements AslMarshallable { } /** Creates an on-device DOM element from the {@link SecurityLabels}. */ - @Override - public List<Element> toOdDomElements(Document doc) { + public Element toOdDomElement(Document doc) { Element ele = XmlUtils.createPbundleEleWithName(doc, XmlUtils.OD_NAME_SECURITY_LABELS); if (mIsDataDeletable != null) { ele.appendChild( @@ -48,12 +45,11 @@ public class SecurityLabels implements AslMarshallable { XmlUtils.createOdBooleanEle( doc, XmlUtils.OD_NAME_IS_DATA_ENCRYPTED, mIsDataEncrypted)); } - return XmlUtils.listOf(ele); + return ele; } /** Creates the human-readable DOM elements from the AslMarshallable Java Object. */ - @Override - public List<Element> toHrDomElements(Document doc) { + public Element toHrDomElement(Document doc) { Element ele = doc.createElement(XmlUtils.HR_TAG_SECURITY_LABELS); if (mIsDataDeletable != null) { ele.setAttribute(XmlUtils.HR_ATTR_IS_DATA_DELETABLE, String.valueOf(mIsDataDeletable)); @@ -61,6 +57,6 @@ public class SecurityLabels implements AslMarshallable { if (mIsDataEncrypted != null) { ele.setAttribute(XmlUtils.HR_ATTR_IS_DATA_ENCRYPTED, String.valueOf(mIsDataEncrypted)); } - return XmlUtils.listOf(ele); + return ele; } } diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SecurityLabelsFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SecurityLabelsFactory.java index 525a80388261..da98a4291b4a 100644 --- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SecurityLabelsFactory.java +++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SecurityLabelsFactory.java @@ -22,15 +22,10 @@ import com.android.asllib.util.XmlUtils; import org.w3c.dom.Element; -import java.util.List; - public class SecurityLabelsFactory implements AslMarshallableFactory<SecurityLabels> { /** Creates a {@link SecurityLabels} from the human-readable DOM element. */ - @Override - public SecurityLabels createFromHrElements(List<Element> elements) - throws MalformedXmlException { - Element ele = XmlUtils.getSingleElement(elements); + public SecurityLabels createFromHrElement(Element ele) throws MalformedXmlException { if (ele == null) { AslgenUtil.logI("No SecurityLabels found in hr format."); return null; @@ -43,10 +38,7 @@ public class SecurityLabelsFactory implements AslMarshallableFactory<SecurityLab } /** Creates an {@link AslMarshallableFactory} from on-device DOM elements */ - @Override - public SecurityLabels createFromOdElements(List<Element> elements) - throws MalformedXmlException { - Element ele = XmlUtils.getSingleElement(elements); + public SecurityLabels createFromOdElement(Element ele) throws MalformedXmlException { if (ele == null) { AslgenUtil.logI("No SecurityLabels found in od format."); return null; diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SystemAppSafetyLabel.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SystemAppSafetyLabel.java index 242e7be66d76..10d6e1aaac7d 100644 --- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SystemAppSafetyLabel.java +++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SystemAppSafetyLabel.java @@ -21,34 +21,43 @@ import com.android.asllib.util.XmlUtils; import org.w3c.dom.Document; import org.w3c.dom.Element; -import java.util.List; - /** Safety Label representation containing zero or more {@link DataCategory} for data shared */ public class SystemAppSafetyLabel implements AslMarshallable { + private final String mUrl; private final Boolean mDeclaration; - public SystemAppSafetyLabel(Boolean d) { + public SystemAppSafetyLabel(String url, Boolean d) { this.mDeclaration = d; + this.mUrl = null; } /** Creates an on-device DOM element from the {@link SystemAppSafetyLabel}. */ - @Override - public List<Element> toOdDomElements(Document doc) { + public Element toOdDomElement(Document doc) { Element systemAppSafetyLabelEle = XmlUtils.createPbundleEleWithName(doc, XmlUtils.OD_NAME_SYSTEM_APP_SAFETY_LABEL); - systemAppSafetyLabelEle.appendChild( - XmlUtils.createOdBooleanEle(doc, XmlUtils.OD_NAME_DECLARATION, mDeclaration)); - return XmlUtils.listOf(systemAppSafetyLabelEle); + if (mUrl != null) { + systemAppSafetyLabelEle.appendChild( + XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_URL, mUrl)); + } + if (mDeclaration != null) { + systemAppSafetyLabelEle.appendChild( + XmlUtils.createOdBooleanEle(doc, XmlUtils.OD_NAME_DECLARATION, mDeclaration)); + } + return systemAppSafetyLabelEle; } /** Creates the human-readable DOM elements from the AslMarshallable Java Object. */ - @Override - public List<Element> toHrDomElements(Document doc) { + public Element toHrDomElement(Document doc) { Element systemAppSafetyLabelEle = doc.createElement(XmlUtils.HR_TAG_SYSTEM_APP_SAFETY_LABEL); - XmlUtils.maybeSetHrBoolAttr( - systemAppSafetyLabelEle, XmlUtils.HR_ATTR_DECLARATION, mDeclaration); - return XmlUtils.listOf(systemAppSafetyLabelEle); + if (mUrl != null) { + systemAppSafetyLabelEle.setAttribute(XmlUtils.HR_ATTR_URL, mUrl); + } + if (mDeclaration != null) { + systemAppSafetyLabelEle.setAttribute( + XmlUtils.HR_ATTR_DECLARATION, String.valueOf(mDeclaration)); + } + return systemAppSafetyLabelEle; } } diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SystemAppSafetyLabelFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SystemAppSafetyLabelFactory.java index 7f4aa7a3b690..971ae9296eb8 100644 --- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SystemAppSafetyLabelFactory.java +++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SystemAppSafetyLabelFactory.java @@ -16,42 +16,77 @@ package com.android.asllib.marshallable; -import com.android.asllib.util.AslgenUtil; import com.android.asllib.util.MalformedXmlException; import com.android.asllib.util.XmlUtils; import org.w3c.dom.Element; -import java.util.List; +import java.util.Map; +import java.util.Set; public class SystemAppSafetyLabelFactory implements AslMarshallableFactory<SystemAppSafetyLabel> { + private final Map<Long, Set<String>> mRecognizedHrAttrs = + Map.ofEntries( + Map.entry(1L, Set.of(XmlUtils.HR_ATTR_URL)), + Map.entry(2L, Set.of(XmlUtils.HR_ATTR_DECLARATION))); + private final Map<Long, Set<String>> mRequiredHrAttrs = + Map.ofEntries( + Map.entry(1L, Set.of(XmlUtils.HR_ATTR_URL)), + Map.entry(2L, Set.of(XmlUtils.HR_ATTR_DECLARATION))); + private final Map<Long, Set<String>> mRecognizedHrEles = Map.ofEntries(Map.entry(1L, Set.of())); + private final Map<Long, Set<String>> mRecognizedOdEleNames = + Map.ofEntries( + Map.entry(1L, Set.of(XmlUtils.OD_NAME_URL)), + Map.entry(2L, Set.of(XmlUtils.OD_NAME_DECLARATION))); + private final Map<Long, Set<String>> mRequiredOdEleNames = + Map.ofEntries( + Map.entry(1L, Set.of(XmlUtils.OD_NAME_URL)), + Map.entry(2L, Set.of(XmlUtils.OD_NAME_DECLARATION))); /** Creates a {@link SystemAppSafetyLabel} from the human-readable DOM element. */ - @Override - public SystemAppSafetyLabel createFromHrElements(List<Element> elements) + public SystemAppSafetyLabel createFromHrElement(Element systemAppSafetyLabelEle, long version) throws MalformedXmlException { - Element systemAppSafetyLabelEle = XmlUtils.getSingleElement(elements); if (systemAppSafetyLabelEle == null) { - AslgenUtil.logI("No SystemAppSafetyLabel found in hr format."); return null; } + XmlUtils.throwIfExtraneousAttributes( + systemAppSafetyLabelEle, + XmlUtils.getMostRecentVersion(mRecognizedHrAttrs, version)); + XmlUtils.throwIfExtraneousChildrenHr( + systemAppSafetyLabelEle, XmlUtils.getMostRecentVersion(mRecognizedHrEles, version)); + String url = + XmlUtils.getStringAttr( + systemAppSafetyLabelEle, + XmlUtils.HR_ATTR_URL, + XmlUtils.getMostRecentVersion(mRequiredHrAttrs, version)); Boolean declaration = - XmlUtils.getBoolAttr(systemAppSafetyLabelEle, XmlUtils.HR_ATTR_DECLARATION, true); - return new SystemAppSafetyLabel(declaration); + XmlUtils.getBoolAttr( + systemAppSafetyLabelEle, + XmlUtils.HR_ATTR_DECLARATION, + XmlUtils.getMostRecentVersion(mRequiredHrAttrs, version)); + return new SystemAppSafetyLabel(url, declaration); } /** Creates an {@link AslMarshallableFactory} from on-device DOM elements */ - @Override - public SystemAppSafetyLabel createFromOdElements(List<Element> elements) + public SystemAppSafetyLabel createFromOdElement(Element systemAppSafetyLabelEle, long version) throws MalformedXmlException { - Element systemAppSafetyLabelEle = XmlUtils.getSingleElement(elements); if (systemAppSafetyLabelEle == null) { - AslgenUtil.logI("No SystemAppSafetyLabel found in od format."); return null; } + XmlUtils.throwIfExtraneousChildrenOd( + systemAppSafetyLabelEle, + XmlUtils.getMostRecentVersion(mRecognizedOdEleNames, version)); + String url = + XmlUtils.getOdStringEle( + systemAppSafetyLabelEle, + XmlUtils.OD_NAME_URL, + XmlUtils.getMostRecentVersion(mRequiredOdEleNames, version)); Boolean declaration = - XmlUtils.getOdBoolEle(systemAppSafetyLabelEle, XmlUtils.OD_NAME_DECLARATION, true); - return new SystemAppSafetyLabel(declaration); + XmlUtils.getOdBoolEle( + systemAppSafetyLabelEle, + XmlUtils.OD_NAME_DECLARATION, + XmlUtils.getMostRecentVersion(mRequiredOdEleNames, version)); + return new SystemAppSafetyLabel(url, declaration); } } diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/ThirdPartyVerification.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/ThirdPartyVerification.java index d74f3f062513..151cdb1e2f51 100644 --- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/ThirdPartyVerification.java +++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/ThirdPartyVerification.java @@ -21,8 +21,6 @@ import com.android.asllib.util.XmlUtils; import org.w3c.dom.Document; import org.w3c.dom.Element; -import java.util.List; - /** ThirdPartyVerification representation. */ public class ThirdPartyVerification implements AslMarshallable { @@ -33,19 +31,17 @@ public class ThirdPartyVerification implements AslMarshallable { } /** Creates an on-device DOM element from the {@link ThirdPartyVerification}. */ - @Override - public List<Element> toOdDomElements(Document doc) { + public Element toOdDomElement(Document doc) { Element ele = XmlUtils.createPbundleEleWithName(doc, XmlUtils.OD_NAME_THIRD_PARTY_VERIFICATION); ele.appendChild(XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_URL, mUrl)); - return XmlUtils.listOf(ele); + return ele; } /** Creates the human-readable DOM elements from the AslMarshallable Java Object. */ - @Override - public List<Element> toHrDomElements(Document doc) { + public Element toHrDomElement(Document doc) { Element ele = doc.createElement(XmlUtils.HR_TAG_THIRD_PARTY_VERIFICATION); ele.setAttribute(XmlUtils.HR_ATTR_URL, mUrl); - return XmlUtils.listOf(ele); + return ele; } } diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/ThirdPartyVerificationFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/ThirdPartyVerificationFactory.java index 197e7aa77743..f229ad6c861f 100644 --- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/ThirdPartyVerificationFactory.java +++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/ThirdPartyVerificationFactory.java @@ -22,16 +22,11 @@ import com.android.asllib.util.XmlUtils; import org.w3c.dom.Element; -import java.util.List; - public class ThirdPartyVerificationFactory implements AslMarshallableFactory<ThirdPartyVerification> { /** Creates a {@link ThirdPartyVerification} from the human-readable DOM element. */ - @Override - public ThirdPartyVerification createFromHrElements(List<Element> elements) - throws MalformedXmlException { - Element ele = XmlUtils.getSingleElement(elements); + public ThirdPartyVerification createFromHrElement(Element ele) throws MalformedXmlException { if (ele == null) { AslgenUtil.logI("No ThirdPartyVerification found in hr format."); return null; @@ -42,10 +37,7 @@ public class ThirdPartyVerificationFactory } /** Creates an {@link AslMarshallableFactory} from on-device DOM elements */ - @Override - public ThirdPartyVerification createFromOdElements(List<Element> elements) - throws MalformedXmlException { - Element ele = XmlUtils.getSingleElement(elements); + public ThirdPartyVerification createFromOdElement(Element ele) throws MalformedXmlException { if (ele == null) { AslgenUtil.logI("No ThirdPartyVerification found in od format."); return null; diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/TransparencyInfo.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/TransparencyInfo.java index 9f789f0b9c1c..f24e6bf58efb 100644 --- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/TransparencyInfo.java +++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/TransparencyInfo.java @@ -21,39 +21,39 @@ import com.android.asllib.util.XmlUtils; import org.w3c.dom.Document; import org.w3c.dom.Element; -import java.util.List; - /** TransparencyInfo representation containing {@link AppInfo} */ public class TransparencyInfo implements AslMarshallable { + + private final DeveloperInfo mDeveloperInfo; private final AppInfo mAppInfo; - public TransparencyInfo(AppInfo appInfo) { + public TransparencyInfo(DeveloperInfo developerInfo, AppInfo appInfo) { + this.mDeveloperInfo = developerInfo; this.mAppInfo = appInfo; } - /** Gets the {@link AppInfo} of the {@link TransparencyInfo}. */ - public AppInfo getAppInfo() { - return mAppInfo; - } - /** Creates an on-device DOM element from the {@link TransparencyInfo}. */ - @Override - public List<Element> toOdDomElements(Document doc) { + public Element toOdDomElement(Document doc) { Element transparencyInfoEle = XmlUtils.createPbundleEleWithName(doc, XmlUtils.OD_NAME_TRANSPARENCY_INFO); + if (mDeveloperInfo != null) { + transparencyInfoEle.appendChild(mDeveloperInfo.toOdDomElement(doc)); + } if (mAppInfo != null) { - XmlUtils.appendChildren(transparencyInfoEle, mAppInfo.toOdDomElements(doc)); + transparencyInfoEle.appendChild(mAppInfo.toOdDomElement(doc)); } - return XmlUtils.listOf(transparencyInfoEle); + return transparencyInfoEle; } /** Creates the human-readable DOM elements from the AslMarshallable Java Object. */ - @Override - public List<Element> toHrDomElements(Document doc) { + public Element toHrDomElement(Document doc) { Element transparencyInfoEle = doc.createElement(XmlUtils.HR_TAG_TRANSPARENCY_INFO); + if (mDeveloperInfo != null) { + transparencyInfoEle.appendChild(mDeveloperInfo.toHrDomElement(doc)); + } if (mAppInfo != null) { - XmlUtils.appendChildren(transparencyInfoEle, mAppInfo.toHrDomElements(doc)); + transparencyInfoEle.appendChild(mAppInfo.toHrDomElement(doc)); } - return XmlUtils.listOf(transparencyInfoEle); + return transparencyInfoEle; } } diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/TransparencyInfoFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/TransparencyInfoFactory.java index 40f2872e4380..9e98941e0d6d 100644 --- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/TransparencyInfoFactory.java +++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/TransparencyInfoFactory.java @@ -16,47 +16,84 @@ package com.android.asllib.marshallable; -import com.android.asllib.util.AslgenUtil; import com.android.asllib.util.MalformedXmlException; import com.android.asllib.util.XmlUtils; import org.w3c.dom.Element; -import java.util.List; +import java.util.Map; +import java.util.Set; public class TransparencyInfoFactory implements AslMarshallableFactory<TransparencyInfo> { + private final Map<Long, Set<String>> mRecognizedHrAttrs = + Map.ofEntries(Map.entry(1L, Set.of())); + private final Map<Long, Set<String>> mRequiredHrAttrs = Map.ofEntries(Map.entry(1L, Set.of())); + private final Map<Long, Set<String>> mRecognizedHrEles = + Map.ofEntries( + Map.entry(1L, Set.of(XmlUtils.HR_TAG_DEVELOPER_INFO, XmlUtils.HR_TAG_APP_INFO)), + Map.entry(2L, Set.of(XmlUtils.HR_TAG_APP_INFO))); + private final Map<Long, Set<String>> mRequiredHrEles = + Map.ofEntries(Map.entry(1L, Set.of()), Map.entry(2L, Set.of(XmlUtils.HR_TAG_APP_INFO))); + private final Map<Long, Set<String>> mRecognizedOdEleNames = + Map.ofEntries( + Map.entry( + 1L, Set.of(XmlUtils.OD_NAME_DEVELOPER_INFO, XmlUtils.OD_NAME_APP_INFO)), + Map.entry(2L, Set.of(XmlUtils.OD_NAME_APP_INFO))); + private final Map<Long, Set<String>> mRequiredOdEles = + Map.ofEntries( + Map.entry(1L, Set.of()), Map.entry(2L, Set.of(XmlUtils.OD_NAME_APP_INFO))); /** Creates a {@link TransparencyInfo} from the human-readable DOM element. */ - @Override - public TransparencyInfo createFromHrElements(List<Element> elements) + public TransparencyInfo createFromHrElement(Element transparencyInfoEle, long version) throws MalformedXmlException { - Element transparencyInfoEle = XmlUtils.getSingleElement(elements); if (transparencyInfoEle == null) { - AslgenUtil.logI("No TransparencyInfo found in hr format."); return null; } + XmlUtils.throwIfExtraneousAttributes( + transparencyInfoEle, XmlUtils.getMostRecentVersion(mRecognizedHrAttrs, version)); + XmlUtils.throwIfExtraneousChildrenHr( + transparencyInfoEle, XmlUtils.getMostRecentVersion(mRecognizedHrEles, version)); + Element developerInfoEle = + XmlUtils.getSingleChildElement( + transparencyInfoEle, + XmlUtils.HR_TAG_DEVELOPER_INFO, + XmlUtils.getMostRecentVersion(mRequiredHrEles, version)); + DeveloperInfo developerInfo = + new DeveloperInfoFactory().createFromHrElement(developerInfoEle); Element appInfoEle = - XmlUtils.getSingleChildElement(transparencyInfoEle, XmlUtils.HR_TAG_APP_INFO, true); - AppInfo appInfo = new AppInfoFactory().createFromHrElements(XmlUtils.listOf(appInfoEle)); + XmlUtils.getSingleChildElement( + transparencyInfoEle, + XmlUtils.HR_TAG_APP_INFO, + XmlUtils.getMostRecentVersion(mRequiredHrEles, version)); + AppInfo appInfo = new AppInfoFactory().createFromHrElement(appInfoEle, version); - return new TransparencyInfo(appInfo); + return new TransparencyInfo(developerInfo, appInfo); } /** Creates an {@link AslMarshallableFactory} from on-device DOM elements */ - @Override - public TransparencyInfo createFromOdElements(List<Element> elements) + public TransparencyInfo createFromOdElement(Element transparencyInfoEle, long version) throws MalformedXmlException { - Element transparencyInfoEle = XmlUtils.getSingleElement(elements); if (transparencyInfoEle == null) { - AslgenUtil.logI("No TransparencyInfo found in od format."); return null; } + XmlUtils.throwIfExtraneousChildrenOd( + transparencyInfoEle, XmlUtils.getMostRecentVersion(mRecognizedOdEleNames, version)); + Element developerInfoEle = + XmlUtils.getOdPbundleWithName( + transparencyInfoEle, + XmlUtils.OD_NAME_DEVELOPER_INFO, + XmlUtils.getMostRecentVersion(mRequiredOdEles, version)); + DeveloperInfo developerInfo = + new DeveloperInfoFactory().createFromOdElement(developerInfoEle); Element appInfoEle = - XmlUtils.getOdPbundleWithName(transparencyInfoEle, XmlUtils.OD_NAME_APP_INFO, true); - AppInfo appInfo = new AppInfoFactory().createFromOdElements(XmlUtils.listOf(appInfoEle)); + XmlUtils.getOdPbundleWithName( + transparencyInfoEle, + XmlUtils.OD_NAME_APP_INFO, + XmlUtils.getMostRecentVersion(mRequiredOdEles, version)); + AppInfo appInfo = new AppInfoFactory().createFromOdElement(appInfoEle, version); - return new TransparencyInfo(appInfo); + return new TransparencyInfo(developerInfo, appInfo); } } diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/util/XmlUtils.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/util/XmlUtils.java index 2c1517bdf8ab..52c4390036f3 100644 --- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/util/XmlUtils.java +++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/util/XmlUtils.java @@ -25,6 +25,8 @@ import org.w3c.dom.NodeList; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.stream.Collectors; public class XmlUtils { @@ -70,6 +72,8 @@ public class XmlUtils { public static final String HR_ATTR_ADS_FINGERPRINTING = "adsFingerprinting"; public static final String HR_ATTR_SECURITY_FINGERPRINTING = "securityFingerprinting"; public static final String HR_ATTR_PRIVACY_POLICY = "privacyPolicy"; + public static final String HR_ATTR_DEVELOPER_ID = "developerId"; + public static final String HR_ATTR_APPLICATION_ID = "applicationId"; public static final String HR_ATTR_SECURITY_ENDPOINTS = "securityEndpoints"; public static final String HR_TAG_FIRST_PARTY_ENDPOINTS = "first-party-endpoints"; public static final String HR_TAG_SERVICE_PROVIDER_ENDPOINTS = "service-provider-endpoints"; @@ -102,10 +106,12 @@ public class XmlUtils { public static final String OD_NAME_CONTAINS_ADS = "contains_ads"; public static final String OD_NAME_OBEY_APS = "obey_aps"; public static final String OD_NAME_APS_COMPLIANT = "aps_compliant"; + public static final String OD_NAME_DEVELOPER_ID = "developer_id"; + public static final String OD_NAME_APPLICATION_ID = "application_id"; public static final String OD_NAME_ADS_FINGERPRINTING = "ads_fingerprinting"; public static final String OD_NAME_SECURITY_FINGERPRINTING = "security_fingerprinting"; public static final String OD_NAME_PRIVACY_POLICY = "privacy_policy"; - public static final String OD_NAME_SECURITY_ENDPOINT = "security_endpoints"; + public static final String OD_NAME_SECURITY_ENDPOINTS = "security_endpoints"; public static final String OD_NAME_FIRST_PARTY_ENDPOINTS = "first_party_endpoints"; public static final String OD_NAME_SERVICE_PROVIDER_ENDPOINTS = "service_provider_endpoints"; public static final String OD_NAME_CATEGORY = "category"; @@ -140,6 +146,15 @@ public class XmlUtils { /** * Gets the single {@link Element} within {@param parentEle} and having the {@param tagName}. */ + public static Element getSingleChildElement( + Node parentEle, String tagName, Set<String> requiredStrings) + throws MalformedXmlException { + return getSingleChildElement(parentEle, tagName, requiredStrings.contains(tagName)); + } + + /** + * Gets the single {@link Element} within {@param parentEle} and having the {@param tagName}. + */ public static Element getSingleChildElement(Node parentEle, String tagName, boolean required) throws MalformedXmlException { String parentTagNameForErrorMsg = @@ -287,19 +302,36 @@ public class XmlUtils { } /** Gets a pipeline-split attribute. */ + public static List<String> getPipelineSplitAttr( + Element ele, String attrName, Set<String> requiredNames) throws MalformedXmlException { + return getPipelineSplitAttr(ele, attrName, requiredNames.contains(attrName)); + } + + /** Gets a pipeline-split attribute. */ public static List<String> getPipelineSplitAttr(Element ele, String attrName, boolean required) throws MalformedXmlException { List<String> list = Arrays.stream(ele.getAttribute(attrName).split("\\|")).collect(Collectors.toList()); - if ((list.isEmpty() || list.get(0).isEmpty()) && required) { - throw new MalformedXmlException( - String.format( - "Delimited string %s was required but missing, in %s.", - attrName, ele.getTagName())); + if ((list.isEmpty() || list.get(0).isEmpty())) { + if (required) { + throw new MalformedXmlException( + String.format( + "Delimited string %s was required but missing, in %s.", + attrName, ele.getTagName())); + } + return null; } return list; } + /** + * Gets the single {@link Element} within {@param parentEle} and having the {@param tagName}. + */ + public static Boolean getBoolAttr(Element ele, String attrName, Set<String> requiredStrings) + throws MalformedXmlException { + return getBoolAttr(ele, attrName, requiredStrings.contains(attrName)); + } + /** Gets a Boolean attribute. */ public static Boolean getBoolAttr(Element ele, String attrName, boolean required) throws MalformedXmlException { @@ -314,6 +346,12 @@ public class XmlUtils { } /** Gets a Boolean attribute. */ + public static Boolean getOdBoolEle(Element ele, String nameName, Set<String> requiredNames) + throws MalformedXmlException { + return getOdBoolEle(ele, nameName, requiredNames.contains(nameName)); + } + + /** Gets a Boolean attribute. */ public static Boolean getOdBoolEle(Element ele, String nameName, boolean required) throws MalformedXmlException { List<Element> boolEles = @@ -376,6 +414,12 @@ public class XmlUtils { } /** Gets an on-device String attribute. */ + public static String getOdStringEle(Element ele, String nameName, Set<String> requiredNames) + throws MalformedXmlException { + return getOdStringEle(ele, nameName, requiredNames.contains(nameName)); + } + + /** Gets an on-device String attribute. */ public static String getOdStringEle(Element ele, String nameName, boolean required) throws MalformedXmlException { List<Element> eles = @@ -404,6 +448,13 @@ public class XmlUtils { } /** Gets a OD Pbundle Element attribute with the specified name. */ + public static Element getOdPbundleWithName( + Element ele, String nameName, Set<String> requiredStrings) + throws MalformedXmlException { + return getOdPbundleWithName(ele, nameName, requiredStrings.contains(nameName)); + } + + /** Gets a OD Pbundle Element attribute with the specified name. */ public static Element getOdPbundleWithName(Element ele, String nameName, boolean required) throws MalformedXmlException { List<Element> eles = @@ -425,6 +476,14 @@ public class XmlUtils { return eles.get(0); } + /** + * Gets the single {@link Element} within {@param parentEle} and having the {@param tagName}. + */ + public static String getStringAttr(Element ele, String attrName, Set<String> requiredStrings) + throws MalformedXmlException { + return getStringAttr(ele, attrName, requiredStrings.contains(attrName)); + } + /** Gets a required String attribute. */ public static String getStringAttr(Element ele, String attrName) throws MalformedXmlException { return getStringAttr(ele, attrName, true); @@ -476,6 +535,13 @@ public class XmlUtils { /** Gets human-readable style String array. */ public static List<String> getHrItemsAsStrings( + Element parent, String elementName, Set<String> requiredNames) + throws MalformedXmlException { + return getHrItemsAsStrings(parent, elementName, requiredNames.contains(elementName)); + } + + /** Gets human-readable style String array. */ + public static List<String> getHrItemsAsStrings( Element parent, String elementName, boolean required) throws MalformedXmlException { List<Element> arrayEles = XmlUtils.getChildrenByTagName(parent, elementName); @@ -501,6 +567,12 @@ public class XmlUtils { } /** Gets on-device style String array. */ + public static List<String> getOdStringArray( + Element ele, String nameName, Set<String> requiredNames) throws MalformedXmlException { + return getOdStringArray(ele, nameName, requiredNames.contains(nameName)); + } + + /** Gets on-device style String array. */ public static List<String> getOdStringArray(Element ele, String nameName, boolean required) throws MalformedXmlException { List<Element> arrayEles = @@ -530,6 +602,73 @@ public class XmlUtils { return strs; } + /** Throws if extraneous child elements detected */ + public static void throwIfExtraneousChildrenHr(Element ele, Set<String> expectedChildNames) + throws MalformedXmlException { + var childEles = XmlUtils.asElementList(ele.getChildNodes()); + List<Element> extraneousEles = + childEles.stream() + .filter(e -> !expectedChildNames.contains(e.getTagName())) + .collect(Collectors.toList()); + if (!extraneousEles.isEmpty()) { + throw new MalformedXmlException( + String.format( + "Unexpected element(s) %s in %s.", + extraneousEles.stream() + .map(Element::getTagName) + .collect(Collectors.joining(",")), + ele.getTagName())); + } + } + + /** Throws if extraneous child elements detected */ + public static void throwIfExtraneousChildrenOd(Element ele, Set<String> expectedChildNames) + throws MalformedXmlException { + var allChildElements = XmlUtils.asElementList(ele.getChildNodes()); + List<Element> extraneousEles = + allChildElements.stream() + .filter( + e -> + !e.getAttribute(XmlUtils.OD_ATTR_NAME).isEmpty() + && !expectedChildNames.contains( + e.getAttribute(XmlUtils.OD_ATTR_NAME))) + .collect(Collectors.toList()); + if (!extraneousEles.isEmpty()) { + throw new MalformedXmlException( + String.format( + "Unexpected element(s) in %s: %s", + ele.getTagName(), + extraneousEles.stream() + .map( + e -> + String.format( + "%s name=%s", + e.getTagName(), + e.getAttribute(XmlUtils.OD_ATTR_NAME))) + .collect(Collectors.joining(",")))); + } + } + + /** Throws if extraneous attributes detected */ + public static void throwIfExtraneousAttributes(Element ele, Set<String> expectedAttrNames) + throws MalformedXmlException { + var attrs = ele.getAttributes(); + List<String> attrNames = new ArrayList<>(); + for (int i = 0; i < attrs.getLength(); i++) { + attrNames.add(attrs.item(i).getNodeName()); + } + List<String> extraneousAttrs = + attrNames.stream() + .filter(s -> !expectedAttrNames.contains(s)) + .collect(Collectors.toList()); + if (!extraneousAttrs.isEmpty()) { + throw new MalformedXmlException( + String.format( + "Unexpected attr(s) %s in %s.", + String.join(",", extraneousAttrs), ele.getTagName())); + } + } + /** * Utility method for making a List from one element, to support easier refactoring if needed. * For example, List.of() doesn't support null elements. @@ -537,4 +676,26 @@ public class XmlUtils { public static List<Element> listOf(Element e) { return Arrays.asList(e); } + + /** + * Gets the most recent version of fields in the mapping. This way when a new version is + * released, we only need to update the mappings that were modified. The rest will fall back to + * the most recent previous version. + */ + public static Set<String> getMostRecentVersion( + Map<Long, Set<String>> versionToFieldsMapping, long version) + throws MalformedXmlException { + long bestVersion = 0; + Set<String> bestSet = null; + for (Map.Entry<Long, Set<String>> entry : versionToFieldsMapping.entrySet()) { + if (entry.getKey() > bestVersion && entry.getKey() <= version) { + bestVersion = entry.getKey(); + bestSet = entry.getValue(); + } + } + if (bestSet == null) { + throw new MalformedXmlException("Unexpected version: " + version); + } + return bestSet; + } } diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/AslgenTests.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/AslgenTests.java index 5d1d45a9a29b..262f76d52c90 100644 --- a/tools/app_metadata_bundles/src/test/java/com/android/asllib/AslgenTests.java +++ b/tools/app_metadata_bundles/src/test/java/com/android/asllib/AslgenTests.java @@ -41,6 +41,18 @@ public class AslgenTests { /** Logic for setting up tests (empty if not yet needed). */ public static void main(String[] params) throws Exception {} + @Test + public void testValidOd() throws Exception { + System.out.println("start testing valid od."); + Path odPath = Paths.get(VALID_MAPPINGS_PATH, "general-v1", OD_XML_FILENAME); + InputStream odStream = getClass().getClassLoader().getResourceAsStream(odPath.toString()); + String odContents = + TestUtils.getFormattedXml( + new String(odStream.readAllBytes(), StandardCharsets.UTF_8), false); + AndroidSafetyLabel unusedAsl = + AslConverter.readFromString(odContents, AslConverter.Format.ON_DEVICE); + } + /** Tests valid mappings between HR and OD. */ @Test public void testValidMappings() throws Exception { diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/AndroidSafetyLabelTest.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/AndroidSafetyLabelTest.java index 61a78232801c..283ccbc44791 100644 --- a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/AndroidSafetyLabelTest.java +++ b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/AndroidSafetyLabelTest.java @@ -16,12 +16,18 @@ package com.android.asllib.marshallable; +import static org.junit.Assert.assertThrows; + import com.android.asllib.testutils.TestUtils; +import com.android.asllib.util.MalformedXmlException; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; +import org.w3c.dom.Element; + +import java.nio.file.Paths; @RunWith(JUnit4.class) public class AndroidSafetyLabelTest { @@ -66,47 +72,49 @@ public class AndroidSafetyLabelTest { testOdToHrAndroidSafetyLabel(WITH_SAFETY_LABELS_FILE_NAME); } - /** Test for android safety label with system app safety label. */ - @Test - public void testAndroidSafetyLabelWithSystemAppSafetyLabel() throws Exception { - System.out.println("starting testAndroidSafetyLabelWithSystemAppSafetyLabel."); - testHrToOdAndroidSafetyLabel(WITH_SYSTEM_APP_SAFETY_LABEL_FILE_NAME); - testOdToHrAndroidSafetyLabel(WITH_SYSTEM_APP_SAFETY_LABEL_FILE_NAME); - } - - /** Test for android safety label with transparency info. */ - @Test - public void testAndroidSafetyLabelWithTransparencyInfo() throws Exception { - System.out.println("starting testAndroidSafetyLabelWithTransparencyInfo."); - testHrToOdAndroidSafetyLabel(WITH_TRANSPARENCY_INFO_FILE_NAME); - testOdToHrAndroidSafetyLabel(WITH_TRANSPARENCY_INFO_FILE_NAME); - } - private void hrToOdExpectException(String fileName) { - TestUtils.hrToOdExpectException( - new AndroidSafetyLabelFactory(), ANDROID_SAFETY_LABEL_HR_PATH, fileName); + assertThrows( + MalformedXmlException.class, + () -> { + new AndroidSafetyLabelFactory() + .createFromHrElement( + TestUtils.getElementFromResource( + Paths.get(ANDROID_SAFETY_LABEL_HR_PATH, fileName))); + }); } private void odToHrExpectException(String fileName) { - TestUtils.odToHrExpectException( - new AndroidSafetyLabelFactory(), ANDROID_SAFETY_LABEL_OD_PATH, fileName); + assertThrows( + MalformedXmlException.class, + () -> { + new AndroidSafetyLabelFactory() + .createFromOdElement( + TestUtils.getElementFromResource( + Paths.get(ANDROID_SAFETY_LABEL_OD_PATH, fileName))); + }); } private void testHrToOdAndroidSafetyLabel(String fileName) throws Exception { - TestUtils.testHrToOd( - TestUtils.document(), - new AndroidSafetyLabelFactory(), - ANDROID_SAFETY_LABEL_HR_PATH, - ANDROID_SAFETY_LABEL_OD_PATH, - fileName); + var doc = TestUtils.document(); + AndroidSafetyLabel asl = + new AndroidSafetyLabelFactory() + .createFromHrElement( + TestUtils.getElementFromResource( + Paths.get(ANDROID_SAFETY_LABEL_HR_PATH, fileName))); + Element aslEle = asl.toOdDomElement(doc); + doc.appendChild(aslEle); + TestUtils.testFormatToFormat(doc, Paths.get(ANDROID_SAFETY_LABEL_OD_PATH, fileName)); } private void testOdToHrAndroidSafetyLabel(String fileName) throws Exception { - TestUtils.testOdToHr( - TestUtils.document(), - new AndroidSafetyLabelFactory(), - ANDROID_SAFETY_LABEL_OD_PATH, - ANDROID_SAFETY_LABEL_HR_PATH, - fileName); + var doc = TestUtils.document(); + AndroidSafetyLabel asl = + new AndroidSafetyLabelFactory() + .createFromOdElement( + TestUtils.getElementFromResource( + Paths.get(ANDROID_SAFETY_LABEL_OD_PATH, fileName))); + Element aslEle = asl.toHrDomElement(doc); + doc.appendChild(aslEle); + TestUtils.testFormatToFormat(doc, Paths.get(ANDROID_SAFETY_LABEL_HR_PATH, fileName)); } } diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/AppInfoTest.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/AppInfoTest.java index d823c482adfe..7806061f00bb 100644 --- a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/AppInfoTest.java +++ b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/AppInfoTest.java @@ -26,12 +26,14 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; +import org.w3c.dom.Element; import java.nio.file.Paths; import java.util.List; @RunWith(JUnit4.class) public class AppInfoTest { + private static final long DEFAULT_VERSION = 2L; private static final String APP_INFO_HR_PATH = "com/android/asllib/appinfo/hr"; private static final String APP_INFO_OD_PATH = "com/android/asllib/appinfo/od"; public static final List<String> REQUIRED_FIELD_NAMES = @@ -45,7 +47,24 @@ public class AppInfoTest { public static final List<String> OPTIONAL_FIELD_NAMES = List.of(); public static final List<String> OPTIONAL_FIELD_NAMES_OD = List.of(); + public static final List<String> REQUIRED_FIELD_NAMES_OD_V1 = + List.of( + "title", + "description", + "contains_ads", + "obey_aps", + "ads_fingerprinting", + "security_fingerprinting", + "privacy_policy", + "security_endpoints", + "first_party_endpoints", + "service_provider_endpoints", + "category"); + public static final List<String> OPTIONAL_FIELD_NAMES_OD_V1 = List.of("website", "email"); + private static final String ALL_FIELDS_VALID_FILE_NAME = "all-fields-valid.xml"; + private static final String ALL_FIELDS_VALID_V1_FILE_NAME = "all-fields-valid-v1.xml"; + public static final String UNRECOGNIZED_V1_FILE_NAME = "unrecognized-v1.xml"; /** Logic for setting up tests (empty if not yet needed). */ public static void main(String[] params) throws Exception {} @@ -63,6 +82,61 @@ public class AppInfoTest { testOdToHrAppInfo(ALL_FIELDS_VALID_FILE_NAME); } + /** Test for all fields valid v1. */ + @Test + public void testAllFieldsValidV1() throws Exception { + System.out.println("starting testAllFieldsValidV1."); + new AppInfoFactory() + .createFromOdElement( + TestUtils.getElementFromResource( + Paths.get(APP_INFO_OD_PATH, ALL_FIELDS_VALID_V1_FILE_NAME)), + 1L); + } + + /** Test for unrecognized field v1. */ + @Test + public void testUnrecognizedFieldV1() throws Exception { + System.out.println("starting testUnrecognizedFieldV1."); + assertThrows( + MalformedXmlException.class, + () -> + new AppInfoFactory() + .createFromOdElement( + TestUtils.getElementFromResource( + Paths.get( + APP_INFO_OD_PATH, + UNRECOGNIZED_V1_FILE_NAME)), + 1L)); + } + + /** Tests missing required fields fails, V1. */ + @Test + public void testMissingRequiredFieldsOdV1() throws Exception { + for (String reqField : REQUIRED_FIELD_NAMES_OD_V1) { + System.out.println("testing missing required field od v1: " + reqField); + var appInfoEle = + TestUtils.getElementFromResource( + Paths.get(APP_INFO_OD_PATH, ALL_FIELDS_VALID_V1_FILE_NAME)); + TestUtils.removeOdChildEleWithName(appInfoEle, reqField); + assertThrows( + MalformedXmlException.class, + () -> new AppInfoFactory().createFromOdElement(appInfoEle, 1L)); + } + } + + /** Tests missing optional fields passes, V1. */ + @Test + public void testMissingOptionalFieldsOdV1() throws Exception { + for (String optField : OPTIONAL_FIELD_NAMES_OD_V1) { + System.out.println("testing missing optional field od v1: " + optField); + var appInfoEle = + TestUtils.getElementFromResource( + Paths.get(APP_INFO_OD_PATH, ALL_FIELDS_VALID_V1_FILE_NAME)); + TestUtils.removeOdChildEleWithName(appInfoEle, optField); + new AppInfoFactory().createFromOdElement(appInfoEle, 1L); + } + } + /** Tests missing required fields fails. */ @Test public void testMissingRequiredFields() throws Exception { @@ -70,24 +144,24 @@ public class AppInfoTest { for (String reqField : REQUIRED_FIELD_NAMES) { System.out.println("testing missing required field hr: " + reqField); var appInfoEle = - TestUtils.getElementsFromResource( + TestUtils.getElementFromResource( Paths.get(APP_INFO_HR_PATH, ALL_FIELDS_VALID_FILE_NAME)); - appInfoEle.get(0).removeAttribute(reqField); + appInfoEle.removeAttribute(reqField); assertThrows( MalformedXmlException.class, - () -> new AppInfoFactory().createFromHrElements(appInfoEle)); + () -> new AppInfoFactory().createFromHrElement(appInfoEle, DEFAULT_VERSION)); } for (String reqField : REQUIRED_FIELD_NAMES_OD) { System.out.println("testing missing required field od: " + reqField); var appInfoEle = - TestUtils.getElementsFromResource( + TestUtils.getElementFromResource( Paths.get(APP_INFO_OD_PATH, ALL_FIELDS_VALID_FILE_NAME)); - TestUtils.removeOdChildEleWithName(appInfoEle.get(0), reqField); + TestUtils.removeOdChildEleWithName(appInfoEle, reqField); assertThrows( MalformedXmlException.class, - () -> new AppInfoFactory().createFromOdElements(appInfoEle)); + () -> new AppInfoFactory().createFromOdElement(appInfoEle, DEFAULT_VERSION)); } } @@ -98,24 +172,24 @@ public class AppInfoTest { for (String reqChildName : REQUIRED_CHILD_NAMES) { System.out.println("testing missing required child hr: " + reqChildName); var appInfoEle = - TestUtils.getElementsFromResource( + TestUtils.getElementFromResource( Paths.get(APP_INFO_HR_PATH, ALL_FIELDS_VALID_FILE_NAME)); - var child = XmlUtils.getChildrenByTagName(appInfoEle.get(0), reqChildName).get(0); - appInfoEle.get(0).removeChild(child); + var child = XmlUtils.getChildrenByTagName(appInfoEle, reqChildName).get(0); + appInfoEle.removeChild(child); assertThrows( MalformedXmlException.class, - () -> new AppInfoFactory().createFromHrElements(appInfoEle)); + () -> new AppInfoFactory().createFromHrElement(appInfoEle, DEFAULT_VERSION)); } for (String reqField : REQUIRED_CHILD_NAMES_OD) { System.out.println("testing missing required child od: " + reqField); var appInfoEle = - TestUtils.getElementsFromResource( + TestUtils.getElementFromResource( Paths.get(APP_INFO_OD_PATH, ALL_FIELDS_VALID_FILE_NAME)); - TestUtils.removeOdChildEleWithName(appInfoEle.get(0), reqField); + TestUtils.removeOdChildEleWithName(appInfoEle, reqField); assertThrows( MalformedXmlException.class, - () -> new AppInfoFactory().createFromOdElements(appInfoEle)); + () -> new AppInfoFactory().createFromOdElement(appInfoEle, DEFAULT_VERSION)); } } @@ -124,38 +198,51 @@ public class AppInfoTest { public void testMissingOptionalFields() throws Exception { for (String optField : OPTIONAL_FIELD_NAMES) { var ele = - TestUtils.getElementsFromResource( + TestUtils.getElementFromResource( Paths.get(APP_INFO_HR_PATH, ALL_FIELDS_VALID_FILE_NAME)); - ele.get(0).removeAttribute(optField); - AppInfo appInfo = new AppInfoFactory().createFromHrElements(ele); - appInfo.toOdDomElements(TestUtils.document()); + ele.removeAttribute(optField); + AppInfo appInfo = new AppInfoFactory().createFromHrElement(ele, DEFAULT_VERSION); + appInfo.toOdDomElement(TestUtils.document()); } for (String optField : OPTIONAL_FIELD_NAMES_OD) { var ele = - TestUtils.getElementsFromResource( + TestUtils.getElementFromResource( Paths.get(APP_INFO_OD_PATH, ALL_FIELDS_VALID_FILE_NAME)); - TestUtils.removeOdChildEleWithName(ele.get(0), optField); - AppInfo appInfo = new AppInfoFactory().createFromOdElements(ele); - appInfo.toHrDomElements(TestUtils.document()); + TestUtils.removeOdChildEleWithName(ele, optField); + AppInfo appInfo = new AppInfoFactory().createFromOdElement(ele, DEFAULT_VERSION); + appInfo.toHrDomElement(TestUtils.document()); } } private void testHrToOdAppInfo(String fileName) throws Exception { - TestUtils.testHrToOd( - TestUtils.document(), - new AppInfoFactory(), - APP_INFO_HR_PATH, - APP_INFO_OD_PATH, - fileName); + var doc = TestUtils.document(); + AppInfo appInfo = + new AppInfoFactory() + .createFromHrElement( + TestUtils.getElementFromResource( + Paths.get(APP_INFO_HR_PATH, fileName)), + DEFAULT_VERSION); + Element appInfoEle = appInfo.toOdDomElement(doc); + doc.appendChild(appInfoEle); + TestUtils.testFormatToFormat(doc, Paths.get(APP_INFO_OD_PATH, fileName)); } + private void testOdToHrAppInfo(String fileName) throws Exception { - TestUtils.testOdToHr( - TestUtils.document(), - new AppInfoFactory(), - APP_INFO_OD_PATH, - APP_INFO_HR_PATH, - fileName); + testOdToHrAppInfo(fileName, DEFAULT_VERSION); + } + + private void testOdToHrAppInfo(String fileName, long version) throws Exception { + var doc = TestUtils.document(); + AppInfo appInfo = + new AppInfoFactory() + .createFromOdElement( + TestUtils.getElementFromResource( + Paths.get(APP_INFO_OD_PATH, fileName)), + version); + Element appInfoEle = appInfo.toHrDomElement(doc); + doc.appendChild(appInfoEle); + TestUtils.testFormatToFormat(doc, Paths.get(APP_INFO_HR_PATH, fileName)); } } diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/DataLabelsTest.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/DataLabelsTest.java index ff4374166dd3..b557fea9572b 100644 --- a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/DataLabelsTest.java +++ b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/DataLabelsTest.java @@ -16,15 +16,27 @@ package com.android.asllib.marshallable; +import static org.junit.Assert.assertThrows; + import com.android.asllib.testutils.TestUtils; +import com.android.asllib.util.MalformedXmlException; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; +import org.w3c.dom.Element; +import org.xml.sax.SAXException; + +import java.io.IOException; +import java.nio.file.Paths; + +import javax.xml.parsers.ParserConfigurationException; @RunWith(JUnit4.class) public class DataLabelsTest { + private static final long DEFAULT_VERSION = 2L; + private static final String DATA_LABELS_HR_PATH = "com/android/asllib/datalabels/hr"; private static final String DATA_LABELS_OD_PATH = "com/android/asllib/datalabels/od"; @@ -297,29 +309,43 @@ public class DataLabelsTest { odToHrExpectException(PERSONAL_EMPTY_PURPOSE_FILE_NAME); } - private void hrToOdExpectException(String fileName) { - TestUtils.hrToOdExpectException(new DataLabelsFactory(), DATA_LABELS_HR_PATH, fileName); + private void hrToOdExpectException(String fileName) + throws ParserConfigurationException, IOException, SAXException { + var ele = TestUtils.getElementFromResource(Paths.get(DATA_LABELS_HR_PATH, fileName)); + assertThrows( + MalformedXmlException.class, + () -> new DataLabelsFactory().createFromHrElement(ele)); } - private void odToHrExpectException(String fileName) { - TestUtils.odToHrExpectException(new DataLabelsFactory(), DATA_LABELS_OD_PATH, fileName); + private void odToHrExpectException(String fileName) + throws ParserConfigurationException, IOException, SAXException { + var ele = TestUtils.getElementFromResource(Paths.get(DATA_LABELS_OD_PATH, fileName)); + assertThrows( + MalformedXmlException.class, + () -> new DataLabelsFactory().createFromOdElement(ele)); } private void testHrToOdDataLabels(String fileName) throws Exception { - TestUtils.testHrToOd( - TestUtils.document(), - new DataLabelsFactory(), - DATA_LABELS_HR_PATH, - DATA_LABELS_OD_PATH, - fileName); + var doc = TestUtils.document(); + DataLabels dataLabels = + new DataLabelsFactory() + .createFromHrElement( + TestUtils.getElementFromResource( + Paths.get(DATA_LABELS_HR_PATH, fileName))); + Element resultingEle = dataLabels.toOdDomElement(doc); + doc.appendChild(resultingEle); + TestUtils.testFormatToFormat(doc, Paths.get(DATA_LABELS_OD_PATH, fileName)); } private void testOdToHrDataLabels(String fileName) throws Exception { - TestUtils.testOdToHr( - TestUtils.document(), - new DataLabelsFactory(), - DATA_LABELS_OD_PATH, - DATA_LABELS_HR_PATH, - fileName); + var doc = TestUtils.document(); + DataLabels dataLabels = + new DataLabelsFactory() + .createFromOdElement( + TestUtils.getElementFromResource( + Paths.get(DATA_LABELS_OD_PATH, fileName))); + Element resultingEle = dataLabels.toHrDomElement(doc); + doc.appendChild(resultingEle); + TestUtils.testFormatToFormat(doc, Paths.get(DATA_LABELS_HR_PATH, fileName)); } } diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/SafetyLabelsTest.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/SafetyLabelsTest.java index 19d1626f7054..7cd510f0ddfc 100644 --- a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/SafetyLabelsTest.java +++ b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/SafetyLabelsTest.java @@ -16,15 +16,27 @@ package com.android.asllib.marshallable; +import static org.junit.Assert.assertThrows; + import com.android.asllib.testutils.TestUtils; +import com.android.asllib.util.MalformedXmlException; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; +import org.w3c.dom.Element; +import org.xml.sax.SAXException; + +import java.io.IOException; +import java.nio.file.Paths; + +import javax.xml.parsers.ParserConfigurationException; @RunWith(JUnit4.class) public class SafetyLabelsTest { + private static final long DEFAULT_VERSION = 2L; + private static final String SAFETY_LABELS_HR_PATH = "com/android/asllib/safetylabels/hr"; private static final String SAFETY_LABELS_OD_PATH = "com/android/asllib/safetylabels/od"; @@ -52,29 +64,51 @@ public class SafetyLabelsTest { testOdToHrSafetyLabels(WITH_DATA_LABELS_FILE_NAME); } - private void hrToOdExpectException(String fileName) { - TestUtils.hrToOdExpectException(new SafetyLabelsFactory(), SAFETY_LABELS_HR_PATH, fileName); + private void hrToOdExpectException(String fileName) + throws ParserConfigurationException, IOException, SAXException { + var safetyLabelsEle = + TestUtils.getElementFromResource(Paths.get(SAFETY_LABELS_HR_PATH, fileName)); + assertThrows( + MalformedXmlException.class, + () -> + new SafetyLabelsFactory() + .createFromHrElement(safetyLabelsEle, DEFAULT_VERSION)); } - private void odToHrExpectException(String fileName) { - TestUtils.odToHrExpectException(new SafetyLabelsFactory(), SAFETY_LABELS_OD_PATH, fileName); + private void odToHrExpectException(String fileName) + throws ParserConfigurationException, IOException, SAXException { + var safetyLabelsEle = + TestUtils.getElementFromResource(Paths.get(SAFETY_LABELS_OD_PATH, fileName)); + assertThrows( + MalformedXmlException.class, + () -> + new SafetyLabelsFactory() + .createFromOdElement(safetyLabelsEle, DEFAULT_VERSION)); } private void testHrToOdSafetyLabels(String fileName) throws Exception { - TestUtils.testHrToOd( - TestUtils.document(), - new SafetyLabelsFactory(), - SAFETY_LABELS_HR_PATH, - SAFETY_LABELS_OD_PATH, - fileName); + var doc = TestUtils.document(); + SafetyLabels safetyLabels = + new SafetyLabelsFactory() + .createFromHrElement( + TestUtils.getElementFromResource( + Paths.get(SAFETY_LABELS_HR_PATH, fileName)), + DEFAULT_VERSION); + Element appInfoEle = safetyLabels.toOdDomElement(doc); + doc.appendChild(appInfoEle); + TestUtils.testFormatToFormat(doc, Paths.get(SAFETY_LABELS_OD_PATH, fileName)); } private void testOdToHrSafetyLabels(String fileName) throws Exception { - TestUtils.testOdToHr( - TestUtils.document(), - new SafetyLabelsFactory(), - SAFETY_LABELS_OD_PATH, - SAFETY_LABELS_HR_PATH, - fileName); + var doc = TestUtils.document(); + SafetyLabels safetyLabels = + new SafetyLabelsFactory() + .createFromOdElement( + TestUtils.getElementFromResource( + Paths.get(SAFETY_LABELS_OD_PATH, fileName)), + DEFAULT_VERSION); + Element appInfoEle = safetyLabels.toHrDomElement(doc); + doc.appendChild(appInfoEle); + TestUtils.testFormatToFormat(doc, Paths.get(SAFETY_LABELS_HR_PATH, fileName)); } } diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/SystemAppSafetyLabelTest.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/SystemAppSafetyLabelTest.java index 87d3e4499f5c..9dcc6529969e 100644 --- a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/SystemAppSafetyLabelTest.java +++ b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/SystemAppSafetyLabelTest.java @@ -16,15 +16,27 @@ package com.android.asllib.marshallable; +import static org.junit.Assert.assertThrows; + import com.android.asllib.testutils.TestUtils; +import com.android.asllib.util.MalformedXmlException; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; +import org.w3c.dom.Element; +import org.xml.sax.SAXException; + +import java.io.IOException; +import java.nio.file.Paths; + +import javax.xml.parsers.ParserConfigurationException; @RunWith(JUnit4.class) public class SystemAppSafetyLabelTest { + private static final long DEFAULT_VERSION = 2L; + private static final String SYSTEM_APP_SAFETY_LABEL_HR_PATH = "com/android/asllib/systemappsafetylabel/hr"; private static final String SYSTEM_APP_SAFETY_LABEL_OD_PATH = @@ -57,31 +69,49 @@ public class SystemAppSafetyLabelTest { odToHrExpectException(MISSING_BOOL_FILE_NAME); } - private void hrToOdExpectException(String fileName) { - TestUtils.hrToOdExpectException( - new SystemAppSafetyLabelFactory(), SYSTEM_APP_SAFETY_LABEL_HR_PATH, fileName); + private void hrToOdExpectException(String fileName) + throws ParserConfigurationException, IOException, SAXException { + var ele = + TestUtils.getElementFromResource( + Paths.get(SYSTEM_APP_SAFETY_LABEL_HR_PATH, fileName)); + assertThrows( + MalformedXmlException.class, + () -> new SystemAppSafetyLabelFactory().createFromHrElement(ele, DEFAULT_VERSION)); } - private void odToHrExpectException(String fileName) { - TestUtils.odToHrExpectException( - new SystemAppSafetyLabelFactory(), SYSTEM_APP_SAFETY_LABEL_OD_PATH, fileName); + private void odToHrExpectException(String fileName) + throws ParserConfigurationException, IOException, SAXException { + var ele = + TestUtils.getElementFromResource( + Paths.get(SYSTEM_APP_SAFETY_LABEL_OD_PATH, fileName)); + assertThrows( + MalformedXmlException.class, + () -> new SystemAppSafetyLabelFactory().createFromOdElement(ele, DEFAULT_VERSION)); } private void testHrToOdSystemAppSafetyLabel(String fileName) throws Exception { - TestUtils.testHrToOd( - TestUtils.document(), - new SystemAppSafetyLabelFactory(), - SYSTEM_APP_SAFETY_LABEL_HR_PATH, - SYSTEM_APP_SAFETY_LABEL_OD_PATH, - fileName); + var doc = TestUtils.document(); + SystemAppSafetyLabel systemAppSafetyLabel = + new SystemAppSafetyLabelFactory() + .createFromHrElement( + TestUtils.getElementFromResource( + Paths.get(SYSTEM_APP_SAFETY_LABEL_HR_PATH, fileName)), + DEFAULT_VERSION); + Element resultingEle = systemAppSafetyLabel.toOdDomElement(doc); + doc.appendChild(resultingEle); + TestUtils.testFormatToFormat(doc, Paths.get(SYSTEM_APP_SAFETY_LABEL_OD_PATH, fileName)); } private void testOdToHrSystemAppSafetyLabel(String fileName) throws Exception { - TestUtils.testOdToHr( - TestUtils.document(), - new SystemAppSafetyLabelFactory(), - SYSTEM_APP_SAFETY_LABEL_OD_PATH, - SYSTEM_APP_SAFETY_LABEL_HR_PATH, - fileName); + var doc = TestUtils.document(); + SystemAppSafetyLabel systemAppSafetyLabel = + new SystemAppSafetyLabelFactory() + .createFromOdElement( + TestUtils.getElementFromResource( + Paths.get(SYSTEM_APP_SAFETY_LABEL_OD_PATH, fileName)), + DEFAULT_VERSION); + Element resultingEle = systemAppSafetyLabel.toHrDomElement(doc); + doc.appendChild(resultingEle); + TestUtils.testFormatToFormat(doc, Paths.get(SYSTEM_APP_SAFETY_LABEL_HR_PATH, fileName)); } } diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/TransparencyInfoTest.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/TransparencyInfoTest.java index 8a0b35eac7c8..6547fb952944 100644 --- a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/TransparencyInfoTest.java +++ b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/TransparencyInfoTest.java @@ -22,9 +22,14 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; +import org.w3c.dom.Element; + +import java.nio.file.Paths; @RunWith(JUnit4.class) public class TransparencyInfoTest { + private static final long DEFAULT_VERSION = 2L; + private static final String TRANSPARENCY_INFO_HR_PATH = "com/android/asllib/transparencyinfo/hr"; private static final String TRANSPARENCY_INFO_OD_PATH = @@ -45,20 +50,28 @@ public class TransparencyInfoTest { } private void testHrToOdTransparencyInfo(String fileName) throws Exception { - TestUtils.testHrToOd( - TestUtils.document(), - new TransparencyInfoFactory(), - TRANSPARENCY_INFO_HR_PATH, - TRANSPARENCY_INFO_OD_PATH, - fileName); + var doc = TestUtils.document(); + TransparencyInfo transparencyInfo = + new TransparencyInfoFactory() + .createFromHrElement( + TestUtils.getElementFromResource( + Paths.get(TRANSPARENCY_INFO_HR_PATH, fileName)), + DEFAULT_VERSION); + Element resultingEle = transparencyInfo.toOdDomElement(doc); + doc.appendChild(resultingEle); + TestUtils.testFormatToFormat(doc, Paths.get(TRANSPARENCY_INFO_OD_PATH, fileName)); } private void testOdToHrTransparencyInfo(String fileName) throws Exception { - TestUtils.testOdToHr( - TestUtils.document(), - new TransparencyInfoFactory(), - TRANSPARENCY_INFO_OD_PATH, - TRANSPARENCY_INFO_HR_PATH, - fileName); + var doc = TestUtils.document(); + TransparencyInfo transparencyInfo = + new TransparencyInfoFactory() + .createFromOdElement( + TestUtils.getElementFromResource( + Paths.get(TRANSPARENCY_INFO_OD_PATH, fileName)), + DEFAULT_VERSION); + Element resultingEle = transparencyInfo.toHrDomElement(doc); + doc.appendChild(resultingEle); + TestUtils.testFormatToFormat(doc, Paths.get(TRANSPARENCY_INFO_HR_PATH, fileName)); } } diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/testutils/TestUtils.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/testutils/TestUtils.java index ea90993e0785..f8ef40a9c509 100644 --- a/tools/app_metadata_bundles/src/test/java/com/android/asllib/testutils/TestUtils.java +++ b/tools/app_metadata_bundles/src/test/java/com/android/asllib/testutils/TestUtils.java @@ -17,11 +17,8 @@ package com.android.asllib.testutils; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThrows; import com.android.asllib.marshallable.AslMarshallable; -import com.android.asllib.marshallable.AslMarshallableFactory; -import com.android.asllib.util.MalformedXmlException; import com.android.asllib.util.XmlUtils; import org.w3c.dom.Document; @@ -36,7 +33,6 @@ import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.List; import java.util.Optional; @@ -60,7 +56,19 @@ public class TestUtils { } /** Gets List of Element from a path to an existing Resource. */ - public static List<Element> getElementsFromResource(Path filePath) + public static Element getElementFromResource(Path filePath) + throws ParserConfigurationException, IOException, SAXException { + String str = readStrFromResource(filePath); + InputStream stream = new ByteArrayInputStream(str.getBytes(StandardCharsets.UTF_8)); + + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); + Document document = factory.newDocumentBuilder().parse(stream); + return document.getDocumentElement(); + } + + /** Gets List of Element from a path to an existing Resource. */ + public static List<Element> getChildElementsFromResource(Path filePath) throws ParserConfigurationException, IOException, SAXException { String str = readStrFromResource(filePath); InputStream stream = new ByteArrayInputStream(str.getBytes(StandardCharsets.UTF_8)); @@ -69,16 +77,13 @@ public class TestUtils { factory.setNamespaceAware(true); Document document = factory.newDocumentBuilder().parse(stream); Element root = document.getDocumentElement(); - if (root.getTagName().equals(HOLDER_TAG_NAME)) { - String tagName = - XmlUtils.asElementList(root.getChildNodes()).stream() - .findFirst() - .get() - .getTagName(); - return XmlUtils.getChildrenByTagName(root, tagName); - } else { - return List.of(root); - } + + String tagName = + XmlUtils.asElementList(root.getChildNodes()).stream() + .findFirst() + .get() + .getTagName(); + return XmlUtils.getChildrenByTagName(root, tagName); } /** Reads a Document into a String. */ @@ -130,86 +135,13 @@ public class TestUtils { return DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); } - /** Helper for testing human-readable to on-device conversion expecting exception */ - public static <T extends AslMarshallable> void hrToOdExpectException( - AslMarshallableFactory<T> factory, String hrFolderPath, String fileName) { - assertThrows( - MalformedXmlException.class, - () -> { - factory.createFromHrElements( - TestUtils.getElementsFromResource(Paths.get(hrFolderPath, fileName))); - }); - } - - /** Helper for testing on-device to human-readable conversion expecting exception */ - public static <T extends AslMarshallable> void odToHrExpectException( - AslMarshallableFactory<T> factory, String odFolderPath, String fileName) { - assertThrows( - MalformedXmlException.class, - () -> { - factory.createFromOdElements( - TestUtils.getElementsFromResource(Paths.get(odFolderPath, fileName))); - }); - } - - /** Helper for testing human-readable to on-device conversion */ - public static <T extends AslMarshallable> void testHrToOd( - Document doc, - AslMarshallableFactory<T> factory, - String hrFolderPath, - String odFolderPath, - String fileName) - throws Exception { - testFormatToFormat(doc, factory, hrFolderPath, odFolderPath, fileName, true); - } - - /** Helper for testing on-device to human-readable conversion */ - public static <T extends AslMarshallable> void testOdToHr( - Document doc, - AslMarshallableFactory<T> factory, - String odFolderPath, - String hrFolderPath, - String fileName) - throws Exception { - testFormatToFormat(doc, factory, odFolderPath, hrFolderPath, fileName, false); - } - /** Helper for testing format to format conversion */ - private static <T extends AslMarshallable> void testFormatToFormat( - Document doc, - AslMarshallableFactory<T> factory, - String inFolderPath, - String outFolderPath, - String fileName, - boolean hrToOd) - throws Exception { - AslMarshallable marshallable = - hrToOd - ? factory.createFromHrElements( - TestUtils.getElementsFromResource( - Paths.get(inFolderPath, fileName))) - : factory.createFromOdElements( - TestUtils.getElementsFromResource( - Paths.get(inFolderPath, fileName))); - - List<Element> elements = - hrToOd ? marshallable.toOdDomElements(doc) : marshallable.toHrDomElements(doc); - if (elements.isEmpty()) { - throw new IllegalStateException("elements was empty."); - } else if (elements.size() == 1) { - doc.appendChild(elements.get(0)); - } else { - Element root = doc.createElement(TestUtils.HOLDER_TAG_NAME); - for (var child : elements) { - root.appendChild(child); - } - doc.appendChild(root); - } + public static <T extends AslMarshallable> void testFormatToFormat( + Document doc, Path expectedOutPath) throws Exception { String converted = TestUtils.getFormattedXml(TestUtils.docToStr(doc, true), true); System.out.println("Converted: " + converted); String expectedOutContents = - TestUtils.getFormattedXml( - TestUtils.readStrFromResource(Paths.get(outFolderPath, fileName)), true); + TestUtils.getFormattedXml(TestUtils.readStrFromResource(expectedOutPath), true); System.out.println("Expected: " + expectedOutContents); assertEquals(expectedOutContents, converted); } diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/missing-version.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/missing-version.xml index ec0cd702fd43..7478e39ce366 100644 --- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/missing-version.xml +++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/missing-version.xml @@ -1,3 +1,17 @@ <app-metadata-bundles> - + <system-app-safety-label declaration="true"> + </system-app-safety-label> + <transparency-info> + <app-info + apsCompliant="false" + privacyPolicy="www.example.com" developerId="dev1" applicationId="app1"> + <first-party-endpoints> + <item>url1</item> + </first-party-endpoints> + <service-provider-endpoints> + <item>url55</item> + <item>url56</item> + </service-provider-endpoints> + </app-info> + </transparency-info> </app-metadata-bundles>
\ No newline at end of file diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/valid-empty.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/valid-empty.xml index 19bfd826f770..587c49add47e 100644 --- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/valid-empty.xml +++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/valid-empty.xml @@ -1 +1,17 @@ -<app-metadata-bundles version="123456"></app-metadata-bundles>
\ No newline at end of file +<app-metadata-bundles version="2"> + <system-app-safety-label declaration="true"> + </system-app-safety-label> + <transparency-info> + <app-info + apsCompliant="false" + privacyPolicy="www.example.com" developerId="dev1" applicationId="app1"> + <first-party-endpoints> + <item>url1</item> + </first-party-endpoints> + <service-provider-endpoints> + <item>url55</item> + <item>url56</item> + </service-provider-endpoints> + </app-info> + </transparency-info> +</app-metadata-bundles>
\ No newline at end of file diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/with-safety-labels.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/with-safety-labels.xml index 03e71d28f4cc..9cfb8bc4d5da 100644 --- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/with-safety-labels.xml +++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/with-safety-labels.xml @@ -1,4 +1,19 @@ -<app-metadata-bundles version="123456"> +<app-metadata-bundles version="2"> <safety-labels> </safety-labels> + <system-app-safety-label declaration="true"> + </system-app-safety-label> + <transparency-info> + <app-info + apsCompliant="false" + privacyPolicy="www.example.com" developerId="dev1" applicationId="app1"> + <first-party-endpoints> + <item>url1</item> + </first-party-endpoints> + <service-provider-endpoints> + <item>url55</item> + <item>url56</item> + </service-provider-endpoints> + </app-info> + </transparency-info> </app-metadata-bundles>
\ No newline at end of file diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/with-system-app-safety-label.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/with-system-app-safety-label.xml deleted file mode 100644 index afb048632bc6..000000000000 --- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/with-system-app-safety-label.xml +++ /dev/null @@ -1,4 +0,0 @@ -<app-metadata-bundles version="123456"> -<system-app-safety-label declaration="true"> -</system-app-safety-label> -</app-metadata-bundles>
\ No newline at end of file diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/with-transparency-info.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/with-transparency-info.xml deleted file mode 100644 index a00ef6565cf4..000000000000 --- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/with-transparency-info.xml +++ /dev/null @@ -1,15 +0,0 @@ -<app-metadata-bundles version="123456"> - <transparency-info> - <app-info - apsCompliant="false" - privacyPolicy="www.example.com"> - <first-party-endpoints> - <item>url1</item> - </first-party-endpoints> - <service-provider-endpoints> - <item>url55</item> - <item>url56</item> - </service-provider-endpoints> - </app-info> - </transparency-info> -</app-metadata-bundles>
\ No newline at end of file diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/missing-version.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/missing-version.xml index 1aa3aa94ca6d..9adfa98f05a3 100644 --- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/missing-version.xml +++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/missing-version.xml @@ -1,2 +1,20 @@ <bundle> + <pbundle_as_map name="system_app_safety_label"> + <boolean name="declaration" value="true"/> + </pbundle_as_map> + <pbundle_as_map name="transparency_info"> + <pbundle_as_map name="app_info"> + <boolean name="aps_compliant" value="false"/> + <string name="privacy_policy" value="www.example.com"/> + <string-array name="first_party_endpoints" num="1"> + <item value="url1"/> + </string-array> + <string-array name="service_provider_endpoints" num="2"> + <item value="url55"/> + <item value="url56"/> + </string-array> + <string name="developer_id" value="dev1"/> + <string name="application_id" value="app1"/> + </pbundle_as_map> + </pbundle_as_map> </bundle>
\ No newline at end of file diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/valid-empty.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/valid-empty.xml index 37bdfad4065f..7a4c82a9e65f 100644 --- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/valid-empty.xml +++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/valid-empty.xml @@ -1,3 +1,21 @@ <bundle> - <long name="version" value="123456"/> + <long name="version" value="2"/> + <pbundle_as_map name="system_app_safety_label"> + <boolean name="declaration" value="true"/> + </pbundle_as_map> + <pbundle_as_map name="transparency_info"> + <pbundle_as_map name="app_info"> + <string name="privacy_policy" value="www.example.com"/> + <string-array name="first_party_endpoints" num="1"> + <item value="url1"/> + </string-array> + <string-array name="service_provider_endpoints" num="2"> + <item value="url55"/> + <item value="url56"/> + </string-array> + <boolean name="aps_compliant" value="false"/> + <string name="developer_id" value="dev1"/> + <string name="application_id" value="app1"/> + </pbundle_as_map> + </pbundle_as_map> </bundle>
\ No newline at end of file diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/with-safety-labels.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/with-safety-labels.xml index f00fb26bf1ee..3a3e5d383ca9 100644 --- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/with-safety-labels.xml +++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/with-safety-labels.xml @@ -1,5 +1,22 @@ <bundle> - <long name="version" value="123456"/> - <pbundle_as_map name="safety_labels"> + <long name="version" value="2"/> + <pbundle_as_map name="safety_labels"/> + <pbundle_as_map name="system_app_safety_label"> + <boolean name="declaration" value="true"/> </pbundle_as_map> -</bundle> + <pbundle_as_map name="transparency_info"> + <pbundle_as_map name="app_info"> + <string name="privacy_policy" value="www.example.com"/> + <string-array name="first_party_endpoints" num="1"> + <item value="url1"/> + </string-array> + <string-array name="service_provider_endpoints" num="2"> + <item value="url55"/> + <item value="url56"/> + </string-array> + <boolean name="aps_compliant" value="false"/> + <string name="developer_id" value="dev1"/> + <string name="application_id" value="app1"/> + </pbundle_as_map> + </pbundle_as_map> +</bundle>
\ No newline at end of file diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/with-system-app-safety-label.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/with-system-app-safety-label.xml deleted file mode 100644 index e8640c4f0934..000000000000 --- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/with-system-app-safety-label.xml +++ /dev/null @@ -1,6 +0,0 @@ -<bundle> - <long name="version" value="123456"/> - <pbundle_as_map name="system_app_safety_label"> - <boolean name="declaration" value="true"/> - </pbundle_as_map> -</bundle>
\ No newline at end of file diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/with-transparency-info.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/with-transparency-info.xml deleted file mode 100644 index d0c8668564bd..000000000000 --- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/with-transparency-info.xml +++ /dev/null @@ -1,16 +0,0 @@ -<bundle> - <long name="version" value="123456"/> - <pbundle_as_map name="transparency_info"> - <pbundle_as_map name="app_info"> - <boolean name="aps_compliant" value="false"/> - <string name="privacy_policy" value="www.example.com"/> - <string-array name="first_party_endpoints" num="1"> - <item value="url1"/> - </string-array> - <string-array name="service_provider_endpoints" num="2"> - <item value="url55"/> - <item value="url56"/> - </string-array> - </pbundle_as_map> - </pbundle_as_map> -</bundle>
\ No newline at end of file diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/hr/all-fields-valid.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/hr/all-fields-valid.xml index 0d15efc4eac3..306e01533731 100644 --- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/hr/all-fields-valid.xml +++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/hr/all-fields-valid.xml @@ -1,6 +1,6 @@ <app-info apsCompliant="false" - privacyPolicy="www.example.com"> + privacyPolicy="www.example.com" developerId="dev1" applicationId="app1"> <first-party-endpoints> <item>url1</item> </first-party-endpoints> diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/od/all-fields-valid-v1.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/od/all-fields-valid-v1.xml new file mode 100644 index 000000000000..b026cf33e5f0 --- /dev/null +++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/od/all-fields-valid-v1.xml @@ -0,0 +1,24 @@ +<pbundle_as_map name="app_info"> + <string name="title" value="beervision"/> + <string name="description" value="a beer app"/> + <boolean name="contains_ads" value="true"/> + <boolean name="obey_aps" value="false"/> + <boolean name="ads_fingerprinting" value="false"/> + <boolean name="security_fingerprinting" value="false"/> + <string name="privacy_policy" value="www.example.com"/> + <string-array name="security_endpoints" num="3"> + <item value="url1"/> + <item value="url2"/> + <item value="url3"/> + </string-array> + <string-array name="first_party_endpoints" num="1"> + <item value="url1"/> + </string-array> + <string-array name="service_provider_endpoints" num="2"> + <item value="url55"/> + <item value="url56"/> + </string-array> + <string name="category" value="Food and drink"/> + <string name="email" value="max@maxloh.com"/> + <string name="website" value="www.example.com"/> +</pbundle_as_map> diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/od/all-fields-valid.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/od/all-fields-valid.xml index bce51799c7ff..7aae4a715b79 100644 --- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/od/all-fields-valid.xml +++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/od/all-fields-valid.xml @@ -1,6 +1,5 @@ <pbundle_as_map name="app_info"> - <boolean name="aps_compliant" value="false"/> <string name="privacy_policy" value="www.example.com"/> <string-array name="first_party_endpoints" num="1"> <item value="url1"/> @@ -9,4 +8,7 @@ <item value="url55"/> <item value="url56"/> </string-array> + <boolean name="aps_compliant" value="false"/> + <string name="developer_id" value="dev1"/> + <string name="application_id" value="app1"/> </pbundle_as_map>
\ No newline at end of file diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/od/unrecognized-v1.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/od/unrecognized-v1.xml new file mode 100644 index 000000000000..810078e777fb --- /dev/null +++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/od/unrecognized-v1.xml @@ -0,0 +1,25 @@ +<pbundle_as_map name="app_info"> + <string name="title" value="beervision"/> + <string name="description" value="a beer app"/> + <boolean name="contains_ads" value="true"/> + <boolean name="obey_aps" value="false"/> + <boolean name="ads_fingerprinting" value="false"/> + <boolean name="security_fingerprinting" value="false"/> + <string name="privacy_policy" value="www.example.com"/> + <string-array name="security_endpoints" num="3"> + <item value="url1"/> + <item value="url2"/> + <item value="url3"/> + </string-array> + <string-array name="first_party_endpoints" num="1"> + <item value="url1"/> + </string-array> + <string-array name="service_provider_endpoints" num="2"> + <item value="url55"/> + <item value="url56"/> + </string-array> + <string name="category" value="Food and drink"/> + <string name="email" value="max@maxloh.com"/> + <string name="website" value="www.example.com"/> + <string name="unrecognized" value="www.example.com"/> +</pbundle_as_map> diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/hr/with-app-info.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/hr/with-app-info.xml index 2512ca415d55..2c5cf866547a 100644 --- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/hr/with-app-info.xml +++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/hr/with-app-info.xml @@ -2,7 +2,7 @@ <transparency-info> <app-info apsCompliant="false" - privacyPolicy="www.example.com"> + privacyPolicy="www.example.com" developerId="dev1" applicationId="app1"> <first-party-endpoints> <item>url1</item> </first-party-endpoints> diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/hr/with-developer-info.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/hr/with-developer-info.xml index d16caaea320f..29c88d23abad 100644 --- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/hr/with-developer-info.xml +++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/hr/with-developer-info.xml @@ -1,5 +1,16 @@ <transparency-info> + <app-info + apsCompliant="false" + privacyPolicy="www.example.com" developerId="dev1" applicationId="app1"> + <first-party-endpoints> + <item>url1</item> + </first-party-endpoints> + <service-provider-endpoints> + <item>url55</item> + <item>url56</item> + </service-provider-endpoints> + </app-info> <developer-info name="max" email="max@example.com" diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/od/with-app-info.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/od/with-app-info.xml index c7bdd97a356c..c46cec1da336 100644 --- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/od/with-app-info.xml +++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/od/with-app-info.xml @@ -1,7 +1,6 @@ <pbundle_as_map name="transparency_info"> <pbundle_as_map name="app_info"> - <boolean name="aps_compliant" value="false"/> <string name="privacy_policy" value="www.example.com"/> <string-array name="first_party_endpoints" num="1"> <item value="url1"/> @@ -10,5 +9,8 @@ <item value="url55"/> <item value="url56"/> </string-array> + <boolean name="aps_compliant" value="false"/> + <string name="developer_id" value="dev1"/> + <string name="application_id" value="app1"/> </pbundle_as_map> </pbundle_as_map>
\ No newline at end of file diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/od/with-developer-info.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/od/with-developer-info.xml index d7a4e1a959b7..b5e64b925ca5 100644 --- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/od/with-developer-info.xml +++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/od/with-developer-info.xml @@ -1,5 +1,18 @@ <pbundle_as_map name="transparency_info"> + <pbundle_as_map name="app_info"> + <string name="privacy_policy" value="www.example.com"/> + <string-array name="first_party_endpoints" num="1"> + <item value="url1"/> + </string-array> + <string-array name="service_provider_endpoints" num="2"> + <item value="url55"/> + <item value="url56"/> + </string-array> + <boolean name="aps_compliant" value="false"/> + <string name="developer_id" value="dev1"/> + <string name="application_id" value="app1"/> + </pbundle_as_map> <pbundle_as_map name="developer_info"> <string name="name" value="max"/> <string name="email" value="max@example.com"/> diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/general-v1/od.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/general-v1/od.xml new file mode 100644 index 000000000000..e8b0c17ecada --- /dev/null +++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/general-v1/od.xml @@ -0,0 +1,70 @@ +<bundle> + <long name="version" value="1"/> + <pbundle_as_map name="safety_labels"> + <pbundle_as_map name="data_labels"> + <pbundle_as_map name="data_shared"> + <pbundle_as_map name="location"> + <pbundle_as_map name="approx_location"> + <int-array name="purposes" num="1"> + <item value="1"/> + </int-array> + <boolean name="is_sharing_optional" value="false"/> + <boolean name="ephemeral" value="false"/> + </pbundle_as_map> + <pbundle_as_map name="precise_location"> + <int-array name="purposes" num="2"> + <item value="1"/> + <item value="2"/> + </int-array> + <boolean name="is_sharing_optional" value="true"/> + <boolean name="ephemeral" value="true"/> + </pbundle_as_map> + </pbundle_as_map> + </pbundle_as_map> + </pbundle_as_map> + <pbundle_as_map name="security_labels"> + <boolean name="is_data_deletable" value="true"/> + <boolean name="is_data_encrypted" value="false"/> + </pbundle_as_map> + <pbundle_as_map name="third_party_verification"> + <string name="url" value="www.example.com"/> + </pbundle_as_map> + </pbundle_as_map> + <pbundle_as_map name="system_app_safety_label"> + <string name="url" value="www.example.com"/> + </pbundle_as_map> + <pbundle_as_map name="transparency_info"> + <pbundle_as_map name="developer_info"> + <string name="name" value="max"/> + <string name="email" value="max@example.com"/> + <string name="address" value="111 blah lane"/> + <string name="country_region" value="US"/> + <long name="relationship" value="5"/> + <string name="website" value="example.com"/> + <string name="app_developer_registry_id" value="registry_id"/> + </pbundle_as_map> + <pbundle_as_map name="app_info"> + <string name="title" value="beervision"/> + <string name="description" value="a beer app"/> + <boolean name="contains_ads" value="true"/> + <boolean name="obey_aps" value="false"/> + <boolean name="ads_fingerprinting" value="false"/> + <boolean name="security_fingerprinting" value="false"/> + <string name="privacy_policy" value="www.example.com"/> + <string-array name="security_endpoints" num="3"> + <item value="url1"/> + <item value="url2"/> + <item value="url3"/> + </string-array> + <string-array name="first_party_endpoints" num="1"> + <item value="url1"/> + </string-array> + <string-array name="service_provider_endpoints" num="2"> + <item value="url55"/> + <item value="url56"/> + </string-array> + <string name="category" value="Food and drink"/> + <string name="email" value="max@maxloh.com"/> + </pbundle_as_map> + </pbundle_as_map> +</bundle>
\ No newline at end of file diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/general/hr.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/general/hr.xml index 592307937896..f93298286944 100644 --- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/general/hr.xml +++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/general/hr.xml @@ -1,20 +1,13 @@ -<app-metadata-bundles version="123"> +<app-metadata-bundles version="2"> <safety-labels> <data-labels> - <data-shared - dataType="location_data_type_approx_location" - isSharingOptional="false" - purposes="app_functionality" /> - <data-shared - dataType="location_data_type_precise_location" - isSharingOptional="true" - purposes="app_functionality|analytics" /> + <data-shared dataType="location_data_type_approx_location" isSharingOptional="false" purposes="app_functionality"/> + <data-shared dataType="location_data_type_precise_location" isSharingOptional="true" purposes="app_functionality|analytics"/> </data-labels> </safety-labels> - <system-app-safety-label declaration="true"> - </system-app-safety-label> + <system-app-safety-label declaration="true"/> <transparency-info> - <app-info apsCompliant="false" privacyPolicy="www.example.com"> + <app-info applicationId="app1" apsCompliant="false" developerId="dev1" privacyPolicy="www.example.com"> <first-party-endpoints> <item>url1</item> </first-party-endpoints> diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/general/od.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/general/od.xml index c24087e483b6..c7def7227a34 100644 --- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/general/od.xml +++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/general/od.xml @@ -1,5 +1,5 @@ <bundle> - <long name="version" value="123"/> + <long name="version" value="2"/> <pbundle_as_map name="safety_labels"> <pbundle_as_map name="data_labels"> <pbundle_as_map name="data_shared"> @@ -26,7 +26,6 @@ </pbundle_as_map> <pbundle_as_map name="transparency_info"> <pbundle_as_map name="app_info"> - <boolean name="aps_compliant" value="false"/> <string name="privacy_policy" value="www.example.com"/> <string-array name="first_party_endpoints" num="1"> <item value="url1"/> @@ -35,6 +34,9 @@ <item value="url55"/> <item value="url56"/> </string-array> + <boolean name="aps_compliant" value="false"/> + <string name="developer_id" value="dev1"/> + <string name="application_id" value="app1"/> </pbundle_as_map> </pbundle_as_map> </bundle>
\ No newline at end of file |