Search in sources :

Example 11 with TinkerRuntimeException

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

the class TinkerLoadLibrary method loadArmV7Library.

/**
     * you can use TinkerInstaller.loadArmV7Library replace your System.loadLibrary for auto update library!
     * only support auto load lib/armeabi-v7a library from patch.
     * for other library in lib/* or assets,
     * you can load through {@code TinkerInstaller#loadLibraryFromTinker}
     */
public static void loadArmV7Library(Context context, String libName) {
    if (libName == null || libName.isEmpty() || context == null) {
        throw new TinkerRuntimeException("libName or context is null!");
    }
    Tinker tinker = Tinker.with(context);
    if (tinker.isEnabledForNativeLib()) {
        if (TinkerLoadLibrary.loadLibraryFromTinker(context, "lib/armeabi-v7a", libName)) {
            return;
        }
    }
    System.loadLibrary(libName);
}
Also used : TinkerRuntimeException(com.tencent.tinker.loader.TinkerRuntimeException) Tinker(com.tencent.tinker.lib.tinker.Tinker)

Example 12 with TinkerRuntimeException

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

the class DexDiffPatchInternal method extractDexDiffInternals.

private static boolean extractDexDiffInternals(Context context, String dir, String meta, File patchFile, int type) {
    //parse
    ArrayList<ShareDexDiffPatchInfo> patchList = new ArrayList<>();
    ShareDexDiffPatchInfo.parseDexDiffPatchInfo(meta, patchList);
    if (patchList.isEmpty()) {
        TinkerLog.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);
    ZipFile apk = null;
    ZipFile patch = null;
    try {
        ApplicationInfo applicationInfo = context.getApplicationInfo();
        if (applicationInfo == null) {
            // Looks like running on a test Context, so just return without patching.
            TinkerLog.w(TAG, "applicationInfo == null!!!!");
            return false;
        }
        String apkPath = applicationInfo.sourceDir;
        apk = new ZipFile(apkPath);
        patch = new ZipFile(patchFile);
        for (ShareDexDiffPatchInfo info : patchList) {
            long start = System.currentTimeMillis();
            final String infoPath = info.path;
            String patchRealPath;
            if (infoPath.equals("")) {
                patchRealPath = info.rawName;
            } else {
                patchRealPath = info.path + "/" + info.rawName;
            }
            String dexDiffMd5 = info.dexDiffMd5;
            String oldDexCrc = info.oldDexCrC;
            if (!ShareTinkerInternals.isVmArt() && info.destMd5InDvm.equals("0")) {
                TinkerLog.w(TAG, "patch dex %s is only for art, just continue", patchRealPath);
                continue;
            }
            String extractedFileMd5 = ShareTinkerInternals.isVmArt() ? info.destMd5InArt : info.destMd5InDvm;
            if (!SharePatchFileUtil.checkIfMd5Valid(extractedFileMd5)) {
                TinkerLog.w(TAG, "meta file md5 invalid, type:%s, name: %s, md5: %s", ShareTinkerInternals.getTypeString(type), info.rawName, extractedFileMd5);
                manager.getPatchReporter().onPatchPackageCheckFail(patchFile, BasePatchInternal.getMetaCorruptedCode(type));
                return false;
            }
            File extractedFile = new File(dir + info.realName);
            //check file whether already exist
            if (extractedFile.exists()) {
                if (SharePatchFileUtil.verifyDexFileMd5(extractedFile, extractedFileMd5)) {
                    //it is ok, just continue
                    TinkerLog.w(TAG, "dex file %s is already exist, and md5 match, just continue", extractedFile.getPath());
                    continue;
                } else {
                    TinkerLog.w(TAG, "have a mismatch corrupted dex " + extractedFile.getPath());
                    extractedFile.delete();
                }
            } else {
                extractedFile.getParentFile().mkdirs();
            }
            ZipEntry patchFileEntry = patch.getEntry(patchRealPath);
            ZipEntry rawApkFileEntry = apk.getEntry(patchRealPath);
            if (oldDexCrc.equals("0")) {
                if (patchFileEntry == null) {
                    TinkerLog.w(TAG, "patch entry is null. path:" + patchRealPath);
                    manager.getPatchReporter().onPatchTypeExtractFail(patchFile, extractedFile, info.rawName, type);
                    return false;
                }
                //it is a new file, but maybe we need to repack the dex file
                if (!extractDexFile(patch, patchFileEntry, extractedFile, info)) {
                    TinkerLog.w(TAG, "Failed to extract raw patch file " + extractedFile.getPath());
                    manager.getPatchReporter().onPatchTypeExtractFail(patchFile, extractedFile, info.rawName, type);
                    return false;
                }
            } else if (dexDiffMd5.equals("0")) {
                // skip process old dex for real dalvik vm
                if (!ShareTinkerInternals.isVmArt()) {
                    continue;
                }
                if (rawApkFileEntry == null) {
                    TinkerLog.w(TAG, "apk entry is null. path:" + patchRealPath);
                    manager.getPatchReporter().onPatchTypeExtractFail(patchFile, extractedFile, info.rawName, type);
                    return false;
                }
                //check source crc instead of md5 for faster
                String rawEntryCrc = String.valueOf(rawApkFileEntry.getCrc());
                if (!rawEntryCrc.equals(oldDexCrc)) {
                    TinkerLog.e(TAG, "apk entry %s crc is not equal, expect crc: %s, got crc: %s", patchRealPath, oldDexCrc, rawEntryCrc);
                    manager.getPatchReporter().onPatchTypeExtractFail(patchFile, extractedFile, info.rawName, type);
                    return false;
                }
                // Small patched dex generating strategy was disabled, we copy full original dex directly now.
                //patchDexFile(apk, patch, rawApkFileEntry, null, info, smallPatchInfoFile, extractedFile);
                extractDexFile(apk, rawApkFileEntry, extractedFile, info);
                if (!SharePatchFileUtil.verifyDexFileMd5(extractedFile, extractedFileMd5)) {
                    TinkerLog.w(TAG, "Failed to recover dex file when verify patched dex: " + extractedFile.getPath());
                    manager.getPatchReporter().onPatchTypeExtractFail(patchFile, extractedFile, info.rawName, type);
                    SharePatchFileUtil.safeDeleteFile(extractedFile);
                    return false;
                }
            } else {
                if (patchFileEntry == null) {
                    TinkerLog.w(TAG, "patch entry is null. path:" + patchRealPath);
                    manager.getPatchReporter().onPatchTypeExtractFail(patchFile, extractedFile, info.rawName, type);
                    return false;
                }
                if (!SharePatchFileUtil.checkIfMd5Valid(dexDiffMd5)) {
                    TinkerLog.w(TAG, "meta file md5 invalid, type:%s, name: %s, md5: %s", ShareTinkerInternals.getTypeString(type), info.rawName, dexDiffMd5);
                    manager.getPatchReporter().onPatchPackageCheckFail(patchFile, BasePatchInternal.getMetaCorruptedCode(type));
                    return false;
                }
                if (rawApkFileEntry == null) {
                    TinkerLog.w(TAG, "apk entry is null. path:" + patchRealPath);
                    manager.getPatchReporter().onPatchTypeExtractFail(patchFile, extractedFile, info.rawName, type);
                    return false;
                }
                //check source crc instead of md5 for faster
                String rawEntryCrc = String.valueOf(rawApkFileEntry.getCrc());
                if (!rawEntryCrc.equals(oldDexCrc)) {
                    TinkerLog.e(TAG, "apk entry %s crc is not equal, expect crc: %s, got crc: %s", patchRealPath, oldDexCrc, rawEntryCrc);
                    manager.getPatchReporter().onPatchTypeExtractFail(patchFile, extractedFile, info.rawName, type);
                    return false;
                }
                patchDexFile(apk, patch, rawApkFileEntry, patchFileEntry, info, extractedFile);
                if (!SharePatchFileUtil.verifyDexFileMd5(extractedFile, extractedFileMd5)) {
                    TinkerLog.w(TAG, "Failed to recover dex file when verify patched dex: " + extractedFile.getPath());
                    manager.getPatchReporter().onPatchTypeExtractFail(patchFile, extractedFile, info.rawName, type);
                    SharePatchFileUtil.safeDeleteFile(extractedFile);
                    return false;
                }
                TinkerLog.w(TAG, "success recover dex file: %s, size: %d, use time: %d", extractedFile.getPath(), extractedFile.length(), (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) ZipFile(java.util.zip.ZipFile) ZipEntry(java.util.zip.ZipEntry) ArrayList(java.util.ArrayList) ApplicationInfo(android.content.pm.ApplicationInfo) ZipFile(java.util.zip.ZipFile) DexFile(dalvik.system.DexFile) File(java.io.File) Tinker(com.tencent.tinker.lib.tinker.Tinker) ShareDexDiffPatchInfo(com.tencent.tinker.loader.shareutil.ShareDexDiffPatchInfo)

Example 13 with TinkerRuntimeException

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

the class ResDiffPatchInternal method extractResourceDiffInternals.

private static boolean extractResourceDiffInternals(Context context, String dir, String meta, File patchFile, int type) {
    ShareResPatchInfo resPatchInfo = new ShareResPatchInfo();
    ShareResPatchInfo.parseAllResPatchInfo(meta, resPatchInfo);
    TinkerLog.i(TAG, "res dir: %s, meta: %s", dir, resPatchInfo.toString());
    Tinker manager = Tinker.with(context);
    if (!SharePatchFileUtil.checkIfMd5Valid(resPatchInfo.resArscMd5)) {
        TinkerLog.w(TAG, "resource meta file md5 mismatch, type:%s, md5: %s", ShareTinkerInternals.getTypeString(type), resPatchInfo.resArscMd5);
        manager.getPatchReporter().onPatchPackageCheckFail(patchFile, BasePatchInternal.getMetaCorruptedCode(type));
        return false;
    }
    File directory = new File(dir);
    File resOutput = new File(directory, ShareConstants.RES_NAME);
    //check result file whether already exist
    if (resOutput.exists()) {
        if (SharePatchFileUtil.checkResourceArscMd5(resOutput, resPatchInfo.resArscMd5)) {
            //it is ok, just continue
            TinkerLog.w(TAG, "resource file %s is already exist, and md5 match, just return true", resOutput.getPath());
            return true;
        } else {
            TinkerLog.w(TAG, "have a mismatch corrupted resource " + resOutput.getPath());
            resOutput.delete();
        }
    } else {
        resOutput.getParentFile().mkdirs();
    }
    try {
        ApplicationInfo applicationInfo = context.getApplicationInfo();
        if (applicationInfo == null) {
            //Looks like running on a test Context, so just return without patching.
            TinkerLog.w(TAG, "applicationInfo == null!!!!");
            return false;
        }
        String apkPath = applicationInfo.sourceDir;
        if (!checkAndExtractResourceLargeFile(context, apkPath, directory, patchFile, resPatchInfo, type)) {
            return false;
        }
        TinkerZipOutputStream out = null;
        TinkerZipFile oldApk = null;
        TinkerZipFile newApk = null;
        int totalEntryCount = 0;
        try {
            out = new TinkerZipOutputStream(new BufferedOutputStream(new FileOutputStream(resOutput)));
            oldApk = new TinkerZipFile(apkPath);
            newApk = new TinkerZipFile(patchFile);
            final Enumeration<? extends TinkerZipEntry> entries = oldApk.entries();
            while (entries.hasMoreElements()) {
                TinkerZipEntry zipEntry = entries.nextElement();
                if (zipEntry == null) {
                    throw new TinkerRuntimeException("zipEntry is null when get from oldApk");
                }
                String name = zipEntry.getName();
                if (name.contains("../")) {
                    continue;
                }
                if (ShareResPatchInfo.checkFileInPattern(resPatchInfo.patterns, name)) {
                    //won't contain in add set.
                    if (!resPatchInfo.deleteRes.contains(name) && !resPatchInfo.modRes.contains(name) && !resPatchInfo.largeModRes.contains(name) && !name.equals(ShareConstants.RES_MANIFEST)) {
                        ResUtil.extractTinkerEntry(oldApk, zipEntry, out);
                        totalEntryCount++;
                    }
                }
            }
            //process manifest
            TinkerZipEntry manifestZipEntry = oldApk.getEntry(ShareConstants.RES_MANIFEST);
            if (manifestZipEntry == null) {
                TinkerLog.w(TAG, "manifest patch entry is null. path:" + ShareConstants.RES_MANIFEST);
                manager.getPatchReporter().onPatchTypeExtractFail(patchFile, resOutput, ShareConstants.RES_MANIFEST, type);
                return false;
            }
            ResUtil.extractTinkerEntry(oldApk, manifestZipEntry, out);
            totalEntryCount++;
            for (String name : resPatchInfo.largeModRes) {
                TinkerZipEntry largeZipEntry = oldApk.getEntry(name);
                if (largeZipEntry == null) {
                    TinkerLog.w(TAG, "large patch entry is null. path:" + name);
                    manager.getPatchReporter().onPatchTypeExtractFail(patchFile, resOutput, name, type);
                    return false;
                }
                ShareResPatchInfo.LargeModeInfo largeModeInfo = resPatchInfo.largeModMap.get(name);
                ResUtil.extractLargeModifyFile(largeZipEntry, largeModeInfo.file, largeModeInfo.crc, out);
                totalEntryCount++;
            }
            for (String name : resPatchInfo.addRes) {
                TinkerZipEntry addZipEntry = newApk.getEntry(name);
                if (addZipEntry == null) {
                    TinkerLog.w(TAG, "add patch entry is null. path:" + name);
                    manager.getPatchReporter().onPatchTypeExtractFail(patchFile, resOutput, name, type);
                    return false;
                }
                ResUtil.extractTinkerEntry(newApk, addZipEntry, out);
                totalEntryCount++;
            }
            for (String name : resPatchInfo.modRes) {
                TinkerZipEntry modZipEntry = newApk.getEntry(name);
                if (modZipEntry == null) {
                    TinkerLog.w(TAG, "mod patch entry is null. path:" + name);
                    manager.getPatchReporter().onPatchTypeExtractFail(patchFile, resOutput, name, type);
                    return false;
                }
                ResUtil.extractTinkerEntry(newApk, modZipEntry, out);
                totalEntryCount++;
            }
        } finally {
            if (out != null) {
                out.close();
            }
            if (oldApk != null) {
                oldApk.close();
            }
            if (newApk != null) {
                newApk.close();
            }
            //delete temp files
            for (ShareResPatchInfo.LargeModeInfo largeModeInfo : resPatchInfo.largeModMap.values()) {
                SharePatchFileUtil.safeDeleteFile(largeModeInfo.file);
            }
        }
        boolean result = SharePatchFileUtil.checkResourceArscMd5(resOutput, resPatchInfo.resArscMd5);
        if (!result) {
            TinkerLog.i(TAG, "check final new resource file fail path:%s, entry count:%d, size:%d", resOutput.getAbsolutePath(), totalEntryCount, resOutput.length());
            SharePatchFileUtil.safeDeleteFile(resOutput);
            manager.getPatchReporter().onPatchTypeExtractFail(patchFile, resOutput, ShareConstants.RES_NAME, type);
            return false;
        }
        TinkerLog.i(TAG, "final new resource file:%s, entry count:%d, size:%d", resOutput.getAbsolutePath(), totalEntryCount, resOutput.length());
    } catch (Throwable e) {
        //            e.printStackTrace();
        throw new TinkerRuntimeException("patch " + ShareTinkerInternals.getTypeString(type) + " extract failed (" + e.getMessage() + ").", e);
    }
    return true;
}
Also used : TinkerRuntimeException(com.tencent.tinker.loader.TinkerRuntimeException) ApplicationInfo(android.content.pm.ApplicationInfo) TinkerZipEntry(com.tencent.tinker.commons.ziputil.TinkerZipEntry) Tinker(com.tencent.tinker.lib.tinker.Tinker) TinkerZipOutputStream(com.tencent.tinker.commons.ziputil.TinkerZipOutputStream) ShareResPatchInfo(com.tencent.tinker.loader.shareutil.ShareResPatchInfo) FileOutputStream(java.io.FileOutputStream) TinkerZipFile(com.tencent.tinker.commons.ziputil.TinkerZipFile) File(java.io.File) ZipFile(java.util.zip.ZipFile) BufferedOutputStream(java.io.BufferedOutputStream) TinkerZipFile(com.tencent.tinker.commons.ziputil.TinkerZipFile)

Example 14 with TinkerRuntimeException

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

the class TinkerLoadResult method parseTinkerResult.

public boolean parseTinkerResult(Context context, Intent intentResult) {
    Tinker tinker = Tinker.with(context);
    loadCode = ShareIntentUtil.getIntentReturnCode(intentResult);
    costTime = ShareIntentUtil.getIntentPatchCostTime(intentResult);
    systemOTA = ShareIntentUtil.getBooleanExtra(intentResult, ShareIntentUtil.INTENT_PATCH_SYSTEM_OTA, false);
    TinkerLog.i(TAG, "parseTinkerResult loadCode:%d, systemOTA:%b", loadCode, systemOTA);
    //@Nullable
    final String oldVersion = ShareIntentUtil.getStringExtra(intentResult, ShareIntentUtil.INTENT_PATCH_OLD_VERSION);
    //@Nullable
    final String newVersion = ShareIntentUtil.getStringExtra(intentResult, ShareIntentUtil.INTENT_PATCH_NEW_VERSION);
    final File patchDirectory = tinker.getPatchDirectory();
    final File patchInfoFile = tinker.getPatchInfoFile();
    final boolean isMainProcess = tinker.isMainProcess();
    if (oldVersion != null && newVersion != null) {
        if (isMainProcess) {
            currentVersion = newVersion;
        } else {
            currentVersion = oldVersion;
        }
        TinkerLog.i(TAG, "parseTinkerResult oldVersion:%s, newVersion:%s, current:%s", oldVersion, newVersion, currentVersion);
        //current version may be nil
        String patchName = SharePatchFileUtil.getPatchVersionDirectory(currentVersion);
        if (!ShareTinkerInternals.isNullOrNil(patchName)) {
            patchVersionDirectory = new File(patchDirectory.getAbsolutePath() + "/" + patchName);
            patchVersionFile = new File(patchVersionDirectory.getAbsolutePath(), SharePatchFileUtil.getPatchVersionFile(currentVersion));
            dexDirectory = new File(patchVersionDirectory, ShareConstants.DEX_PATH);
            libraryDirectory = new File(patchVersionDirectory, ShareConstants.SO_PATH);
            resourceDirectory = new File(patchVersionDirectory, ShareConstants.RES_PATH);
            resourceFile = new File(resourceDirectory, ShareConstants.RES_NAME);
        }
        patchInfo = new SharePatchInfo(oldVersion, newVersion, Build.FINGERPRINT);
        versionChanged = !(oldVersion.equals(newVersion));
    }
    //found uncaught exception, just return
    Throwable exception = ShareIntentUtil.getIntentPatchException(intentResult);
    if (exception != null) {
        TinkerLog.i(TAG, "Tinker load have exception loadCode:%d", loadCode);
        int errorCode = ShareConstants.ERROR_LOAD_EXCEPTION_UNKNOWN;
        switch(loadCode) {
            case ShareConstants.ERROR_LOAD_PATCH_UNKNOWN_EXCEPTION:
                errorCode = ShareConstants.ERROR_LOAD_EXCEPTION_UNKNOWN;
                break;
            case ShareConstants.ERROR_LOAD_PATCH_VERSION_DEX_LOAD_EXCEPTION:
                errorCode = ShareConstants.ERROR_LOAD_EXCEPTION_DEX;
                break;
            case ShareConstants.ERROR_LOAD_PATCH_VERSION_PARALLEL_DEX_OPT_EXCEPTION:
                errorCode = ShareConstants.ERROR_LOAD_EXCEPTION_DEX_OPT;
                break;
            case ShareConstants.ERROR_LOAD_PATCH_VERSION_RESOURCE_LOAD_EXCEPTION:
                errorCode = ShareConstants.ERROR_LOAD_EXCEPTION_RESOURCE;
                break;
            case ShareConstants.ERROR_LOAD_PATCH_UNCAUGHT_EXCEPTION:
                errorCode = ShareConstants.ERROR_LOAD_EXCEPTION_UNCAUGHT;
                break;
        }
        tinker.getLoadReporter().onLoadException(exception, errorCode);
        return false;
    }
    switch(loadCode) {
        case ShareConstants.ERROR_LOAD_GET_INTENT_FAIL:
            TinkerLog.e(TAG, "can't get the right intent return code");
            throw new TinkerRuntimeException("can't get the right intent return code");
        //                    break;
        case ShareConstants.ERROR_LOAD_DISABLE:
            TinkerLog.w(TAG, "tinker is disable, just return");
            break;
        //                break;
        case ShareConstants.ERROR_LOAD_PATCH_DIRECTORY_NOT_EXIST:
        case ShareConstants.ERROR_LOAD_PATCH_INFO_NOT_EXIST:
            TinkerLog.w(TAG, "can't find patch file, is ok, just return");
            break;
        case ShareConstants.ERROR_LOAD_PATCH_INFO_CORRUPTED:
            TinkerLog.e(TAG, "path info corrupted");
            tinker.getLoadReporter().onLoadPatchInfoCorrupted(oldVersion, newVersion, patchInfoFile);
            break;
        case ShareConstants.ERROR_LOAD_PATCH_INFO_BLANK:
            TinkerLog.e(TAG, "path info blank, wait main process to restart");
            break;
        case ShareConstants.ERROR_LOAD_PATCH_VERSION_DIRECTORY_NOT_EXIST:
            TinkerLog.e(TAG, "patch version directory not found, current version:%s", currentVersion);
            tinker.getLoadReporter().onLoadFileNotFound(patchVersionDirectory, ShareConstants.TYPE_PATCH_FILE, true);
            break;
        case ShareConstants.ERROR_LOAD_PATCH_VERSION_FILE_NOT_EXIST:
            TinkerLog.e(TAG, "patch version file not found, current version:%s", currentVersion);
            if (patchVersionFile == null) {
                throw new TinkerRuntimeException("error load patch version file not exist, but file is null");
            }
            tinker.getLoadReporter().onLoadFileNotFound(patchVersionFile, ShareConstants.TYPE_PATCH_FILE, false);
            break;
        case ShareConstants.ERROR_LOAD_PATCH_PACKAGE_CHECK_FAIL:
            TinkerLog.i(TAG, "patch package check fail");
            if (patchVersionFile == null) {
                throw new TinkerRuntimeException("error patch package check fail , but file is null");
            }
            int errorCode = intentResult.getIntExtra(ShareIntentUtil.INTENT_PATCH_PACKAGE_PATCH_CHECK, ShareConstants.ERROR_LOAD_GET_INTENT_FAIL);
            tinker.getLoadReporter().onLoadPackageCheckFail(patchVersionFile, errorCode);
            break;
        case ShareConstants.ERROR_LOAD_PATCH_VERSION_DEX_DIRECTORY_NOT_EXIST:
            if (dexDirectory != null) {
                TinkerLog.e(TAG, "patch dex file directory not found:%s", dexDirectory.getAbsolutePath());
                tinker.getLoadReporter().onLoadFileNotFound(dexDirectory, ShareConstants.TYPE_DEX, true);
            } else {
                //should be not here
                TinkerLog.e(TAG, "patch dex file directory not found, warning why the path is null!!!!");
                throw new TinkerRuntimeException("patch dex file directory not found, warning why the path is null!!!!");
            }
            break;
        case ShareConstants.ERROR_LOAD_PATCH_VERSION_DEX_FILE_NOT_EXIST:
            String dexPath = ShareIntentUtil.getStringExtra(intentResult, ShareIntentUtil.INTENT_PATCH_MISSING_DEX_PATH);
            if (dexPath != null) {
                //we only pass one missing file
                TinkerLog.e(TAG, "patch dex file not found:%s", dexPath);
                tinker.getLoadReporter().onLoadFileNotFound(new File(dexPath), ShareConstants.TYPE_DEX, false);
            } else {
                TinkerLog.e(TAG, "patch dex file not found, but path is null!!!!");
                throw new TinkerRuntimeException("patch dex file not found, but path is null!!!!");
            //                        tinker.getLoadReporter().onLoadFileNotFound(null,
            //                            ShareConstants.TYPE_DEX, false);
            }
            break;
        case ShareConstants.ERROR_LOAD_PATCH_VERSION_DEX_OPT_FILE_NOT_EXIST:
            String dexOptPath = ShareIntentUtil.getStringExtra(intentResult, ShareIntentUtil.INTENT_PATCH_MISSING_DEX_PATH);
            if (dexOptPath != null) {
                //we only pass one missing file
                TinkerLog.e(TAG, "patch dex opt file not found:%s", dexOptPath);
                tinker.getLoadReporter().onLoadFileNotFound(new File(dexOptPath), ShareConstants.TYPE_DEX_OPT, false);
            } else {
                TinkerLog.e(TAG, "patch dex opt file not found, but path is null!!!!");
                throw new TinkerRuntimeException("patch dex opt file not found, but path is null!!!!");
            //                        tinker.getLoadReporter().onLoadFileNotFound(null,
            //                            ShareConstants.TYPE_DEX, false);
            }
            break;
        case ShareConstants.ERROR_LOAD_PATCH_VERSION_LIB_DIRECTORY_NOT_EXIST:
            if (patchVersionDirectory != null) {
                TinkerLog.e(TAG, "patch lib file directory not found:%s", libraryDirectory.getAbsolutePath());
                tinker.getLoadReporter().onLoadFileNotFound(libraryDirectory, ShareConstants.TYPE_LIBRARY, true);
            } else {
                //should be not here
                TinkerLog.e(TAG, "patch lib file directory not found, warning why the path is null!!!!");
                throw new TinkerRuntimeException("patch lib file directory not found, warning why the path is null!!!!");
            //                        tinker.getLoadReporter().onLoadFileNotFound(null,
            //                            ShareConstants.TYPE_LIBRARY, true);
            }
            break;
        case ShareConstants.ERROR_LOAD_PATCH_VERSION_LIB_FILE_NOT_EXIST:
            String libPath = ShareIntentUtil.getStringExtra(intentResult, ShareIntentUtil.INTENT_PATCH_MISSING_LIB_PATH);
            if (libPath != null) {
                //we only pass one missing file and then we break
                TinkerLog.e(TAG, "patch lib file not found:%s", libPath);
                tinker.getLoadReporter().onLoadFileNotFound(new File(libPath), ShareConstants.TYPE_LIBRARY, false);
            } else {
                TinkerLog.e(TAG, "patch lib file not found, but path is null!!!!");
                throw new TinkerRuntimeException("patch lib file not found, but path is null!!!!");
            //                        tinker.getLoadReporter().onLoadFileNotFound(null,
            //                            ShareConstants.TYPE_LIBRARY, false);
            }
            break;
        case ShareConstants.ERROR_LOAD_PATCH_VERSION_DEX_CLASSLOADER_NULL:
            TinkerLog.e(TAG, "patch dex load fail, classloader is null");
            break;
        case ShareConstants.ERROR_LOAD_PATCH_VERSION_DEX_MD5_MISMATCH:
            String mismatchPath = ShareIntentUtil.getStringExtra(intentResult, ShareIntentUtil.INTENT_PATCH_MISMATCH_DEX_PATH);
            if (mismatchPath == null) {
                TinkerLog.e(TAG, "patch dex file md5 is mismatch, but path is null!!!!");
                throw new TinkerRuntimeException("patch dex file md5 is mismatch, but path is null!!!!");
            } else {
                TinkerLog.e(TAG, "patch dex file md5 is mismatch: %s", mismatchPath);
                tinker.getLoadReporter().onLoadFileMd5Mismatch(new File(mismatchPath), ShareConstants.TYPE_DEX);
            }
            break;
        case ShareConstants.ERROR_LOAD_PATCH_REWRITE_PATCH_INFO_FAIL:
            TinkerLog.i(TAG, "rewrite patch info file corrupted");
            tinker.getLoadReporter().onLoadPatchInfoCorrupted(oldVersion, newVersion, patchInfoFile);
            break;
        case ShareConstants.ERROR_LOAD_PATCH_VERSION_RESOURCE_DIRECTORY_NOT_EXIST:
            if (patchVersionDirectory != null) {
                TinkerLog.e(TAG, "patch resource file directory not found:%s", resourceDirectory.getAbsolutePath());
                tinker.getLoadReporter().onLoadFileNotFound(resourceDirectory, ShareConstants.TYPE_RESOURCE, true);
            } else {
                //should be not here
                TinkerLog.e(TAG, "patch resource file directory not found, warning why the path is null!!!!");
                throw new TinkerRuntimeException("patch resource file directory not found, warning why the path is null!!!!");
            }
            break;
        case ShareConstants.ERROR_LOAD_PATCH_VERSION_RESOURCE_FILE_NOT_EXIST:
            if (patchVersionDirectory != null) {
                TinkerLog.e(TAG, "patch resource file not found:%s", resourceFile.getAbsolutePath());
                tinker.getLoadReporter().onLoadFileNotFound(resourceFile, ShareConstants.TYPE_RESOURCE, false);
            } else {
                //should be not here
                TinkerLog.e(TAG, "patch resource file not found, warning why the path is null!!!!");
                throw new TinkerRuntimeException("patch resource file not found, warning why the path is null!!!!");
            }
            break;
        case ShareConstants.ERROR_LOAD_PATCH_VERSION_RESOURCE_MD5_MISMATCH:
            if (resourceFile == null) {
                TinkerLog.e(TAG, "resource file md5 mismatch, but patch resource file not found!");
                throw new TinkerRuntimeException("resource file md5 mismatch, but patch resource file not found!");
            }
            TinkerLog.e(TAG, "patch resource file md5 is mismatch: %s", resourceFile.getAbsolutePath());
            tinker.getLoadReporter().onLoadFileMd5Mismatch(resourceFile, ShareConstants.TYPE_RESOURCE);
            break;
        case ShareConstants.ERROR_LOAD_OK:
            TinkerLog.i(TAG, "oh yeah, tinker load all success");
            tinker.setTinkerLoaded(true);
            //get load dex
            dexes = ShareIntentUtil.getIntentPatchDexPaths(intentResult);
            libs = ShareIntentUtil.getIntentPatchLibsPaths(intentResult);
            packageConfig = ShareIntentUtil.getIntentPackageConfig(intentResult);
            if (isMainProcess && versionChanged) {
                //change the old version to new
                tinker.getLoadReporter().onLoadPatchVersionChanged(oldVersion, newVersion, patchDirectory, patchVersionDirectory.getName());
            }
            return true;
    }
    return false;
}
Also used : SharePatchInfo(com.tencent.tinker.loader.shareutil.SharePatchInfo) TinkerRuntimeException(com.tencent.tinker.loader.TinkerRuntimeException) File(java.io.File)

Example 15 with TinkerRuntimeException

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

the class TinkerPatchService method onHandleIntent.

@Override
protected void onHandleIntent(Intent intent) {
    final Context context = getApplicationContext();
    Tinker tinker = Tinker.with(context);
    tinker.getPatchReporter().onPatchServiceStart(intent);
    if (intent == null) {
        TinkerLog.e(TAG, "TinkerPatchService received a null intent, ignoring.");
        return;
    }
    String path = getPatchPathExtra(intent);
    if (path == null) {
        TinkerLog.e(TAG, "TinkerPatchService can't get the path extra, ignoring.");
        return;
    }
    File patchFile = new File(path);
    long begin = SystemClock.elapsedRealtime();
    boolean result;
    long cost;
    Throwable e = null;
    increasingPriority();
    PatchResult patchResult = new PatchResult();
    try {
        if (upgradePatchProcessor == null) {
            throw new TinkerRuntimeException("upgradePatchProcessor is null.");
        }
        result = upgradePatchProcessor.tryPatch(context, path, patchResult);
    } catch (Throwable throwable) {
        e = throwable;
        result = false;
        tinker.getPatchReporter().onPatchException(patchFile, e);
    }
    cost = SystemClock.elapsedRealtime() - begin;
    tinker.getPatchReporter().onPatchResult(patchFile, result, cost);
    patchResult.isSuccess = result;
    patchResult.rawPatchFilePath = path;
    patchResult.costTime = cost;
    patchResult.e = e;
    AbstractResultService.runResultService(context, patchResult, getPatchResultExtra(intent));
}
Also used : Context(android.content.Context) TinkerRuntimeException(com.tencent.tinker.loader.TinkerRuntimeException) Tinker(com.tencent.tinker.lib.tinker.Tinker) File(java.io.File)

Aggregations

TinkerRuntimeException (com.tencent.tinker.loader.TinkerRuntimeException)21 File (java.io.File)9 Tinker (com.tencent.tinker.lib.tinker.Tinker)8 Intent (android.content.Intent)6 ZipFile (java.util.zip.ZipFile)5 IOException (java.io.IOException)4 ZipEntry (java.util.zip.ZipEntry)4 ApplicationInfo (android.content.pm.ApplicationInfo)3 InputStream (java.io.InputStream)3 TinkerZipEntry (com.tencent.tinker.commons.ziputil.TinkerZipEntry)2 TinkerZipFile (com.tencent.tinker.commons.ziputil.TinkerZipFile)2 ShareResPatchInfo (com.tencent.tinker.loader.shareutil.ShareResPatchInfo)2 DexFile (dalvik.system.DexFile)2 BufferedOutputStream (java.io.BufferedOutputStream)2 FileOutputStream (java.io.FileOutputStream)2 X509Certificate (java.security.cert.X509Certificate)2 ArrayList (java.util.ArrayList)2 SuppressLint (android.annotation.SuppressLint)1 Context (android.content.Context)1 PackageInfo (android.content.pm.PackageInfo)1