Search in sources :

Example 1 with TinkerRuntimeException

use of com.tencent.tinker.loader.TinkerRuntimeException in project tinker by Tencent.

the class DexDiffPatchInternal method patchDexExtractViaDexDiff.

private static boolean patchDexExtractViaDexDiff(Context context, String patchVersionDirectory, String meta, final File patchFile) {
    String dir = patchVersionDirectory + "/" + DEX_PATH + "/";
    if (!extractDexDiffInternals(context, dir, meta, patchFile, TYPE_DEX)) {
        TinkerLog.w(TAG, "patch recover, extractDiffInternals fail");
        return false;
    }
    final Tinker manager = Tinker.with(context);
    File dexFiles = new File(dir);
    File[] files = dexFiles.listFiles();
    optFiles.clear();
    if (files != null) {
        final String optimizeDexDirectory = patchVersionDirectory + "/" + DEX_OPTIMIZE_PATH + "/";
        File optimizeDexDirectoryFile = new File(optimizeDexDirectory);
        if (!optimizeDexDirectoryFile.exists() && !optimizeDexDirectoryFile.mkdirs()) {
            TinkerLog.w(TAG, "patch recover, make optimizeDexDirectoryFile fail");
            return false;
        }
        // add opt files
        for (File file : files) {
            String outputPathName = SharePatchFileUtil.optimizedPathFor(file, optimizeDexDirectoryFile);
            optFiles.add(new File(outputPathName));
        }
        TinkerLog.w(TAG, "patch recover, try to optimize dex file count:%d", files.length);
        // only use parallel dex optimizer for art
        if (ShareTinkerInternals.isVmArt()) {
            failOptDexFile.clear();
            // try parallel dex optimizer
            TinkerParallelDexOptimizer.optimizeAll(files, optimizeDexDirectoryFile, new TinkerParallelDexOptimizer.ResultCallback() {

                long startTime;

                @Override
                public void onStart(File dexFile, File optimizedDir) {
                    startTime = System.currentTimeMillis();
                    TinkerLog.i(TAG, "start to parallel optimize dex %s, size: %d", dexFile.getPath(), dexFile.length());
                }

                @Override
                public void onSuccess(File dexFile, File optimizedDir, File optimizedFile) {
                    // Do nothing.
                    TinkerLog.i(TAG, "success to parallel optimize dex %s, opt file size: %d, use time %d", dexFile.getPath(), optimizedFile.length(), (System.currentTimeMillis() - startTime));
                }

                @Override
                public void onFailed(File dexFile, File optimizedDir, Throwable thr) {
                    TinkerLog.i(TAG, "fail to parallel optimize dex %s use time %d", dexFile.getPath(), (System.currentTimeMillis() - startTime));
                    failOptDexFile.add(dexFile);
                }
            });
            // try again
            for (File retryDexFile : failOptDexFile) {
                try {
                    String outputPathName = SharePatchFileUtil.optimizedPathFor(retryDexFile, optimizeDexDirectoryFile);
                    if (!SharePatchFileUtil.isLegalFile(retryDexFile)) {
                        manager.getPatchReporter().onPatchDexOptFail(patchFile, retryDexFile, optimizeDexDirectory, retryDexFile.getName(), new TinkerRuntimeException("retry dex optimize file is not exist, name: " + retryDexFile.getName()));
                        return false;
                    }
                    TinkerLog.i(TAG, "try to retry dex optimize file, path: %s, size: %d", retryDexFile.getPath(), retryDexFile.length());
                    long start = System.currentTimeMillis();
                    DexFile.loadDex(retryDexFile.getAbsolutePath(), outputPathName, 0);
                    TinkerLog.i(TAG, "success retry dex optimize file, path: %s, opt file size: %d, use time: %d", retryDexFile.getPath(), new File(outputPathName).length(), (System.currentTimeMillis() - start));
                } catch (Throwable e) {
                    TinkerLog.e(TAG, "retry dex optimize or load failed, path:" + retryDexFile.getPath());
                    manager.getPatchReporter().onPatchDexOptFail(patchFile, retryDexFile, optimizeDexDirectory, retryDexFile.getName(), e);
                    return false;
                }
            }
        // for dalvik, machine hardware performance is much worse than art machine
        } else {
            for (File file : files) {
                try {
                    String outputPathName = SharePatchFileUtil.optimizedPathFor(file, optimizeDexDirectoryFile);
                    long start = System.currentTimeMillis();
                    DexFile.loadDex(file.getAbsolutePath(), outputPathName, 0);
                    TinkerLog.i(TAG, "success single dex optimize file, path: %s, opt file size: %d, use time: %d", file.getPath(), new File(outputPathName).length(), (System.currentTimeMillis() - start));
                } catch (Throwable e) {
                    TinkerLog.e(TAG, "single dex optimize or load failed, path:" + file.getPath());
                    manager.getPatchReporter().onPatchDexOptFail(patchFile, file, optimizeDexDirectory, file.getName(), e);
                    return false;
                }
            }
        }
    }
    return true;
}
Also used : TinkerRuntimeException(com.tencent.tinker.loader.TinkerRuntimeException) TinkerParallelDexOptimizer(com.tencent.tinker.loader.TinkerParallelDexOptimizer) Tinker(com.tencent.tinker.lib.tinker.Tinker) ZipFile(java.util.zip.ZipFile) DexFile(dalvik.system.DexFile) File(java.io.File)

