use of com.tencent.tinker.loader.shareutil.SharePatchInfo 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;
}
use of com.tencent.tinker.loader.shareutil.SharePatchInfo in project tinker by Tencent.
the class UpgradePatch method tryPatch.
@Override
public boolean tryPatch(Context context, String tempPatchPath, PatchResult patchResult) {
Tinker manager = Tinker.with(context);
final File patchFile = new File(tempPatchPath);
if (!manager.isTinkerEnabled() || !ShareTinkerInternals.isTinkerEnableWithSharedPreferences(context)) {
TinkerLog.e(TAG, "UpgradePatch tryPatch:patch is disabled, just return");
return false;
}
if (!SharePatchFileUtil.isLegalFile(patchFile)) {
TinkerLog.e(TAG, "UpgradePatch tryPatch:patch file is not found, just return");
return false;
}
//check the signature, we should create a new checker
ShareSecurityCheck signatureCheck = new ShareSecurityCheck(context);
int returnCode = ShareTinkerInternals.checkTinkerPackage(context, manager.getTinkerFlags(), patchFile, signatureCheck);
if (returnCode != ShareConstants.ERROR_PACKAGE_CHECK_OK) {
TinkerLog.e(TAG, "UpgradePatch tryPatch:onPatchPackageCheckFail");
manager.getPatchReporter().onPatchPackageCheckFail(patchFile, returnCode);
return false;
}
//it is a new patch, so we should not find a exist
SharePatchInfo oldInfo = manager.getTinkerLoadResultIfPresent().patchInfo;
String patchMd5 = SharePatchFileUtil.getMD5(patchFile);
if (patchMd5 == null) {
TinkerLog.e(TAG, "UpgradePatch tryPatch:patch md5 is null, just return");
return false;
}
//use md5 as version
patchResult.patchVersion = patchMd5;
SharePatchInfo newInfo;
//already have patch
if (oldInfo != null) {
if (oldInfo.oldVersion == null || oldInfo.newVersion == null) {
TinkerLog.e(TAG, "UpgradePatch tryPatch:onPatchInfoCorrupted");
manager.getPatchReporter().onPatchInfoCorrupted(patchFile, oldInfo.oldVersion, oldInfo.newVersion);
return false;
}
if (!SharePatchFileUtil.checkIfMd5Valid(patchMd5)) {
TinkerLog.e(TAG, "UpgradePatch tryPatch:onPatchVersionCheckFail md5 %s is valid", patchMd5);
manager.getPatchReporter().onPatchVersionCheckFail(patchFile, oldInfo, patchMd5);
return false;
}
newInfo = new SharePatchInfo(oldInfo.oldVersion, patchMd5, Build.FINGERPRINT);
} else {
newInfo = new SharePatchInfo("", patchMd5, Build.FINGERPRINT);
}
//check ok, we can real recover a new patch
final String patchDirectory = manager.getPatchDirectory().getAbsolutePath();
TinkerLog.i(TAG, "UpgradePatch tryPatch:patchMd5:%s", patchMd5);
final String patchName = SharePatchFileUtil.getPatchVersionDirectory(patchMd5);
final String patchVersionDirectory = patchDirectory + "/" + patchName;
TinkerLog.i(TAG, "UpgradePatch tryPatch:patchVersionDirectory:%s", patchVersionDirectory);
//it is a new patch, we first delete if there is any files
//don't delete dir for faster retry
// SharePatchFileUtil.deleteDir(patchVersionDirectory);
//copy file
File destPatchFile = new File(patchVersionDirectory + "/" + SharePatchFileUtil.getPatchVersionFile(patchMd5));
try {
// check md5 first
if (!patchMd5.equals(SharePatchFileUtil.getMD5(destPatchFile))) {
SharePatchFileUtil.copyFileUsingStream(patchFile, destPatchFile);
TinkerLog.w(TAG, "UpgradePatch copy patch file, src file: %s size: %d, dest file: %s size:%d", patchFile.getAbsolutePath(), patchFile.length(), destPatchFile.getAbsolutePath(), destPatchFile.length());
}
} catch (IOException e) {
// e.printStackTrace();
TinkerLog.e(TAG, "UpgradePatch tryPatch:copy patch file fail from %s to %s", patchFile.getPath(), destPatchFile.getPath());
manager.getPatchReporter().onPatchTypeExtractFail(patchFile, destPatchFile, patchFile.getName(), ShareConstants.TYPE_PATCH_FILE);
return false;
}
//we use destPatchFile instead of patchFile, because patchFile may be deleted during the patch process
if (!DexDiffPatchInternal.tryRecoverDexFiles(manager, signatureCheck, context, patchVersionDirectory, destPatchFile)) {
TinkerLog.e(TAG, "UpgradePatch tryPatch:new patch recover, try patch dex failed");
return false;
}
if (!BsDiffPatchInternal.tryRecoverLibraryFiles(manager, signatureCheck, context, patchVersionDirectory, destPatchFile)) {
TinkerLog.e(TAG, "UpgradePatch tryPatch:new patch recover, try patch library failed");
return false;
}
if (!ResDiffPatchInternal.tryRecoverResourceFiles(manager, signatureCheck, context, patchVersionDirectory, destPatchFile)) {
TinkerLog.e(TAG, "UpgradePatch tryPatch:new patch recover, try patch resource failed");
return false;
}
// just warn
if (!DexDiffPatchInternal.waitDexOptFile()) {
TinkerLog.e(TAG, "UpgradePatch tryPatch:new patch recover, check dex opt file failed");
}
final File patchInfoFile = manager.getPatchInfoFile();
if (!SharePatchInfo.rewritePatchInfoFileWithLock(patchInfoFile, newInfo, SharePatchFileUtil.getPatchInfoLockFile(patchDirectory))) {
TinkerLog.e(TAG, "UpgradePatch tryPatch:new patch recover, rewrite patch info failed");
manager.getPatchReporter().onPatchInfoCorrupted(patchFile, newInfo.oldVersion, newInfo.newVersion);
return false;
}
TinkerLog.w(TAG, "UpgradePatch tryPatch: done, it is ok");
return true;
}
use of com.tencent.tinker.loader.shareutil.SharePatchInfo in project tinker by Tencent.
the class DefaultLoadReporter method checkAndCleanPatch.
/**
* other process may have installed old patch version,
* if we try to clean patch, we should kill other process first
*/
public void checkAndCleanPatch() {
Tinker tinker = Tinker.with(context);
//only main process can load a new patch
if (tinker.isMainProcess()) {
TinkerLoadResult tinkerLoadResult = tinker.getTinkerLoadResultIfPresent();
//if versionChange and the old patch version is not ""
if (tinkerLoadResult.versionChanged) {
SharePatchInfo sharePatchInfo = tinkerLoadResult.patchInfo;
if (sharePatchInfo != null && !ShareTinkerInternals.isNullOrNil(sharePatchInfo.oldVersion)) {
TinkerLog.w(TAG, "checkAndCleanPatch, oldVersion %s is not null, try kill all other process", sharePatchInfo.oldVersion);
ShareTinkerInternals.killAllOtherProcess(context);
}
}
}
tinker.cleanPatch();
}
Aggregations