Loading tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataCategory.java +6 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import com.android.asllib.util.XmlUtils; import org.w3c.dom.Document; import org.w3c.dom.Element; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; Loading @@ -40,6 +41,11 @@ public class DataCategory implements AslMarshallable { this.mDataTypes = dataTypes; } public DataCategory(String categoryName) { this.mCategoryName = categoryName; this.mDataTypes = new LinkedHashMap<String, DataType>(); } public String getCategoryName() { return mCategoryName; } Loading tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataCategoryFactory.java +1 −26 Original line number Diff line number Diff line Loading @@ -26,33 +26,8 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; public class DataCategoryFactory implements AslMarshallableFactory<DataCategory> { @Override public DataCategory createFromHrElements(List<Element> elements) throws MalformedXmlException { String categoryName = null; Map<String, DataType> dataTypeMap = new LinkedHashMap<String, DataType>(); for (Element ele : elements) { categoryName = XmlUtils.getStringAttr(ele, XmlUtils.HR_ATTR_DATA_CATEGORY, true); String dataTypeName = XmlUtils.getStringAttr(ele, XmlUtils.HR_ATTR_DATA_TYPE, true); if (!DataTypeConstants.getValidDataTypes().containsKey(categoryName)) { throw new MalformedXmlException( String.format("Unrecognized data category %s", categoryName)); } if (!DataTypeConstants.getValidDataTypes().get(categoryName).contains(dataTypeName)) { throw new MalformedXmlException( String.format( "Unrecognized data type name %s for category %s", dataTypeName, categoryName)); } dataTypeMap.put( dataTypeName, new DataTypeFactory().createFromHrElements(XmlUtils.listOf(ele))); } return new DataCategory(categoryName, dataTypeMap); } public class DataCategoryFactory { /** Creates an {@link AslMarshallableFactory} from on-device DOM elements */ @Override public DataCategory createFromOdElements(List<Element> elements) throws MalformedXmlException { Element dataCategoryEle = XmlUtils.getSingleElement(elements); Map<String, DataType> dataTypeMap = new LinkedHashMap<String, DataType>(); Loading tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataLabels.java +16 −21 Original line number Diff line number Diff line Loading @@ -30,27 +30,16 @@ import java.util.Map; * DataCategory} */ public class DataLabels implements AslMarshallable { private final Map<String, DataCategory> mDataAccessed; private final Map<String, DataCategory> mDataCollected; private final Map<String, DataCategory> mDataShared; public DataLabels( Map<String, DataCategory> dataAccessed, Map<String, DataCategory> dataCollected, Map<String, DataCategory> dataShared) { mDataAccessed = dataAccessed; mDataCollected = dataCollected; mDataShared = dataShared; } /** * Returns the data accessed {@link Map} of {@link DataCategoryConstants} to {@link * DataCategory} */ public Map<String, DataCategory> getDataAccessed() { return mDataAccessed; } /** * Returns the data collected {@link Map} of {@link DataCategoryConstants} to {@link * DataCategory} Loading @@ -72,7 +61,6 @@ public class DataLabels implements AslMarshallable { Element dataLabelsEle = XmlUtils.createPbundleEleWithName(doc, XmlUtils.OD_NAME_DATA_LABELS); maybeAppendDataUsages(doc, dataLabelsEle, mDataAccessed, XmlUtils.OD_NAME_DATA_ACCESSED); maybeAppendDataUsages(doc, dataLabelsEle, mDataCollected, XmlUtils.OD_NAME_DATA_COLLECTED); maybeAppendDataUsages(doc, dataLabelsEle, mDataShared, XmlUtils.OD_NAME_DATA_SHARED); Loading @@ -83,9 +71,12 @@ public class DataLabels implements AslMarshallable { @Override public List<Element> toHrDomElements(Document doc) { Element dataLabelsEle = doc.createElement(XmlUtils.HR_TAG_DATA_LABELS); maybeAppendHrDataUsages(doc, dataLabelsEle, mDataAccessed, XmlUtils.HR_TAG_DATA_ACCESSED); maybeAppendHrDataUsages(doc, dataLabelsEle, mDataCollected, XmlUtils.HR_TAG_DATA_COLLECTED); maybeAppendHrDataUsages(doc, dataLabelsEle, mDataShared, XmlUtils.HR_TAG_DATA_SHARED); maybeAppendHrDataUsages( doc, dataLabelsEle, mDataCollected, XmlUtils.HR_TAG_DATA_COLLECTED, false); maybeAppendHrDataUsages( doc, dataLabelsEle, mDataCollected, XmlUtils.HR_TAG_DATA_COLLECTED_EPHEMERAL, true); maybeAppendHrDataUsages( doc, dataLabelsEle, mDataShared, XmlUtils.HR_TAG_DATA_SHARED, false); return XmlUtils.listOf(dataLabelsEle); } Loading Loading @@ -115,7 +106,8 @@ public class DataLabels implements AslMarshallable { Document doc, Element dataLabelsEle, Map<String, DataCategory> dataCategoriesMap, String dataUsageTypeName) { String dataUsageTypeName, boolean ephemeral) { if (dataCategoriesMap.isEmpty()) { return; } Loading @@ -123,10 +115,15 @@ public class DataLabels implements AslMarshallable { DataCategory dataCategory = dataCategoriesMap.get(dataCategoryName); for (String dataTypeName : dataCategory.getDataTypes().keySet()) { DataType dataType = dataCategory.getDataTypes().get(dataTypeName); // XmlUtils.appendChildren(dataLabelsEle, dataType.toHrDomElements(doc)); if (ephemeral != (dataType.getEphemeral() != null ? dataType.getEphemeral() : false)) { continue; } Element hrDataTypeEle = doc.createElement(dataUsageTypeName); hrDataTypeEle.setAttribute(XmlUtils.HR_ATTR_DATA_CATEGORY, dataCategoryName); hrDataTypeEle.setAttribute(XmlUtils.HR_ATTR_DATA_TYPE, dataTypeName); hrDataTypeEle.setAttribute( XmlUtils.HR_ATTR_DATA_TYPE, dataCategoryName + XmlUtils.DATA_TYPE_SEPARATOR + dataTypeName); XmlUtils.maybeSetHrBoolAttr( hrDataTypeEle, XmlUtils.HR_ATTR_IS_COLLECTION_OPTIONAL, Loading @@ -135,8 +132,6 @@ public class DataLabels implements AslMarshallable { hrDataTypeEle, XmlUtils.HR_ATTR_IS_SHARING_OPTIONAL, dataType.getIsSharingOptional()); XmlUtils.maybeSetHrBoolAttr( hrDataTypeEle, XmlUtils.HR_ATTR_EPHEMERAL, dataType.getEphemeral()); hrDataTypeEle.setAttribute( XmlUtils.HR_ATTR_PURPOSES, String.join( Loading tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataLabelsFactory.java +74 −44 Original line number Diff line number Diff line Loading @@ -18,16 +18,15 @@ package com.android.asllib.marshallable; import com.android.asllib.util.AslgenUtil; import com.android.asllib.util.DataCategoryConstants; import com.android.asllib.util.DataTypeConstants; import com.android.asllib.util.MalformedXmlException; import com.android.asllib.util.XmlUtils; import org.w3c.dom.Element; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; public class DataLabelsFactory implements AslMarshallableFactory<DataLabels> { Loading @@ -39,13 +38,46 @@ public class DataLabelsFactory implements AslMarshallableFactory<DataLabels> { AslgenUtil.logI("Found no DataLabels in hr format."); return null; } Map<String, DataCategory> dataAccessed = getDataCategoriesWithTag(ele, XmlUtils.HR_TAG_DATA_ACCESSED); Map<String, DataCategory> dataCollected = getDataCategoriesWithTag(ele, XmlUtils.HR_TAG_DATA_COLLECTED); getDataCategoriesWithTag(ele, XmlUtils.HR_TAG_DATA_COLLECTED, false); Map<String, DataCategory> dataCollectedEphemeral = getDataCategoriesWithTag(ele, XmlUtils.HR_TAG_DATA_COLLECTED_EPHEMERAL, true); Map<String, DataCategory> dataShared = getDataCategoriesWithTag(ele, XmlUtils.HR_TAG_DATA_SHARED); DataLabels dataLabels = new DataLabels(dataAccessed, dataCollected, dataShared); getDataCategoriesWithTag(ele, XmlUtils.HR_TAG_DATA_SHARED, null); for (String dataCollectedEphemeralDataCategoryKey : dataCollectedEphemeral.keySet()) { DataCategory dataCategoryEphemeral = dataCollectedEphemeral.get(dataCollectedEphemeralDataCategoryKey); for (String dataCollectedEphemeralDataTypeKey : dataCategoryEphemeral.getDataTypes().keySet()) { if (dataCollected.containsKey(dataCollectedEphemeralDataCategoryKey) && dataCollected .get(dataCollectedEphemeralDataCategoryKey) .getDataTypes() .containsKey(dataCollectedEphemeralDataTypeKey)) { throw new MalformedXmlException( String.format( "Duplicate entries in data-collected and" + " data-collected-ephemeral: %s %s", dataCollectedEphemeralDataCategoryKey, dataCollectedEphemeralDataTypeKey)); } if (!dataCollected.containsKey(dataCollectedEphemeralDataCategoryKey)) { dataCollected.put( dataCollectedEphemeralDataCategoryKey, new DataCategory(dataCollectedEphemeralDataCategoryKey)); } DataType dataTypeEphemeral = dataCategoryEphemeral.getDataTypes().get(dataCollectedEphemeralDataTypeKey); dataCollected .get(dataCollectedEphemeralDataCategoryKey) .getDataTypes() .put(dataCollectedEphemeralDataTypeKey, dataTypeEphemeral); } } DataLabels dataLabels = new DataLabels(dataCollected, dataShared); validateIsXOptional(dataLabels); return dataLabels; } Loading @@ -58,13 +90,11 @@ public class DataLabelsFactory implements AslMarshallableFactory<DataLabels> { AslgenUtil.logI("Found no DataLabels in od format."); return null; } Map<String, DataCategory> dataAccessed = getOdDataCategoriesWithTag(dataLabelsEle, XmlUtils.OD_NAME_DATA_ACCESSED); Map<String, DataCategory> dataCollected = getOdDataCategoriesWithTag(dataLabelsEle, XmlUtils.OD_NAME_DATA_COLLECTED); Map<String, DataCategory> dataShared = getOdDataCategoriesWithTag(dataLabelsEle, XmlUtils.OD_NAME_DATA_SHARED); DataLabels dataLabels = new DataLabels(dataAccessed, dataCollected, dataShared); DataLabels dataLabels = new DataLabels(dataCollected, dataShared); validateIsXOptional(dataLabels); return dataLabels; } Loading @@ -88,56 +118,56 @@ public class DataLabelsFactory implements AslMarshallableFactory<DataLabels> { } private static Map<String, DataCategory> getDataCategoriesWithTag( Element dataLabelsEle, String dataCategoryUsageTypeTag) throws MalformedXmlException { Element dataLabelsEle, String dataCategoryUsageTypeTag, Boolean ephemeral) throws MalformedXmlException { List<Element> dataUsedElements = XmlUtils.getChildrenByTagName(dataLabelsEle, dataCategoryUsageTypeTag); Map<String, DataCategory> dataCategoryMap = new LinkedHashMap<String, DataCategory>(); Set<String> dataCategoryNames = new HashSet<String>(); for (int i = 0; i < dataUsedElements.size(); i++) { Element dataUsedEle = dataUsedElements.get(i); String dataCategoryName = dataUsedEle.getAttribute(XmlUtils.HR_ATTR_DATA_CATEGORY); String dataCategoryAndTypeCombinedStr = dataUsedEle.getAttribute(XmlUtils.HR_ATTR_DATA_TYPE); String[] strs = dataCategoryAndTypeCombinedStr.split(XmlUtils.DATA_TYPE_SEPARATOR); if (strs.length != 2) { throw new MalformedXmlException( String.format( "Could not parse human-readable data type string (expecting" + " substring of _data_type_): %s", dataCategoryAndTypeCombinedStr)); } String dataCategoryName = strs[0]; String dataTypeName = strs[1]; if (!DataCategoryConstants.getValidDataCategories().contains(dataCategoryName)) { throw new MalformedXmlException( String.format("Unrecognized category name: %s", dataCategoryName)); } dataCategoryNames.add(dataCategoryName); if (!DataTypeConstants.getValidDataTypes() .get(dataCategoryName) .contains(dataTypeName)) { throw new MalformedXmlException( String.format( "Unrecognized data type name %s for category %s", dataTypeName, dataCategoryName)); } for (String dataCategoryName : dataCategoryNames) { var dataCategoryElements = dataUsedElements.stream() .filter( ele -> ele.getAttribute(XmlUtils.HR_ATTR_DATA_CATEGORY) .equals(dataCategoryName)) .toList(); DataCategory dataCategory = new DataCategoryFactory().createFromHrElements(dataCategoryElements); dataCategoryMap.put(dataCategoryName, dataCategory); if (!dataCategoryMap.containsKey(dataCategoryName)) { dataCategoryMap.put(dataCategoryName, new DataCategory(dataCategoryName)); } dataCategoryMap .get(dataCategoryName) .getDataTypes() .put( dataTypeName, new DataTypeFactory().createFromHrElements(dataUsedEle, ephemeral)); } return dataCategoryMap; } private void validateIsXOptional(DataLabels dataLabels) throws MalformedXmlException { // Validate booleans such as isCollectionOptional, isSharingOptional. for (DataCategory dataCategory : dataLabels.getDataAccessed().values()) { for (DataType dataType : dataCategory.getDataTypes().values()) { if (dataType.getIsSharingOptional() != null) { throw new MalformedXmlException( String.format( "isSharingOptional was unexpectedly defined on a DataType" + " belonging to data accessed: %s", dataType.getDataTypeName())); } if (dataType.getIsCollectionOptional() != null) { throw new MalformedXmlException( String.format( "isCollectionOptional was unexpectedly defined on a DataType" + " belonging to data accessed: %s", dataType.getDataTypeName())); } } } for (DataCategory dataCategory : dataLabels.getDataCollected().values()) { for (DataType dataType : dataCategory.getDataTypes().values()) { if (dataType.getIsSharingOptional() != null) { Loading tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataTypeFactory.java +17 −7 Original line number Diff line number Diff line Loading @@ -25,12 +25,22 @@ import java.util.HashSet; import java.util.List; import java.util.stream.Collectors; public class DataTypeFactory implements AslMarshallableFactory<DataType> { public class DataTypeFactory { /** Creates a {@link DataType} from the human-readable DOM element. */ @Override public DataType createFromHrElements(List<Element> elements) throws MalformedXmlException { Element hrDataTypeEle = XmlUtils.getSingleElement(elements); String dataTypeName = hrDataTypeEle.getAttribute(XmlUtils.HR_ATTR_DATA_TYPE); public DataType createFromHrElements(Element hrDataTypeEle, Boolean ephemeral) throws MalformedXmlException { String dataCategoryAndTypeCombinedStr = hrDataTypeEle.getAttribute(XmlUtils.HR_ATTR_DATA_TYPE); String[] strs = dataCategoryAndTypeCombinedStr.split(XmlUtils.DATA_TYPE_SEPARATOR); if (strs.length != 2) { throw new MalformedXmlException( String.format( "Could not parse human-readable data type string (expecting substring" + " of _data_type_): %s", dataCategoryAndTypeCombinedStr)); } String dataTypeName = strs[1]; List<DataType.Purpose> purposes = XmlUtils.getPipelineSplitAttr(hrDataTypeEle, XmlUtils.HR_ATTR_PURPOSES, true) .stream() Loading @@ -47,13 +57,13 @@ public class DataTypeFactory implements AslMarshallableFactory<DataType> { XmlUtils.getBoolAttr(hrDataTypeEle, XmlUtils.HR_ATTR_IS_COLLECTION_OPTIONAL, false); Boolean isSharingOptional = XmlUtils.getBoolAttr(hrDataTypeEle, XmlUtils.HR_ATTR_IS_SHARING_OPTIONAL, false); Boolean ephemeral = XmlUtils.getBoolAttr(hrDataTypeEle, XmlUtils.HR_ATTR_EPHEMERAL, false); // Boolean ephemeral = XmlUtils.getBoolAttr(hrDataTypeEle, XmlUtils.HR_ATTR_EPHEMERAL, // false); return new DataType( dataTypeName, purposes, isCollectionOptional, isSharingOptional, ephemeral); } /** Creates an {@link AslMarshallableFactory} from on-device DOM elements */ @Override public DataType createFromOdElements(List<Element> elements) throws MalformedXmlException { Element odDataTypeEle = XmlUtils.getSingleElement(elements); String dataTypeName = odDataTypeEle.getAttribute(XmlUtils.OD_ATTR_NAME); Loading Loading
tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataCategory.java +6 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import com.android.asllib.util.XmlUtils; import org.w3c.dom.Document; import org.w3c.dom.Element; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; Loading @@ -40,6 +41,11 @@ public class DataCategory implements AslMarshallable { this.mDataTypes = dataTypes; } public DataCategory(String categoryName) { this.mCategoryName = categoryName; this.mDataTypes = new LinkedHashMap<String, DataType>(); } public String getCategoryName() { return mCategoryName; } Loading
tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataCategoryFactory.java +1 −26 Original line number Diff line number Diff line Loading @@ -26,33 +26,8 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; public class DataCategoryFactory implements AslMarshallableFactory<DataCategory> { @Override public DataCategory createFromHrElements(List<Element> elements) throws MalformedXmlException { String categoryName = null; Map<String, DataType> dataTypeMap = new LinkedHashMap<String, DataType>(); for (Element ele : elements) { categoryName = XmlUtils.getStringAttr(ele, XmlUtils.HR_ATTR_DATA_CATEGORY, true); String dataTypeName = XmlUtils.getStringAttr(ele, XmlUtils.HR_ATTR_DATA_TYPE, true); if (!DataTypeConstants.getValidDataTypes().containsKey(categoryName)) { throw new MalformedXmlException( String.format("Unrecognized data category %s", categoryName)); } if (!DataTypeConstants.getValidDataTypes().get(categoryName).contains(dataTypeName)) { throw new MalformedXmlException( String.format( "Unrecognized data type name %s for category %s", dataTypeName, categoryName)); } dataTypeMap.put( dataTypeName, new DataTypeFactory().createFromHrElements(XmlUtils.listOf(ele))); } return new DataCategory(categoryName, dataTypeMap); } public class DataCategoryFactory { /** Creates an {@link AslMarshallableFactory} from on-device DOM elements */ @Override public DataCategory createFromOdElements(List<Element> elements) throws MalformedXmlException { Element dataCategoryEle = XmlUtils.getSingleElement(elements); Map<String, DataType> dataTypeMap = new LinkedHashMap<String, DataType>(); Loading
tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataLabels.java +16 −21 Original line number Diff line number Diff line Loading @@ -30,27 +30,16 @@ import java.util.Map; * DataCategory} */ public class DataLabels implements AslMarshallable { private final Map<String, DataCategory> mDataAccessed; private final Map<String, DataCategory> mDataCollected; private final Map<String, DataCategory> mDataShared; public DataLabels( Map<String, DataCategory> dataAccessed, Map<String, DataCategory> dataCollected, Map<String, DataCategory> dataShared) { mDataAccessed = dataAccessed; mDataCollected = dataCollected; mDataShared = dataShared; } /** * Returns the data accessed {@link Map} of {@link DataCategoryConstants} to {@link * DataCategory} */ public Map<String, DataCategory> getDataAccessed() { return mDataAccessed; } /** * Returns the data collected {@link Map} of {@link DataCategoryConstants} to {@link * DataCategory} Loading @@ -72,7 +61,6 @@ public class DataLabels implements AslMarshallable { Element dataLabelsEle = XmlUtils.createPbundleEleWithName(doc, XmlUtils.OD_NAME_DATA_LABELS); maybeAppendDataUsages(doc, dataLabelsEle, mDataAccessed, XmlUtils.OD_NAME_DATA_ACCESSED); maybeAppendDataUsages(doc, dataLabelsEle, mDataCollected, XmlUtils.OD_NAME_DATA_COLLECTED); maybeAppendDataUsages(doc, dataLabelsEle, mDataShared, XmlUtils.OD_NAME_DATA_SHARED); Loading @@ -83,9 +71,12 @@ public class DataLabels implements AslMarshallable { @Override public List<Element> toHrDomElements(Document doc) { Element dataLabelsEle = doc.createElement(XmlUtils.HR_TAG_DATA_LABELS); maybeAppendHrDataUsages(doc, dataLabelsEle, mDataAccessed, XmlUtils.HR_TAG_DATA_ACCESSED); maybeAppendHrDataUsages(doc, dataLabelsEle, mDataCollected, XmlUtils.HR_TAG_DATA_COLLECTED); maybeAppendHrDataUsages(doc, dataLabelsEle, mDataShared, XmlUtils.HR_TAG_DATA_SHARED); maybeAppendHrDataUsages( doc, dataLabelsEle, mDataCollected, XmlUtils.HR_TAG_DATA_COLLECTED, false); maybeAppendHrDataUsages( doc, dataLabelsEle, mDataCollected, XmlUtils.HR_TAG_DATA_COLLECTED_EPHEMERAL, true); maybeAppendHrDataUsages( doc, dataLabelsEle, mDataShared, XmlUtils.HR_TAG_DATA_SHARED, false); return XmlUtils.listOf(dataLabelsEle); } Loading Loading @@ -115,7 +106,8 @@ public class DataLabels implements AslMarshallable { Document doc, Element dataLabelsEle, Map<String, DataCategory> dataCategoriesMap, String dataUsageTypeName) { String dataUsageTypeName, boolean ephemeral) { if (dataCategoriesMap.isEmpty()) { return; } Loading @@ -123,10 +115,15 @@ public class DataLabels implements AslMarshallable { DataCategory dataCategory = dataCategoriesMap.get(dataCategoryName); for (String dataTypeName : dataCategory.getDataTypes().keySet()) { DataType dataType = dataCategory.getDataTypes().get(dataTypeName); // XmlUtils.appendChildren(dataLabelsEle, dataType.toHrDomElements(doc)); if (ephemeral != (dataType.getEphemeral() != null ? dataType.getEphemeral() : false)) { continue; } Element hrDataTypeEle = doc.createElement(dataUsageTypeName); hrDataTypeEle.setAttribute(XmlUtils.HR_ATTR_DATA_CATEGORY, dataCategoryName); hrDataTypeEle.setAttribute(XmlUtils.HR_ATTR_DATA_TYPE, dataTypeName); hrDataTypeEle.setAttribute( XmlUtils.HR_ATTR_DATA_TYPE, dataCategoryName + XmlUtils.DATA_TYPE_SEPARATOR + dataTypeName); XmlUtils.maybeSetHrBoolAttr( hrDataTypeEle, XmlUtils.HR_ATTR_IS_COLLECTION_OPTIONAL, Loading @@ -135,8 +132,6 @@ public class DataLabels implements AslMarshallable { hrDataTypeEle, XmlUtils.HR_ATTR_IS_SHARING_OPTIONAL, dataType.getIsSharingOptional()); XmlUtils.maybeSetHrBoolAttr( hrDataTypeEle, XmlUtils.HR_ATTR_EPHEMERAL, dataType.getEphemeral()); hrDataTypeEle.setAttribute( XmlUtils.HR_ATTR_PURPOSES, String.join( Loading
tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataLabelsFactory.java +74 −44 Original line number Diff line number Diff line Loading @@ -18,16 +18,15 @@ package com.android.asllib.marshallable; import com.android.asllib.util.AslgenUtil; import com.android.asllib.util.DataCategoryConstants; import com.android.asllib.util.DataTypeConstants; import com.android.asllib.util.MalformedXmlException; import com.android.asllib.util.XmlUtils; import org.w3c.dom.Element; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; public class DataLabelsFactory implements AslMarshallableFactory<DataLabels> { Loading @@ -39,13 +38,46 @@ public class DataLabelsFactory implements AslMarshallableFactory<DataLabels> { AslgenUtil.logI("Found no DataLabels in hr format."); return null; } Map<String, DataCategory> dataAccessed = getDataCategoriesWithTag(ele, XmlUtils.HR_TAG_DATA_ACCESSED); Map<String, DataCategory> dataCollected = getDataCategoriesWithTag(ele, XmlUtils.HR_TAG_DATA_COLLECTED); getDataCategoriesWithTag(ele, XmlUtils.HR_TAG_DATA_COLLECTED, false); Map<String, DataCategory> dataCollectedEphemeral = getDataCategoriesWithTag(ele, XmlUtils.HR_TAG_DATA_COLLECTED_EPHEMERAL, true); Map<String, DataCategory> dataShared = getDataCategoriesWithTag(ele, XmlUtils.HR_TAG_DATA_SHARED); DataLabels dataLabels = new DataLabels(dataAccessed, dataCollected, dataShared); getDataCategoriesWithTag(ele, XmlUtils.HR_TAG_DATA_SHARED, null); for (String dataCollectedEphemeralDataCategoryKey : dataCollectedEphemeral.keySet()) { DataCategory dataCategoryEphemeral = dataCollectedEphemeral.get(dataCollectedEphemeralDataCategoryKey); for (String dataCollectedEphemeralDataTypeKey : dataCategoryEphemeral.getDataTypes().keySet()) { if (dataCollected.containsKey(dataCollectedEphemeralDataCategoryKey) && dataCollected .get(dataCollectedEphemeralDataCategoryKey) .getDataTypes() .containsKey(dataCollectedEphemeralDataTypeKey)) { throw new MalformedXmlException( String.format( "Duplicate entries in data-collected and" + " data-collected-ephemeral: %s %s", dataCollectedEphemeralDataCategoryKey, dataCollectedEphemeralDataTypeKey)); } if (!dataCollected.containsKey(dataCollectedEphemeralDataCategoryKey)) { dataCollected.put( dataCollectedEphemeralDataCategoryKey, new DataCategory(dataCollectedEphemeralDataCategoryKey)); } DataType dataTypeEphemeral = dataCategoryEphemeral.getDataTypes().get(dataCollectedEphemeralDataTypeKey); dataCollected .get(dataCollectedEphemeralDataCategoryKey) .getDataTypes() .put(dataCollectedEphemeralDataTypeKey, dataTypeEphemeral); } } DataLabels dataLabels = new DataLabels(dataCollected, dataShared); validateIsXOptional(dataLabels); return dataLabels; } Loading @@ -58,13 +90,11 @@ public class DataLabelsFactory implements AslMarshallableFactory<DataLabels> { AslgenUtil.logI("Found no DataLabels in od format."); return null; } Map<String, DataCategory> dataAccessed = getOdDataCategoriesWithTag(dataLabelsEle, XmlUtils.OD_NAME_DATA_ACCESSED); Map<String, DataCategory> dataCollected = getOdDataCategoriesWithTag(dataLabelsEle, XmlUtils.OD_NAME_DATA_COLLECTED); Map<String, DataCategory> dataShared = getOdDataCategoriesWithTag(dataLabelsEle, XmlUtils.OD_NAME_DATA_SHARED); DataLabels dataLabels = new DataLabels(dataAccessed, dataCollected, dataShared); DataLabels dataLabels = new DataLabels(dataCollected, dataShared); validateIsXOptional(dataLabels); return dataLabels; } Loading @@ -88,56 +118,56 @@ public class DataLabelsFactory implements AslMarshallableFactory<DataLabels> { } private static Map<String, DataCategory> getDataCategoriesWithTag( Element dataLabelsEle, String dataCategoryUsageTypeTag) throws MalformedXmlException { Element dataLabelsEle, String dataCategoryUsageTypeTag, Boolean ephemeral) throws MalformedXmlException { List<Element> dataUsedElements = XmlUtils.getChildrenByTagName(dataLabelsEle, dataCategoryUsageTypeTag); Map<String, DataCategory> dataCategoryMap = new LinkedHashMap<String, DataCategory>(); Set<String> dataCategoryNames = new HashSet<String>(); for (int i = 0; i < dataUsedElements.size(); i++) { Element dataUsedEle = dataUsedElements.get(i); String dataCategoryName = dataUsedEle.getAttribute(XmlUtils.HR_ATTR_DATA_CATEGORY); String dataCategoryAndTypeCombinedStr = dataUsedEle.getAttribute(XmlUtils.HR_ATTR_DATA_TYPE); String[] strs = dataCategoryAndTypeCombinedStr.split(XmlUtils.DATA_TYPE_SEPARATOR); if (strs.length != 2) { throw new MalformedXmlException( String.format( "Could not parse human-readable data type string (expecting" + " substring of _data_type_): %s", dataCategoryAndTypeCombinedStr)); } String dataCategoryName = strs[0]; String dataTypeName = strs[1]; if (!DataCategoryConstants.getValidDataCategories().contains(dataCategoryName)) { throw new MalformedXmlException( String.format("Unrecognized category name: %s", dataCategoryName)); } dataCategoryNames.add(dataCategoryName); if (!DataTypeConstants.getValidDataTypes() .get(dataCategoryName) .contains(dataTypeName)) { throw new MalformedXmlException( String.format( "Unrecognized data type name %s for category %s", dataTypeName, dataCategoryName)); } for (String dataCategoryName : dataCategoryNames) { var dataCategoryElements = dataUsedElements.stream() .filter( ele -> ele.getAttribute(XmlUtils.HR_ATTR_DATA_CATEGORY) .equals(dataCategoryName)) .toList(); DataCategory dataCategory = new DataCategoryFactory().createFromHrElements(dataCategoryElements); dataCategoryMap.put(dataCategoryName, dataCategory); if (!dataCategoryMap.containsKey(dataCategoryName)) { dataCategoryMap.put(dataCategoryName, new DataCategory(dataCategoryName)); } dataCategoryMap .get(dataCategoryName) .getDataTypes() .put( dataTypeName, new DataTypeFactory().createFromHrElements(dataUsedEle, ephemeral)); } return dataCategoryMap; } private void validateIsXOptional(DataLabels dataLabels) throws MalformedXmlException { // Validate booleans such as isCollectionOptional, isSharingOptional. for (DataCategory dataCategory : dataLabels.getDataAccessed().values()) { for (DataType dataType : dataCategory.getDataTypes().values()) { if (dataType.getIsSharingOptional() != null) { throw new MalformedXmlException( String.format( "isSharingOptional was unexpectedly defined on a DataType" + " belonging to data accessed: %s", dataType.getDataTypeName())); } if (dataType.getIsCollectionOptional() != null) { throw new MalformedXmlException( String.format( "isCollectionOptional was unexpectedly defined on a DataType" + " belonging to data accessed: %s", dataType.getDataTypeName())); } } } for (DataCategory dataCategory : dataLabels.getDataCollected().values()) { for (DataType dataType : dataCategory.getDataTypes().values()) { if (dataType.getIsSharingOptional() != null) { Loading
tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataTypeFactory.java +17 −7 Original line number Diff line number Diff line Loading @@ -25,12 +25,22 @@ import java.util.HashSet; import java.util.List; import java.util.stream.Collectors; public class DataTypeFactory implements AslMarshallableFactory<DataType> { public class DataTypeFactory { /** Creates a {@link DataType} from the human-readable DOM element. */ @Override public DataType createFromHrElements(List<Element> elements) throws MalformedXmlException { Element hrDataTypeEle = XmlUtils.getSingleElement(elements); String dataTypeName = hrDataTypeEle.getAttribute(XmlUtils.HR_ATTR_DATA_TYPE); public DataType createFromHrElements(Element hrDataTypeEle, Boolean ephemeral) throws MalformedXmlException { String dataCategoryAndTypeCombinedStr = hrDataTypeEle.getAttribute(XmlUtils.HR_ATTR_DATA_TYPE); String[] strs = dataCategoryAndTypeCombinedStr.split(XmlUtils.DATA_TYPE_SEPARATOR); if (strs.length != 2) { throw new MalformedXmlException( String.format( "Could not parse human-readable data type string (expecting substring" + " of _data_type_): %s", dataCategoryAndTypeCombinedStr)); } String dataTypeName = strs[1]; List<DataType.Purpose> purposes = XmlUtils.getPipelineSplitAttr(hrDataTypeEle, XmlUtils.HR_ATTR_PURPOSES, true) .stream() Loading @@ -47,13 +57,13 @@ public class DataTypeFactory implements AslMarshallableFactory<DataType> { XmlUtils.getBoolAttr(hrDataTypeEle, XmlUtils.HR_ATTR_IS_COLLECTION_OPTIONAL, false); Boolean isSharingOptional = XmlUtils.getBoolAttr(hrDataTypeEle, XmlUtils.HR_ATTR_IS_SHARING_OPTIONAL, false); Boolean ephemeral = XmlUtils.getBoolAttr(hrDataTypeEle, XmlUtils.HR_ATTR_EPHEMERAL, false); // Boolean ephemeral = XmlUtils.getBoolAttr(hrDataTypeEle, XmlUtils.HR_ATTR_EPHEMERAL, // false); return new DataType( dataTypeName, purposes, isCollectionOptional, isSharingOptional, ephemeral); } /** Creates an {@link AslMarshallableFactory} from on-device DOM elements */ @Override public DataType createFromOdElements(List<Element> elements) throws MalformedXmlException { Element odDataTypeEle = XmlUtils.getSingleElement(elements); String dataTypeName = odDataTypeEle.getAttribute(XmlUtils.OD_ATTR_NAME); Loading