Example 2 with TinkerRuntimeException

use of com.tencent.tinker.loader.TinkerRuntimeException in project tinker by Tencent.

the class BsDiffPatchInternal method extractBsDiffInternals.

private static boolean extractBsDiffInternals(Context context, String dir, String meta, File patchFile, int type) {
    // parse
    ArrayList<ShareBsDiffPatchInfo> patchList = new ArrayList<>();
    ShareBsDiffPatchInfo.parseDiffPatchInfo(meta, patchList);
    if (patchList.isEmpty()) {
        ShareTinkerLog.w(TAG, "extract patch list is empty! type:%s:", ShareTinkerInternals.getTypeString(type));
        return true;
    }
    File directory = new File(dir);
    if (!directory.exists()) {
        directory.mkdirs();
    }
    // I think it is better to extract the raw files from apk
    Tinker manager = Tinker.with(context);
    ApplicationInfo applicationInfo = context.getApplicationInfo();
    if (applicationInfo == null) {
        // Looks like running on a test Context, so just return without patching.
        ShareTinkerLog.w(TAG, "applicationInfo == null!!!!");
        return false;
    }
    ZipFile apk = null;
    ZipFile patch = null;
    try {
        String apkPath = applicationInfo.sourceDir;
        apk = new ZipFile(apkPath);
        patch = new ZipFile(patchFile);
        for (ShareBsDiffPatchInfo info : patchList) {
            long start = System.currentTimeMillis();
            final String infoPath = info.path;
            String patchRealPath;
            if (infoPath.equals("")) {
                patchRealPath = info.name;
            } else {
                patchRealPath = info.path + "/" + info.name;
            }
            final String fileMd5 = info.md5;
            if (!SharePatchFileUtil.checkIfMd5Valid(fileMd5)) {
                ShareTinkerLog.w(TAG, "meta file md5 mismatch, type:%s, name: %s, md5: %s", ShareTinkerInternals.getTypeString(type), info.name, info.md5);
                manager.getPatchReporter().onPatchPackageCheckFail(patchFile, BasePatchInternal.getMetaCorruptedCode(type));
                return false;
            }
            String middle;
            middle = info.path + "/" + info.name;
            File extractedFile = new File(dir + middle);
            // check file whether already exist
            if (extractedFile.exists()) {
                if (fileMd5.equals(SharePatchFileUtil.getMD5(extractedFile))) {
                    // it is ok, just continue
                    ShareTinkerLog.w(TAG, "bsdiff file %s is already exist, and md5 match, just continue", extractedFile.getPath());
                    continue;
                } else {
                    ShareTinkerLog.w(TAG, "have a mismatch corrupted dex " + extractedFile.getPath());
                    extractedFile.delete();
                }
            } else {
                extractedFile.getParentFile().mkdirs();
            }
            String patchFileMd5 = info.patchMd5;
            // it is a new file, just copy
            ZipEntry patchFileEntry = patch.getEntry(patchRealPath);
            if (patchFileEntry == null) {
                ShareTinkerLog.w(TAG, "patch entry is null. path:" + patchRealPath);
                manager.getPatchReporter().onPatchTypeExtractFail(patchFile, extractedFile, info.name, type);
                return false;
            }
            if (patchFileMd5.equals("0")) {
                if (!extract(patch, patchFileEntry, extractedFile, fileMd5, false)) {
                    ShareTinkerLog.w(TAG, "Failed to extract file " + extractedFile.getPath());
                    manager.getPatchReporter().onPatchTypeExtractFail(patchFile, extractedFile, info.name, type);
                    return false;
                }
            } else {
                // we do not check the intermediate files' md5 to save time, use check whether it is 32 length
                if (!SharePatchFileUtil.checkIfMd5Valid(patchFileMd5)) {
                    ShareTinkerLog.w(TAG, "meta file md5 mismatch, type:%s, name: %s, md5: %s", ShareTinkerInternals.getTypeString(type), info.name, patchFileMd5);
                    manager.getPatchReporter().onPatchPackageCheckFail(patchFile, BasePatchInternal.getMetaCorruptedCode(type));
                    return false;
                }
                ZipEntry rawApkFileEntry = apk.getEntry(patchRealPath);
                if (rawApkFileEntry == null) {
                    ShareTinkerLog.w(TAG, "apk entry is null. path:" + patchRealPath);
                    manager.getPatchReporter().onPatchTypeExtractFail(patchFile, extractedFile, info.name, type);
                    return false;
                }
                String rawApkCrc = info.rawCrc;
                // check source crc instead of md5 for faster
                String rawEntryCrc = String.valueOf(rawApkFileEntry.getCrc());
                if (!rawEntryCrc.equals(rawApkCrc)) {
                    ShareTinkerLog.e(TAG, "apk entry %s crc is not equal, expect crc: %s, got crc: %s", patchRealPath, rawApkCrc, rawEntryCrc);
                    manager.getPatchReporter().onPatchTypeExtractFail(patchFile, extractedFile, info.name, type);
                    return false;
                }
                InputStream oldStream = null;
                InputStream newStream = null;
                try {
                    oldStream = apk.getInputStream(rawApkFileEntry);
                    newStream = patch.getInputStream(patchFileEntry);
                    BSPatch.patchFast(oldStream, newStream, extractedFile);
                } finally {
                    IOHelper.closeQuietly(oldStream);
                    IOHelper.closeQuietly(newStream);
                }
                // go go go bsdiff get the
                if (!SharePatchFileUtil.verifyFileMd5(extractedFile, fileMd5)) {
                    ShareTinkerLog.w(TAG, "Failed to recover diff file " + extractedFile.getPath());
                    manager.getPatchReporter().onPatchTypeExtractFail(patchFile, extractedFile, info.name, type);
                    SharePatchFileUtil.safeDeleteFile(extractedFile);
                    return false;
                }
                ShareTinkerLog.w(TAG, "success recover bsdiff file: %s, use time: %d", extractedFile.getPath(), (System.currentTimeMillis() - start));
            }
        }
    } catch (Throwable e) {
        throw new TinkerRuntimeException("patch " + ShareTinkerInternals.getTypeString(type) + " extract failed (" + e.getMessage() + ").", e);
    } finally {
        SharePatchFileUtil.closeZip(apk);
        SharePatchFileUtil.closeZip(patch);
    }
    return true;
}
Also used : TinkerRuntimeException(com.tencent.tinker.loader.TinkerRuntimeException) InputStream(java.io.InputStream) ZipEntry(java.util.zip.ZipEntry) ArrayList(java.util.ArrayList) ApplicationInfo(android.content.pm.ApplicationInfo) Tinker(com.tencent.tinker.lib.tinker.Tinker) ZipFile(java.util.zip.ZipFile) ShareBsDiffPatchInfo(com.tencent.tinker.loader.shareutil.ShareBsDiffPatchInfo) File(java.io.File) ZipFile(java.util.zip.ZipFile)

