Search in sources :

Example 1 with Dex

use of com.tencent.tinker.android.dex.Dex in project tinker by Tencent.

the class DexDiffDecoder method collectAddedOrDeletedClasses.

/**
 * Before starting real diff works, we collect added class descriptor
 * and deleted class descriptor for further analysing in {@code checkCrossDexMovingClasses}.
 */
private void collectAddedOrDeletedClasses(File oldFile, File newFile) throws IOException {
    Dex oldDex = new Dex(oldFile);
    Dex newDex = new Dex(newFile);
    Set<String> oldClassDescs = new HashSet<>();
    for (ClassDef oldClassDef : oldDex.classDefs()) {
        oldClassDescs.add(oldDex.typeNames().get(oldClassDef.typeIndex));
    }
    Set<String> newClassDescs = new HashSet<>();
    for (ClassDef newClassDef : newDex.classDefs()) {
        newClassDescs.add(newDex.typeNames().get(newClassDef.typeIndex));
    }
    Set<String> addedClassDescs = new HashSet<>(newClassDescs);
    addedClassDescs.removeAll(oldClassDescs);
    Set<String> deletedClassDescs = new HashSet<>(oldClassDescs);
    deletedClassDescs.removeAll(newClassDescs);
    for (String addedClassDesc : addedClassDescs) {
        if (addedClassDescToDexNameMap.containsKey(addedClassDesc)) {
            throw new TinkerPatchException(String.format("Class Duplicate. Class [%s] is added in both new dex: [%s] and [%s]. Please check your newly apk.", addedClassDesc, addedClassDescToDexNameMap.get(addedClassDesc), newFile.toString()));
        } else {
            addedClassDescToDexNameMap.put(addedClassDesc, newFile.toString());
        }
    }
    for (String deletedClassDesc : deletedClassDescs) {
        if (deletedClassDescToDexNameMap.containsKey(deletedClassDesc)) {
            throw new TinkerPatchException(String.format("Class Duplicate. Class [%s] is deleted in both old dex: [%s] and [%s]. Please check your base apk.", deletedClassDesc, addedClassDescToDexNameMap.get(deletedClassDesc), oldFile.toString()));
        } else {
            deletedClassDescToDexNameMap.put(deletedClassDesc, newFile.toString());
        }
    }
}
Also used : ClassDef(com.tencent.tinker.android.dex.ClassDef) Dex(com.tencent.tinker.android.dex.Dex) HashSet(java.util.HashSet) TinkerPatchException(com.tencent.tinker.build.util.TinkerPatchException)

Example 2 with Dex

use of com.tencent.tinker.android.dex.Dex in project tinker by Tencent.

the class ExcludedClassModifiedChecker method checkIfExcludedClassWasModifiedInNewDex.

