mirror of
https://github.com/YTVanced/VancedManager
synced 2024-11-16 16:25:11 +00:00
Updated Downloader to only download apks if they are needed also sha256 moved from install to download
This commit is contained in:
parent
6965cf8585
commit
42b3354d43
3 changed files with 98 additions and 105 deletions
|
@ -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()
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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<FileInfo>) : Boolean {
|
||||
var sessionId: Int?
|
||||
|
@ -203,36 +184,23 @@ class RootSplitInstallerService: Service() {
|
|||
}
|
||||
|
||||
//install Vanced
|
||||
private fun overwriteBase(apkFile: FileInfo,baseApkFiles: ArrayList<FileInfo>, versionCode: Int,hash: String): Boolean
|
||||
private fun overwriteBase(apkFile: FileInfo,baseApkFiles: ArrayList<FileInfo>, 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) }!!)
|
||||
{
|
||||
val fpath = SuFile.open(path).parent!!
|
||||
return chConV(path)
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sendFailure(listOf("Corrupt_Data").toMutableList(), applicationContext)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
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<FileInfo>): 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()
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue