[dev_opt_2.15.0] patch升级代码提交

This commit is contained in:
renwj
2023-03-06 19:50:41 +08:00
parent 91547ae873
commit 3c58608ca6
55 changed files with 2100 additions and 156 deletions

View File

@@ -0,0 +1,21 @@
package com.mogo.launcer.patch
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class) class ExampleInstrumentedTest {
@Test fun useAppContext() { // Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.mogo.launcer.patch.test", appContext.packageName)
}
}

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mogo.launcher.patch">
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<application>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
<meta-data android:name="SUPPORT_PATCH" android:value="1" />
</application>
</manifest>

View File

@@ -0,0 +1,12 @@
package com.github.sisong;
public class ApkPatch{
static {
System.loadLibrary("apkpatch");
}
// return TPatchResult, 0 is ok; patchFilePath file created by ZipDiff;
public static native int patch(String oldApkPath,String patchFilePath,String outNewApkPath,
long maxUncompressMemory,String tempUncompressFilePath,int threadNum);
}

View File

@@ -0,0 +1,80 @@
package com.mogo.launcher.patch
import android.content.*
import android.text.TextUtils
import android.util.*
import com.github.sisong.*
import com.mogo.eagle.core.utilcode.util.AppUtils
import com.mogo.launcher.patch.utils.*
import java.io.File
internal object PatchManager {
private const val TAG = "PatchManager"
fun isPatchAccept(context: Context, expectSourceMd5: String, patchSize: Long): Boolean {
val apkMd5 = AppUtils.getAppApkMd5()
if (TextUtils.isEmpty(apkMd5)) {
return false
}
if (apkMd5 != expectSourceMd5) {
return false
}
return true
}
fun applyPatch(ctx: Context, patch: File, newApk: File): Boolean {
val oldApkPath = ctx.packageManager.getPackageInfo(ctx.packageName, 0).applicationInfo.sourceDir
if (TextUtils.isEmpty(oldApkPath)) {
throw AssertionError("旧的apk文件的文件路径为空.")
}
val oldApk = File(oldApkPath)
Log.d(TAG, "applyPatch -- 1 --:oldApk -> ${oldApk.absolutePath}, patch: -> ${patch.absolutePath}, newApk: ${newApk.absolutePath}")
if (!oldApk.exists()) {
throw AssertionError("旧的apk文件不存在, 文件所在路径:${oldApk.absolutePath}")
}
Log.d(TAG, "applyPatch -- 2 --")
if (!patch.exists()) {
throw AssertionError("差分包文件不存在,文件所在路径:${patch.absolutePath}")
}
Log.d(TAG, "applyPatch -- 3 --")
val newApkParent = newApk.parentFile
if (newApkParent != null && !newApkParent.exists()) {
val ret = newApkParent.mkdirs()
if (!ret) {
throw AssertionError("新包创建父目录失败")
}
}
Log.d(TAG, "applyPatch -- 4 --")
if (newApk.exists()) {
newApk.delete()
}
if (newApkParent == null) {
throw AssertionError("新包父目录为空")
}
Log.d(TAG, "applyPatch -- 5 --")
val tempFilePath = File(ctx.getExternalFilesDir(null), "temp/temp.patch")
if (tempFilePath.exists()) {
tempFilePath.delete()
}
tempFilePath.parentFile?.takeIf { !it.exists() }?.mkdirs()
val result = ApkPatch.patch(oldApk.absolutePath, patch.absolutePath, newApk.absolutePath, 4 * 1024 * 1024, "", 4)
Log.d(TAG, "applyPatch -- end ---: result: $result")
if (result != 0) {
throw AssertionError("文件合成失败")
}
return true
}
fun checkMd5ForMergedApk(mergedApk: File, expectNewApkMd5: String): Boolean {
if (!mergedApk.exists()) {
return false
}
val md5 = Md5Util.getMd5FromFile(mergedApk)
if (md5 != expectNewApkMd5) {
return false
}
return true
}
}

View File

@@ -0,0 +1,33 @@
package com.mogo.launcher.patch.provider
import android.content.*
import com.alibaba.android.arouter.facade.annotation.Route
import com.mogo.eagle.core.data.constants.MogoServicePaths
import com.mogo.eagle.core.function.api.patch.*
import com.mogo.launcher.patch.*
import java.io.*
@Route(path = MogoServicePaths.PATH_PATCH_UPGRADE)
class MoGoPatchProviderImpl : IMoGoPatchProvider {
override fun isPatchAccept(context: Context, expectOldApkMd5: String, patchSize: Long): Boolean {
return PatchManager.isPatchAccept(context, expectOldApkMd5, patchSize)
}
override fun applyPatch(context: Context, patch: File, newApk: File): Boolean {
return try {
PatchManager.applyPatch(context, patch, newApk)
} catch (t: Throwable) {
t.printStackTrace()
false
}
}
override fun checkMd5ForMergedApk(context: Context, mergedApk: File, expectNewApkMd5: String): Boolean {
return PatchManager.checkMd5ForMergedApk(mergedApk, expectNewApkMd5)
}
override fun init(context: Context?) { }
}

View File

@@ -0,0 +1,42 @@
package com.mogo.launcher.patch.utils
import java.io.*
import java.nio.channels.FileChannel.MapMode
import java.security.*
class Md5Util {
companion object {
/**
* 获取单个文件的MD5值
* @param file
* @return
* 解决首位0被省略问题
*/
fun getMd5FromFile(file: File): String? {
var stringbuffer: StringBuffer? = null
try {
val hexDigits = charArrayOf('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f')
val input = FileInputStream(file)
val ch = input.channel
val byteBuffer = ch.map(MapMode.READ_ONLY, 0, file.length())
val digest = MessageDigest.getInstance("MD5")
digest.update(byteBuffer)
val bytes = digest.digest()
val n = bytes.size
stringbuffer = StringBuffer(2 * n)
for (l in 0 until n) {
val bt = bytes[l]
val c0 = hexDigits[bt.toInt() and 0xf0 shr 4]
val c1 = hexDigits[bt.toInt() and 0xf]
stringbuffer.append(c0)
stringbuffer.append(c1)
}
} catch (e: java.lang.Exception) {
e.printStackTrace()
}
return stringbuffer?.toString()
}
}
}

View File

@@ -0,0 +1,16 @@
package com.mogo.launcer.patch
import org.junit.Test
import org.junit.Assert.*
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}