public void checkIfExcludedClassWasModifiedInNewDex(File oldFile, File newFile) throws IOException, TinkerPatchException {
    if (oldFile == null && newFile == null) {
        throw new TinkerPatchException("both oldFile and newFile are null.");
    }
    oldDex = (oldFile != null ? new Dex(oldFile) : null);
    newDex = (newFile != null ? new Dex(newFile) : null);
    int stmCode = STMCODE_START;
    while (stmCode != STMCODE_END) {
        switch(stmCode) {
            /**
             * Check rule:
             * Loader classes must only appear in primary dex and each of them in primary old dex should keep
             * completely consistent in new primary dex.
             *
             * An error is announced when any of these conditions below is fit:
             * 1. Primary old dex is missing.
             * 2. Primary new dex is missing.
             * 3. There are not any loader classes in primary old dex.
             * 4. There are some new loader classes added in new primary dex.
             * 5. Loader classes in old primary dex are modified in new primary dex.
             * 6. Loader classes are found in secondary old dexes.
             * 7. Loader classes are found in secondary new dexes.
             */
            case STMCODE_START:
                {
                    boolean isPrimaryDex = isPrimaryDex((oldFile == null ? newFile : oldFile));
                    if (isPrimaryDex) {
                        if (oldFile == null) {
                            stmCode = STMCODE_ERROR_PRIMARY_OLD_DEX_IS_MISSING;
                        } else if (newFile == null) {
                            stmCode = STMCODE_ERROR_PRIMARY_NEW_DEX_IS_MISSING;
                        } else {
                            dexCmptor.startCheck(oldDex, newDex);
                            deletedClassInfos = dexCmptor.getDeletedClassInfos();
                            addedClassInfos = dexCmptor.getAddedClassInfos();
                            changedClassInfosMap = new HashMap<>(dexCmptor.getChangedClassDescToInfosMap());
                            // All loader classes are in new dex, while none of them in old one.
                            if (deletedClassInfos.isEmpty() && changedClassInfosMap.isEmpty() && !addedClassInfos.isEmpty()) {
                                stmCode = STMCODE_ERROR_LOADER_CLASS_NOT_IN_PRIMARY_OLD_DEX;
                            } else {
                                if (addedClassInfos.isEmpty()) {
                                    // class descriptor is completely matches, see if any contents changes.
                                    ArrayList<String> removeClasses = new ArrayList<>();
                                    for (String classname : changedClassInfosMap.keySet()) {
                                        if (Utils.checkFileInPattern(ignoreChangeWarning, classname)) {
                                            Logger.e("loader class pattern: " + classname + " has changed, but it match ignore change pattern, just ignore!");
                                            removeClasses.add(classname);
                                        }
                                    }
                                    changedClassInfosMap.keySet().removeAll(removeClasses);
                                    if (changedClassInfosMap.isEmpty()) {
                                        stmCode = STMCODE_END;
                                    } else {
                                        stmCode = STMCODE_ERROR_LOADER_CLASS_CHANGED;
                                    }
                                } else {
                                    stmCode = STMCODE_ERROR_LOADER_CLASS_IN_PRIMARY_DEX_MISMATCH;
                                }
                            }
                        }
                    } else {
                        Set<Pattern> patternsOfClassDescToCheck = new HashSet<>();
                        for (String patternStr : config.mDexLoaderPattern) {
                            patternsOfClassDescToCheck.add(Pattern.compile(PatternUtils.dotClassNamePatternToDescriptorRegEx(patternStr)));
                        }
                        if (oldDex != null) {
                            oldClassesDescToCheck.clear();
                            for (ClassDef classDef : oldDex.classDefs()) {
                                String desc = oldDex.typeNames().get(classDef.typeIndex);
                                if (Utils.isStringMatchesPatterns(desc, patternsOfClassDescToCheck)) {
                                    oldClassesDescToCheck.add(desc);
                                }
                            }
                            if (!oldClassesDescToCheck.isEmpty()) {
                                stmCode = STMCODE_ERROR_LOADER_CLASS_FOUND_IN_SECONDARY_OLD_DEX;
                                break;
                            }
                        }
                        if (newDex != null) {
                            newClassesDescToCheck.clear();
                            for (ClassDef classDef : newDex.classDefs()) {
                                String desc = newDex.typeNames().get(classDef.typeIndex);
                                if (Utils.isStringMatchesPatterns(desc, patternsOfClassDescToCheck)) {
                                    newClassesDescToCheck.add(desc);
                                }
                            }
                            if (!newClassesDescToCheck.isEmpty()) {
                                stmCode = STMCODE_ERROR_LOADER_CLASS_FOUND_IN_SECONDARY_NEW_DEX;
                                break;
                            }
                        }
                        stmCode = STMCODE_END;
                    }
                    break;
                }
            case STMCODE_ERROR_PRIMARY_OLD_DEX_IS_MISSING:
                {
                    throw new TinkerPatchException("old primary dex is missing.");
                }
            case STMCODE_ERROR_PRIMARY_NEW_DEX_IS_MISSING:
                {
                    throw new TinkerPatchException("new primary dex is missing.");
                }
            case STMCODE_ERROR_LOADER_CLASS_NOT_IN_PRIMARY_OLD_DEX:
                {
                    throw new TinkerPatchException("all loader classes don't appear in old primary dex.");
                }
            case STMCODE_ERROR_LOADER_CLASS_IN_PRIMARY_DEX_MISMATCH:
                {
                    throw new TinkerPatchException("there's loader classes added in new primary dex, such these changes will not take effect.\n" + "added classes: " + Utils.collectionToString(addedClassInfos));
                }
            case STMCODE_ERROR_LOADER_CLASS_FOUND_IN_SECONDARY_OLD_DEX:
                {
                    final String msg = "loader classes are found in old secondary dex. Found classes: " + Utils.collectionToString(oldClassesDescToCheck);
                    if (config.mAllowLoaderInAnyDex) {
                        Logger.d(msg);
                        return;
                    } else {
                        throw new TinkerPatchException(msg);
                    }
                }
            case STMCODE_ERROR_LOADER_CLASS_FOUND_IN_SECONDARY_NEW_DEX:
                {
                    final String msg = "loader classes are found in new secondary dex. Found classes: " + Utils.collectionToString(newClassesDescToCheck);
                    if (config.mAllowLoaderInAnyDex) {
                        Logger.d(msg);
                        return;
                    } else {
                        throw new TinkerPatchException(msg);
                    }
                }
            case STMCODE_ERROR_LOADER_CLASS_CHANGED:
                {
                    String msg = "some loader class has been changed in new primary dex." + " Such these changes will not take effect!!" + " related classes: " + Utils.collectionToString(changedClassInfosMap.keySet());
                    throw new TinkerPatchException(msg);
                }
            default:
                {
                    Logger.e("internal-error: unexpected stmCode.");
                    stmCode = STMCODE_END;
                    break;
                }
        }
    }
}
Also used : ClassDef(com.tencent.tinker.android.dex.ClassDef) Set(java.util.Set) HashSet(java.util.HashSet) Dex(com.tencent.tinker.android.dex.Dex) ArrayList(java.util.ArrayList)

