Loading tools/app_metadata_bundles/src/aslgen/java/com/android/aslgen/Main.java +13 −15 Original line number Diff line number Diff line Loading @@ -16,8 +16,8 @@ package com.android.aslgen; import com.android.asllib.AndroidSafetyLabel; import com.android.asllib.AndroidSafetyLabel.Format; import com.android.asllib.AslConverter; import com.android.asllib.AslConverter.Format; import com.android.asllib.util.MalformedXmlException; import org.xml.sax.SAXException; Loading @@ -41,9 +41,8 @@ public class Main { String inFile = null; String outFile = null; Format inFormat = Format.NULL; Format outFormat = Format.NULL; Format inFormat = AslConverter.Format.NULL; Format outFormat = AslConverter.Format.NULL; // Except for "--help", all arguments require a value currently. // So just make sure we have an even number and Loading Loading @@ -79,11 +78,11 @@ public class Main { throw new IllegalArgumentException("output file is required"); } if (inFormat == Format.NULL) { if (inFormat == AslConverter.Format.NULL) { throw new IllegalArgumentException("input format is required"); } if (outFormat == Format.NULL) { if (outFormat == AslConverter.Format.NULL) { throw new IllegalArgumentException("output format is required"); } Loading @@ -92,24 +91,23 @@ public class Main { System.out.println("in format: " + inFormat); System.out.println("out format: " + outFormat); var asl = AndroidSafetyLabel.readFromStream(new FileInputStream(inFile), inFormat); asl.writeToStream(new FileOutputStream(outFile), outFormat); var asl = AslConverter.readFromStream(new FileInputStream(inFile), inFormat); AslConverter.writeToStream(new FileOutputStream(outFile), asl, outFormat); } private static Format getFormat(String argValue) { if ("hr".equals(argValue)) { return Format.HUMAN_READABLE; return AslConverter.Format.HUMAN_READABLE; } else if ("od".equals(argValue)) { return Format.ON_DEVICE; return AslConverter.Format.ON_DEVICE; } else { return Format.NULL; return AslConverter.Format.NULL; } } private static void showUsage() { AndroidSafetyLabel.test(); System.err.println( "Usage:\n" ); "Usage: aslgen --in-path [input-file] --out-path [output-file] --in-format [hr|od]" + " --out-format [hr|od]"); } } tools/app_metadata_bundles/src/lib/java/com/android/asllib/AndroidSafetyLabel.java +22 −100 Original line number Diff line number Diff line Loading @@ -16,125 +16,47 @@ package com.android.asllib; import com.android.asllib.util.MalformedXmlException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.xml.sax.SAXException; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.charset.StandardCharsets; import java.util.List; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; public class AndroidSafetyLabel implements AslMarshallable { public enum Format { NULL, HUMAN_READABLE, ON_DEVICE; } private final Long mVersion; private final SystemAppSafetyLabel mSystemAppSafetyLabel; private final SafetyLabels mSafetyLabels; private final TransparencyInfo mTransparencyInfo; public SafetyLabels getSafetyLabels() { return mSafetyLabels; } public AndroidSafetyLabel(SafetyLabels safetyLabels) { public AndroidSafetyLabel( Long version, SystemAppSafetyLabel systemAppSafetyLabel, SafetyLabels safetyLabels, TransparencyInfo transparencyInfo) { this.mVersion = version; this.mSystemAppSafetyLabel = systemAppSafetyLabel; this.mSafetyLabels = safetyLabels; } /** Reads a {@link AndroidSafetyLabel} from an {@link InputStream}. */ // TODO(b/329902686): Support parsing from on-device. public static AndroidSafetyLabel readFromStream(InputStream in, Format format) throws IOException, ParserConfigurationException, SAXException, MalformedXmlException { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); Document document = factory.newDocumentBuilder().parse(in); switch (format) { case HUMAN_READABLE: Element appMetadataBundles = XmlUtils.getSingleElement(document, XmlUtils.HR_TAG_APP_METADATA_BUNDLES); return new AndroidSafetyLabelFactory() .createFromHrElements( List.of( XmlUtils.getSingleElement( document, XmlUtils.HR_TAG_APP_METADATA_BUNDLES))); case ON_DEVICE: throw new IllegalArgumentException( "Parsing from on-device format is not supported at this time."); default: throw new IllegalStateException("Unrecognized input format."); } } /** Reads a {@link AndroidSafetyLabel} from a String. */ public static AndroidSafetyLabel readFromString(String in, Format format) throws IOException, ParserConfigurationException, SAXException, MalformedXmlException { InputStream stream = new ByteArrayInputStream(in.getBytes(StandardCharsets.UTF_8)); return readFromStream(stream, format); } /** Write the content of the {@link AndroidSafetyLabel} to a {@link OutputStream}. */ // TODO(b/329902686): Support outputting human-readable format. public void writeToStream(OutputStream out, Format format) throws IOException, ParserConfigurationException, TransformerException { var docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); var document = docBuilder.newDocument(); switch (format) { case HUMAN_READABLE: throw new IllegalArgumentException( "Outputting human-readable format is not supported at this time."); case ON_DEVICE: for (var child : this.toOdDomElements(document)) { document.appendChild(child); } break; default: throw new IllegalStateException("Unrecognized input format."); } TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); StreamResult streamResult = new StreamResult(out); // out DOMSource domSource = new DOMSource(document); transformer.transform(domSource, streamResult); } /** Get the content of the {@link AndroidSafetyLabel} as String. */ public String getXmlAsString(Format format) throws IOException, ParserConfigurationException, TransformerException { ByteArrayOutputStream out = new ByteArrayOutputStream(); this.writeToStream(out, format); return out.toString(StandardCharsets.UTF_8); this.mTransparencyInfo = transparencyInfo; } /** Creates an on-device DOM element from an {@link AndroidSafetyLabel} */ @Override public List<Element> toOdDomElements(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)); return List.of(aslEle); } public static void test() { // TODO(b/329902686): Add tests. if (mSystemAppSafetyLabel != null) { XmlUtils.appendChildren(aslEle, mSystemAppSafetyLabel.toOdDomElements(doc)); } if (mTransparencyInfo != null) { XmlUtils.appendChildren(aslEle, mTransparencyInfo.toOdDomElements(doc)); } return XmlUtils.listOf(aslEle); } } tools/app_metadata_bundles/src/lib/java/com/android/asllib/AndroidSafetyLabelFactory.java +21 −3 Original line number Diff line number Diff line Loading @@ -29,11 +29,29 @@ public class AndroidSafetyLabelFactory implements AslMarshallableFactory<Android public AndroidSafetyLabel createFromHrElements(List<Element> appMetadataBundles) throws MalformedXmlException { Element appMetadataBundlesEle = XmlUtils.getSingleElement(appMetadataBundles); long version = XmlUtils.tryGetVersion(appMetadataBundlesEle); Element safetyLabelsEle = XmlUtils.getSingleChildElement( appMetadataBundlesEle, XmlUtils.HR_TAG_SAFETY_LABELS); appMetadataBundlesEle, XmlUtils.HR_TAG_SAFETY_LABELS, false); SafetyLabels safetyLabels = new SafetyLabelsFactory().createFromHrElements(List.of(safetyLabelsEle)); return new AndroidSafetyLabel(safetyLabels); new SafetyLabelsFactory().createFromHrElements(XmlUtils.listOf(safetyLabelsEle)); Element systemAppSafetyLabelEle = XmlUtils.getSingleChildElement( appMetadataBundlesEle, XmlUtils.HR_TAG_SYSTEM_APP_SAFETY_LABEL, false); SystemAppSafetyLabel systemAppSafetyLabel = new SystemAppSafetyLabelFactory() .createFromHrElements(XmlUtils.listOf(systemAppSafetyLabelEle)); Element transparencyInfoEle = XmlUtils.getSingleChildElement( appMetadataBundlesEle, XmlUtils.HR_TAG_TRANSPARENCY_INFO, false); TransparencyInfo transparencyInfo = new TransparencyInfoFactory() .createFromHrElements(XmlUtils.listOf(transparencyInfoEle)); return new AndroidSafetyLabel( version, systemAppSafetyLabel, safetyLabels, transparencyInfo); } } tools/app_metadata_bundles/src/lib/java/com/android/asllib/AppInfo.java 0 → 100644 +143 −0 Original line number Diff line number Diff line /* * 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; import org.w3c.dom.Document; import org.w3c.dom.Element; import java.util.List; /** AppInfo representation */ public class AppInfo implements AslMarshallable { 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; public AppInfo( String title, String description, Boolean containsAds, Boolean obeyAps, Boolean adsFingerprinting, Boolean securityFingerprinting, String privacyPolicy, List<String> securityEndpoints, List<String> firstPartyEndpoints, List<String> serviceProviderEndpoints, String category, String email, String website) { 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; } /** Creates an on-device DOM element from the {@link SafetyLabels}. */ @Override public List<Element> toOdDomElements(Document doc) { Element appInfoEle = XmlUtils.createPbundleEleWithName(doc, XmlUtils.OD_NAME_APP_INFO); 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_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_ENDPOINT, mSecurityEndpoints)); } if (this.mFirstPartyEndpoints != null) { appInfoEle.appendChild( XmlUtils.createOdArray( doc, XmlUtils.OD_TAG_STRING_ARRAY, XmlUtils.OD_NAME_FIRST_PARTY_ENDPOINT, mFirstPartyEndpoints)); } if (this.mServiceProviderEndpoints != null) { appInfoEle.appendChild( XmlUtils.createOdArray( doc, XmlUtils.OD_TAG_STRING_ARRAY, XmlUtils.OD_NAME_SERVICE_PROVIDER_ENDPOINT, mServiceProviderEndpoints)); } 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)); } return XmlUtils.listOf(appInfoEle); } } tools/app_metadata_bundles/src/lib/java/com/android/asllib/AppInfoFactory.java 0 → 100644 +84 −0 Original line number Diff line number Diff line /* * 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; import com.android.asllib.util.AslgenUtil; import com.android.asllib.util.MalformedXmlException; import org.w3c.dom.Element; import java.util.Arrays; import java.util.List; public class AppInfoFactory implements AslMarshallableFactory<AppInfo> { /** 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; } String title = XmlUtils.getStringAttr(appInfoEle, XmlUtils.HR_ATTR_TITLE); String description = XmlUtils.getStringAttr(appInfoEle, XmlUtils.HR_ATTR_DESCRIPTION); Boolean containsAds = XmlUtils.getBoolAttr(appInfoEle, XmlUtils.HR_ATTR_CONTAINS_ADS); Boolean obeyAps = XmlUtils.getBoolAttr(appInfoEle, XmlUtils.HR_ATTR_OBEY_APS); Boolean adsFingerprinting = XmlUtils.getBoolAttr(appInfoEle, XmlUtils.HR_ATTR_ADS_FINGERPRINTING); Boolean securityFingerprinting = XmlUtils.getBoolAttr(appInfoEle, XmlUtils.HR_ATTR_SECURITY_FINGERPRINTING); String privacyPolicy = XmlUtils.getStringAttr(appInfoEle, XmlUtils.HR_ATTR_PRIVACY_POLICY); List<String> securityEndpoints = Arrays.stream( appInfoEle .getAttribute(XmlUtils.HR_ATTR_SECURITY_ENDPOINTS) .split("\\|")) .toList(); List<String> firstPartyEndpoints = Arrays.stream( appInfoEle .getAttribute(XmlUtils.HR_ATTR_FIRST_PARTY_ENDPOINTS) .split("\\|")) .toList(); List<String> serviceProviderEndpoints = Arrays.stream( appInfoEle .getAttribute(XmlUtils.HR_ATTR_SERVICE_PROVIDER_ENDPOINTS) .split("\\|")) .toList(); String category = XmlUtils.getStringAttr(appInfoEle, XmlUtils.HR_ATTR_CATEGORY); String email = XmlUtils.getStringAttr(appInfoEle, XmlUtils.HR_ATTR_EMAIL); String website = XmlUtils.getStringAttr(appInfoEle, XmlUtils.HR_ATTR_WEBSITE, false); return new AppInfo( title, description, containsAds, obeyAps, adsFingerprinting, securityFingerprinting, privacyPolicy, securityEndpoints, firstPartyEndpoints, serviceProviderEndpoints, category, email, website); } } Loading
tools/app_metadata_bundles/src/aslgen/java/com/android/aslgen/Main.java +13 −15 Original line number Diff line number Diff line Loading @@ -16,8 +16,8 @@ package com.android.aslgen; import com.android.asllib.AndroidSafetyLabel; import com.android.asllib.AndroidSafetyLabel.Format; import com.android.asllib.AslConverter; import com.android.asllib.AslConverter.Format; import com.android.asllib.util.MalformedXmlException; import org.xml.sax.SAXException; Loading @@ -41,9 +41,8 @@ public class Main { String inFile = null; String outFile = null; Format inFormat = Format.NULL; Format outFormat = Format.NULL; Format inFormat = AslConverter.Format.NULL; Format outFormat = AslConverter.Format.NULL; // Except for "--help", all arguments require a value currently. // So just make sure we have an even number and Loading Loading @@ -79,11 +78,11 @@ public class Main { throw new IllegalArgumentException("output file is required"); } if (inFormat == Format.NULL) { if (inFormat == AslConverter.Format.NULL) { throw new IllegalArgumentException("input format is required"); } if (outFormat == Format.NULL) { if (outFormat == AslConverter.Format.NULL) { throw new IllegalArgumentException("output format is required"); } Loading @@ -92,24 +91,23 @@ public class Main { System.out.println("in format: " + inFormat); System.out.println("out format: " + outFormat); var asl = AndroidSafetyLabel.readFromStream(new FileInputStream(inFile), inFormat); asl.writeToStream(new FileOutputStream(outFile), outFormat); var asl = AslConverter.readFromStream(new FileInputStream(inFile), inFormat); AslConverter.writeToStream(new FileOutputStream(outFile), asl, outFormat); } private static Format getFormat(String argValue) { if ("hr".equals(argValue)) { return Format.HUMAN_READABLE; return AslConverter.Format.HUMAN_READABLE; } else if ("od".equals(argValue)) { return Format.ON_DEVICE; return AslConverter.Format.ON_DEVICE; } else { return Format.NULL; return AslConverter.Format.NULL; } } private static void showUsage() { AndroidSafetyLabel.test(); System.err.println( "Usage:\n" ); "Usage: aslgen --in-path [input-file] --out-path [output-file] --in-format [hr|od]" + " --out-format [hr|od]"); } }
tools/app_metadata_bundles/src/lib/java/com/android/asllib/AndroidSafetyLabel.java +22 −100 Original line number Diff line number Diff line Loading @@ -16,125 +16,47 @@ package com.android.asllib; import com.android.asllib.util.MalformedXmlException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.xml.sax.SAXException; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.charset.StandardCharsets; import java.util.List; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; public class AndroidSafetyLabel implements AslMarshallable { public enum Format { NULL, HUMAN_READABLE, ON_DEVICE; } private final Long mVersion; private final SystemAppSafetyLabel mSystemAppSafetyLabel; private final SafetyLabels mSafetyLabels; private final TransparencyInfo mTransparencyInfo; public SafetyLabels getSafetyLabels() { return mSafetyLabels; } public AndroidSafetyLabel(SafetyLabels safetyLabels) { public AndroidSafetyLabel( Long version, SystemAppSafetyLabel systemAppSafetyLabel, SafetyLabels safetyLabels, TransparencyInfo transparencyInfo) { this.mVersion = version; this.mSystemAppSafetyLabel = systemAppSafetyLabel; this.mSafetyLabels = safetyLabels; } /** Reads a {@link AndroidSafetyLabel} from an {@link InputStream}. */ // TODO(b/329902686): Support parsing from on-device. public static AndroidSafetyLabel readFromStream(InputStream in, Format format) throws IOException, ParserConfigurationException, SAXException, MalformedXmlException { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); Document document = factory.newDocumentBuilder().parse(in); switch (format) { case HUMAN_READABLE: Element appMetadataBundles = XmlUtils.getSingleElement(document, XmlUtils.HR_TAG_APP_METADATA_BUNDLES); return new AndroidSafetyLabelFactory() .createFromHrElements( List.of( XmlUtils.getSingleElement( document, XmlUtils.HR_TAG_APP_METADATA_BUNDLES))); case ON_DEVICE: throw new IllegalArgumentException( "Parsing from on-device format is not supported at this time."); default: throw new IllegalStateException("Unrecognized input format."); } } /** Reads a {@link AndroidSafetyLabel} from a String. */ public static AndroidSafetyLabel readFromString(String in, Format format) throws IOException, ParserConfigurationException, SAXException, MalformedXmlException { InputStream stream = new ByteArrayInputStream(in.getBytes(StandardCharsets.UTF_8)); return readFromStream(stream, format); } /** Write the content of the {@link AndroidSafetyLabel} to a {@link OutputStream}. */ // TODO(b/329902686): Support outputting human-readable format. public void writeToStream(OutputStream out, Format format) throws IOException, ParserConfigurationException, TransformerException { var docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); var document = docBuilder.newDocument(); switch (format) { case HUMAN_READABLE: throw new IllegalArgumentException( "Outputting human-readable format is not supported at this time."); case ON_DEVICE: for (var child : this.toOdDomElements(document)) { document.appendChild(child); } break; default: throw new IllegalStateException("Unrecognized input format."); } TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); StreamResult streamResult = new StreamResult(out); // out DOMSource domSource = new DOMSource(document); transformer.transform(domSource, streamResult); } /** Get the content of the {@link AndroidSafetyLabel} as String. */ public String getXmlAsString(Format format) throws IOException, ParserConfigurationException, TransformerException { ByteArrayOutputStream out = new ByteArrayOutputStream(); this.writeToStream(out, format); return out.toString(StandardCharsets.UTF_8); this.mTransparencyInfo = transparencyInfo; } /** Creates an on-device DOM element from an {@link AndroidSafetyLabel} */ @Override public List<Element> toOdDomElements(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)); return List.of(aslEle); } public static void test() { // TODO(b/329902686): Add tests. if (mSystemAppSafetyLabel != null) { XmlUtils.appendChildren(aslEle, mSystemAppSafetyLabel.toOdDomElements(doc)); } if (mTransparencyInfo != null) { XmlUtils.appendChildren(aslEle, mTransparencyInfo.toOdDomElements(doc)); } return XmlUtils.listOf(aslEle); } }
tools/app_metadata_bundles/src/lib/java/com/android/asllib/AndroidSafetyLabelFactory.java +21 −3 Original line number Diff line number Diff line Loading @@ -29,11 +29,29 @@ public class AndroidSafetyLabelFactory implements AslMarshallableFactory<Android public AndroidSafetyLabel createFromHrElements(List<Element> appMetadataBundles) throws MalformedXmlException { Element appMetadataBundlesEle = XmlUtils.getSingleElement(appMetadataBundles); long version = XmlUtils.tryGetVersion(appMetadataBundlesEle); Element safetyLabelsEle = XmlUtils.getSingleChildElement( appMetadataBundlesEle, XmlUtils.HR_TAG_SAFETY_LABELS); appMetadataBundlesEle, XmlUtils.HR_TAG_SAFETY_LABELS, false); SafetyLabels safetyLabels = new SafetyLabelsFactory().createFromHrElements(List.of(safetyLabelsEle)); return new AndroidSafetyLabel(safetyLabels); new SafetyLabelsFactory().createFromHrElements(XmlUtils.listOf(safetyLabelsEle)); Element systemAppSafetyLabelEle = XmlUtils.getSingleChildElement( appMetadataBundlesEle, XmlUtils.HR_TAG_SYSTEM_APP_SAFETY_LABEL, false); SystemAppSafetyLabel systemAppSafetyLabel = new SystemAppSafetyLabelFactory() .createFromHrElements(XmlUtils.listOf(systemAppSafetyLabelEle)); Element transparencyInfoEle = XmlUtils.getSingleChildElement( appMetadataBundlesEle, XmlUtils.HR_TAG_TRANSPARENCY_INFO, false); TransparencyInfo transparencyInfo = new TransparencyInfoFactory() .createFromHrElements(XmlUtils.listOf(transparencyInfoEle)); return new AndroidSafetyLabel( version, systemAppSafetyLabel, safetyLabels, transparencyInfo); } }
tools/app_metadata_bundles/src/lib/java/com/android/asllib/AppInfo.java 0 → 100644 +143 −0 Original line number Diff line number Diff line /* * 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; import org.w3c.dom.Document; import org.w3c.dom.Element; import java.util.List; /** AppInfo representation */ public class AppInfo implements AslMarshallable { 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; public AppInfo( String title, String description, Boolean containsAds, Boolean obeyAps, Boolean adsFingerprinting, Boolean securityFingerprinting, String privacyPolicy, List<String> securityEndpoints, List<String> firstPartyEndpoints, List<String> serviceProviderEndpoints, String category, String email, String website) { 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; } /** Creates an on-device DOM element from the {@link SafetyLabels}. */ @Override public List<Element> toOdDomElements(Document doc) { Element appInfoEle = XmlUtils.createPbundleEleWithName(doc, XmlUtils.OD_NAME_APP_INFO); 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_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_ENDPOINT, mSecurityEndpoints)); } if (this.mFirstPartyEndpoints != null) { appInfoEle.appendChild( XmlUtils.createOdArray( doc, XmlUtils.OD_TAG_STRING_ARRAY, XmlUtils.OD_NAME_FIRST_PARTY_ENDPOINT, mFirstPartyEndpoints)); } if (this.mServiceProviderEndpoints != null) { appInfoEle.appendChild( XmlUtils.createOdArray( doc, XmlUtils.OD_TAG_STRING_ARRAY, XmlUtils.OD_NAME_SERVICE_PROVIDER_ENDPOINT, mServiceProviderEndpoints)); } 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)); } return XmlUtils.listOf(appInfoEle); } }
tools/app_metadata_bundles/src/lib/java/com/android/asllib/AppInfoFactory.java 0 → 100644 +84 −0 Original line number Diff line number Diff line /* * 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; import com.android.asllib.util.AslgenUtil; import com.android.asllib.util.MalformedXmlException; import org.w3c.dom.Element; import java.util.Arrays; import java.util.List; public class AppInfoFactory implements AslMarshallableFactory<AppInfo> { /** 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; } String title = XmlUtils.getStringAttr(appInfoEle, XmlUtils.HR_ATTR_TITLE); String description = XmlUtils.getStringAttr(appInfoEle, XmlUtils.HR_ATTR_DESCRIPTION); Boolean containsAds = XmlUtils.getBoolAttr(appInfoEle, XmlUtils.HR_ATTR_CONTAINS_ADS); Boolean obeyAps = XmlUtils.getBoolAttr(appInfoEle, XmlUtils.HR_ATTR_OBEY_APS); Boolean adsFingerprinting = XmlUtils.getBoolAttr(appInfoEle, XmlUtils.HR_ATTR_ADS_FINGERPRINTING); Boolean securityFingerprinting = XmlUtils.getBoolAttr(appInfoEle, XmlUtils.HR_ATTR_SECURITY_FINGERPRINTING); String privacyPolicy = XmlUtils.getStringAttr(appInfoEle, XmlUtils.HR_ATTR_PRIVACY_POLICY); List<String> securityEndpoints = Arrays.stream( appInfoEle .getAttribute(XmlUtils.HR_ATTR_SECURITY_ENDPOINTS) .split("\\|")) .toList(); List<String> firstPartyEndpoints = Arrays.stream( appInfoEle .getAttribute(XmlUtils.HR_ATTR_FIRST_PARTY_ENDPOINTS) .split("\\|")) .toList(); List<String> serviceProviderEndpoints = Arrays.stream( appInfoEle .getAttribute(XmlUtils.HR_ATTR_SERVICE_PROVIDER_ENDPOINTS) .split("\\|")) .toList(); String category = XmlUtils.getStringAttr(appInfoEle, XmlUtils.HR_ATTR_CATEGORY); String email = XmlUtils.getStringAttr(appInfoEle, XmlUtils.HR_ATTR_EMAIL); String website = XmlUtils.getStringAttr(appInfoEle, XmlUtils.HR_ATTR_WEBSITE, false); return new AppInfo( title, description, containsAds, obeyAps, adsFingerprinting, securityFingerprinting, privacyPolicy, securityEndpoints, firstPartyEndpoints, serviceProviderEndpoints, category, email, website); } }