Example 3 with TinkerRuntimeException

use of com.tencent.tinker.loader.TinkerRuntimeException in project tinker by Tencent.

the class DexDiffPatchInternal method patchDexFile.

/**
 * Generate patched dex file (May wrapped it by a jar if needed.)
 *
 * @param baseApk        OldApk.
 * @param patchPkg       Patch package, it is also a zip file.
 * @param oldDexEntry    ZipEntry of old dex.
 * @param patchFileEntry ZipEntry of patch file. (also ends with .dex) This could be null.
 * @param patchInfo      Parsed patch info from package-meta.txt
 * @param patchedDexFile Patched dex file, may be a jar.
 *                       <p>
 *                       <b>Notice: patchFileEntry and smallPatchInfoFile cannot both be null.</b>
 * @throws IOException
 */
private static void patchDexFile(ZipFile baseApk, ZipFile patchPkg, ZipEntry oldDexEntry, ZipEntry patchFileEntry, ShareDexDiffPatchInfo patchInfo, File patchedDexFile) throws IOException {
    InputStream oldDexStream = null;
    InputStream patchFileStream = null;
    try {
        oldDexStream = new BufferedInputStream(baseApk.getInputStream(oldDexEntry));
        patchFileStream = (patchFileEntry != null ? new BufferedInputStream(patchPkg.getInputStream(patchFileEntry)) : null);
        final boolean isRawDexFile = SharePatchFileUtil.isRawDexFile(patchInfo.rawName);
        if (!isRawDexFile || patchInfo.isJarMode) {
            ZipOutputStream zos = null;
            try {
                zos = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(patchedDexFile)));
                zos.putNextEntry(new ZipEntry(ShareConstants.DEX_IN_JAR));
                // Old dex is not a raw dex file.
                if (!isRawDexFile) {
                    ZipInputStream zis = null;
                    try {
                        zis = new ZipInputStream(oldDexStream);
                        ZipEntry entry;
                        while ((entry = zis.getNextEntry()) != null) {
                            if (ShareConstants.DEX_IN_JAR.equals(entry.getName()))
                                break;
                        }
                        if (entry == null) {
                            throw new TinkerRuntimeException("can't recognize zip dex format file:" + patchedDexFile.getAbsolutePath());
                        }
                        new DexPatchApplier(zis, patchFileStream).executeAndSaveTo(zos);
                    } finally {
                        IOHelper.closeQuietly(zis);
                    }
                } else {
                    new DexPatchApplier(oldDexStream, patchFileStream).executeAndSaveTo(zos);
                }
                zos.closeEntry();
            } finally {
                IOHelper.closeQuietly(zos);
            }
        } else {
            new DexPatchApplier(oldDexStream, patchFileStream).executeAndSaveTo(patchedDexFile);
        }
    } finally {
        IOHelper.closeQuietly(oldDexStream);
        IOHelper.closeQuietly(patchFileStream);
    }
}
Also used : TinkerRuntimeException(com.tencent.tinker.loader.TinkerRuntimeException) ZipInputStream(java.util.zip.ZipInputStream) DexPatchApplier(com.tencent.tinker.commons.dexpatcher.DexPatchApplier) BufferedInputStream(java.io.BufferedInputStream) BufferedInputStream(java.io.BufferedInputStream) ZipInputStream(java.util.zip.ZipInputStream) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) ZipOutputStream(java.util.zip.ZipOutputStream) AlignedZipOutputStream(com.tencent.tinker.ziputils.ziputil.AlignedZipOutputStream) FileOutputStream(java.io.FileOutputStream) ZipEntry(java.util.zip.ZipEntry) BufferedOutputStream(java.io.BufferedOutputStream)