Example 3 with Dex

use of com.tencent.tinker.android.dex.Dex in project tinker by Tencent.

the class DexDiffDecoder method generateChangedClassesDexFile.

@SuppressWarnings("NewApi")
private void generateChangedClassesDexFile() throws IOException {
    final String dexMode = config.mDexRaw ? "raw" : "jar";
    List<File> oldDexList = new ArrayList<>();
    List<File> newDexList = new ArrayList<>();
    for (AbstractMap.SimpleEntry<File, File> oldAndNewDexFilePair : oldAndNewDexFilePairList) {
        File oldDexFile = oldAndNewDexFilePair.getKey();
        File newDexFile = oldAndNewDexFilePair.getValue();
        if (oldDexFile != null) {
            oldDexList.add(oldDexFile);
        }
        if (newDexFile != null) {
            newDexList.add(newDexFile);
        }
    }
    DexGroup oldDexGroup = DexGroup.wrap(oldDexList);
    DexGroup newDexGroup = DexGroup.wrap(newDexList);
    ChangedClassesDexClassInfoCollector collector = new ChangedClassesDexClassInfoCollector();
    collector.setExcludedClassPatterns(config.mDexLoaderPattern);
    collector.setLogger(dexPatcherLoggerBridge);
    collector.setIncludeRefererToRefererAffectedClasses(true);
    Set<DexClassInfo> classInfosInChangedClassesDex = collector.doCollect(oldDexGroup, newDexGroup);
    Set<Dex> owners = new HashSet<>();
    Map<Dex, Set<String>> ownerToDescOfChangedClassesMap = new HashMap<>();
    for (DexClassInfo classInfo : classInfosInChangedClassesDex) {
        owners.add(classInfo.owner);
        Set<String> descOfChangedClasses = ownerToDescOfChangedClassesMap.get(classInfo.owner);
        if (descOfChangedClasses == null) {
            descOfChangedClasses = new HashSet<>();
            ownerToDescOfChangedClassesMap.put(classInfo.owner, descOfChangedClasses);
        }
        descOfChangedClasses.add(classInfo.classDesc);
    }
    StringBuilder metaBuilder = new StringBuilder();
    int changedDexId = 1;
    for (Dex dex : owners) {
        Set<String> descOfChangedClassesInCurrDex = ownerToDescOfChangedClassesMap.get(dex);
        DexFile dexFile = new DexBackedDexFile(org.jf.dexlib2.Opcodes.forApi(20), dex.getBytes());
        boolean isCurrentDexHasChangedClass = false;
        for (org.jf.dexlib2.iface.ClassDef classDef : dexFile.getClasses()) {
            if (descOfChangedClassesInCurrDex.contains(classDef.getType())) {
                isCurrentDexHasChangedClass = true;
                break;
            }
        }
        if (!isCurrentDexHasChangedClass) {
            continue;
        }
        DexBuilder dexBuilder = new DexBuilder(Opcodes.forApi(23));
        for (org.jf.dexlib2.iface.ClassDef classDef : dexFile.getClasses()) {
            if (!descOfChangedClassesInCurrDex.contains(classDef.getType())) {
                continue;
            }
            Logger.d("Class %s will be added into changed classes dex ...", classDef.getType());
            List<BuilderField> builderFields = new ArrayList<>();
            for (Field field : classDef.getFields()) {
                final BuilderField builderField = dexBuilder.internField(field.getDefiningClass(), field.getName(), field.getType(), field.getAccessFlags(), field.getInitialValue(), field.getAnnotations());
                builderFields.add(builderField);
            }
            List<BuilderMethod> builderMethods = new ArrayList<>();
            for (Method method : classDef.getMethods()) {
                MethodImplementation methodImpl = method.getImplementation();
                if (methodImpl != null) {
                    methodImpl = new BuilderMutableMethodImplementation(dexBuilder, methodImpl);
                }
                BuilderMethod builderMethod = dexBuilder.internMethod(method.getDefiningClass(), method.getName(), method.getParameters(), method.getReturnType(), method.getAccessFlags(), method.getAnnotations(), methodImpl);
                builderMethods.add(builderMethod);
            }
            dexBuilder.internClassDef(classDef.getType(), classDef.getAccessFlags(), classDef.getSuperclass(), classDef.getInterfaces(), classDef.getSourceFile(), classDef.getAnnotations(), builderFields, builderMethods);
        }
        // Write constructed changed classes dex to file and record it in meta file.
        String changedDexName = null;
        if (changedDexId == 1) {
            changedDexName = "classes.dex";
        } else {
            changedDexName = "classes" + changedDexId + ".dex";
        }
        final File dest = new File(config.mTempResultDir + "/" + changedDexName);
        final FileDataStore fileDataStore = new FileDataStore(dest);
        dexBuilder.writeTo(fileDataStore);
        final String md5 = MD5.getMD5(dest);
        appendMetaLine(metaBuilder, changedDexName, "", md5, md5, 0, 0, 0, dexMode);
        ++changedDexId;
    }
    final String meta = metaBuilder.toString();
    Logger.d("\nDexDecoder:write changed classes dex meta file data:\n%s", meta);
    metaWriter.writeLineToInfoFile(meta);
}
Also used : DexGroup(com.tencent.tinker.build.util.DexClassesComparator.DexGroup) MethodImplementation(org.jf.dexlib2.iface.MethodImplementation) BuilderMutableMethodImplementation(org.jf.dexlib2.builder.BuilderMutableMethodImplementation) Set(java.util.Set) HashSet(java.util.HashSet) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) AbstractMap(java.util.AbstractMap) BuilderField(org.jf.dexlib2.writer.builder.BuilderField) Field(org.jf.dexlib2.iface.Field) BuilderField(org.jf.dexlib2.writer.builder.BuilderField) FileDataStore(org.jf.dexlib2.writer.io.FileDataStore) HashSet(java.util.HashSet) DexBackedDexFile(org.jf.dexlib2.dexbacked.DexBackedDexFile) ChangedClassesDexClassInfoCollector(com.tencent.tinker.build.dexpatcher.util.ChangedClassesDexClassInfoCollector) BuilderMutableMethodImplementation(org.jf.dexlib2.builder.BuilderMutableMethodImplementation) Method(org.jf.dexlib2.iface.Method) BuilderMethod(org.jf.dexlib2.writer.builder.BuilderMethod) DexFile(org.jf.dexlib2.iface.DexFile) DexBackedDexFile(org.jf.dexlib2.dexbacked.DexBackedDexFile) DexBuilder(org.jf.dexlib2.writer.builder.DexBuilder) Dex(com.tencent.tinker.android.dex.Dex) BuilderMethod(org.jf.dexlib2.writer.builder.BuilderMethod) JarFile(java.util.jar.JarFile) DexFile(org.jf.dexlib2.iface.DexFile) DexBackedDexFile(org.jf.dexlib2.dexbacked.DexBackedDexFile) File(java.io.File) DexClassInfo(com.tencent.tinker.build.util.DexClassesComparator.DexClassInfo)

