use of com.tencent.tinker.build.util.TinkerPatchException in project tinker by Tencent.
the class DexDiffDecoder method diffDexPairAndFillRelatedInfo.
private void diffDexPairAndFillRelatedInfo(File oldDexFile, File newDexFile, RelatedInfo relatedInfo) {
File tempFullPatchDexPath = new File(config.mOutFolder + File.separator + TypedValue.DEX_TEMP_PATCH_DIR);
final String dexName = getRelativeDexName(oldDexFile, newDexFile);
File dexDiffOut = getOutputPath(newDexFile).toFile();
ensureDirectoryExist(dexDiffOut.getParentFile());
try {
DexPatchGenerator dexPatchGen = new DexPatchGenerator(oldDexFile, newDexFile);
dexPatchGen.setAdditionalRemovingClassPatterns(config.mDexLoaderPattern);
logWriter.writeLineToInfoFile(String.format("Start diff between [%s] as old and [%s] as new:", getRelativeStringBy(oldDexFile, config.mTempUnzipOldDir), getRelativeStringBy(newDexFile, config.mTempUnzipNewDir)));
dexPatchGen.executeAndSaveTo(dexDiffOut);
} catch (Exception e) {
throw new TinkerPatchException(e);
}
if (!dexDiffOut.exists()) {
throw new TinkerPatchException("can not find the diff file:" + dexDiffOut.getAbsolutePath());
}
relatedInfo.dexDiffFile = dexDiffOut;
relatedInfo.dexDiffMd5 = MD5.getMD5(dexDiffOut);
Logger.d("\nGen %s patch file:%s, size:%d, md5:%s", dexName, relatedInfo.dexDiffFile.getAbsolutePath(), relatedInfo.dexDiffFile.length(), relatedInfo.dexDiffMd5);
File tempFullPatchedDexFile = new File(tempFullPatchDexPath, dexName);
if (!tempFullPatchedDexFile.exists()) {
ensureDirectoryExist(tempFullPatchedDexFile.getParentFile());
}
try {
new DexPatchApplier(oldDexFile, dexDiffOut).executeAndSaveTo(tempFullPatchedDexFile);
Logger.d(String.format("Verifying if patched new dex is logically the same as original new dex: %s ...", getRelativeStringBy(newDexFile, config.mTempUnzipNewDir)));
Dex origNewDex = new Dex(newDexFile);
Dex patchedNewDex = new Dex(tempFullPatchedDexFile);
checkDexChange(origNewDex, patchedNewDex);
relatedInfo.newOrFullPatchedFile = tempFullPatchedDexFile;
relatedInfo.newOrFullPatchedMd5 = MD5.getMD5(tempFullPatchedDexFile);
} catch (Exception e) {
e.printStackTrace();
throw new TinkerPatchException("Failed to generate temporary patched dex, which makes MD5 generating procedure of new dex failed, either.", e);
}
if (!tempFullPatchedDexFile.exists()) {
throw new TinkerPatchException("can not find the temporary full patched dex file:" + tempFullPatchedDexFile.getAbsolutePath());
}
Logger.d("\nGen %s for dalvik full dex file:%s, size:%d, md5:%s", dexName, tempFullPatchedDexFile.getAbsolutePath(), tempFullPatchedDexFile.length(), relatedInfo.newOrFullPatchedMd5);
}
use of com.tencent.tinker.build.util.TinkerPatchException in project tinker by Tencent.
the class DexDiffDecoder method patch.
@SuppressWarnings("NewApi")
@Override
public boolean patch(final File oldFile, final File newFile) throws IOException, TinkerPatchException {
final String dexName = getRelativeDexName(oldFile, newFile);
// first of all, we should check input files if excluded classes were modified.
Logger.d("Check for loader classes in dex: %s", dexName);
try {
excludedClassModifiedChecker.checkIfExcludedClassWasModifiedInNewDex(oldFile, newFile);
} catch (IOException e) {
throw new TinkerPatchException(e);
} catch (TinkerPatchException e) {
if (config.mIgnoreWarning) {
Logger.e("Warning:ignoreWarning is true, but we found %s", e.getMessage());
} else {
Logger.e("Warning:ignoreWarning is false, but we found %s", e.getMessage());
throw e;
}
} catch (Exception e) {
e.printStackTrace();
}
// don't process 0 length dex
if (newFile == null || !newFile.exists() || newFile.length() == 0) {
return false;
}
File dexDiffOut = getOutputPath(newFile).toFile();
final String newMd5 = getRawOrWrappedDexMD5(newFile);
//new add file
if (oldFile == null || !oldFile.exists() || oldFile.length() == 0) {
hasDexChanged = true;
copyNewDexAndLogToDexMeta(newFile, newMd5, dexDiffOut);
return true;
}
final String oldMd5 = getRawOrWrappedDexMD5(oldFile);
if ((oldMd5 != null && !oldMd5.equals(newMd5)) || (oldMd5 == null && newMd5 != null)) {
hasDexChanged = true;
if (oldMd5 != null) {
collectAddedOrDeletedClasses(oldFile, newFile);
}
}
RelatedInfo relatedInfo = new RelatedInfo();
relatedInfo.oldMd5 = oldMd5;
relatedInfo.newMd5 = newMd5;
// collect current old dex file and corresponding new dex file for further processing.
oldAndNewDexFilePairList.add(new AbstractMap.SimpleEntry<>(oldFile, newFile));
dexNameToRelatedInfoMap.put(dexName, relatedInfo);
return true;
}
use of com.tencent.tinker.build.util.TinkerPatchException in project tinker by Tencent.
the class ManifestDecoder method patch.
@Override
public boolean patch(File oldFile, File newFile) throws IOException, TinkerPatchException {
final boolean ignoreWarning = config.mIgnoreWarning;
try {
AndroidParser oldAndroidManifest = AndroidParser.getAndroidManifest(oldFile);
AndroidParser newAndroidManifest = AndroidParser.getAndroidManifest(newFile);
//check minSdkVersion
int minSdkVersion = Integer.parseInt(oldAndroidManifest.apkMeta.getMinSdkVersion());
if (minSdkVersion < TypedValue.ANDROID_40_API_LEVEL) {
if (config.mDexRaw) {
if (ignoreWarning) {
//ignoreWarning, just log
Logger.e("Warning:ignoreWarning is true, but your old apk's minSdkVersion %d is below 14, you should set the dexMode to 'jar', otherwise, it will crash at some time", minSdkVersion);
} else {
Logger.e("Warning:ignoreWarning is false, but your old apk's minSdkVersion %d is below 14, you should set the dexMode to 'jar', otherwise, it will crash at some time", minSdkVersion);
throw new TinkerPatchException(String.format("ignoreWarning is false, but your old apk's minSdkVersion %d is below 14, you should set the dexMode to 'jar', otherwise, it will crash at some time", minSdkVersion));
}
}
}
//check whether there is any new Android Component
List<String> oldAndroidComponent = oldAndroidManifest.getComponents();
List<String> newAndroidComponent = newAndroidManifest.getComponents();
for (String newComponentName : newAndroidComponent) {
boolean found = false;
for (String oldComponentName : oldAndroidComponent) {
if (newComponentName.equals(oldComponentName)) {
found = true;
break;
}
}
if (!found) {
if (ignoreWarning) {
Logger.e("Warning:ignoreWarning is true, but we found a new AndroidComponent %s, it will crash at some time", newComponentName);
} else {
Logger.e("Warning:ignoreWarning is false, but we found a new AndroidComponent %s, it will crash at some time", newComponentName);
throw new TinkerPatchException(String.format("ignoreWarning is false, but we found a new AndroidComponent %s, it will crash at some time", newComponentName));
}
}
}
} catch (ParseException e) {
e.printStackTrace();
throw new TinkerPatchException("parse android manifest error!");
}
return false;
}
use of com.tencent.tinker.build.util.TinkerPatchException in project tinker by Tencent.
the class PatchInfoGen method addTinkerID.
private void addTinkerID() throws IOException, ParseException {
if (!config.mPackageFields.containsKey(TypedValue.TINKER_ID)) {
AndroidParser oldAndroidManifest = AndroidParser.getAndroidManifest(config.mOldApkFile);
String tinkerID = oldAndroidManifest.metaDatas.get(TypedValue.TINKER_ID);
if (tinkerID == null) {
throw new TinkerPatchException("can't find TINKER_ID from the old apk manifest file, it must be set!");
}
config.mPackageFields.put(TypedValue.TINKER_ID, tinkerID);
}
if (!config.mPackageFields.containsKey(TypedValue.NEW_TINKER_ID)) {
AndroidParser newAndroidManifest = AndroidParser.getAndroidManifest(config.mNewApkFile);
String tinkerID = newAndroidManifest.metaDatas.get(TypedValue.TINKER_ID);
if (tinkerID == null) {
throw new TinkerPatchException("can't find TINKER_ID from the new apk manifest file, it must be set!");
}
config.mPackageFields.put(TypedValue.NEW_TINKER_ID, tinkerID);
}
}
use of com.tencent.tinker.build.util.TinkerPatchException in project tinker by Tencent.
the class Configuration method createTempDirectory.
private void createTempDirectory() throws TinkerPatchException {
mTempResultDir = new File(mOutFolder + File.separator + TypedValue.PATH_PATCH_FILES);
FileOperation.deleteDir(mTempResultDir);
if (!mTempResultDir.exists()) {
mTempResultDir.mkdir();
}
String oldApkName = mOldApkFile.getName();
if (!oldApkName.endsWith(TypedValue.FILE_APK)) {
throw new TinkerPatchException(String.format("input apk file path must end with .apk, yours %s\n", oldApkName));
}
String newApkName = mNewApkFile.getName();
if (!newApkName.endsWith(TypedValue.FILE_APK)) {
throw new TinkerPatchException(String.format("input apk file path must end with .apk, yours %s\n", newApkName));
}
String tempOldName = oldApkName.substring(0, oldApkName.indexOf(TypedValue.FILE_APK));
String tempNewName = newApkName.substring(0, newApkName.indexOf(TypedValue.FILE_APK));
// Bugfix: For windows user, filename is case-insensitive.
if (tempNewName.equalsIgnoreCase(tempOldName)) {
tempOldName += "-old";
tempNewName += "-new";
}
mTempUnzipOldDir = new File(mOutFolder, tempOldName);
mTempUnzipNewDir = new File(mOutFolder, tempNewName);
}
Aggregations