mirror of
https://github.com/revanced/Apktool.git
synced 2024-12-12 05:47:46 +01:00
Merge pull request #109 from iBotPeaches/shared_rebuild
Shared Library Rebuilding Support
This commit is contained in:
commit
35f9786fac
@ -270,6 +270,7 @@ public class Androlib {
|
|||||||
mAndRes.setPackageId((Map<String, String>) meta.get("packageInfo"));
|
mAndRes.setPackageId((Map<String, String>) meta.get("packageInfo"));
|
||||||
mAndRes.setPackageInfo((Map<String, String>) meta.get("packageInfo"));
|
mAndRes.setPackageInfo((Map<String, String>) meta.get("packageInfo"));
|
||||||
mAndRes.setVersionInfo((Map<String, String>) meta.get("versionInfo"));
|
mAndRes.setVersionInfo((Map<String, String>) meta.get("versionInfo"));
|
||||||
|
mAndRes.setSharedLibrary((boolean) (meta.get("sharedLibrary") == null ? false : meta.get("sharedLibrary")));
|
||||||
|
|
||||||
if (outFile == null) {
|
if (outFile == null) {
|
||||||
String outFileName = (String) meta.get("apkFileName");
|
String outFileName = (String) meta.get("apkFileName");
|
||||||
|
@ -320,6 +320,7 @@ public class ApkDecoder {
|
|||||||
putPackageInfo(meta);
|
putPackageInfo(meta);
|
||||||
putVersionInfo(meta);
|
putVersionInfo(meta);
|
||||||
putCompressionInfo(meta);
|
putCompressionInfo(meta);
|
||||||
|
putSharedLibraryInfo(meta);
|
||||||
}
|
}
|
||||||
putUnknownInfo(meta);
|
putUnknownInfo(meta);
|
||||||
|
|
||||||
@ -393,6 +394,10 @@ public class ApkDecoder {
|
|||||||
meta.put("compressionType", getCompressionType());
|
meta.put("compressionType", getCompressionType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void putSharedLibraryInfo(Map<String, Object> meta) throws AndrolibException {
|
||||||
|
meta.put("sharedLibrary", mResTable.getSharedLibrary());
|
||||||
|
}
|
||||||
|
|
||||||
private boolean getCompressionType() {
|
private boolean getCompressionType() {
|
||||||
return mCompressResources;
|
return mCompressResources;
|
||||||
}
|
}
|
||||||
|
@ -379,6 +379,10 @@ final public class AndrolibResources {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setSharedLibrary(boolean flag) {
|
||||||
|
mSharedLibrary = flag;
|
||||||
|
}
|
||||||
|
|
||||||
public void aaptPackage(File apkFile, File manifest, File resDir, File rawDir, File assetDir, File[] include)
|
public void aaptPackage(File apkFile, File manifest, File resDir, File rawDir, File assetDir, File[] include)
|
||||||
throws AndrolibException {
|
throws AndrolibException {
|
||||||
|
|
||||||
@ -428,10 +432,13 @@ final public class AndrolibResources {
|
|||||||
|
|
||||||
// force package id so that some frameworks build with correct id
|
// force package id so that some frameworks build with correct id
|
||||||
// disable if user adds own aapt (can't know if they have this feature)
|
// disable if user adds own aapt (can't know if they have this feature)
|
||||||
if (mPackageId != null && ! customAapt) {
|
if (mPackageId != null && ! customAapt && ! mSharedLibrary) {
|
||||||
cmd.add("--forced-package-id");
|
cmd.add("--forced-package-id");
|
||||||
cmd.add(mPackageId);
|
cmd.add(mPackageId);
|
||||||
}
|
}
|
||||||
|
if (mSharedLibrary) {
|
||||||
|
cmd.add("--shared-lib");
|
||||||
|
}
|
||||||
if (mMinSdkVersion != null) {
|
if (mMinSdkVersion != null) {
|
||||||
cmd.add("--min-sdk-version");
|
cmd.add("--min-sdk-version");
|
||||||
cmd.add(mMinSdkVersion);
|
cmd.add(mMinSdkVersion);
|
||||||
@ -847,6 +854,8 @@ final public class AndrolibResources {
|
|||||||
private String mPackageOriginal = null;
|
private String mPackageOriginal = null;
|
||||||
private String mPackageId = null;
|
private String mPackageId = null;
|
||||||
|
|
||||||
|
private boolean mSharedLibrary = false;
|
||||||
|
|
||||||
private File mAaptBinary = null;
|
private File mAaptBinary = null;
|
||||||
|
|
||||||
private final static String[] IGNORED_PACKAGES = new String[] {
|
private final static String[] IGNORED_PACKAGES = new String[] {
|
||||||
|
@ -35,7 +35,7 @@ public class ResID {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ResID(int package_, int type, int entry, int id) {
|
public ResID(int package_, int type, int entry, int id) {
|
||||||
this.package_ = package_;
|
this.package_ = (package_ == 0) ? 2 : package_;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.entry = entry;
|
this.entry = entry;
|
||||||
this.id = id;
|
this.id = id;
|
||||||
|
@ -37,6 +37,7 @@ public class ResTable {
|
|||||||
private String mPackageOriginal;
|
private String mPackageOriginal;
|
||||||
private int mPackageId;
|
private int mPackageId;
|
||||||
private boolean mAnalysisMode = false;
|
private boolean mAnalysisMode = false;
|
||||||
|
private boolean mSharedLibrary = false;
|
||||||
|
|
||||||
private Map<String, String> mSdkInfo = new LinkedHashMap<String, String>();
|
private Map<String, String> mSdkInfo = new LinkedHashMap<String, String>();
|
||||||
private Map<String, String> mVersionInfo = new LinkedHashMap<String, String>();
|
private Map<String, String> mVersionInfo = new LinkedHashMap<String, String>();
|
||||||
@ -50,6 +51,13 @@ public class ResTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ResResSpec getResSpec(int resID) throws AndrolibException {
|
public ResResSpec getResSpec(int resID) throws AndrolibException {
|
||||||
|
// The pkgId is 0x00. That means a shared library is using its
|
||||||
|
// own resource, so lie to the caller replacing with its own
|
||||||
|
// packageId
|
||||||
|
if (resID >> 24 == 0) {
|
||||||
|
int pkgId = (mPackageId == 0 ? 2 : mPackageId);
|
||||||
|
resID = (0xFF000000 & (pkgId << 24)) | resID;
|
||||||
|
}
|
||||||
return getResSpec(new ResID(resID));
|
return getResSpec(new ResID(resID));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,6 +166,10 @@ public class ResTable {
|
|||||||
mPackageId = id;
|
mPackageId = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setSharedLibrary(boolean flag) {
|
||||||
|
mSharedLibrary = flag;
|
||||||
|
}
|
||||||
|
|
||||||
public void clearSdkInfo() {
|
public void clearSdkInfo() {
|
||||||
mSdkInfo.clear();
|
mSdkInfo.clear();
|
||||||
}
|
}
|
||||||
@ -193,4 +205,8 @@ public class ResTable {
|
|||||||
public int getPackageId() {
|
public int getPackageId() {
|
||||||
return mPackageId;
|
return mPackageId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean getSharedLibrary() {
|
||||||
|
return mSharedLibrary;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,6 +90,7 @@ public class ARSCDecoder {
|
|||||||
// for Apktool's use we need a non-zero packageId.
|
// for Apktool's use we need a non-zero packageId.
|
||||||
// AOSP indicates 0x02 is next, as 0x01 is system and 0x7F is private.
|
// AOSP indicates 0x02 is next, as 0x01 is system and 0x7F is private.
|
||||||
id = 2;
|
id = 2;
|
||||||
|
mResTable.setSharedLibrary(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
String name = mIn.readNullEndedString(128, true);
|
String name = mIn.readNullEndedString(128, true);
|
||||||
|
@ -70,29 +70,42 @@ public class SharedLibraryTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void isSharedResourceDecodingWorking() throws IOException, BrutException {
|
public void isSharedResourceDecodingAndRebuildingWorking() throws IOException, BrutException {
|
||||||
String framework = "library.apk";
|
String library = "library.apk";
|
||||||
String client = "client.apk";
|
String client = "client.apk";
|
||||||
|
|
||||||
|
// setup apkOptions
|
||||||
ApkOptions apkOptions = new ApkOptions();
|
ApkOptions apkOptions = new ApkOptions();
|
||||||
apkOptions.frameworkFolderLocation = sTmpDir.getAbsolutePath();
|
apkOptions.frameworkFolderLocation = sTmpDir.getAbsolutePath();
|
||||||
apkOptions.frameworkTag = "shared";
|
apkOptions.frameworkTag = "shared";
|
||||||
|
|
||||||
new Androlib(apkOptions).installFramework(new File(sTmpDir + File.separator + framework));
|
// install library/framework
|
||||||
|
new Androlib(apkOptions).installFramework(new File(sTmpDir + File.separator + library));
|
||||||
assertTrue(fileExists("2-shared.apk"));
|
assertTrue(fileExists("2-shared.apk"));
|
||||||
|
|
||||||
|
// decode client.apk
|
||||||
ApkDecoder apkDecoder = new ApkDecoder(new File(sTmpDir + File.separator + client));
|
ApkDecoder apkDecoder = new ApkDecoder(new File(sTmpDir + File.separator + client));
|
||||||
apkDecoder.setOutDir(new File(sTmpDir + File.separator + client + ".out"));
|
apkDecoder.setOutDir(new File(sTmpDir + File.separator + client + ".out"));
|
||||||
apkDecoder.setFrameworkDir(apkOptions.frameworkFolderLocation);
|
apkDecoder.setFrameworkDir(apkOptions.frameworkFolderLocation);
|
||||||
apkDecoder.setFrameworkTag(apkOptions.frameworkTag);
|
apkDecoder.setFrameworkTag(apkOptions.frameworkTag);
|
||||||
apkDecoder.decode();
|
apkDecoder.decode();
|
||||||
|
|
||||||
ExtFile testApk = new ExtFile(sTmpDir, client + ".out");
|
// decode library.apk
|
||||||
new Androlib(apkOptions).build(testApk, null);
|
ApkDecoder libraryDecoder = new ApkDecoder(new File(sTmpDir + File.separator + library));
|
||||||
|
libraryDecoder.setOutDir(new File(sTmpDir + File.separator + library + ".out"));
|
||||||
|
libraryDecoder.setFrameworkDir(apkOptions.frameworkFolderLocation);
|
||||||
|
libraryDecoder.setFrameworkTag(apkOptions.frameworkTag);
|
||||||
|
libraryDecoder.decode();
|
||||||
|
|
||||||
|
// build client.apk
|
||||||
|
ExtFile clientApk = new ExtFile(sTmpDir, client + ".out");
|
||||||
|
new Androlib(apkOptions).build(clientApk, null);
|
||||||
assertTrue(fileExists(client + ".out" + File.separator + "dist" + File.separator + client));
|
assertTrue(fileExists(client + ".out" + File.separator + "dist" + File.separator + client));
|
||||||
|
|
||||||
|
// build library.apk (shared library)
|
||||||
|
ExtFile libraryApk = new ExtFile(sTmpDir, library + ".out");
|
||||||
|
new Androlib(apkOptions).build(libraryApk, null);
|
||||||
|
assertTrue(fileExists(library + ".out" + File.separator + "dist" + File.separator + library));
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean fileExists(String filepath) {
|
private boolean fileExists(String filepath) {
|
||||||
|
Loading…
Reference in New Issue
Block a user