Example 4 with Dex

use of com.tencent.tinker.android.dex.Dex 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);
        relatedInfo.newOrFullPatchedCRC = FileOperation.getFileCrc32(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) DexFile(org.jf.dexlib2.iface.DexFile) DexBackedDexFile(org.jf.dexlib2.dexbacked.DexBackedDexFile) 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 5 with Dex

use of com.tencent.tinker.android.dex.Dex in project tinker by Tencent.

the class DexPatchApplier method executeAndSaveTo.

public void executeAndSaveTo(OutputStream out) throws IOException {
    // Before executing, we should check if this patch can be applied to
    // old dex we passed in.
    byte[] oldDexSign = this.oldDex.computeSignature(false);
    if (oldDexSign == null) {
        throw new IOException("failed to compute old dex's signature.");
    }
    if (this.patchFile == null) {
        throw new IllegalArgumentException("patch file is null.");
    }
    byte[] oldDexSignInPatchFile = this.patchFile.getOldDexSignature();
    if (CompareUtils.uArrCompare(oldDexSign, oldDexSignInPatchFile) != 0) {
        throw new IOException(String.format("old dex signature mismatch! expected: %s, actual: %s", Arrays.toString(oldDexSign), Arrays.toString(oldDexSignInPatchFile)));
    }
    // Firstly, set sections' offset after patched, sort according to their offset so that
    // the dex lib of aosp can calculate section size.
    TableOfContents patchedToc = this.patchedDex.getTableOfContents();
    patchedToc.header.off = 0;
    patchedToc.header.size = 1;
    patchedToc.mapList.size = 1;
    patchedToc.stringIds.off = this.patchFile.getPatchedStringIdSectionOffset();
    patchedToc.typeIds.off = this.patchFile.getPatchedTypeIdSectionOffset();
    patchedToc.typeLists.off = this.patchFile.getPatchedTypeListSectionOffset();
    patchedToc.protoIds.off = this.patchFile.getPatchedProtoIdSectionOffset();
    patchedToc.fieldIds.off = this.patchFile.getPatchedFieldIdSectionOffset();
    patchedToc.methodIds.off = this.patchFile.getPatchedMethodIdSectionOffset();
    patchedToc.classDefs.off = this.patchFile.getPatchedClassDefSectionOffset();
    patchedToc.mapList.off = this.patchFile.getPatchedMapListSectionOffset();
    patchedToc.stringDatas.off = this.patchFile.getPatchedStringDataSectionOffset();
    patchedToc.annotations.off = this.patchFile.getPatchedAnnotationSectionOffset();
    patchedToc.annotationSets.off = this.patchFile.getPatchedAnnotationSetSectionOffset();
    patchedToc.annotationSetRefLists.off = this.patchFile.getPatchedAnnotationSetRefListSectionOffset();
    patchedToc.annotationsDirectories.off = this.patchFile.getPatchedAnnotationsDirectorySectionOffset();
    patchedToc.encodedArrays.off = this.patchFile.getPatchedEncodedArraySectionOffset();
    patchedToc.debugInfos.off = this.patchFile.getPatchedDebugInfoSectionOffset();
    patchedToc.codes.off = this.patchFile.getPatchedCodeSectionOffset();
    patchedToc.classDatas.off = this.patchFile.getPatchedClassDataSectionOffset();
    patchedToc.fileSize = this.patchFile.getPatchedDexSize();
    Arrays.sort(patchedToc.sections);
    patchedToc.computeSizesFromOffsets();
    // Secondly, run patch algorithms according to sections' dependencies.
    this.stringDataSectionPatchAlg = new StringDataSectionPatchAlgorithm(patchFile, oldDex, patchedDex, oldToPatchedIndexMap);
    this.typeIdSectionPatchAlg = new TypeIdSectionPatchAlgorithm(patchFile, oldDex, patchedDex, oldToPatchedIndexMap);
    this.protoIdSectionPatchAlg = new ProtoIdSectionPatchAlgorithm(patchFile, oldDex, patchedDex, oldToPatchedIndexMap);
    this.fieldIdSectionPatchAlg = new FieldIdSectionPatchAlgorithm(patchFile, oldDex, patchedDex, oldToPatchedIndexMap);
    this.methodIdSectionPatchAlg = new MethodIdSectionPatchAlgorithm(patchFile, oldDex, patchedDex, oldToPatchedIndexMap);
    this.classDefSectionPatchAlg = new ClassDefSectionPatchAlgorithm(patchFile, oldDex, patchedDex, oldToPatchedIndexMap);
    this.typeListSectionPatchAlg = new TypeListSectionPatchAlgorithm(patchFile, oldDex, patchedDex, oldToPatchedIndexMap);
    this.annotationSetRefListSectionPatchAlg = new AnnotationSetRefListSectionPatchAlgorithm(patchFile, oldDex, patchedDex, oldToPatchedIndexMap);
    this.annotationSetSectionPatchAlg = new AnnotationSetSectionPatchAlgorithm(patchFile, oldDex, patchedDex, oldToPatchedIndexMap);
    this.classDataSectionPatchAlg = new ClassDataSectionPatchAlgorithm(patchFile, oldDex, patchedDex, oldToPatchedIndexMap);
    this.codeSectionPatchAlg = new CodeSectionPatchAlgorithm(patchFile, oldDex, patchedDex, oldToPatchedIndexMap);
    this.debugInfoSectionPatchAlg = new DebugInfoItemSectionPatchAlgorithm(patchFile, oldDex, patchedDex, oldToPatchedIndexMap);
    this.annotationSectionPatchAlg = new AnnotationSectionPatchAlgorithm(patchFile, oldDex, patchedDex, oldToPatchedIndexMap);
    this.encodedArraySectionPatchAlg = new StaticValueSectionPatchAlgorithm(patchFile, oldDex, patchedDex, oldToPatchedIndexMap);
    this.annotationsDirectorySectionPatchAlg = new AnnotationsDirectorySectionPatchAlgorithm(patchFile, oldDex, patchedDex, oldToPatchedIndexMap);
    this.stringDataSectionPatchAlg.execute();
    this.typeIdSectionPatchAlg.execute();
    this.typeListSectionPatchAlg.execute();
    this.protoIdSectionPatchAlg.execute();
    this.fieldIdSectionPatchAlg.execute();
    this.methodIdSectionPatchAlg.execute();
    this.annotationSectionPatchAlg.execute();
    this.annotationSetSectionPatchAlg.execute();
    this.annotationSetRefListSectionPatchAlg.execute();
    this.annotationsDirectorySectionPatchAlg.execute();
    this.debugInfoSectionPatchAlg.execute();
    this.codeSectionPatchAlg.execute();
    this.classDataSectionPatchAlg.execute();
    this.encodedArraySectionPatchAlg.execute();
    this.classDefSectionPatchAlg.execute();
    // Thirdly, write header, mapList. Calculate and write patched dex's sign and checksum.
    Dex.Section headerOut = this.patchedDex.openSection(patchedToc.header.off);
    patchedToc.writeHeader(headerOut);
    Dex.Section mapListOut = this.patchedDex.openSection(patchedToc.mapList.off);
    patchedToc.writeMap(mapListOut);
    this.patchedDex.writeHashes();
    // Finally, write patched dex to file.
    this.patchedDex.writeTo(out);
}
Also used : MethodIdSectionPatchAlgorithm(com.tencent.tinker.commons.dexpatcher.algorithms.patch.MethodIdSectionPatchAlgorithm) TypeIdSectionPatchAlgorithm(com.tencent.tinker.commons.dexpatcher.algorithms.patch.TypeIdSectionPatchAlgorithm) TypeListSectionPatchAlgorithm(com.tencent.tinker.commons.dexpatcher.algorithms.patch.TypeListSectionPatchAlgorithm) DebugInfoItemSectionPatchAlgorithm(com.tencent.tinker.commons.dexpatcher.algorithms.patch.DebugInfoItemSectionPatchAlgorithm) AnnotationSectionPatchAlgorithm(com.tencent.tinker.commons.dexpatcher.algorithms.patch.AnnotationSectionPatchAlgorithm) IOException(java.io.IOException) TableOfContents(com.tencent.tinker.android.dex.TableOfContents) CodeSectionPatchAlgorithm(com.tencent.tinker.commons.dexpatcher.algorithms.patch.CodeSectionPatchAlgorithm) StringDataSectionPatchAlgorithm(com.tencent.tinker.commons.dexpatcher.algorithms.patch.StringDataSectionPatchAlgorithm) StaticValueSectionPatchAlgorithm(com.tencent.tinker.commons.dexpatcher.algorithms.patch.StaticValueSectionPatchAlgorithm) FieldIdSectionPatchAlgorithm(com.tencent.tinker.commons.dexpatcher.algorithms.patch.FieldIdSectionPatchAlgorithm) AnnotationSetSectionPatchAlgorithm(com.tencent.tinker.commons.dexpatcher.algorithms.patch.AnnotationSetSectionPatchAlgorithm) Dex(com.tencent.tinker.android.dex.Dex) AnnotationsDirectorySectionPatchAlgorithm(com.tencent.tinker.commons.dexpatcher.algorithms.patch.AnnotationsDirectorySectionPatchAlgorithm) AnnotationSetRefListSectionPatchAlgorithm(com.tencent.tinker.commons.dexpatcher.algorithms.patch.AnnotationSetRefListSectionPatchAlgorithm) ClassDefSectionPatchAlgorithm(com.tencent.tinker.commons.dexpatcher.algorithms.patch.ClassDefSectionPatchAlgorithm) ProtoIdSectionPatchAlgorithm(com.tencent.tinker.commons.dexpatcher.algorithms.patch.ProtoIdSectionPatchAlgorithm) ClassDataSectionPatchAlgorithm(com.tencent.tinker.commons.dexpatcher.algorithms.patch.ClassDataSectionPatchAlgorithm)

