mirror of
https://github.com/revanced/ARSCLib.git
synced 2025-05-13 20:07:06 +02:00
make ApkFile as parent
This commit is contained in:
parent
76aa8ec7d7
commit
71437db825
@ -16,6 +16,7 @@
|
|||||||
package com.reandroid.apk;
|
package com.reandroid.apk;
|
||||||
|
|
||||||
import com.reandroid.archive.*;
|
import com.reandroid.archive.*;
|
||||||
|
import com.reandroid.arsc.ApkFile;
|
||||||
import com.reandroid.arsc.array.PackageArray;
|
import com.reandroid.arsc.array.PackageArray;
|
||||||
import com.reandroid.arsc.chunk.Chunk;
|
import com.reandroid.arsc.chunk.Chunk;
|
||||||
import com.reandroid.arsc.chunk.PackageBlock;
|
import com.reandroid.arsc.chunk.PackageBlock;
|
||||||
@ -34,12 +35,13 @@ import com.reandroid.xml.XMLDocument;
|
|||||||
import com.reandroid.xml.XMLException;
|
import com.reandroid.xml.XMLException;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
|
|
||||||
public class ApkModule {
|
public class ApkModule implements ApkFile {
|
||||||
private final String moduleName;
|
private final String moduleName;
|
||||||
private final APKArchive apkArchive;
|
private final APKArchive apkArchive;
|
||||||
private boolean loadDefaultFramework = true;
|
private boolean loadDefaultFramework = true;
|
||||||
@ -91,9 +93,7 @@ public class ApkModule {
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
public XMLDocument decodeXMLFile(String path) throws IOException, XMLException {
|
public XMLDocument decodeXMLFile(String path) throws IOException, XMLException {
|
||||||
InputSource inputSource = apkArchive.getInputSource(path);
|
ResXmlDocument resXmlDocument = loadResXmlDocument(path);
|
||||||
ResXmlDocument resXmlDocument = new ResXmlDocument();
|
|
||||||
resXmlDocument.readBytes(inputSource.openStream());
|
|
||||||
AndroidManifestBlock manifestBlock = getAndroidManifestBlock();
|
AndroidManifestBlock manifestBlock = getAndroidManifestBlock();
|
||||||
int pkgId = manifestBlock.guessCurrentPackageId();
|
int pkgId = manifestBlock.guessCurrentPackageId();
|
||||||
return resXmlDocument.decodeToXml(getTableEntryStore(), pkgId);
|
return resXmlDocument.decodeToXml(getTableEntryStore(), pkgId);
|
||||||
@ -124,10 +124,10 @@ public class ApkModule {
|
|||||||
AndroidManifestBlock manifestBlock;
|
AndroidManifestBlock manifestBlock;
|
||||||
try {
|
try {
|
||||||
manifestBlock=getAndroidManifestBlock();
|
manifestBlock=getAndroidManifestBlock();
|
||||||
} catch (IOException ignored) {
|
return manifestBlock.getMainActivity()!=null;
|
||||||
|
} catch (Exception ignored) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return manifestBlock.getMainActivity()!=null;
|
|
||||||
}
|
}
|
||||||
public String getModuleName(){
|
public String getModuleName(){
|
||||||
return moduleName;
|
return moduleName;
|
||||||
@ -315,35 +315,61 @@ public class ApkModule {
|
|||||||
return mManifestBlock!=null
|
return mManifestBlock!=null
|
||||||
|| getApkArchive().getInputSource(AndroidManifestBlock.FILE_NAME)!=null;
|
|| getApkArchive().getInputSource(AndroidManifestBlock.FILE_NAME)!=null;
|
||||||
}
|
}
|
||||||
public AndroidManifestBlock getAndroidManifestBlock() throws IOException {
|
public boolean hasTableBlock(){
|
||||||
|
return mTableBlock!=null
|
||||||
|
|| getApkArchive().getInputSource(TableBlock.FILE_NAME)!=null;
|
||||||
|
}
|
||||||
|
public AndroidManifestBlock getAndroidManifestBlock() {
|
||||||
if(mManifestBlock!=null){
|
if(mManifestBlock!=null){
|
||||||
return mManifestBlock;
|
return mManifestBlock;
|
||||||
}
|
}
|
||||||
APKArchive archive=getApkArchive();
|
APKArchive archive=getApkArchive();
|
||||||
InputSource inputSource = archive.getInputSource(AndroidManifestBlock.FILE_NAME);
|
InputSource inputSource = archive.getInputSource(AndroidManifestBlock.FILE_NAME);
|
||||||
if(inputSource==null){
|
if(inputSource==null){
|
||||||
throw new IOException("Entry not found: "+AndroidManifestBlock.FILE_NAME);
|
return null;
|
||||||
|
}
|
||||||
|
InputStream inputStream = null;
|
||||||
|
try {
|
||||||
|
inputStream = inputSource.openStream();
|
||||||
|
AndroidManifestBlock manifestBlock=AndroidManifestBlock.load(inputStream);
|
||||||
|
inputStream.close();
|
||||||
|
BlockInputSource<AndroidManifestBlock> blockInputSource=new BlockInputSource<>(inputSource.getName(),manifestBlock);
|
||||||
|
blockInputSource.setSort(inputSource.getSort());
|
||||||
|
blockInputSource.setMethod(inputSource.getMethod());
|
||||||
|
archive.add(blockInputSource);
|
||||||
|
manifestBlock.setApkFile(this);
|
||||||
|
mManifestBlock = manifestBlock;
|
||||||
|
} catch (IOException exception) {
|
||||||
|
throw new IllegalArgumentException(exception);
|
||||||
}
|
}
|
||||||
InputStream inputStream = inputSource.openStream();
|
|
||||||
AndroidManifestBlock manifestBlock=AndroidManifestBlock.load(inputStream);
|
|
||||||
inputStream.close();
|
|
||||||
BlockInputSource<AndroidManifestBlock> blockInputSource=new BlockInputSource<>(inputSource.getName(),manifestBlock);
|
|
||||||
blockInputSource.setSort(inputSource.getSort());
|
|
||||||
blockInputSource.setMethod(inputSource.getMethod());
|
|
||||||
archive.add(blockInputSource);
|
|
||||||
mManifestBlock=manifestBlock;
|
|
||||||
return mManifestBlock;
|
return mManifestBlock;
|
||||||
}
|
}
|
||||||
public boolean hasTableBlock(){
|
@Override
|
||||||
return mTableBlock!=null
|
public TableBlock getTableBlock() {
|
||||||
|| getApkArchive().getInputSource(TableBlock.FILE_NAME)!=null;
|
|
||||||
}
|
|
||||||
public TableBlock getTableBlock() throws IOException {
|
|
||||||
if(mTableBlock==null){
|
if(mTableBlock==null){
|
||||||
mTableBlock=loadTableBlock();
|
if(!hasTableBlock()){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
mTableBlock = loadTableBlock();
|
||||||
|
} catch (IOException exception) {
|
||||||
|
throw new IllegalArgumentException(exception);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return mTableBlock;
|
return mTableBlock;
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public ResXmlDocument loadResXmlDocument(String path) throws IOException{
|
||||||
|
InputSource inputSource = getApkArchive().getInputSource(path);
|
||||||
|
if(inputSource==null){
|
||||||
|
throw new FileNotFoundException("No such file in apk: " + path);
|
||||||
|
}
|
||||||
|
ResXmlDocument resXmlDocument = new ResXmlDocument();
|
||||||
|
resXmlDocument.setApkFile(this);
|
||||||
|
resXmlDocument.readBytes(inputSource.openStream());
|
||||||
|
return resXmlDocument;
|
||||||
|
}
|
||||||
|
|
||||||
// If we need TableStringPool only, this loads pool without
|
// If we need TableStringPool only, this loads pool without
|
||||||
// loading packages and other chunk blocks for faster and less memory usage
|
// loading packages and other chunk blocks for faster and less memory usage
|
||||||
public TableStringPool getVolatileTableStringPool() throws IOException{
|
public TableStringPool getVolatileTableStringPool() throws IOException{
|
||||||
@ -391,6 +417,7 @@ public class ApkModule {
|
|||||||
blockInputSource.setMethod(inputSource.getMethod());
|
blockInputSource.setMethod(inputSource.getMethod());
|
||||||
blockInputSource.setSort(inputSource.getSort());
|
blockInputSource.setSort(inputSource.getSort());
|
||||||
archive.add(blockInputSource);
|
archive.add(blockInputSource);
|
||||||
|
tableBlock.setApkFile(this);
|
||||||
return tableBlock;
|
return tableBlock;
|
||||||
}
|
}
|
||||||
public APKArchive getApkArchive() {
|
public APKArchive getApkArchive() {
|
||||||
|
@ -124,14 +124,14 @@ import java.util.*;
|
|||||||
resFile.getInputSource().write(outputStream);
|
resFile.getInputSource().write(outputStream);
|
||||||
outputStream.close();
|
outputStream.close();
|
||||||
|
|
||||||
addDecodedEntry(resFile.pickOne());
|
addDecodedEntry(entry);
|
||||||
}
|
}
|
||||||
private void decodeResXml(EntryStore entryStore, File outDir, ResFile resFile)
|
private void decodeResXml(EntryStore entryStore, File outDir, ResFile resFile)
|
||||||
throws IOException, XMLException{
|
throws IOException, XMLException{
|
||||||
Entry entry =resFile.pickOne();
|
Entry entry =resFile.pickOne();
|
||||||
PackageBlock packageBlock= entry.getPackageBlock();
|
PackageBlock packageBlock= entry.getPackageBlock();
|
||||||
ResXmlDocument resXmlDocument =new ResXmlDocument();
|
ResXmlDocument resXmlDocument = apkModule.loadResXmlDocument(
|
||||||
resXmlDocument.readBytes(resFile.getInputSource().openStream());
|
resFile.getInputSource().getName());
|
||||||
|
|
||||||
File pkgDir=new File(outDir, getPackageDirName(packageBlock));
|
File pkgDir=new File(outDir, getPackageDirName(packageBlock));
|
||||||
File resDir=new File(pkgDir, ApkUtil.RES_DIR_NAME);
|
File resDir=new File(pkgDir, ApkUtil.RES_DIR_NAME);
|
||||||
|
@ -55,7 +55,8 @@ public class FrameworkApk extends ApkModule{
|
|||||||
archive.add(tableSource);
|
archive.add(tableSource);
|
||||||
archive.add(manifestSource);
|
archive.add(manifestSource);
|
||||||
}
|
}
|
||||||
public FrameworkTable getTableBlock() throws IOException {
|
@Override
|
||||||
|
public FrameworkTable getTableBlock() {
|
||||||
return (FrameworkTable) super.getTableBlock();
|
return (FrameworkTable) super.getTableBlock();
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
@ -67,6 +68,7 @@ public class FrameworkApk extends ApkModule{
|
|||||||
}
|
}
|
||||||
InputStream inputStream = inputSource.openStream();
|
InputStream inputStream = inputSource.openStream();
|
||||||
FrameworkTable frameworkTable=FrameworkTable.load(inputStream);
|
FrameworkTable frameworkTable=FrameworkTable.load(inputStream);
|
||||||
|
frameworkTable.setApkFile(this);
|
||||||
if(hasAndroidManifestBlock()){
|
if(hasAndroidManifestBlock()){
|
||||||
optimizeTable(frameworkTable);
|
optimizeTable(frameworkTable);
|
||||||
}
|
}
|
||||||
|
@ -129,19 +129,6 @@ public class ResFile {
|
|||||||
}
|
}
|
||||||
return mBinXml;
|
return mBinXml;
|
||||||
}
|
}
|
||||||
public boolean dumpToJson(File rootDir) throws IOException {
|
|
||||||
if(!isBinaryXml()){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
String fileName=getFilePath()+ApkUtil.JSON_FILE_EXTENSION;
|
|
||||||
fileName=fileName.replace('/', File.separatorChar);
|
|
||||||
File file=new File(rootDir, fileName);
|
|
||||||
ResXmlDocument resXmlDocument =new ResXmlDocument();
|
|
||||||
resXmlDocument.readBytes(getInputSource().openStream());
|
|
||||||
JSONObject jsonObject= resXmlDocument.toJson();
|
|
||||||
jsonObject.write(file);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
public File buildOutFile(File dir){
|
public File buildOutFile(File dir){
|
||||||
String path=getFilePath();
|
String path=getFilePath();
|
||||||
path=path.replace('/', File.separatorChar);
|
path=path.replace('/', File.separatorChar);
|
||||||
|
28
src/main/java/com/reandroid/arsc/ApkFile.java
Normal file
28
src/main/java/com/reandroid/arsc/ApkFile.java
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import com.reandroid.arsc.chunk.TableBlock;
|
||||||
|
import com.reandroid.arsc.chunk.xml.AndroidManifestBlock;
|
||||||
|
import com.reandroid.arsc.chunk.xml.ResXmlDocument;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public interface ApkFile {
|
||||||
|
AndroidManifestBlock getAndroidManifestBlock();
|
||||||
|
TableBlock getTableBlock();
|
||||||
|
ResXmlDocument loadResXmlDocument(String path) throws IOException;
|
||||||
|
}
|
@ -1,7 +1,10 @@
|
|||||||
package com.reandroid.arsc.chunk;
|
package com.reandroid.arsc.chunk;
|
||||||
|
|
||||||
|
import com.reandroid.arsc.ApkFile;
|
||||||
import com.reandroid.arsc.pool.StringPool;
|
import com.reandroid.arsc.pool.StringPool;
|
||||||
|
|
||||||
public interface MainChunk {
|
public interface MainChunk {
|
||||||
public StringPool<?> getStringPool();
|
StringPool<?> getStringPool();
|
||||||
|
ApkFile getApkFile();
|
||||||
|
void setApkFile(ApkFile apkFile);
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.reandroid.arsc.chunk;
|
package com.reandroid.arsc.chunk;
|
||||||
|
|
||||||
|
import com.reandroid.arsc.ApkFile;
|
||||||
import com.reandroid.arsc.BuildInfo;
|
import com.reandroid.arsc.BuildInfo;
|
||||||
import com.reandroid.arsc.array.PackageArray;
|
import com.reandroid.arsc.array.PackageArray;
|
||||||
import com.reandroid.arsc.group.EntryGroup;
|
import com.reandroid.arsc.group.EntryGroup;
|
||||||
@ -22,24 +23,23 @@ import com.reandroid.arsc.header.HeaderBlock;
|
|||||||
import com.reandroid.arsc.header.InfoHeader;
|
import com.reandroid.arsc.header.InfoHeader;
|
||||||
import com.reandroid.arsc.header.TableHeader;
|
import com.reandroid.arsc.header.TableHeader;
|
||||||
import com.reandroid.arsc.io.BlockReader;
|
import com.reandroid.arsc.io.BlockReader;
|
||||||
import com.reandroid.arsc.pool.StringPool;
|
|
||||||
import com.reandroid.arsc.pool.TableStringPool;
|
import com.reandroid.arsc.pool.TableStringPool;
|
||||||
import com.reandroid.arsc.value.StagedAliasEntry;
|
import com.reandroid.arsc.value.StagedAliasEntry;
|
||||||
|
import com.reandroid.common.EntryStore;
|
||||||
import com.reandroid.common.Frameworks;
|
import com.reandroid.common.Frameworks;
|
||||||
import com.reandroid.json.JSONConvert;
|
import com.reandroid.json.JSONConvert;
|
||||||
import com.reandroid.json.JSONArray;
|
import com.reandroid.json.JSONArray;
|
||||||
import com.reandroid.json.JSONObject;
|
import com.reandroid.json.JSONObject;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.Collection;
|
import java.util.*;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class TableBlock extends Chunk<TableHeader>
|
public class TableBlock extends Chunk<TableHeader>
|
||||||
implements MainChunk, JSONConvert<JSONObject> {
|
implements MainChunk, JSONConvert<JSONObject>, EntryStore {
|
||||||
private final TableStringPool mTableStringPool;
|
private final TableStringPool mTableStringPool;
|
||||||
private final PackageArray mPackageArray;
|
private final PackageArray mPackageArray;
|
||||||
private final Set<TableBlock> mFrameWorks=new HashSet<>();
|
private final Set<TableBlock> mFrameWorks=new HashSet<>();
|
||||||
|
private ApkFile mApkFile;
|
||||||
public TableBlock() {
|
public TableBlock() {
|
||||||
super(new TableHeader(), 2);
|
super(new TableHeader(), 2);
|
||||||
TableHeader header = getHeaderBlock();
|
TableHeader header = getHeaderBlock();
|
||||||
@ -61,6 +61,14 @@ public class TableBlock extends Chunk<TableHeader>
|
|||||||
public TableStringPool getStringPool() {
|
public TableStringPool getStringPool() {
|
||||||
return mTableStringPool;
|
return mTableStringPool;
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public ApkFile getApkFile(){
|
||||||
|
return mApkFile;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void setApkFile(ApkFile apkFile){
|
||||||
|
this.mApkFile = apkFile;
|
||||||
|
}
|
||||||
public TableStringPool getTableStringPool(){
|
public TableStringPool getTableStringPool(){
|
||||||
return mTableStringPool;
|
return mTableStringPool;
|
||||||
}
|
}
|
||||||
@ -132,16 +140,23 @@ public class TableBlock extends Chunk<TableHeader>
|
|||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString(){
|
|
||||||
StringBuilder builder=new StringBuilder();
|
|
||||||
builder.append(super.toString());
|
|
||||||
builder.append(", packages=");
|
|
||||||
int pkgCount=mPackageArray.childesCount();
|
|
||||||
builder.append(pkgCount);
|
|
||||||
return builder.toString();
|
|
||||||
}
|
|
||||||
public EntryGroup search(int resourceId){
|
public EntryGroup search(int resourceId){
|
||||||
|
if(resourceId==0){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
EntryGroup entryGroup = searchLocal(resourceId);
|
||||||
|
if(entryGroup!=null){
|
||||||
|
return entryGroup;
|
||||||
|
}
|
||||||
|
for(TableBlock tableBlock:getFrameWorks()){
|
||||||
|
entryGroup = tableBlock.search(resourceId);
|
||||||
|
if(entryGroup!=null){
|
||||||
|
return entryGroup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
private EntryGroup searchLocal(int resourceId){
|
||||||
if(resourceId==0){
|
if(resourceId==0){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -156,14 +171,36 @@ public class TableBlock extends Chunk<TableHeader>
|
|||||||
return entryGroup;
|
return entryGroup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(TableBlock tableBlock:getFrameWorks()){
|
|
||||||
EntryGroup entryGroup = tableBlock.search(resourceId);
|
|
||||||
if(entryGroup!=null){
|
|
||||||
return entryGroup;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public Collection<EntryGroup> getEntryGroups(int resourceId) {
|
||||||
|
List<EntryGroup> results = new ArrayList<>();
|
||||||
|
EntryGroup entryGroup = searchLocal(resourceId);
|
||||||
|
if(entryGroup!=null){
|
||||||
|
results.add(entryGroup);
|
||||||
|
}
|
||||||
|
for(TableBlock framework:getFrameWorks()){
|
||||||
|
results.addAll(framework.getEntryGroups(resourceId));
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public EntryGroup getEntryGroup(int resourceId) {
|
||||||
|
return search(resourceId);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public Collection<PackageBlock> getPackageBlocks(int packageId) {
|
||||||
|
List<PackageBlock> results=new ArrayList<>();
|
||||||
|
PackageBlock packageBlock = getPackageBlockById(packageId);
|
||||||
|
if(packageBlock!=null){
|
||||||
|
results.add(packageBlock);
|
||||||
|
}
|
||||||
|
for(TableBlock tableBlock:getFrameWorks()){
|
||||||
|
results.addAll(tableBlock.getPackageBlocks(packageId));
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
public int searchResourceIdAlias(int resourceId){
|
public int searchResourceIdAlias(int resourceId){
|
||||||
for(PackageBlock packageBlock:listPackages()){
|
for(PackageBlock packageBlock:listPackages()){
|
||||||
StagedAliasEntry stagedAliasEntry =
|
StagedAliasEntry stagedAliasEntry =
|
||||||
@ -216,6 +253,16 @@ public class TableBlock extends Chunk<TableHeader>
|
|||||||
getPackageArray().merge(tableBlock.getPackageArray());
|
getPackageArray().merge(tableBlock.getPackageArray());
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public String toString(){
|
||||||
|
StringBuilder builder=new StringBuilder();
|
||||||
|
builder.append(super.toString());
|
||||||
|
builder.append(", packages=");
|
||||||
|
int pkgCount=mPackageArray.childesCount();
|
||||||
|
builder.append(pkgCount);
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
public static TableBlock loadWithAndroidFramework(InputStream inputStream) throws IOException{
|
public static TableBlock loadWithAndroidFramework(InputStream inputStream) throws IOException{
|
||||||
TableBlock tableBlock=load(inputStream);
|
TableBlock tableBlock=load(inputStream);
|
||||||
tableBlock.addFramework(Frameworks.getAndroid());
|
tableBlock.addFramework(Frameworks.getAndroid());
|
||||||
|
@ -25,13 +25,17 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class AndroidManifestBlock extends ResXmlDocument {
|
public class AndroidManifestBlock extends ResXmlDocument {
|
||||||
|
private int mGuessedPackageId;
|
||||||
public AndroidManifestBlock(){
|
public AndroidManifestBlock(){
|
||||||
super();
|
super();
|
||||||
super.getStringPool().setUtf8(false);
|
super.getStringPool().setUtf8(false);
|
||||||
}
|
}
|
||||||
// TODO: find a better way
|
// TODO: find a better way
|
||||||
public byte guessCurrentPackageId(){
|
public int guessCurrentPackageId(){
|
||||||
return (byte) ((getIconResourceId()>>24) & 0xff);
|
if(mGuessedPackageId == 0){
|
||||||
|
mGuessedPackageId = ((getIconResourceId()>>24) & 0xff);
|
||||||
|
}
|
||||||
|
return mGuessedPackageId;
|
||||||
}
|
}
|
||||||
public int getIconResourceId(){
|
public int getIconResourceId(){
|
||||||
ResXmlElement applicationElement = getApplicationElement();
|
ResXmlElement applicationElement = getApplicationElement();
|
||||||
|
@ -15,10 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package com.reandroid.arsc.chunk.xml;
|
package com.reandroid.arsc.chunk.xml;
|
||||||
|
|
||||||
import com.reandroid.arsc.chunk.Chunk;
|
import com.reandroid.arsc.ApkFile;
|
||||||
import com.reandroid.arsc.chunk.ChunkType;
|
import com.reandroid.arsc.chunk.*;
|
||||||
import com.reandroid.arsc.chunk.MainChunk;
|
|
||||||
import com.reandroid.arsc.chunk.ParentChunk;
|
|
||||||
import com.reandroid.arsc.container.SingleBlockContainer;
|
import com.reandroid.arsc.container.SingleBlockContainer;
|
||||||
import com.reandroid.arsc.header.HeaderBlock;
|
import com.reandroid.arsc.header.HeaderBlock;
|
||||||
import com.reandroid.arsc.io.BlockReader;
|
import com.reandroid.arsc.io.BlockReader;
|
||||||
@ -45,6 +43,7 @@
|
|||||||
private final ResXmlIDMap mResXmlIDMap;
|
private final ResXmlIDMap mResXmlIDMap;
|
||||||
private ResXmlElement mResXmlElement;
|
private ResXmlElement mResXmlElement;
|
||||||
private final SingleBlockContainer<ResXmlElement> mResXmlElementContainer;
|
private final SingleBlockContainer<ResXmlElement> mResXmlElementContainer;
|
||||||
|
private ApkFile mApkFile;
|
||||||
public ResXmlDocument() {
|
public ResXmlDocument() {
|
||||||
super(new HeaderBlock(ChunkType.XML),3);
|
super(new HeaderBlock(ChunkType.XML),3);
|
||||||
this.mResXmlStringPool=new ResXmlStringPool(true);
|
this.mResXmlStringPool=new ResXmlStringPool(true);
|
||||||
@ -169,6 +168,14 @@
|
|||||||
return mResXmlStringPool;
|
return mResXmlStringPool;
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
|
public ApkFile getApkFile(){
|
||||||
|
return mApkFile;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void setApkFile(ApkFile apkFile){
|
||||||
|
this.mApkFile = apkFile;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
public StringPool<?> getSpecStringPool() {
|
public StringPool<?> getSpecStringPool() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -224,6 +231,24 @@
|
|||||||
xmlElement.fromJson(json.optJSONObject(ResXmlDocument.NAME_element));
|
xmlElement.fromJson(json.optJSONObject(ResXmlDocument.NAME_element));
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
public XMLDocument decodeToXml() throws XMLException {
|
||||||
|
ApkFile apkFile = getApkFile();
|
||||||
|
if(apkFile == null){
|
||||||
|
throw new XMLException("Null parent apk file");
|
||||||
|
}
|
||||||
|
int currentPackageId = 0;
|
||||||
|
AndroidManifestBlock manifestBlock;
|
||||||
|
if(this instanceof AndroidManifestBlock){
|
||||||
|
manifestBlock = ((AndroidManifestBlock)this);
|
||||||
|
}else {
|
||||||
|
manifestBlock = apkFile.getAndroidManifestBlock();
|
||||||
|
}
|
||||||
|
if(manifestBlock!=null){
|
||||||
|
currentPackageId = manifestBlock.guessCurrentPackageId();
|
||||||
|
}
|
||||||
|
TableBlock tableBlock = apkFile.getTableBlock();
|
||||||
|
return decodeToXml(tableBlock, currentPackageId);
|
||||||
|
}
|
||||||
public XMLDocument decodeToXml(EntryStore entryStore, int currentPackageId) throws XMLException {
|
public XMLDocument decodeToXml(EntryStore entryStore, int currentPackageId) throws XMLException {
|
||||||
XMLDocument xmlDocument = new XMLDocument();
|
XMLDocument xmlDocument = new XMLDocument();
|
||||||
XMLElement xmlElement = getResXmlElement()
|
XMLElement xmlElement = getResXmlElement()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user