Example 4 with TinkerRuntimeException

use of com.tencent.tinker.loader.TinkerRuntimeException in project tinker by Tencent.

the class DexDiffPatchInternal method waitAndCheckDexOptFile.

protected static boolean waitAndCheckDexOptFile(File patchFile, Tinker manager) {
    if (optFiles.isEmpty()) {
        return true;
    }
    // should use patch list size
    int size = patchList.size() * 30;
    if (size > MAX_WAIT_COUNT) {
        size = MAX_WAIT_COUNT;
    }
    ShareTinkerLog.i(TAG, "raw dex count: %d, dex opt dex count: %d, final wait times: %d", patchList.size(), optFiles.size(), size);
    for (int i = 0; i < size; i++) {
        if (!checkAllDexOptFile(optFiles, i + 1)) {
            try {
                Thread.sleep(WAIT_ASYN_OAT_TIME);
            } catch (InterruptedException e) {
                ShareTinkerLog.e(TAG, "thread sleep InterruptedException e:" + e);
            }
        }
    }
    List<File> failDexFiles = new ArrayList<>();
    // check again, if still can't be found, just return
    for (File file : optFiles) {
        ShareTinkerLog.i(TAG, "check dex optimizer file exist: %s, size %d", file.getPath(), file.length());
        if (!SharePatchFileUtil.isLegalFile(file) && !SharePatchFileUtil.shouldAcceptEvenIfIllegal(file)) {
            ShareTinkerLog.e(TAG, "final parallel dex optimizer file %s is not exist, return false", file.getName());
            failDexFiles.add(file);
        }
    }
    if (!failDexFiles.isEmpty()) {
        manager.getPatchReporter().onPatchDexOptFail(patchFile, failDexFiles, new TinkerRuntimeException(ShareConstants.CHECK_DEX_OAT_EXIST_FAIL));
        return false;
    }
    if (Build.VERSION.SDK_INT >= 21) {
        Throwable lastThrowable = null;
        for (File file : optFiles) {
            if (SharePatchFileUtil.shouldAcceptEvenIfIllegal(file)) {
                continue;
            }
            ShareTinkerLog.i(TAG, "check dex optimizer file format: %s, size %d", file.getName(), file.length());
            int returnType;
            try {
                returnType = ShareElfFile.getFileTypeByMagic(file);
            } catch (IOException e) {
                // read error just continue
                continue;
            }
            if (returnType == ShareElfFile.FILE_TYPE_ELF) {
                ShareElfFile elfFile = null;
                try {
                    elfFile = new ShareElfFile(file);
                } catch (Throwable e) {
                    ShareTinkerLog.e(TAG, "final parallel dex optimizer file %s is not elf format, return false", file.getName());
                    failDexFiles.add(file);
                    lastThrowable = e;
                } finally {
                    IOHelper.closeQuietly(elfFile);
                }
            }
        }
        if (!failDexFiles.isEmpty()) {
            Throwable returnThrowable = lastThrowable == null ? new TinkerRuntimeException(ShareConstants.CHECK_DEX_OAT_FORMAT_FAIL) : new TinkerRuntimeException(ShareConstants.CHECK_DEX_OAT_FORMAT_FAIL, lastThrowable);
            manager.getPatchReporter().onPatchDexOptFail(patchFile, failDexFiles, returnThrowable);
            return false;
        }
    }
    return true;
}
Also used : TinkerRuntimeException(com.tencent.tinker.loader.TinkerRuntimeException) ShareElfFile(com.tencent.tinker.loader.shareutil.ShareElfFile) ArrayList(java.util.ArrayList) IOException(java.io.IOException) ZipFile(java.util.zip.ZipFile) ShareElfFile(com.tencent.tinker.loader.shareutil.ShareElfFile) File(java.io.File)

