|
23 | 23 | import com.reandroid.arsc.model.ResourceEntry;
|
24 | 24 | import com.reandroid.arsc.value.ValueType;
|
25 | 25 | import com.reandroid.utils.ObjectsUtil;
|
26 |
| -import com.reandroid.utils.collection.*; |
| 26 | +import com.reandroid.utils.StringsUtil; |
| 27 | +import com.reandroid.utils.collection.ArrayCollection; |
| 28 | +import com.reandroid.utils.collection.CollectionUtil; |
| 29 | +import com.reandroid.utils.collection.CombiningIterator; |
| 30 | +import com.reandroid.utils.collection.ComputeIterator; |
27 | 31 |
|
28 | 32 | import java.io.File;
|
29 | 33 | import java.io.IOException;
|
30 | 34 | import java.io.InputStream;
|
31 | 35 | import java.util.Iterator;
|
32 | 36 | import java.util.List;
|
| 37 | +import java.util.function.Predicate; |
33 | 38 |
|
34 | 39 | @SuppressWarnings("unused")
|
35 | 40 | public class AndroidManifestBlock extends ResXmlDocument implements AndroidManifest {
|
@@ -101,6 +106,78 @@ public void setSplit(String split, boolean forceCreate) {
|
101 | 106 | }
|
102 | 107 | attribute.setValueAsString(split);
|
103 | 108 | }
|
| 109 | + |
| 110 | + /** |
| 111 | + * Returns "include" value from split manifest |
| 112 | + * |
| 113 | + * e.g. |
| 114 | + * <dist:module type="asset-pack"> |
| 115 | + * <dist:fusing include="true" /> |
| 116 | + * </dist:module> |
| 117 | + */ |
| 118 | + public boolean isFusingInclude() { |
| 119 | + ResXmlElement manifestElement = getManifestElement(); |
| 120 | + if (manifestElement != null) { |
| 121 | + Iterator<ResXmlElement> modules = manifestElement.getElements("module"); |
| 122 | + while (modules.hasNext()) { |
| 123 | + Iterator<ResXmlElement> iterator = modules.next().getElements("fusing"); |
| 124 | + while (iterator.hasNext()) { |
| 125 | + ResXmlAttribute attribute = iterator.next() |
| 126 | + .searchAttributeByName("include"); |
| 127 | + if (attribute != null && attribute.getValueType() == ValueType.BOOLEAN) { |
| 128 | + return attribute.getValueAsBoolean(); |
| 129 | + } |
| 130 | + } |
| 131 | + } |
| 132 | + } |
| 133 | + return false; |
| 134 | + } |
| 135 | + public String[] getFusedModules() { |
| 136 | + ResXmlElement manifestElement = getManifestElement(); |
| 137 | + if (manifestElement != null) { |
| 138 | + ResXmlElement metaData = CollectionUtil.getFirst( |
| 139 | + manifestElement.getElements(PREDICATE_FUSED_MODULES)); |
| 140 | + if (metaData != null) { |
| 141 | + ResXmlAttribute attribute = metaData.searchAttributeByResourceId(ID_value); |
| 142 | + if (attribute != null && attribute.getValueType() == ValueType.STRING) { |
| 143 | + return StringsUtil.split(attribute.getValueAsString(), ','); |
| 144 | + } |
| 145 | + } |
| 146 | + } |
| 147 | + return null; |
| 148 | + } |
| 149 | + public void addFusedModules(String ... names) { |
| 150 | + if (names == null || names.length == 0) { |
| 151 | + return; |
| 152 | + } |
| 153 | + ResXmlElement manifestElement = getOrCreateManifestElement(); |
| 154 | + ResXmlElement metaData = CollectionUtil.getFirst( |
| 155 | + manifestElement.getElements(PREDICATE_FUSED_MODULES)); |
| 156 | + if (metaData == null) { |
| 157 | + metaData = manifestElement.newElement(TAG_meta_data); |
| 158 | + metaData.getOrCreateAndroidAttribute(NAME_name, ID_name) |
| 159 | + .setValueAsString(VALUE_com_android_dynamic_apk_fused_modules); |
| 160 | + } |
| 161 | + ResXmlAttribute attribute = metaData.getOrCreateAndroidAttribute(NAME_value, ID_value); |
| 162 | + ArrayCollection<String> nameList = new ArrayCollection<>(); |
| 163 | + String value = attribute.getValueAsString(); |
| 164 | + if (value != null) { |
| 165 | + nameList.addAll(StringsUtil.split(value, ',')); |
| 166 | + } |
| 167 | + for (String name : names) { |
| 168 | + if (!StringsUtil.isEmpty(name) && !nameList.contains(name)) { |
| 169 | + nameList.add(name); |
| 170 | + } |
| 171 | + } |
| 172 | + attribute.setValueAsString(StringsUtil.join(nameList, ',')); |
| 173 | + } |
| 174 | + public boolean clearFusedModules() { |
| 175 | + ResXmlElement manifestElement = getManifestElement(); |
| 176 | + if (manifestElement != null) { |
| 177 | + return manifestElement.removeElementsIf(PREDICATE_FUSED_MODULES); |
| 178 | + } |
| 179 | + return false; |
| 180 | + } |
104 | 181 | // TODO: find a better way
|
105 | 182 | public int guessCurrentPackageId() {
|
106 | 183 | if (mGuessedPackageId == 0) {
|
@@ -700,4 +777,9 @@ public static AndroidManifestBlock empty() {
|
700 | 777 | manifestBlock.getOrCreateElement(EMPTY_MANIFEST_TAG);
|
701 | 778 | return manifestBlock;
|
702 | 779 | }
|
| 780 | + |
| 781 | + public static final Predicate<ResXmlElement> PREDICATE_FUSED_MODULES = element -> |
| 782 | + element.equalsName(TAG_meta_data) && |
| 783 | + VALUE_com_android_dynamic_apk_fused_modules.equals( |
| 784 | + getAndroidNameValue(element)); |
703 | 785 | }
|
0 commit comments