1616package com .reandroid .apk ;
1717
1818import com .reandroid .app .AndroidManifest ;
19+ import com .reandroid .arsc .chunk .TableBlock ;
1920import com .reandroid .arsc .chunk .xml .AndroidManifestBlock ;
21+ import com .reandroid .arsc .chunk .xml .ResXmlAttribute ;
22+ import com .reandroid .arsc .chunk .xml .ResXmlElement ;
23+ import com .reandroid .arsc .model .ResourceEntry ;
24+ import com .reandroid .arsc .value .Entry ;
25+ import com .reandroid .arsc .value .ValueType ;
2026import com .reandroid .utils .collection .CollectionUtil ;
27+ import com .reandroid .utils .collection .ComputeIterator ;
2128import com .reandroid .xml .XMLPath ;
2229
2330import java .util .Set ;
@@ -27,15 +34,11 @@ public class AndroidManifestBlockSplitSanitizer {
2734 private boolean mEnabled ;
2835 private final Set <XMLPath > removeAttributeList ;
2936 private final Set <XMLPath > removeElementList ;
37+ private final XMLPath splitsPath ;
3038
3139 public AndroidManifestBlockSplitSanitizer () {
3240 this .mEnabled = true ;
3341
34- XMLPath manifest = XMLPath .newElement (AndroidManifest .TAG_manifest );
35- XMLPath application = manifest .element (AndroidManifest .TAG_application );
36- XMLPath appMetaData = application .element (AndroidManifest .TAG_meta_data );
37- XMLPath appMetaDataName = appMetaData .attribute (AndroidManifest .ID_name );
38-
3942 this .removeAttributeList = CollectionUtil .asHashSet (
4043 XMLPath .newElement (XMLPath .ANY_ELEMENT_PATH )
4144 .attribute (AndroidManifest .ID_isFeatureSplit )
@@ -51,12 +54,16 @@ public AndroidManifestBlockSplitSanitizer() {
5154 .alternate (AndroidManifest .NAME_isSplitRequired )
5255 );
5356
57+ XMLPath appMetaDataName = AndroidManifest .PATH_APPLICATION_META_DATA_NAME ;
58+
59+ this .splitsPath = appMetaDataName .value ("com.android.vending.splits" );
60+
5461 this .removeElementList = CollectionUtil .asHashSet (
55- manifest .element (AndroidManifest .TAG_uses_split ),
56- appMetaDataName .value ("com.android.vending.splits.required" ),
57- appMetaDataName .value ("com.android.vending.splits " ),
58- appMetaDataName .value ("com.android.stamp.source " ),
59- appMetaDataName .value ("com.android.stamp.type " )
62+ AndroidManifest . PATH_MANIFEST .element (AndroidManifest .TAG_uses_split ),
63+ appMetaDataName .alternateValue ("com.android.vending.splits.required" ),
64+ appMetaDataName .alternateValue ("com.android.stamp.source " ),
65+ appMetaDataName .alternateValue ("com.android.stamp.type " ),
66+ appMetaDataName .alternateValue ("com.android.vending.derived.apk.id " )
6067 );
6168 }
6269
@@ -77,6 +84,19 @@ public boolean isEnabled() {
7784 return mEnabled ;
7885 }
7986
87+ public boolean sanitize (ApkModule apkModule ) {
88+ if (!isEnabled ()) {
89+ return false ;
90+ }
91+ AndroidManifestBlock manifestBlock = apkModule .getAndroidManifest ();
92+ if (manifestBlock == null ) {
93+ return false ;
94+ }
95+ boolean result = sanitize (manifestBlock );
96+ result = deleteSplitsXml (apkModule , manifestBlock ) || result ;
97+ apkModule .setExtractNativeLibs (manifestBlock .isExtractNativeLibs ());
98+ return result ;
99+ }
80100 public boolean sanitize (AndroidManifestBlock manifestBlock ) {
81101 if (!isEnabled ()) {
82102 return false ;
@@ -89,7 +109,35 @@ public boolean sanitize(AndroidManifestBlock manifestBlock) {
89109 result = removeElements (manifestBlock ) || result ;
90110 return result ;
91111 }
92-
112+ private boolean deleteSplitsXml (ApkModule apkModule , AndroidManifestBlock manifestBlock ) {
113+ ResXmlElement element = manifestBlock .getNamedElement (AndroidManifest .PATH_APPLICATION_META_DATA ,
114+ "com.android.vending.splits" );
115+ if (element == null ) {
116+ return false ;
117+ }
118+ ResXmlAttribute attribute = element .searchAttributeByResourceId (AndroidManifest .ID_resource );
119+ if (attribute == null ) {
120+ attribute = element .searchAttributeByResourceId (AndroidManifest .ID_value );
121+ }
122+ if (attribute == null || attribute .getValueType () != ValueType .REFERENCE ) {
123+ return false ;
124+ }
125+ TableBlock tableBlock = apkModule .getTableBlock ();
126+ if (tableBlock == null ) {
127+ return false ;
128+ }
129+ ResourceEntry resourceEntry = tableBlock .getResource (attribute .getData ());
130+ if (resourceEntry == null ) {
131+ return false ;
132+ }
133+ element .removeSelf ();
134+ String path = CollectionUtil .getFirst (ComputeIterator .of (
135+ resourceEntry .iterator (true ), Entry ::getValueAsString ));
136+ if (path != null ) {
137+ return apkModule .removeResFile (path , false );
138+ }
139+ return true ;
140+ }
93141 private boolean removeAttributes (AndroidManifestBlock manifestBlock ) {
94142 boolean results = false ;
95143 for (XMLPath path : removeAttributeList ) {
0 commit comments