Example 5 with TinkerRuntimeException

use of com.tencent.tinker.loader.TinkerRuntimeException in project tinker by Tencent.

the class ResDiffPatchInternal method checkAndExtractResourceLargeFile.

private static boolean checkAndExtractResourceLargeFile(Context context, String apkPath, File directory, File tempFileDirtory, File patchFile, ShareResPatchInfo resPatchInfo, int type) {
    long start = System.currentTimeMillis();
    Tinker manager = Tinker.with(context);
    ZipFile apkFile = null;
    ZipFile patchZipFile = null;
    try {
        // recover resources.arsc first
        apkFile = new ZipFile(apkPath);
        ZipEntry arscEntry = apkFile.getEntry(ShareConstants.RES_ARSC);
        File arscFile = new File(directory, ShareConstants.RES_ARSC);
        if (arscEntry == null) {
            ShareTinkerLog.w(TAG, "resources apk entry is null. path:" + ShareConstants.RES_ARSC);
            manager.getPatchReporter().onPatchTypeExtractFail(patchFile, arscFile, ShareConstants.RES_ARSC, type);
            return false;
        }
        // use base resources.arsc crc to identify base.apk
        String baseArscCrc = String.valueOf(arscEntry.getCrc());
        if (!baseArscCrc.equals(resPatchInfo.arscBaseCrc)) {
            ShareTinkerLog.e(TAG, "resources.arsc's crc is not equal, expect crc: %s, got crc: %s", resPatchInfo.arscBaseCrc, baseArscCrc);
            manager.getPatchReporter().onPatchTypeExtractFail(patchFile, arscFile, ShareConstants.RES_ARSC, type);
            return false;
        }
        // resource arsc is not changed, just return true
        if (resPatchInfo.largeModRes.isEmpty() && resPatchInfo.storeRes.isEmpty()) {
            ShareTinkerLog.i(TAG, "no large modify or store resources, just return");
            return true;
        }
        patchZipFile = new ZipFile(patchFile);
        for (String name : resPatchInfo.storeRes.keySet()) {
            long storeStart = System.currentTimeMillis();
            File destCopy = new File(tempFileDirtory, name);
            SharePatchFileUtil.ensureFileDirectory(destCopy);
            ZipEntry patchEntry = patchZipFile.getEntry(name);
            if (patchEntry == null) {
                ShareTinkerLog.w(TAG, "store patch entry is null. path:" + name);
                manager.getPatchReporter().onPatchTypeExtractFail(patchFile, destCopy, name, type);
                return false;
            }
            extract(patchZipFile, patchEntry, destCopy, null, false);
            // fast check, only check size
            if (patchEntry.getSize() != destCopy.length()) {
                ShareTinkerLog.w(TAG, "resource meta file size mismatch, type:%s, name: %s, patch size: %d, file size; %d", ShareTinkerInternals.getTypeString(type), name, patchEntry.getSize(), destCopy.length());
                manager.getPatchReporter().onPatchPackageCheckFail(patchFile, BasePatchInternal.getMetaCorruptedCode(type));
                return false;
            }
            resPatchInfo.storeRes.put(name, destCopy);
            ShareTinkerLog.w(TAG, "success recover store file:%s, file size:%d, use time:%d", destCopy.getPath(), destCopy.length(), (System.currentTimeMillis() - storeStart));
        }
        for (String name : resPatchInfo.largeModRes) {
            long largeStart = System.currentTimeMillis();
            ShareResPatchInfo.LargeModeInfo largeModeInfo = resPatchInfo.largeModMap.get(name);
            if (largeModeInfo == null) {
                ShareTinkerLog.w(TAG, "resource not found largeModeInfo, type:%s, name: %s", ShareTinkerInternals.getTypeString(type), name);
                manager.getPatchReporter().onPatchPackageCheckFail(patchFile, BasePatchInternal.getMetaCorruptedCode(type));
                return false;
            }
            largeModeInfo.file = new File(tempFileDirtory, name);
            SharePatchFileUtil.ensureFileDirectory(largeModeInfo.file);
            // we do not check the intermediate files' md5 to save time, use check whether it is 32 length
            if (!SharePatchFileUtil.checkIfMd5Valid(largeModeInfo.md5)) {
                ShareTinkerLog.w(TAG, "resource meta file md5 mismatch, type:%s, name: %s, md5: %s", ShareTinkerInternals.getTypeString(type), name, largeModeInfo.md5);
                manager.getPatchReporter().onPatchPackageCheckFail(patchFile, BasePatchInternal.getMetaCorruptedCode(type));
                return false;
            }
            ZipEntry patchEntry = patchZipFile.getEntry(name);
            if (patchEntry == null) {
                ShareTinkerLog.w(TAG, "large mod patch entry is null. path:" + name);
                manager.getPatchReporter().onPatchTypeExtractFail(patchFile, largeModeInfo.file, name, type);
                return false;
            }
            ZipEntry baseEntry = apkFile.getEntry(name);
            if (baseEntry == null) {
                ShareTinkerLog.w(TAG, "resources apk entry is null. path:" + name);
                manager.getPatchReporter().onPatchTypeExtractFail(patchFile, largeModeInfo.file, name, type);
                return false;
            }
            InputStream oldStream = null;
            InputStream newStream = null;
            try {
                oldStream = apkFile.getInputStream(baseEntry);
                newStream = patchZipFile.getInputStream(patchEntry);
                BSPatch.patchFast(oldStream, newStream, largeModeInfo.file);
            } finally {
                IOHelper.closeQuietly(oldStream);
                IOHelper.closeQuietly(newStream);
            }
            // go go go bsdiff get the
            if (!SharePatchFileUtil.verifyFileMd5(largeModeInfo.file, largeModeInfo.md5)) {
                ShareTinkerLog.w(TAG, "Failed to recover large modify file:%s", largeModeInfo.file.getPath());
                SharePatchFileUtil.safeDeleteFile(largeModeInfo.file);
                manager.getPatchReporter().onPatchTypeExtractFail(patchFile, largeModeInfo.file, name, type);
                return false;
            }
            ShareTinkerLog.w(TAG, "success recover large modify file:%s, file size:%d, use time:%d", largeModeInfo.file.getPath(), largeModeInfo.file.length(), (System.currentTimeMillis() - largeStart));
        }
        ShareTinkerLog.w(TAG, "success recover all large modify and store resources use time:%d", (System.currentTimeMillis() - start));
    } catch (Throwable e) {
        throw new TinkerRuntimeException("patch " + ShareTinkerInternals.getTypeString(type) + " extract failed (" + e.getMessage() + ").", e);
    } finally {
        SharePatchFileUtil.closeZip(apkFile);
        SharePatchFileUtil.closeZip(patchZipFile);
    }
    return true;
}
Also used : TinkerRuntimeException(com.tencent.tinker.loader.TinkerRuntimeException) TinkerZipFile(com.tencent.tinker.ziputils.ziputil.TinkerZipFile) ZipFile(java.util.zip.ZipFile) ShareResPatchInfo(com.tencent.tinker.loader.shareutil.ShareResPatchInfo) InputStream(java.io.InputStream) TinkerZipEntry(com.tencent.tinker.ziputils.ziputil.TinkerZipEntry) ZipEntry(java.util.zip.ZipEntry) Tinker(com.tencent.tinker.lib.tinker.Tinker) File(java.io.File) TinkerZipFile(com.tencent.tinker.ziputils.ziputil.TinkerZipFile) ZipFile(java.util.zip.ZipFile)

Aggregations

TinkerRuntimeException (com.tencent.tinker.loader.TinkerRuntimeException)31 File (java.io.File)14 Tinker (com.tencent.tinker.lib.tinker.Tinker)10 ZipFile (java.util.zip.ZipFile)9 IOException (java.io.IOException)7 Intent (android.content.Intent)6 ZipEntry (java.util.zip.ZipEntry)5 ApplicationInfo (android.content.pm.ApplicationInfo)3 InputStream (java.io.InputStream)3 SuppressLint (android.annotation.SuppressLint)2 ShareElfFile (com.tencent.tinker.loader.shareutil.ShareElfFile)2 ShareResPatchInfo (com.tencent.tinker.loader.shareutil.ShareResPatchInfo)2 TinkerZipEntry (com.tencent.tinker.ziputils.ziputil.TinkerZipEntry)2 TinkerZipFile (com.tencent.tinker.ziputils.ziputil.TinkerZipFile)2 BufferedOutputStream (java.io.BufferedOutputStream)2 FileOutputStream (java.io.FileOutputStream)2 Field (java.lang.reflect.Field)2 ArrayList (java.util.ArrayList)2 JarFile (java.util.jar.JarFile)2 Instrumentation (android.app.Instrumentation)1