From 42b3354d43aaeb53c5956500b24703daaaaef1e8 Mon Sep 17 00:00:00 2001 From: ostajic Date: Tue, 25 Aug 2020 03:00:26 +0200 Subject: [PATCH] Updated Downloader to only download apks if they are needed also sha256 moved from install to download --- .../core/downloader/VancedDownloadService.kt | 87 +++++++++++++- .../installer/RootSplitInstallerService.kt | 107 ++---------------- .../com/vanced/manager/utils/PackageHelper.kt | 9 ++ 3 files changed, 98 insertions(+), 105 deletions(-) diff --git a/app/src/main/java/com/vanced/manager/core/downloader/VancedDownloadService.kt b/app/src/main/java/com/vanced/manager/core/downloader/VancedDownloadService.kt index 65175c3f..31758dd3 100644 --- a/app/src/main/java/com/vanced/manager/core/downloader/VancedDownloadService.kt +++ b/app/src/main/java/com/vanced/manager/core/downloader/VancedDownloadService.kt @@ -16,30 +16,47 @@ import com.vanced.manager.core.installer.RootSplitInstallerService import com.vanced.manager.core.installer.SplitInstaller import com.vanced.manager.ui.fragments.HomeFragment import com.vanced.manager.utils.AppUtils.installing +import com.vanced.manager.utils.InternetTools import com.vanced.manager.utils.InternetTools.baseUrl import com.vanced.manager.utils.InternetTools.getFileNameFromUrl import com.vanced.manager.utils.InternetTools.getObjectFromJson +import com.vanced.manager.utils.PackageHelper.getPkgVerCode import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking import java.io.File +import java.io.IOException +import java.security.MessageDigest class VancedDownloadService: Service() { + private var sha256Val: String? = null + private var vancedVersionCode: Int? = null + //private var downloadId: Long = 0 //private var apkType: String = "arch" private var count: Int = 0 private val localBroadcastManager by lazy { LocalBroadcastManager.getInstance(this) } + private var hashUrl = "" + + private val yPkg = "com.google.android.youtube" + + suspend fun getVer() + { + vancedVersionCode = InternetTools.getJsonInt("vanced.json", "versionCode", application) + } override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { //registerReceiver(receiver, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) + runBlocking { getVer() } downloadSplits() stopSelf() return START_NOT_STICKY } private fun downloadSplits( - type: String = "arch" + type: String = "theme" ) { CoroutineScope(Dispatchers.IO).launch { File(getExternalFilesDir("apk")?.path as String).deleteRecursively() @@ -58,10 +75,10 @@ class VancedDownloadService: Service() { else -> "armeabi_v7a" } val themePath = "$installUrl/apks/v$vancedVer/$variant/Theme" + hashUrl = "apks/v$vancedVer/$variant/Theme/hash.json" val url = when (type) { "arch" -> "$installUrl/apks/v$vancedVer/$variant/Arch/split_config.$arch.apk" - "hash" -> "$themePath/hash.json" "theme" -> "$themePath/$theme.apk" "stock" -> "$themePath/stock.apk" "dpi" -> "$themePath/dpi.apk" @@ -83,11 +100,12 @@ class VancedDownloadService: Service() { .start(object : OnDownloadListener { override fun onDownloadComplete() { when (type) { - "arch" -> downloadSplits("theme") - "theme" -> if(variant=="root") downloadSplits("stock") else downloadSplits("lang") + "theme" -> if(variant=="root") { + if(ValidateTheme()) {if(downloadStockCheck())downloadSplits("arch") else prepareInstall(variant)} else downloadSplits("theme") + } else downloadSplits("arch") + "arch" -> if(variant=="root") downloadSplits("stock") else downloadSplits("lang") "stock" -> downloadSplits("dpi") - "dpi" -> downloadSplits("hash") - "hash" -> downloadSplits("lang") + "dpi" -> downloadSplits("lang") "lang" -> { count++ if (count < lang?.count()!!) @@ -107,6 +125,23 @@ class VancedDownloadService: Service() { } } + private fun downloadStockCheck():Boolean + { + return getPkgVerCode(yPkg, packageManager) != vancedVersionCode + } + suspend fun getSha256(obj: String) { + sha256Val = InternetTools.getJsonString(hashUrl,obj,applicationContext) + } + private fun ValidateTheme(): Boolean + { + val prefs = getSharedPreferences("installPrefs", Context.MODE_PRIVATE) + val theme = prefs?.getString("theme", "dark") + val themeS = getExternalFilesDir("apks")?.path + "/${theme}.apk" + val themeF = File(themeS) + runBlocking { getSha256(theme!!) } + return checkSHA256(sha256Val!!,themeF) + } + /* private val receiver = object : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { @@ -147,4 +182,44 @@ class VancedDownloadService: Service() { return null } + private fun checkSHA256(sha256: String, updateFile: File?): Boolean { + return try { + val dataBuffer = updateFile!!.readBytes() + // Generate the checksum + val sum = generateChecksum(dataBuffer) + + sum == sha256 + } catch (e: Exception) { + e.printStackTrace() + false + } + } + + @Throws(IOException::class) + private fun generateChecksum(data: ByteArray): String { + try { + val digest: MessageDigest = MessageDigest.getInstance("SHA-256") + val hash: ByteArray = digest.digest(data) + return printableHexString(hash) + } catch (e: Exception) { + e.printStackTrace() + } + + return "" + } + + + private fun printableHexString(data: ByteArray): String { + // Create Hex String + val hexString: StringBuilder = StringBuilder() + for (aMessageDigest:Byte in data) { + var h: String = Integer.toHexString(0xFF and aMessageDigest.toInt()) + while (h.length < 2) + h = "0$h" + hexString.append(h) + } + return hexString.toString() + } + + } \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/core/installer/RootSplitInstallerService.kt b/app/src/main/java/com/vanced/manager/core/installer/RootSplitInstallerService.kt index b1bac8be..58f2d64e 100644 --- a/app/src/main/java/com/vanced/manager/core/installer/RootSplitInstallerService.kt +++ b/app/src/main/java/com/vanced/manager/core/installer/RootSplitInstallerService.kt @@ -8,10 +8,7 @@ import android.os.IBinder import android.util.Log import androidx.annotation.Nullable import androidx.annotation.WorkerThread -import androidx.core.net.toUri import androidx.localbroadcastmanager.content.LocalBroadcastManager -import com.beust.klaxon.JsonObject -import com.beust.klaxon.Parser import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.io.SuFile import com.vanced.manager.BuildConfig @@ -20,15 +17,13 @@ import com.vanced.manager.utils.AppUtils.sendFailure import com.vanced.manager.utils.FileInfo import com.vanced.manager.utils.InternetTools.getJsonInt import com.vanced.manager.utils.PackageHelper +import com.vanced.manager.utils.PackageHelper.getPkgVerCode import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking -import java.io.ByteArrayOutputStream import java.io.File -import java.io.FileInputStream import java.io.IOException -import java.security.MessageDigest import java.text.SimpleDateFormat import java.util.* import java.util.regex.Pattern @@ -37,7 +32,6 @@ import kotlin.collections.ArrayList class RootSplitInstallerService: Service() { - private var hashjson: FileInfo? = null private var vancedVersionCode: Int = 0 val yPkg = "com.google.android.youtube" @@ -71,15 +65,10 @@ class RootSplitInstallerService: Service() { { modApk = fil } - if(fil.name == "hash.json") - { - hashjson = fil - } } - if (modApk != null && hashjson != null) { + if (modApk != null) { - val hash = parseJson(modApk.name.split(".")[0], hashjson!!) - if(overwriteBase(modApk, fileInfoList, vancedVersionCode,hash)) + if(overwriteBase(modApk, fileInfoList, vancedVersionCode)) { with(localBroadcastManager) { sendBroadcast(Intent(HomeFragment.REFRESH_HOME)) @@ -104,14 +93,6 @@ class RootSplitInstallerService: Service() { return START_NOT_STICKY } - private fun parseJson(s: String, hashjson: FileInfo): String - { - val jsonData = SuFile.open(hashjson.file!!.absolutePath).readText(Charsets.UTF_8) - val jsonObject = Parser.default().parse(StringBuilder(jsonData)) as JsonObject - return jsonObject.string(s)!! - } - - @WorkerThread private fun installSplitApkFiles(apkFiles: ArrayList) : Boolean { var sessionId: Int? @@ -203,36 +184,23 @@ class RootSplitInstallerService: Service() { } //install Vanced - private fun overwriteBase(apkFile: FileInfo,baseApkFiles: ArrayList, versionCode: Int,hash: String): Boolean + private fun overwriteBase(apkFile: FileInfo,baseApkFiles: ArrayList, versionCode: Int): Boolean { if(checkVersion(versionCode,baseApkFiles)) { val path = getVPath() apkFile.file?.let { val apath = it.absolutePath - if(sha256Check(apath,hash)) + if(path?.let { it1 -> moveAPK(apath, it1) }!!) { - if(path?.let { it1 -> moveAPK(apath, it1) }!!) - { - val fpath = SuFile.open(path).parent!! - return chConV(path) - } - } - else - { - sendFailure(listOf("Corrupt_Data").toMutableList(), applicationContext) - + val fpath = SuFile.open(path).parent!! + return chConV(path) } } } return false } - //do sha256 check on downloaded apk - private fun sha256Check(apath: String, hash: String): Boolean { - val sfile = SuFile.open(apath) - return checkSHA256(hash,sfile) - } //check version and perform action based on result private fun checkVersion(versionCode: Int, baseApkFiles: ArrayList): Boolean { @@ -240,7 +208,7 @@ class RootSplitInstallerService: Service() { if (path != null) { if(path.contains("/data/app/")) { - when(getPkgVerCode(yPkg)?.let { compareVersion(it,versionCode) }) + when(getPkgVerCode(yPkg,packageManager)?.let { compareVersion(it,versionCode) }) { 1 -> {return fixHigherVer(baseApkFiles) } -1 -> {return fixLowerVer(baseApkFiles) } @@ -255,17 +223,6 @@ class RootSplitInstallerService: Service() { return fixNoInstall(baseApkFiles) } - - - private fun getPkgVerCode(pkg: String): Int? { - val pm = packageManager - return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) - pm.getPackageInfo(pkg, 0)?.longVersionCode?.and(0xFFFFFFFF)?.toInt() - else - pm.getPackageInfo(pkg, 0)?.versionCode - - } - private fun getPkgInfo(pkg: String): PackageInfo? { return try { @@ -373,54 +330,6 @@ class RootSplitInstallerService: Service() { } - private fun checkSHA256(sha256: String, updateFile: File?): Boolean { - try { - val mInputPFD = contentResolver.openFileDescriptor(updateFile!!.toUri() , "r") - val mContentFileDescriptor = mInputPFD!!.fileDescriptor - val fIS = FileInputStream(mContentFileDescriptor) - val dataBuffer = ByteArrayOutputStream() - val buf = ByteArray(1024) - while (true) { - val readNum = fIS.read(buf) - if (readNum == -1) break - dataBuffer.write(buf, 0, readNum) - } - - // Generate the checksum - val sum = generateChecksum(dataBuffer) - - return sum == sha256 - } catch (e: Exception) { - e.printStackTrace() - return false - } - } - - @Throws(IOException::class) - private fun generateChecksum(data: ByteArrayOutputStream): String { - try { - val digest: MessageDigest = MessageDigest.getInstance("SHA-256") - val hash: ByteArray = digest.digest(data.toByteArray()) - return printableHexString(hash) - } catch (e: Exception) { - e.printStackTrace() - } - - return "" - } - - - private fun printableHexString(data: ByteArray): String { - // Create Hex String - val hexString: StringBuilder = StringBuilder() - for (aMessageDigest:Byte in data) { - var h: String = Integer.toHexString(0xFF and aMessageDigest.toInt()) - while (h.length < 2) - h = "0$h" - hexString.append(h) - } - return hexString.toString() - } } \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/utils/PackageHelper.kt b/app/src/main/java/com/vanced/manager/utils/PackageHelper.kt index ecc096f6..3f05cd81 100644 --- a/app/src/main/java/com/vanced/manager/utils/PackageHelper.kt +++ b/app/src/main/java/com/vanced/manager/utils/PackageHelper.kt @@ -5,6 +5,7 @@ import android.app.PendingIntent import android.content.Context import android.content.Intent import android.content.pm.PackageManager +import android.os.Build import com.vanced.manager.core.installer.AppUninstallerService import java.lang.Exception @@ -26,6 +27,14 @@ object PackageHelper { "" } + fun getPkgVerCode(pkg: String, pm:PackageManager): Int? { + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) + pm.getPackageInfo(pkg, 0)?.longVersionCode?.and(0xFFFFFFFF)?.toInt() + else + pm.getPackageInfo(pkg, 0)?.versionCode + + } + fun uninstallApk(pkg: String, activity: Activity) { val callbackIntent = Intent(activity.applicationContext, AppUninstallerService::class.java) callbackIntent.putExtra("pkg", pkg)