Fix Bug With Install when youtube is not pre installed in system and added code check, and returns error message on install if there is one

This commit is contained in:
ostajic 2020-08-23 06:37:34 +02:00
parent 042a6a72a1
commit f2cb0e4307
2 changed files with 156 additions and 76 deletions

View File

@ -10,6 +10,10 @@ import androidx.annotation.Nullable
import androidx.annotation.WorkerThread import androidx.annotation.WorkerThread
import androidx.localbroadcastmanager.content.LocalBroadcastManager import androidx.localbroadcastmanager.content.LocalBroadcastManager
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
import com.topjohnwu.superuser.io.SuFile
import com.topjohnwu.superuser.io.SuFileInputStream
import com.topjohnwu.superuser.io.SuFileOutputStream
import com.vanced.manager.BuildConfig
import com.vanced.manager.ui.fragments.HomeFragment import com.vanced.manager.ui.fragments.HomeFragment
import com.vanced.manager.utils.AppUtils.sendFailure import com.vanced.manager.utils.AppUtils.sendFailure
import com.vanced.manager.utils.FileInfo import com.vanced.manager.utils.FileInfo
@ -20,12 +24,14 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import java.io.File import java.io.File
import java.io.IOException
import java.io.InputStream
import java.io.OutputStream
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
import java.util.regex.Pattern import java.util.regex.Pattern
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
class RootSplitInstallerService: Service() { class RootSplitInstallerService: Service() {
private var vancedVersionCode: Int = 0 private var vancedVersionCode: Int = 0
@ -33,43 +39,55 @@ class RootSplitInstallerService: Service() {
private val localBroadcastManager by lazy { LocalBroadcastManager.getInstance(this) } private val localBroadcastManager by lazy { LocalBroadcastManager.getInstance(this) }
suspend fun getVer() suspend fun getVer()
{ {
vancedVersionCode = getJsonInt("vanced.json","versionCode", application) vancedVersionCode = getJsonInt("vanced.json","versionCode", application)
} }
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
logDebug("RunBlockBefore");
Shell.enableVerboseLogging = BuildConfig.DEBUG
Shell.setDefaultBuilder(
Shell.Builder.create()
.setFlags(Shell.FLAG_REDIRECT_STDERR)
.setTimeout(10)
)
runBlocking { getVer() } runBlocking { getVer() }
logDebug("RunBlockAfter");
Shell.getShell { Shell.getShell {
CoroutineScope(Dispatchers.IO).launch { var job = CoroutineScope(Dispatchers.IO).launch{
val apkFilesPath = getExternalFilesDir("apks")?.path val apkFilesPath = getExternalFilesDir("apks")?.path
val fileInfoList = apkFilesPath?.let { it1 -> getFileInfoList(it1) } val fileInfoList = apkFilesPath?.let { it1 -> getFileInfoList(it1) }
logDebug("GotFileInfoList")
if (fileInfoList != null) { if (fileInfoList != null) {
var modApk: FileInfo? = null var modApk: FileInfo? = null
logDebug("FileInfoListIsNotEmpty")
for (fil in fileInfoList) for (fil in fileInfoList)
{ {
logDebug(fil.name)
if(fil.name == "dark.apk" || fil.name == "black.apk") if(fil.name == "dark.apk" || fil.name == "black.apk")
{ {
logDebug("found " + fil.name)
modApk = fil modApk = fil
} }
} }
logDebug("Before modApk Check")
if (modApk != null) { if (modApk != null) {
logDebug("modApkCheck Passed") if(overwriteBase(modApk, fileInfoList,vancedVersionCode))
overwriteBase(modApk, fileInfoList,vancedVersionCode) {
logDebug("Finished Patching") with(localBroadcastManager) {
sendBroadcast(Intent(HomeFragment.REFRESH_HOME))
sendBroadcast(Intent(HomeFragment.VANCED_INSTALLED))
}
} }
else else
{ {
throw IllegalArgumentException("modApk Is Null Cause Missing (dark.apk/black.apk) In apks Folder") sendFailure(listOf("Install Failed").toMutableList(), applicationContext)
}
}
else
{
sendFailure(listOf("modApk Is Null Missing (dark.apk/black.apk) In apks Folder").toMutableList(), applicationContext)
} }
//installSplitApkFiles(fileInfoList) //installSplitApkFiles(fileInfoList)
} }
} }
@ -78,12 +96,9 @@ class RootSplitInstallerService: Service() {
return START_NOT_STICKY return START_NOT_STICKY
} }
private fun logDebug(s: String) {
Log.d("ZLog", s)
}
@WorkerThread @WorkerThread
private fun installSplitApkFiles(apkFiles: ArrayList<FileInfo>) { private fun installSplitApkFiles(apkFiles: ArrayList<FileInfo>) : Boolean {
var sessionId: Int? var sessionId: Int?
Log.d("AppLog", "installing split apk files:$apkFiles") Log.d("AppLog", "installing split apk files:$apkFiles")
run { run {
@ -116,12 +131,10 @@ class RootSplitInstallerService: Service() {
Log.d("AppLog", "committing...") Log.d("AppLog", "committing...")
val installResult = Shell.su("pm install-commit $sessionId").exec() val installResult = Shell.su("pm install-commit $sessionId").exec()
if (installResult.isSuccess) { if (installResult.isSuccess) {
with(localBroadcastManager) { return true
sendBroadcast(Intent(HomeFragment.REFRESH_HOME))
sendBroadcast(Intent(HomeFragment.VANCED_INSTALLED))
}
} else } else
sendFailure(installResult.out, this) sendFailure(installResult.out, this)
return false
} }
private fun SimpleDateFormat.tryParse(str: String) = try { private fun SimpleDateFormat.tryParse(str: String) = try {
@ -176,60 +189,63 @@ class RootSplitInstallerService: Service() {
private fun overwriteBase(apkFile: FileInfo, baseApkFiles: ArrayList<FileInfo>, versionCode: Int) private fun overwriteBase(apkFile: FileInfo, baseApkFiles: ArrayList<FileInfo>, versionCode: Int): Boolean
{
if(checkVersion(versionCode,baseApkFiles))
{ {
logDebug("check version")
checkVersion(versionCode,baseApkFiles)
logDebug("Version Check Done, next getting apk path")
var path = getVPath()
logDebug("Path: $path")
apkFile.file?.let {
var apath = it.absolutePath
logDebug("Moving $apath to: $path")
moveAPK(apath, path)
logDebug("Move done setting chConv $path")
chConV(path)
logDebug("Done with chConv $path")
}
}
private fun checkVersion(versionCode: Int, baseApkFiles: ArrayList<FileInfo>) {
val path = getVPath() val path = getVPath()
logDebug("checking if path is in /data/app") apkFile.file?.let {
val apath = it.absolutePath
if(path?.let { it1 -> moveAPK(apath, it1) }!!)
{
return chConV(path)
}
}
}
return false
}
private fun checkVersion(versionCode: Int, baseApkFiles: ArrayList<FileInfo>): Boolean {
val path = getVPath()
if (path != null) {
if(path.contains("/data/app/")) if(path.contains("/data/app/"))
{ {
logDebug("Path is in /data/app: $path" ) when(getPkgVerCode(yPkg)?.let { compareVersion(it,versionCode) })
when(compareVersion(getPkgVerCode(yPkg),versionCode))
{ {
1 -> {fixHigherVer(baseApkFiles);logDebug("higher version uninstalling then installing base + patched");} 1 -> {return fixHigherVer(baseApkFiles) }
-1 -> {fixLowerVer(baseApkFiles);logDebug("Lower Version installing base + patched");} -1 -> {return fixLowerVer(baseApkFiles) }
} }
return true
} }
else else
{ {
logDebug("No install in /data/app/ now installing") return fixNoInstall(baseApkFiles)
fixNoInstall(baseApkFiles)
} }
} }
return fixNoInstall(baseApkFiles)
}
private fun getPkgVerCode(pkg: String): Int { private fun getPkgVerCode(pkg: String): Int? {
val pm = packageManager val pm = packageManager
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)
pm.getPackageInfo(pkg, 0).longVersionCode.and(0xFFFFFFFF).toInt() pm.getPackageInfo(pkg, 0)?.longVersionCode?.and(0xFFFFFFFF)?.toInt()
else else
pm.getPackageInfo(pkg, 0).versionCode pm.getPackageInfo(pkg, 0)?.versionCode
} }
private fun getPkgInfo(pkg: String): PackageInfo private fun getPkgInfo(pkg: String): PackageInfo?
{ {
return try {
val m = packageManager val m = packageManager
val p: PackageInfo = m.getPackageInfo(pkg, 0) val info = m.getPackageInfo(pkg, 0)
return p info
} catch (e:Exception) {
null
}
} }
private fun compareVersion(pkgVerCode: Int, versionCode: Int): Int private fun compareVersion(pkgVerCode: Int, versionCode: Int): Int
@ -242,33 +258,88 @@ class RootSplitInstallerService: Service() {
0 0
} }
private fun fixHigherVer(apkFiles: ArrayList<FileInfo>) { private fun fixHigherVer(apkFiles: ArrayList<FileInfo>) : Boolean {
PackageHelper.uninstallApk(yPkg, applicationContext) if(PackageHelper.uninstallApk(yPkg, applicationContext))
installSplitApkFiles(apkFiles) {
return installSplitApkFiles(apkFiles)
}
with(localBroadcastManager) {sendFailure(listOf("Failed Uninstall Of Installed Version, Try Manually").toMutableList(), applicationContext)}
return false
} }
private fun fixLowerVer(apkFiles: ArrayList<FileInfo>) { private fun fixLowerVer(apkFiles: ArrayList<FileInfo>): Boolean {
installSplitApkFiles(apkFiles) return installSplitApkFiles(apkFiles)
} }
private fun fixNoInstall(baseApkFiles: ArrayList<FileInfo>) { private fun fixNoInstall(baseApkFiles: ArrayList<FileInfo>): Boolean {
installSplitApkFiles(baseApkFiles) return installSplitApkFiles(baseApkFiles)
} }
private fun chConV(path: String) { private fun chConV(path: String): Boolean {
Shell.su("chcon -R u:object_r:system_file:s0 $path").exec() val response = Shell.su("chcon -R u:object_r:system_file:s0 $path").exec()
return if(response.isSuccess) {
true
} else {
sendFailure(response.out, applicationContext)
false
}
} }
private fun moveAPK(apkFile: String, path: String) { private fun moveAPK(apkFile: String, path: String) : Boolean {
Shell.su("cp $apkFile $path").exec()
Shell.su("chmod 644 $path").exec() val apkinF = SuFile.open(apkFile)
val apkoutF = SuFile.open(path)
if(apkinF.exists())
{
try {
copy(apkinF,apkoutF)
}
catch (e: IOException)
{
sendFailure(listOf("${e.message}").toMutableList(), applicationContext)
}
}
else {
sendFailure(listOf("Input File Missing").toMutableList(), applicationContext)
return false
}
val resultmv = Shell.su("mv $apkFile $path").exec().isSuccess
return if(resultmv) {
Shell.su("chmod 644 $path").exec().isSuccess
} else {
sendFailure(listOf("Failed To Apply Mod").toMutableList(), applicationContext)
false
}
} }
private fun getVPath(): String { @Throws(IOException::class)
fun copy(src: File?, dst: File?) {
val finputStrem: InputStream = SuFileInputStream(src)
finputStrem.use { finputStrem ->
val out: OutputStream = SuFileOutputStream(dst)
out.use { out ->
// Transfer bytes from in to out
val buf = ByteArray(1024)
var len: Int
while (finputStrem.read(buf).also { len = it } > 0) {
out.write(buf, 0, len)
}
}
}
}
private fun getVPath(): String? {
return try {
val p = getPkgInfo(yPkg) val p = getPkgInfo(yPkg)
return p.applicationInfo.sourceDir p?.applicationInfo?.sourceDir
} catch (e: Exception) {
null
}
} }
} }

View File

@ -6,6 +6,7 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
import com.vanced.manager.core.installer.AppUninstallerService import com.vanced.manager.core.installer.AppUninstallerService
import java.lang.Exception
object PackageHelper { object PackageHelper {
@ -32,10 +33,18 @@ object PackageHelper {
activity.packageManager.packageInstaller.uninstall(pkg, pendingIntent.intentSender) activity.packageManager.packageInstaller.uninstall(pkg, pendingIntent.intentSender)
} }
fun uninstallApk(pkg: String, applicationContext: Context) { fun uninstallApk(pkg: String, applicationContext: Context): Boolean {
val callbackIntent = Intent(applicationContext, AppUninstallerService::class.java) val callbackIntent = Intent(applicationContext, AppUninstallerService::class.java)
callbackIntent.putExtra("pkg", pkg) callbackIntent.putExtra("pkg", pkg)
val pendingIntent = PendingIntent.getService(applicationContext, 0, callbackIntent, 0) val pendingIntent = PendingIntent.getService(applicationContext, 0, callbackIntent, 0)
try {
applicationContext.packageManager.packageInstaller.uninstall(pkg, pendingIntent.intentSender) applicationContext.packageManager.packageInstaller.uninstall(pkg, pendingIntent.intentSender)
return true
}
catch (e: Exception)
{
e.printStackTrace()
return false;
}
} }
} }