use of com.tencent.tinker.commons.ziputil.TinkerZipEntry in project tinker by Tencent.
the class ResUtil method extractTinkerEntry.
public static void extractTinkerEntry(TinkerZipFile apk, TinkerZipEntry zipEntry, TinkerZipOutputStream outputStream) throws IOException {
InputStream in = null;
try {
in = apk.getInputStream(zipEntry);
outputStream.putNextEntry(new TinkerZipEntry(zipEntry));
byte[] buffer = new byte[BUFFER_SIZE];
for (int length = in.read(buffer); length != -1; length = in.read(buffer)) {
outputStream.write(buffer, 0, length);
}
outputStream.closeEntry();
} finally {
if (in != null) {
in.close();
}
}
}
use of com.tencent.tinker.commons.ziputil.TinkerZipEntry 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;
}
use of com.tencent.tinker.commons.ziputil.TinkerZipEntry in project tinker by Tencent.
the class Utils method genResOutputFile.
public static String genResOutputFile(File output, File newZipFile, Configuration config, ArrayList<String> addedSet, ArrayList<String> modifiedSet, ArrayList<String> deletedSet, ArrayList<String> largeModifiedSet, HashMap<String, ResDiffDecoder.LargeModeInfo> largeModifiedMap) throws IOException {
TinkerZipFile oldApk = new TinkerZipFile(config.mOldApkFile);
TinkerZipFile newApk = new TinkerZipFile(newZipFile);
TinkerZipOutputStream out = new TinkerZipOutputStream(new BufferedOutputStream(new FileOutputStream(output)));
try {
final Enumeration<? extends TinkerZipEntry> entries = oldApk.entries();
while (entries.hasMoreElements()) {
TinkerZipEntry zipEntry = entries.nextElement();
if (zipEntry == null) {
throw new TinkerPatchException(String.format("zipEntry is null when get from oldApk"));
}
String name = zipEntry.getName();
if (name.contains("../")) {
continue;
}
if (Utils.checkFileInPattern(config.mResFilePattern, name)) {
//won't contain in add set.
if (!deletedSet.contains(name) && !modifiedSet.contains(name) && !largeModifiedSet.contains(name) && !name.equals(TypedValue.RES_MANIFEST)) {
ResUtil.extractTinkerEntry(oldApk, zipEntry, out);
}
}
}
//process manifest
TinkerZipEntry manifestZipEntry = oldApk.getEntry(TypedValue.RES_MANIFEST);
if (manifestZipEntry == null) {
throw new TinkerPatchException(String.format("can't found resource file %s from old apk file %s", TypedValue.RES_MANIFEST, config.mOldApkFile.getAbsolutePath()));
}
ResUtil.extractTinkerEntry(oldApk, manifestZipEntry, out);
for (String name : largeModifiedSet) {
TinkerZipEntry largeZipEntry = oldApk.getEntry(name);
if (largeZipEntry == null) {
throw new TinkerPatchException(String.format("can't found resource file %s from old apk file %s", name, config.mOldApkFile.getAbsolutePath()));
}
ResDiffDecoder.LargeModeInfo largeModeInfo = largeModifiedMap.get(name);
ResUtil.extractLargeModifyFile(largeZipEntry, largeModeInfo.path, largeModeInfo.crc, out);
}
for (String name : addedSet) {
TinkerZipEntry addZipEntry = newApk.getEntry(name);
if (addZipEntry == null) {
throw new TinkerPatchException(String.format("can't found add resource file %s from new apk file %s", name, config.mNewApkFile.getAbsolutePath()));
}
ResUtil.extractTinkerEntry(newApk, addZipEntry, out);
}
for (String name : modifiedSet) {
TinkerZipEntry modZipEntry = newApk.getEntry(name);
if (modZipEntry == null) {
throw new TinkerPatchException(String.format("can't found add resource file %s from new apk file %s", name, config.mNewApkFile.getAbsolutePath()));
}
ResUtil.extractTinkerEntry(newApk, modZipEntry, out);
}
} finally {
out.close();
oldApk.close();
newApk.close();
}
return MD5.getMD5(output);
}
use of com.tencent.tinker.commons.ziputil.TinkerZipEntry in project tinker by Tencent.
the class ResUtil method extractLargeModifyFile.
public static void extractLargeModifyFile(TinkerZipEntry sourceArscEntry, File newFile, long newFileCrc, TinkerZipOutputStream outputStream) throws IOException {
TinkerZipEntry newArscZipEntry = new TinkerZipEntry(sourceArscEntry);
newArscZipEntry.setMethod(TinkerZipEntry.STORED);
newArscZipEntry.setSize(newFile.length());
newArscZipEntry.setCompressedSize(newFile.length());
newArscZipEntry.setCrc(newFileCrc);
FileInputStream in = null;
try {
in = new FileInputStream(newFile);
outputStream.putNextEntry(new TinkerZipEntry(newArscZipEntry));
byte[] buffer = new byte[BUFFER_SIZE];
for (int length = in.read(buffer); length != -1; length = in.read(buffer)) {
outputStream.write(buffer, 0, length);
}
outputStream.closeEntry();
} finally {
if (in != null) {
in.close();
}
}
}
Aggregations