Search in sources :

Example 6 with TinkerPatchException

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);
}
Also used : DexPatchApplier(com.tencent.tinker.commons.dexpatcher.DexPatchApplier) Dex(com.tencent.tinker.android.dex.Dex) JarFile(java.util.jar.JarFile) File(java.io.File) DexPatchGenerator(com.tencent.tinker.build.dexpatcher.DexPatchGenerator) TinkerPatchException(com.tencent.tinker.build.util.TinkerPatchException) IOException(java.io.IOException) TinkerPatchException(com.tencent.tinker.build.util.TinkerPatchException)

Example 7 with TinkerPatchException

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;
}
Also used : AbstractMap(java.util.AbstractMap) IOException(java.io.IOException) JarFile(java.util.jar.JarFile) File(java.io.File) TinkerPatchException(com.tencent.tinker.build.util.TinkerPatchException) IOException(java.io.IOException) TinkerPatchException(com.tencent.tinker.build.util.TinkerPatchException)

Example 8 with TinkerPatchException

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;
}
Also used : AndroidParser(com.tencent.tinker.build.apkparser.AndroidParser) ParseException(java.text.ParseException) TinkerPatchException(com.tencent.tinker.build.util.TinkerPatchException)

Example 9 with TinkerPatchException

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);
    }
}
Also used : AndroidParser(com.tencent.tinker.build.apkparser.AndroidParser) TinkerPatchException(com.tencent.tinker.build.util.TinkerPatchException)

Example 10 with TinkerPatchException

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);
}
Also used : File(java.io.File) TinkerPatchException(com.tencent.tinker.build.util.TinkerPatchException)

Aggregations

TinkerPatchException (com.tencent.tinker.build.util.TinkerPatchException)10 File (java.io.File)5 IOException (java.io.IOException)4 JarFile (java.util.jar.JarFile)3 Dex (com.tencent.tinker.android.dex.Dex)2 AndroidParser (com.tencent.tinker.build.apkparser.AndroidParser)2 HashSet (java.util.HashSet)2 ClassDef (com.tencent.tinker.android.dex.ClassDef)1 DexPatchGenerator (com.tencent.tinker.build.dexpatcher.DexPatchGenerator)1 Configuration (com.tencent.tinker.build.patch.Configuration)1 DexClassesComparator (com.tencent.tinker.build.util.DexClassesComparator)1 DexClassInfo (com.tencent.tinker.build.util.DexClassesComparator.DexClassInfo)1 DexPatchApplier (com.tencent.tinker.commons.dexpatcher.DexPatchApplier)1 ParseException (java.text.ParseException)1 AbstractMap (java.util.AbstractMap)1 ZipEntry (java.util.zip.ZipEntry)1 ParserConfigurationException (javax.xml.parsers.ParserConfigurationException)1 SAXException (org.xml.sax.SAXException)1