From 6fce5ad5ed451bd8ef34ec15e08fe52a5bfccb5e Mon Sep 17 00:00:00 2001 From: REAndroid Date: Fri, 28 Apr 2023 11:57:47 +0200 Subject: [PATCH] disable entry group mapping when not necessary --- .../java/com/reandroid/apk/ApkBundle.java | 12 +- .../java/com/reandroid/apk/ApkModule.java | 16 +- .../reandroid/arsc/array/PackageArray.java | 22 ++- .../reandroid/arsc/chunk/PackageBlock.java | 139 ++++++++++-------- .../com/reandroid/arsc/chunk/TableBlock.java | 53 ++++--- 5 files changed, 145 insertions(+), 97 deletions(-) diff --git a/src/main/java/com/reandroid/apk/ApkBundle.java b/src/main/java/com/reandroid/apk/ApkBundle.java index 6e99cb8..607d3c6 100644 --- a/src/main/java/com/reandroid/apk/ApkBundle.java +++ b/src/main/java/com/reandroid/apk/ApkBundle.java @@ -1,4 +1,4 @@ - /* +/* * Copyright (C) 2022 github.com/REAndroid * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -38,8 +38,9 @@ public class ApkBundle { if(moduleList.size()==0){ throw new FileNotFoundException("Nothing to merge, empty modules"); } - ApkModule result=new ApkModule(generateMergedModuleName(), new APKArchive()); + ApkModule result = new ApkModule(generateMergedModuleName(), new APKArchive()); result.setAPKLogger(apkLogger); + result.setDisableEntryGroupMap(true); result.setLoadDefaultFramework(false); mergeStringPools(result); @@ -157,15 +158,16 @@ public class ApkBundle { logMessage("Found apk files: "+apkList.size()); for(File file:apkList){ logVerbose("Loading: "+file.getName()); - String name=ApkUtil.toModuleName(file); - ApkModule module=ApkModule.loadApkFile(file, name); + String name = ApkUtil.toModuleName(file); + ApkModule module = ApkModule.loadApkFile(file, name); module.setAPKLogger(apkLogger); addModule(module); } } public void addModule(ApkModule apkModule){ apkModule.setLoadDefaultFramework(false); - String name=apkModule.getModuleName(); + apkModule.setDisableEntryGroupMap(true); + String name = apkModule.getModuleName(); mModulesMap.remove(name); mModulesMap.put(name, apkModule); } diff --git a/src/main/java/com/reandroid/apk/ApkModule.java b/src/main/java/com/reandroid/apk/ApkModule.java index 3199adc..75b9a2d 100644 --- a/src/main/java/com/reandroid/apk/ApkModule.java +++ b/src/main/java/com/reandroid/apk/ApkModule.java @@ -1,4 +1,4 @@ - /* +/* * Copyright (C) 2022 github.com/REAndroid * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -57,6 +57,8 @@ public class ApkModule implements ApkFile { private Decoder mDecoder; private ApkType mApkType; private ApkSignatureBlock apkSignatureBlock; + private boolean disableEntryGroupMap; + public ApkModule(String moduleName, APKArchive apkArchive){ this.moduleName=moduleName; this.apkArchive=apkArchive; @@ -64,6 +66,16 @@ public class ApkModule implements ApkFile { this.mUncompressedFiles.addPath(apkArchive); } + public boolean isDisableEntryGroupMap() { + return disableEntryGroupMap; + } + public void setDisableEntryGroupMap(boolean disable) { + this.disableEntryGroupMap = disable; + TableBlock tableBlock = this.mTableBlock; + if(tableBlock != null){ + tableBlock.setDisableEntryGroupMap(disable); + } + } public ApkSignatureBlock getApkSignatureBlock() { return apkSignatureBlock; } @@ -525,6 +537,7 @@ public class ApkModule implements ApkFile { new BlockInputSource<>(TableBlock.FILE_NAME, tableBlock); archive.add(source); mTableBlock = tableBlock; + tableBlock.setDisableEntryGroupMap(isDisableEntryGroupMap()); } @Override public AndroidManifestBlock getAndroidManifestBlock() { @@ -563,6 +576,7 @@ public class ApkModule implements ApkFile { } try { mTableBlock = loadTableBlock(); + mTableBlock.setDisableEntryGroupMap(isDisableEntryGroupMap()); if(initFramework && loadDefaultFramework){ Integer version = getAndroidFrameworkVersion(); initializeAndroidFramework(mTableBlock, version); diff --git a/src/main/java/com/reandroid/arsc/array/PackageArray.java b/src/main/java/com/reandroid/arsc/array/PackageArray.java index 7791538..b40ff49 100755 --- a/src/main/java/com/reandroid/arsc/array/PackageArray.java +++ b/src/main/java/com/reandroid/arsc/array/PackageArray.java @@ -1,4 +1,4 @@ - /* +/* * Copyright (C) 2022 github.com/REAndroid * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,6 +18,7 @@ package com.reandroid.arsc.array; import com.reandroid.arsc.base.Block; import com.reandroid.arsc.base.BlockArray; import com.reandroid.arsc.chunk.PackageBlock; +import com.reandroid.arsc.chunk.TableBlock; import com.reandroid.arsc.io.BlockLoad; import com.reandroid.arsc.io.BlockReader; import com.reandroid.arsc.item.IntegerItem; @@ -84,13 +85,17 @@ public class PackageArray extends BlockArray return getOrCreate(0xff & pkgId); } public PackageBlock getOrCreate(int pkgId){ - PackageBlock packageBlock=getPackageBlockById(pkgId); - if(packageBlock!=null){ + PackageBlock packageBlock = getPackageBlockById(pkgId); + if(packageBlock != null){ return packageBlock; } - packageBlock=createNext(); + packageBlock = createNext(); packageBlock.setId(pkgId); packageBlock.setName("PACKAGE NAME"); + TableBlock tableBlock = getParentInstance(TableBlock.class); + if(tableBlock != null){ + packageBlock.setDisableEntryGroupMap(tableBlock.isDisableEntryGroupMap()); + } return packageBlock; } public PackageBlock getPackageBlockById(byte pkgId){ @@ -126,8 +131,13 @@ public class PackageArray extends BlockArray @Override public void onBlockLoaded(BlockReader reader, Block sender) throws IOException { - if(sender==mPackageCount){ - setChildesCount(mPackageCount.get()); + if(sender != mPackageCount){ + return; + } + setChildesCount(mPackageCount.get()); + TableBlock tableBlock = getParentInstance(TableBlock.class); + if(tableBlock != null){ + tableBlock.setDisableEntryGroupMap(tableBlock.isDisableEntryGroupMap()); } } @Override diff --git a/src/main/java/com/reandroid/arsc/chunk/PackageBlock.java b/src/main/java/com/reandroid/arsc/chunk/PackageBlock.java index ad77dd5..3ac17a5 100755 --- a/src/main/java/com/reandroid/arsc/chunk/PackageBlock.java +++ b/src/main/java/com/reandroid/arsc/chunk/PackageBlock.java @@ -1,48 +1,48 @@ - /* - * Copyright (C) 2022 github.com/REAndroid - * - * 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. - */ +/* + * Copyright (C) 2022 github.com/REAndroid + * + * 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.reandroid.arsc.chunk; - import com.reandroid.arsc.BuildInfo; - import com.reandroid.arsc.array.LibraryInfoArray; - import com.reandroid.arsc.array.SpecTypePairArray; - import com.reandroid.arsc.base.Block; - import com.reandroid.arsc.container.BlockList; - import com.reandroid.arsc.container.PackageBody; - import com.reandroid.arsc.container.SpecTypePair; - import com.reandroid.arsc.group.EntryGroup; - import com.reandroid.arsc.header.PackageHeader; - import com.reandroid.arsc.list.OverlayableList; - import com.reandroid.arsc.list.StagedAliasList; - import com.reandroid.arsc.pool.SpecStringPool; - import com.reandroid.arsc.pool.TypeStringPool; - import com.reandroid.arsc.value.Entry; - import com.reandroid.arsc.value.LibraryInfo; - import com.reandroid.arsc.value.ResConfig; - import com.reandroid.arsc.value.StagedAliasEntry; - import com.reandroid.json.JSONArray; - import com.reandroid.json.JSONConvert; - import com.reandroid.json.JSONObject; +import com.reandroid.arsc.BuildInfo; +import com.reandroid.arsc.array.LibraryInfoArray; +import com.reandroid.arsc.array.SpecTypePairArray; +import com.reandroid.arsc.base.Block; +import com.reandroid.arsc.container.BlockList; +import com.reandroid.arsc.container.PackageBody; +import com.reandroid.arsc.container.SpecTypePair; +import com.reandroid.arsc.group.EntryGroup; +import com.reandroid.arsc.header.PackageHeader; +import com.reandroid.arsc.list.OverlayableList; +import com.reandroid.arsc.list.StagedAliasList; +import com.reandroid.arsc.pool.SpecStringPool; +import com.reandroid.arsc.pool.TypeStringPool; +import com.reandroid.arsc.value.Entry; +import com.reandroid.arsc.value.LibraryInfo; +import com.reandroid.arsc.value.ResConfig; +import com.reandroid.arsc.value.StagedAliasEntry; +import com.reandroid.json.JSONArray; +import com.reandroid.json.JSONConvert; +import com.reandroid.json.JSONObject; - import java.util.*; +import java.util.*; - public class PackageBlock extends Chunk +public class PackageBlock extends Chunk implements ParentChunk, - JSONConvert, - Comparable { + JSONConvert, + Comparable { private final TypeStringPool mTypeStringPool; private final SpecStringPool mSpecStringPool; @@ -50,6 +50,7 @@ package com.reandroid.arsc.chunk; private final PackageBody mBody; private final Map mEntriesGroup; + private boolean disableEntryGroupMap; public PackageBlock() { super(new PackageHeader(), 3); @@ -103,7 +104,7 @@ package com.reandroid.arsc.chunk; return getHeaderBlock().getTypeIdOffset(); } public BlockList getUnknownChunkList(){ - return mBody.getUnknownChunkList(); + return mBody.getUnknownChunkList(); } public StagedAliasEntry searchByStagedResId(int stagedResId){ @@ -142,8 +143,8 @@ package com.reandroid.arsc.chunk; return getHeaderBlock().getPackageId().get(); } public void setId(byte id){ - setId(0xff & id); - } + setId(0xff & id); + } public void setId(int id){ getHeaderBlock().getPackageId().set(id); } @@ -175,7 +176,7 @@ package com.reandroid.arsc.chunk; return getTableBlock(); } public PackageBody getPackageBody() { - return mBody; + return mBody; } public SpecTypePairArray getSpecTypePairArray(){ return mBody.getSpecTypePairArray(); @@ -213,6 +214,13 @@ package com.reandroid.arsc.chunk; public TypeBlock getTypeBlock(byte typeId, String qualifiers){ return getSpecTypePairArray().getTypeBlock(typeId, qualifiers); } + + public boolean isDisableEntryGroupMap() { + return disableEntryGroupMap; + } + public void setDisableEntryGroupMap(boolean disable) { + this.disableEntryGroupMap = disable; + } public Map getEntriesGroupMap(){ return mEntriesGroup; } @@ -240,35 +248,36 @@ package com.reandroid.arsc.chunk; return null; } public void updateEntry(Entry entry){ - if(entry ==null|| entry.isNull()){ + if(isDisableEntryGroupMap()){ return; } - updateEntryGroup(entry); - } - public void removeEntryGroup(Entry entry){ - if(entry ==null){ + if(entry == null || entry.isNull()){ return; } - int id= entry.getResourceId(); - EntryGroup group=getEntriesGroupMap().get(id); - if(group==null){ - return; - } - group.remove(entry); - if(group.size()==0){ - getEntriesGroupMap().remove(id); - } - } - private void updateEntryGroup(Entry entry){ - int resId= entry.getResourceId(); - EntryGroup group=getEntriesGroupMap().get(resId); - if(group==null){ - group=new EntryGroup(resId); - getEntriesGroupMap().put(resId, group); + int resourceId = entry.getResourceId(); + Map map = getEntriesGroupMap(); + EntryGroup group = map.get(resourceId); + if(group == null){ + group = new EntryGroup(resourceId); + map.put(resourceId, group); } group.add(entry); } - + public void removeEntryGroup(Entry entry){ + if(entry == null){ + return; + } + int resourceId = entry.getResourceId(); + Map map = getEntriesGroupMap(); + EntryGroup group = map.get(resourceId); + if(group == null){ + return; + } + group.remove(entry); + if(group.size() == 0){ + map.remove(resourceId); + } + } public List listEntries(byte typeId, int entryId){ List results=new ArrayList<>(); for(SpecTypePair pair:listSpecTypePair(typeId)){ diff --git a/src/main/java/com/reandroid/arsc/chunk/TableBlock.java b/src/main/java/com/reandroid/arsc/chunk/TableBlock.java index 9e30e84..32dff79 100755 --- a/src/main/java/com/reandroid/arsc/chunk/TableBlock.java +++ b/src/main/java/com/reandroid/arsc/chunk/TableBlock.java @@ -1,18 +1,18 @@ - /* - * Copyright (C) 2022 github.com/REAndroid - * - * 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. - */ +/* + * Copyright (C) 2022 github.com/REAndroid + * + * 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.reandroid.arsc.chunk; import com.reandroid.arsc.ApkFile; @@ -35,21 +35,34 @@ import java.io.*; import java.util.*; import java.util.function.Predicate; - public class TableBlock extends Chunk +public class TableBlock extends Chunk implements MainChunk, JSONConvert, EntryStore { private final TableStringPool mTableStringPool; private final PackageArray mPackageArray; - private final List mFrameWorks=new ArrayList<>(); + private final List mFrameWorks; private ApkFile mApkFile; private ReferenceResolver referenceResolver; + private boolean disableEntryGroupMap; + public TableBlock() { super(new TableHeader(), 2); TableHeader header = getHeaderBlock(); - this.mTableStringPool=new TableStringPool(true); - this.mPackageArray=new PackageArray(header.getPackageCount()); + this.mTableStringPool = new TableStringPool(true); + this.mPackageArray = new PackageArray(header.getPackageCount()); + this.mFrameWorks = new ArrayList<>(); addChild(mTableStringPool); addChild(mPackageArray); } + + public boolean isDisableEntryGroupMap() { + return disableEntryGroupMap; + } + public void setDisableEntryGroupMap(boolean disable) { + this.disableEntryGroupMap = disable; + for(PackageBlock packageBlock : listPackages()){ + packageBlock.setDisableEntryGroupMap(disable); + } + } public List resolveReference(int referenceId){ return resolveReference(referenceId, null); } @@ -83,7 +96,7 @@ import java.util.function.Predicate; return getPackageArray().pickOne(); } public PackageBlock pickOne(int packageId){ - return getPackageArray().pickOne(packageId); + return getPackageArray().pickOne(packageId); } public void sortPackages(){ getPackageArray().sort();