From 268f557d473c0058b4e787c04a3b6a60f96b85d4 Mon Sep 17 00:00:00 2001 From: REAndroid Date: Mon, 13 Mar 2023 11:19:45 -0400 Subject: [PATCH] [Framework] remove non default ResConfig entries --- .../java/com/reandroid/apk/FrameworkApk.java | 5 +- .../com/reandroid/apk/FrameworkOptimizer.java | 6 +- .../reandroid/arsc/util/FrameworkTable.java | 72 +++++++++++-------- 3 files changed, 45 insertions(+), 38 deletions(-) diff --git a/src/main/java/com/reandroid/apk/FrameworkApk.java b/src/main/java/com/reandroid/apk/FrameworkApk.java index 01ead82..1c99689 100644 --- a/src/main/java/com/reandroid/apk/FrameworkApk.java +++ b/src/main/java/com/reandroid/apk/FrameworkApk.java @@ -174,9 +174,6 @@ return frameworkTable; } public void optimize(){ - optimize(true); - } - public void optimize(boolean keepOnlyAttrsAndId){ synchronized (mLock){ if(mOptimizing){ return; @@ -190,7 +187,7 @@ mOptimizing = false; return; } - FrameworkOptimizer optimizer = new FrameworkOptimizer(this, keepOnlyAttrsAndId); + FrameworkOptimizer optimizer = new FrameworkOptimizer(this); optimizer.optimize(); mOptimizing = false; } diff --git a/src/main/java/com/reandroid/apk/FrameworkOptimizer.java b/src/main/java/com/reandroid/apk/FrameworkOptimizer.java index c1aaed3..26719fd 100644 --- a/src/main/java/com/reandroid/apk/FrameworkOptimizer.java +++ b/src/main/java/com/reandroid/apk/FrameworkOptimizer.java @@ -36,11 +36,9 @@ import java.util.zip.ZipEntry; private final ApkModule frameworkApk; private APKLogger apkLogger; private boolean mOptimizing; - private final boolean keepOnlyAttrsAndId; - public FrameworkOptimizer(ApkModule frameworkApk, boolean keepOnlyAttrsAndId){ + public FrameworkOptimizer(ApkModule frameworkApk){ this.frameworkApk = frameworkApk; this.apkLogger = frameworkApk.getApkLogger(); - this.keepOnlyAttrsAndId = keepOnlyAttrsAndId; } public void optimize(){ if(mOptimizing){ @@ -102,7 +100,7 @@ import java.util.zip.ZipEntry; backupManifestValue(manifestBlock, table); } logMessage("Optimizing table ..."); - table.optimize(name, version, keepOnlyAttrsAndId); + table.optimize(name, version); long diff=prev - table.countBytes(); long percent=(diff*100L)/prev; logMessage("Table size reduced by: "+percent+" %"); diff --git a/src/main/java/com/reandroid/arsc/util/FrameworkTable.java b/src/main/java/com/reandroid/arsc/util/FrameworkTable.java index 5f573ca..c1144ac 100755 --- a/src/main/java/com/reandroid/arsc/util/FrameworkTable.java +++ b/src/main/java/com/reandroid/arsc/util/FrameworkTable.java @@ -29,6 +29,7 @@ import com.reandroid.arsc.item.ReferenceItem; import com.reandroid.arsc.item.TableString; import com.reandroid.arsc.pool.TableStringPool; import com.reandroid.arsc.value.Entry; +import com.reandroid.arsc.value.ResConfig; import java.io.*; import java.util.*; @@ -173,21 +174,55 @@ public class FrameworkTable extends TableBlock { writeProperty(PROP_NAME, value); } } - - public void optimize(String name, int version, boolean keepOnlyAttrsAndId){ + public void optimize(String name, int version){ mOptimizeChecked = true; mOptimized = false; - if(keepOnlyAttrsAndId){ - removeTypesExceptAttrId(); - }else { - optimizeEntries(); - } + ensureTypeBlockNonNullEntries(); + optimizeEntries(); optimizeTableString(); writeVersionCode(version); mOptimizeChecked = false; setFrameworkName(name); refresh(); } + private void ensureTypeBlockNonNullEntries(){ + for(PackageBlock packageBlock:listPackages()){ + ensureTypeBlockNonNullEntries(packageBlock); + } + } + private void ensureTypeBlockNonNullEntries(PackageBlock packageBlock){ + for(SpecTypePair specTypePair:packageBlock.listAllSpecTypePair()){ + ensureTypeBlockNonNullEntries(specTypePair); + } + } + private void ensureTypeBlockNonNullEntries(SpecTypePair specTypePair){ + Map map = specTypePair.createEntryGroups(); + for(EntryGroup entryGroup:map.values()){ + ensureNonNullDefaultEntry(entryGroup); + } + } + private void ensureNonNullDefaultEntry(EntryGroup entryGroup){ + Entry defEntry = entryGroup.getDefault(false); + Entry entry; + if(defEntry==null){ + entry = entryGroup.pickOne(); + if(entry == null){ + return; + } + SpecTypePair specTypePair = entry.getTypeBlock().getParentSpecTypePair(); + TypeBlock type = specTypePair.getOrCreateTypeBlock(new ResConfig()); + defEntry = type.getOrCreateEntry((short) (entry.getId() & 0xffff)); + } + if(!defEntry.isNull()){ + return; + } + entry = entryGroup.pickOne(); + if(entry.isNull()){ + return; + } + defEntry.merge(entry); + defEntry.isDefault(); + } private void optimizeEntries(){ Map groupMap=scanAllEntryGroups(); for(EntryGroup group:groupMap.values()){ @@ -202,29 +237,6 @@ public class FrameworkTable extends TableBlock { pkg.refresh(); } } - private void removeTypesExceptAttrId(){ - for(PackageBlock pkg:listPackages()){ - SpecTypePairArray pairArray = pkg.getSpecTypePairArray(); - List specTypePairList = - new ArrayList<>(pairArray.listItems()); - for(SpecTypePair specTypePair:specTypePairList){ - String name=specTypePair.getTypeName(); - if(shouldRemoveType(name)){ - specTypePair.destroy(); - pairArray.remove(specTypePair); - } - } - } - } - private boolean shouldRemoveType(String typeName){ - if(typeName==null){ - return true; - } - if("id".equals(typeName)){ - return false; - } - return !typeName.contains("attr"); - } private void removeEmptyBlocks(PackageBlock pkg){ SpecTypePairArray specTypePairArray = pkg.getSpecTypePairArray(); specTypePairArray.sort();