Aggregations

Dex (com.tencent.tinker.android.dex.Dex)6 HashSet (java.util.HashSet)4 ClassDef (com.tencent.tinker.android.dex.ClassDef)3 TinkerPatchException (com.tencent.tinker.build.util.TinkerPatchException)2 File (java.io.File)2 IOException (java.io.IOException)2 ArrayList (java.util.ArrayList)2 Set (java.util.Set)2 JarFile (java.util.jar.JarFile)2 DexBackedDexFile (org.jf.dexlib2.dexbacked.DexBackedDexFile)2 DexFile (org.jf.dexlib2.iface.DexFile)2 TableOfContents (com.tencent.tinker.android.dex.TableOfContents)1 DexPatchGenerator (com.tencent.tinker.build.dexpatcher.DexPatchGenerator)1 ChangedClassesDexClassInfoCollector (com.tencent.tinker.build.dexpatcher.util.ChangedClassesDexClassInfoCollector)1 DexClassInfo (com.tencent.tinker.build.util.DexClassesComparator.DexClassInfo)1 DexGroup (com.tencent.tinker.build.util.DexClassesComparator.DexGroup)1 DexPatchApplier (com.tencent.tinker.commons.dexpatcher.DexPatchApplier)1 AnnotationSectionPatchAlgorithm (com.tencent.tinker.commons.dexpatcher.algorithms.patch.AnnotationSectionPatchAlgorithm)1 AnnotationSetRefListSectionPatchAlgorithm (com.tencent.tinker.commons.dexpatcher.algorithms.patch.AnnotationSetRefListSectionPatchAlgorithm)1 AnnotationSetSectionPatchAlgorithm (com.tencent.tinker.commons.dexpatcher.algorithms.patch.AnnotationSetSectionPatchAlgorithm)1