mirror of
https://github.com/YTVanced/VancedManager
synced 2024-11-23 03:35:11 +00:00
added log fragment
This commit is contained in:
parent
d58a2c3f71
commit
9c2b530d4d
20 changed files with 208 additions and 63 deletions
|
@ -6,6 +6,7 @@ plugins {
|
|||
id("com.google.firebase.crashlytics")
|
||||
id("com.google.firebase.firebase-perf")
|
||||
id("androidx.navigation.safeargs.kotlin")
|
||||
id("kotlin-android")
|
||||
}
|
||||
|
||||
android {
|
||||
|
|
|
@ -2,13 +2,13 @@ package com.vanced.manager.core
|
|||
|
||||
import android.app.Application
|
||||
import android.content.res.Configuration
|
||||
import android.util.Log
|
||||
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
|
||||
import com.crowdin.platform.Crowdin
|
||||
import com.crowdin.platform.CrowdinConfig
|
||||
import com.crowdin.platform.data.model.AuthConfig
|
||||
import com.crowdin.platform.data.remote.NetworkType
|
||||
import com.vanced.manager.BuildConfig.*
|
||||
import com.vanced.manager.utils.AppUtils.log
|
||||
import com.vanced.manager.utils.loadJson
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
@ -35,7 +35,7 @@ open class App: Application() {
|
|||
withSourceLanguage("en")
|
||||
withAuthConfig(AuthConfig(CROWDIN_CLIENT_ID, CROWDIN_CLIENT_SECRET, null))
|
||||
withScreenshotEnabled()
|
||||
Log.d("test", "crowdin credentials")
|
||||
log("test", "crowdin credentials")
|
||||
}
|
||||
}.build()
|
||||
)
|
||||
|
|
|
@ -2,11 +2,11 @@ package com.vanced.manager.core.downloader
|
|||
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import android.util.Log
|
||||
import com.google.firebase.analytics.FirebaseAnalytics
|
||||
import com.google.firebase.analytics.ktx.logEvent
|
||||
import com.vanced.manager.R
|
||||
import com.vanced.manager.utils.*
|
||||
import com.vanced.manager.utils.AppUtils.log
|
||||
import com.vanced.manager.utils.AppUtils.validateTheme
|
||||
import com.vanced.manager.utils.AppUtils.vancedRootPkg
|
||||
import com.vanced.manager.utils.DownloadHelper.download
|
||||
|
@ -58,7 +58,7 @@ object VancedDownloader {
|
|||
try {
|
||||
downloadSplits(context)
|
||||
} catch (e: Exception) {
|
||||
Log.d("VMDownloader", e.stackTraceToString())
|
||||
log("VMDownloader", e.stackTraceToString())
|
||||
downloadProgress.value?.downloadingFile?.postValue(context.getString(R.string.error_downloading, "Vanced"))
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
package com.vanced.manager.core.firebase
|
||||
|
||||
import android.util.Log
|
||||
import com.google.firebase.messaging.FirebaseMessagingService
|
||||
import com.vanced.manager.utils.AppUtils.log
|
||||
|
||||
class CloudMessaging : FirebaseMessagingService() {
|
||||
|
||||
override fun onNewToken(p0: String) {
|
||||
super.onNewToken(p0)
|
||||
Log.d("VMC", "Generated new token: $p0")
|
||||
log("VMC", "Generated new token: $p0")
|
||||
}
|
||||
|
||||
}
|
|
@ -4,7 +4,7 @@ import android.app.Service
|
|||
import android.content.Intent
|
||||
import android.content.pm.PackageInstaller
|
||||
import android.os.IBinder
|
||||
import android.util.Log
|
||||
import com.vanced.manager.utils.AppUtils.log
|
||||
import com.vanced.manager.utils.AppUtils.sendCloseDialog
|
||||
import com.vanced.manager.utils.AppUtils.sendFailure
|
||||
import com.vanced.manager.utils.AppUtils.sendRefresh
|
||||
|
@ -14,17 +14,17 @@ class AppInstallerService: Service() {
|
|||
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
|
||||
when (intent.getIntExtra(PackageInstaller.EXTRA_STATUS, -999)) {
|
||||
PackageInstaller.STATUS_PENDING_USER_ACTION -> {
|
||||
Log.d(TAG, "Requesting user confirmation for installation")
|
||||
log(TAG, "Requesting user confirmation for installation")
|
||||
val confirmationIntent = intent.getParcelableExtra<Intent>(Intent.EXTRA_INTENT)
|
||||
confirmationIntent?.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
try {
|
||||
startActivity(confirmationIntent)
|
||||
} catch (e: Exception) {
|
||||
Log.d("VMInstall", "Unable to start installation")
|
||||
log("VMInstall", "Unable to start installation")
|
||||
}
|
||||
}
|
||||
PackageInstaller.STATUS_SUCCESS -> {
|
||||
Log.d(TAG, "Installation succeed")
|
||||
log(TAG, "Installation succeed")
|
||||
sendCloseDialog(this)
|
||||
sendRefresh(this)
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import android.app.Service
|
|||
import android.content.Intent
|
||||
import android.content.pm.PackageInstaller
|
||||
import android.os.IBinder
|
||||
import android.util.Log
|
||||
import com.vanced.manager.utils.AppUtils.log
|
||||
import com.vanced.manager.utils.AppUtils.sendRefresh
|
||||
|
||||
class AppUninstallerService: Service() {
|
||||
|
@ -13,7 +13,7 @@ class AppUninstallerService: Service() {
|
|||
val pkgName = intent?.getStringExtra("pkg")
|
||||
when (intent?.getIntExtra(PackageInstaller.EXTRA_STATUS, -999)) {
|
||||
PackageInstaller.STATUS_PENDING_USER_ACTION -> {
|
||||
Log.d(AppInstallerService.TAG, "Requesting user confirmation for uninstallation")
|
||||
log(AppInstallerService.TAG, "Requesting user confirmation for uninstallation")
|
||||
val confirmationIntent = intent.getParcelableExtra<Intent>(Intent.EXTRA_INTENT)
|
||||
confirmationIntent?.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
try {
|
||||
|
@ -24,11 +24,11 @@ class AppUninstallerService: Service() {
|
|||
//Delay broadcast until activity (and fragment) show up on the screen
|
||||
PackageInstaller.STATUS_SUCCESS -> {
|
||||
sendRefresh(this)
|
||||
Log.d("VMpm", "Successfully uninstalled $pkgName")
|
||||
log("VMpm", "Successfully uninstalled $pkgName")
|
||||
}
|
||||
PackageInstaller.STATUS_FAILURE -> {
|
||||
sendRefresh(this)
|
||||
Log.d("VMpm", "Failed to uninstall $pkgName")
|
||||
log("VMpm", "Failed to uninstall $pkgName")
|
||||
}
|
||||
}
|
||||
stopSelf()
|
||||
|
|
|
@ -4,7 +4,6 @@ import android.content.Context
|
|||
import android.content.Intent
|
||||
import android.content.res.Configuration
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.MenuItem
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
|
@ -26,6 +25,7 @@ import com.vanced.manager.ui.dialogs.URLChangeDialog
|
|||
import com.vanced.manager.ui.fragments.HomeFragmentDirections
|
||||
import com.vanced.manager.ui.fragments.SettingsFragmentDirections
|
||||
import com.vanced.manager.utils.*
|
||||
import com.vanced.manager.utils.AppUtils.log
|
||||
|
||||
|
||||
class MainActivity : AppCompatActivity() {
|
||||
|
@ -36,11 +36,11 @@ class MainActivity : AppCompatActivity() {
|
|||
private val loadingObserver = object : LoadingStateListener {
|
||||
val tag = "VMLocalisation"
|
||||
override fun onDataChanged() {
|
||||
Log.d(tag, "Loaded data")
|
||||
log(tag, "Loaded data")
|
||||
}
|
||||
|
||||
override fun onFailure(throwable: Throwable) {
|
||||
Log.d(tag, "Failed to load data: $throwable")
|
||||
log(tag, "Failed to load data: $throwable")
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -94,21 +94,26 @@ class MainActivity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
when (item.itemId) {
|
||||
return when (item.itemId) {
|
||||
android.R.id.home -> {
|
||||
onBackPressedDispatcher.onBackPressed()
|
||||
return true
|
||||
true
|
||||
}
|
||||
R.id.toolbar_about -> {
|
||||
navHost.navigate(HomeFragmentDirections.toAboutFragment())
|
||||
return true
|
||||
true
|
||||
}
|
||||
R.id.toolbar_settings -> {
|
||||
navHost.navigate(HomeFragmentDirections.toSettingsFragment())
|
||||
return true
|
||||
true
|
||||
}
|
||||
R.id.toolbar_log -> {
|
||||
navHost.navigate(HomeFragmentDirections.toLogFragment())
|
||||
true
|
||||
}
|
||||
R.id.toolbar_update_manager -> {
|
||||
ManagerUpdateDialog.newInstance(false).show(supportFragmentManager, "manager_update")
|
||||
true
|
||||
}
|
||||
R.id.dev_settings -> {
|
||||
navHost.navigate(SettingsFragmentDirections.toDevSettingsFragment())
|
||||
|
@ -116,8 +121,6 @@ class MainActivity : AppCompatActivity() {
|
|||
}
|
||||
else -> super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
override fun attachBaseContext(newBase: Context) {
|
||||
|
|
|
@ -5,7 +5,6 @@ import android.graphics.Color
|
|||
import android.os.Bundle
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
|
@ -16,6 +15,7 @@ import com.vanced.manager.R
|
|||
import com.vanced.manager.core.ui.base.BindingDialogFragment
|
||||
import com.vanced.manager.databinding.DialogManagerAccentColorBinding
|
||||
import com.vanced.manager.utils.*
|
||||
import com.vanced.manager.utils.AppUtils.log
|
||||
|
||||
class ManagerAccentColorDialog : BindingDialogFragment<DialogManagerAccentColorBinding>() {
|
||||
|
||||
|
@ -93,7 +93,7 @@ class ManagerAccentColorDialog : BindingDialogFragment<DialogManagerAccentColorB
|
|||
mutableAccentColor.value = colorFromEditText
|
||||
prefs.managerAccent = colorFromEditText
|
||||
} catch (e: IllegalArgumentException) {
|
||||
Log.d("VMTheme", getString(R.string.failed_accent))
|
||||
log("VMTheme", getString(R.string.failed_accent))
|
||||
Toast.makeText(requireActivity(), getString(R.string.failed_accent), Toast.LENGTH_SHORT).show()
|
||||
return@setOnClickListener
|
||||
}
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
package com.vanced.manager.ui.fragments
|
||||
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import com.vanced.manager.R
|
||||
import com.vanced.manager.core.ui.base.BindingFragment
|
||||
import com.vanced.manager.databinding.FragmentLogBinding
|
||||
import com.vanced.manager.utils.AppUtils.logs
|
||||
import java.io.File
|
||||
import java.io.FileWriter
|
||||
import java.io.IOException
|
||||
import java.util.*
|
||||
|
||||
class LogFragment : BindingFragment<FragmentLogBinding>() {
|
||||
|
||||
override fun binding(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
) = FragmentLogBinding.inflate(inflater, container, false)
|
||||
|
||||
override fun otherSetups() {
|
||||
binding.bindData()
|
||||
}
|
||||
|
||||
private fun FragmentLogBinding.bindData() {
|
||||
val logs = TextUtils.concat(*logs.toTypedArray())
|
||||
logText.text = logs
|
||||
logSave.setOnClickListener {
|
||||
try {
|
||||
val calendar = Calendar.getInstance()
|
||||
val year = calendar.get(Calendar.YEAR)
|
||||
val month = calendar.get(Calendar.MONTH)
|
||||
val day = calendar.get(Calendar.DAY_OF_MONTH)
|
||||
val hour = calendar.get(Calendar.HOUR_OF_DAY)
|
||||
val minute = calendar.get(Calendar.MINUTE)
|
||||
val second = calendar.get(Calendar.SECOND)
|
||||
val log = File(requireActivity().getExternalFilesDir("logs")?.path + "/$year$month${day}_$hour$minute$second.log")
|
||||
FileWriter(log).apply {
|
||||
append(logs)
|
||||
flush()
|
||||
close()
|
||||
}
|
||||
Toast.makeText(requireActivity(), R.string.logs_saved, Toast.LENGTH_SHORT).show()
|
||||
} catch (e: IOException) {
|
||||
Toast.makeText(requireActivity(), R.string.logs_not_saved, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -3,7 +3,6 @@ package com.vanced.manager.ui.viewmodels
|
|||
import android.content.ActivityNotFoundException
|
||||
import android.content.ComponentName
|
||||
import android.content.Intent
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.content.res.AppCompatResources
|
||||
|
@ -27,6 +26,7 @@ import com.vanced.manager.ui.dialogs.InstallationFilesDetectedDialog
|
|||
import com.vanced.manager.ui.dialogs.MusicPreferencesDialog
|
||||
import com.vanced.manager.ui.dialogs.VancedPreferencesDialog
|
||||
import com.vanced.manager.utils.*
|
||||
import com.vanced.manager.utils.AppUtils.log
|
||||
import com.vanced.manager.utils.AppUtils.managerPkg
|
||||
import com.vanced.manager.utils.AppUtils.microgPkg
|
||||
import com.vanced.manager.utils.AppUtils.musicPkg
|
||||
|
@ -85,7 +85,7 @@ open class HomeViewModel(private val activity: FragmentActivity): ViewModel() {
|
|||
try {
|
||||
activity.startActivity(Intent().setComponent(componentName))
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
Log.d("VMHMV", e.toString())
|
||||
log("VMHMV", e.toString())
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,6 +3,11 @@ package com.vanced.manager.utils
|
|||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageInstaller
|
||||
import android.graphics.Color
|
||||
import android.text.Spannable
|
||||
import android.text.SpannableString
|
||||
import android.text.style.ForegroundColorSpan
|
||||
import android.util.Log
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
||||
import com.vanced.manager.BuildConfig.APPLICATION_ID
|
||||
import com.vanced.manager.R
|
||||
|
@ -24,6 +29,18 @@ object AppUtils: CoroutineScope by CoroutineScope(Dispatchers.IO) {
|
|||
const val managerPkg = APPLICATION_ID
|
||||
const val playStorePkg = "com.android.vending"
|
||||
|
||||
val logs = mutableListOf<Spannable>()
|
||||
|
||||
fun log(tag: String, message: String) {
|
||||
logs.add(
|
||||
SpannableString("$tag: $message\n").apply {
|
||||
setSpan(ForegroundColorSpan(Color.CYAN), 0, tag.length + 1, 0)
|
||||
setSpan(ForegroundColorSpan(Color.GREEN), tag.length + 2, tag.length + message.length + 2, 0)
|
||||
}
|
||||
)
|
||||
Log.d(tag, message)
|
||||
}
|
||||
|
||||
fun sendRefresh(context: Context): Job {
|
||||
return launch {
|
||||
delay(700)
|
||||
|
|
|
@ -4,12 +4,12 @@ import android.content.Context
|
|||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.util.Log
|
||||
import androidx.core.content.FileProvider
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import com.vanced.manager.R
|
||||
import com.vanced.manager.library.network.providers.createService
|
||||
import com.vanced.manager.model.ProgressModel
|
||||
import com.vanced.manager.utils.AppUtils.log
|
||||
import com.vanced.manager.utils.AppUtils.sendCloseDialog
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
@ -55,24 +55,24 @@ object DownloadHelper : CoroutineScope by CoroutineScope(Dispatchers.IO) {
|
|||
} else {
|
||||
onError("Could not save file")
|
||||
downloadProgress.value?.downloadProgress?.postValue(0)
|
||||
Log.d("VMDownloader", "Failed to save file: $url")
|
||||
log("VMDownloader", "Failed to save file: $url")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
onError(response.errorBody().toString())
|
||||
downloadProgress.value?.downloadProgress?.postValue(0)
|
||||
Log.d("VMDownloader", "Failed to download file: $url")
|
||||
log("VMDownloader", "Failed to download file: $url")
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
|
||||
if (call.isCanceled) {
|
||||
Log.d("VMDownloader", "Download canceled")
|
||||
log("VMDownloader", "Download canceled")
|
||||
downloadProgress.value?.downloadProgress?.postValue(0)
|
||||
} else {
|
||||
onError(t.stackTraceToString())
|
||||
downloadProgress.value?.downloadProgress?.postValue(0)
|
||||
Log.d("VMDownloader", "Failed to download file: $url")
|
||||
log("VMDownloader", "Failed to download file: $url")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@ package com.vanced.manager.utils
|
|||
import android.content.Context
|
||||
import android.content.ContextWrapper
|
||||
import android.content.DialogInterface
|
||||
import android.util.Log
|
||||
import android.widget.RadioGroup
|
||||
import androidx.core.graphics.ColorUtils
|
||||
import androidx.fragment.app.DialogFragment
|
||||
|
@ -15,6 +14,7 @@ import com.google.android.material.radiobutton.MaterialRadioButton
|
|||
import com.topjohnwu.superuser.io.SuFile
|
||||
import com.topjohnwu.superuser.io.SuFileOutputStream
|
||||
import com.vanced.manager.R
|
||||
import com.vanced.manager.utils.AppUtils.log
|
||||
import java.util.*
|
||||
|
||||
fun RadioGroup.getCheckedButtonTag(): String? {
|
||||
|
@ -25,7 +25,7 @@ fun DialogFragment.show(activity: FragmentActivity) {
|
|||
try {
|
||||
show(activity.supportFragmentManager, "")
|
||||
} catch (e: Exception) {
|
||||
Log.d("VMUI", e.stackTraceToString())
|
||||
log("VMUI", e.stackTraceToString())
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import com.beust.klaxon.JsonArray
|
|||
import com.beust.klaxon.JsonObject
|
||||
import com.vanced.manager.R
|
||||
import com.vanced.manager.utils.AppUtils.generateChecksum
|
||||
import com.vanced.manager.utils.AppUtils.log
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.File
|
||||
|
@ -78,17 +79,17 @@ suspend fun loadJson(context: Context) = withContext(Dispatchers.IO) {
|
|||
connect()
|
||||
}
|
||||
if (connection.responseCode != 200) {
|
||||
Log.d(TAG, latestbaseUrl + ": " + connection.responseCode.toString())
|
||||
log(TAG, latestbaseUrl + ": " + connection.responseCode.toString())
|
||||
baseInstallUrl = "https://mirror.codebucket.de/vanced/api/v1"
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
baseInstallUrl = "https://mirror.codebucket.de/vanced/api/v1"
|
||||
} catch (e: SocketTimeoutException) {
|
||||
Log.d(TAG, "connection timed out")
|
||||
log(TAG, "connection timed out")
|
||||
baseInstallUrl = "https://mirror.codebucket.de/vanced/api/v1"
|
||||
}
|
||||
|
||||
Log.d(TAG, "Fetching using URL: $baseInstallUrl")
|
||||
log(TAG, "Fetching using URL: $baseInstallUrl")
|
||||
|
||||
val calendar = Calendar.getInstance()
|
||||
val hour = calendar.get(Calendar.HOUR_OF_DAY)
|
||||
|
|
|
@ -13,6 +13,7 @@ import com.topjohnwu.superuser.io.SuFile
|
|||
import com.vanced.manager.BuildConfig
|
||||
import com.vanced.manager.core.installer.AppInstallerService
|
||||
import com.vanced.manager.core.installer.AppUninstallerService
|
||||
import com.vanced.manager.utils.AppUtils.log
|
||||
import com.vanced.manager.utils.AppUtils.musicRootPkg
|
||||
import com.vanced.manager.utils.AppUtils.playStorePkg
|
||||
import com.vanced.manager.utils.AppUtils.sendCloseDialog
|
||||
|
@ -181,7 +182,7 @@ object PackageHelper {
|
|||
outputStream.close()
|
||||
session.commit(pendingIntent.intentSender)
|
||||
} catch (e: IOException) {
|
||||
Log.d(INSTALLER_TAG, e.stackTraceToString())
|
||||
log(INSTALLER_TAG, e.stackTraceToString())
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -216,7 +217,7 @@ object PackageHelper {
|
|||
if (modApk != null) {
|
||||
if (overwriteBase(modApk, fileInfoList, appVerCode, pkg, app, context)) {
|
||||
setInstallerPackage(context, pkg, playStorePkg)
|
||||
Log.d(INSTALLER_TAG, "Finished installation")
|
||||
log(INSTALLER_TAG, "Finished installation")
|
||||
sendRefresh(context)
|
||||
sendCloseDialog(context)
|
||||
}
|
||||
|
@ -265,7 +266,7 @@ object PackageHelper {
|
|||
try {
|
||||
for (listOfFile in listOfFiles!!) {
|
||||
if (listOfFile.isFile) {
|
||||
Log.d(INSTALLER_TAG, "installApk: " + listOfFile.name)
|
||||
log(INSTALLER_TAG, "installApk: " + listOfFile.name)
|
||||
nameSizeMap[listOfFile.name] = listOfFile.length()
|
||||
totalSize += listOfFile.length()
|
||||
}
|
||||
|
@ -278,12 +279,12 @@ object PackageHelper {
|
|||
installParams.setSize(totalSize)
|
||||
try {
|
||||
sessionId = context.packageManager.packageInstaller.createSession(installParams)
|
||||
Log.d(INSTALLER_TAG,"Success: created install session [$sessionId]")
|
||||
log(INSTALLER_TAG,"Success: created install session [$sessionId]")
|
||||
for ((key, value) in nameSizeMap) {
|
||||
doWriteSession(sessionId, apkFolderPath + key, value, key, context)
|
||||
}
|
||||
doCommitSession(sessionId, context)
|
||||
Log.d(INSTALLER_TAG,"Success")
|
||||
log(INSTALLER_TAG,"Success")
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
@ -320,7 +321,7 @@ object PackageHelper {
|
|||
out.write(buffer, 0, c)
|
||||
}
|
||||
session.fsync(out)
|
||||
Log.d(INSTALLER_TAG, "Success: streamed $total bytes")
|
||||
log(INSTALLER_TAG, "Success: streamed $total bytes")
|
||||
return PackageInstaller.STATUS_SUCCESS
|
||||
} catch (e: IOException) {
|
||||
Log.e(INSTALLER_TAG, "Error: failed to write; " + e.message)
|
||||
|
@ -344,9 +345,9 @@ object PackageHelper {
|
|||
val pendingIntent = PendingIntent.getService(context, 0, callbackIntent, 0)
|
||||
session.commit(pendingIntent.intentSender)
|
||||
session.close()
|
||||
Log.d(INSTALLER_TAG, "install request sent")
|
||||
Log.d(INSTALLER_TAG, "doCommitSession: " + context.packageManager.packageInstaller.mySessions)
|
||||
Log.d(INSTALLER_TAG, "doCommitSession: after session commit ")
|
||||
log(INSTALLER_TAG, "install request sent")
|
||||
log(INSTALLER_TAG, "doCommitSession: " + context.packageManager.packageInstaller.mySessions)
|
||||
log(INSTALLER_TAG, "doCommitSession: after session commit ")
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
} finally {
|
||||
|
@ -357,7 +358,7 @@ object PackageHelper {
|
|||
private fun installSplitApkFiles(apkFiles: ArrayList<FileInfo>, context: Context) : Boolean {
|
||||
var sessionId: Int?
|
||||
val filenames = arrayOf("black.apk", "dark.apk", "blue.apk", "pink.apk", "hash.json")
|
||||
Log.d(INSTALLER_TAG, "installing split apk files: $apkFiles")
|
||||
log(INSTALLER_TAG, "installing split apk files: $apkFiles")
|
||||
run {
|
||||
val sessionIdResult = Shell.su("pm install-create -r -t").exec().out
|
||||
val sessionIdPattern = Pattern.compile("(\\d+)")
|
||||
|
@ -367,7 +368,7 @@ object PackageHelper {
|
|||
}
|
||||
apkFiles.forEach { apkFile ->
|
||||
if (!filenames.any { apkFile.name == it }) {
|
||||
Log.d(INSTALLER_TAG, "installing APK: ${apkFile.name} ${apkFile.fileSize}")
|
||||
log(INSTALLER_TAG, "installing APK: ${apkFile.name} ${apkFile.fileSize}")
|
||||
val command = arrayOf("su", "-c", "pm", "install-write", "-S", "${apkFile.fileSize}", "$sessionId", apkFile.name)
|
||||
val process: Process = Runtime.getRuntime().exec(command)
|
||||
val inputPipe = apkFile.getInputStream()
|
||||
|
@ -385,7 +386,7 @@ object PackageHelper {
|
|||
process.waitFor()
|
||||
}
|
||||
}
|
||||
Log.d(INSTALLER_TAG, "committing...")
|
||||
log(INSTALLER_TAG, "committing...")
|
||||
val installResult = Shell.su("pm install-commit $sessionId").exec()
|
||||
if (installResult.isSuccess) {
|
||||
return true
|
||||
|
@ -473,7 +474,7 @@ object PackageHelper {
|
|||
private fun setupScript(apkFPath: String, path: String, app: String, pkg: String, context: Context): Boolean
|
||||
{
|
||||
try {
|
||||
Log.d(INSTALLER_TAG, "Setting up script")
|
||||
log(INSTALLER_TAG, "Setting up script")
|
||||
context.writeServiceDScript(apkFPath, path, app)
|
||||
Shell.su("""echo "#!/system/bin/sh\nwhile read line; do echo \${"$"}{line} | grep $pkg | awk '{print \${'$'}2}' | xargs umount -l; done< /proc/mounts" > /data/adb/post-fs-data.d/$app.sh""").exec()
|
||||
return Shell.su("chmod 744 /data/adb/service.d/$app.sh").exec().isSuccess
|
||||
|
@ -484,7 +485,7 @@ object PackageHelper {
|
|||
}
|
||||
|
||||
private fun linkApp(apkFPath: String, pkg: String, path: String): Boolean {
|
||||
Log.d(INSTALLER_TAG, "Linking app")
|
||||
log(INSTALLER_TAG, "Linking app")
|
||||
Shell.su("am force-stop $pkg").exec()
|
||||
Shell.su("""for i in ${'$'}(ls /data/app/ | grep $pkg | tr " "); do umount -l "/data/app/${"$"}i/base.apk"; done """).exec()
|
||||
val response = Shell.su("""su -mm -c "mount -o bind $apkFPath $path"""").exec()
|
||||
|
@ -499,7 +500,7 @@ object PackageHelper {
|
|||
|
||||
//check version and perform action based on result
|
||||
private fun checkVersion(versionCode: Int, baseApkFiles: ArrayList<FileInfo>, pkg: String, context: Context): Boolean {
|
||||
Log.d(INSTALLER_TAG, "Checking stock version")
|
||||
log(INSTALLER_TAG, "Checking stock version")
|
||||
val path = getPackageDir(context, pkg)
|
||||
if (path != null) {
|
||||
if (path.contains("/data/app/")) {
|
||||
|
@ -518,7 +519,7 @@ object PackageHelper {
|
|||
return try {
|
||||
context.packageManager.getPackageInfo(pkg, 0)
|
||||
} catch (e:Exception) {
|
||||
Log.d(INSTALLER_TAG, "Unable to get package info")
|
||||
log(INSTALLER_TAG, "Unable to get package info")
|
||||
null
|
||||
}
|
||||
}
|
||||
|
@ -533,7 +534,7 @@ object PackageHelper {
|
|||
|
||||
//uninstall current update and install base that works with patch
|
||||
private fun fixHigherVer(apkFiles: ArrayList<FileInfo>, pkg: String, context: Context) : Boolean {
|
||||
Log.d(INSTALLER_TAG, "Downgrading stock")
|
||||
log(INSTALLER_TAG, "Downgrading stock")
|
||||
if (uninstallRootApk(pkg)) {
|
||||
return if (pkg == vancedRootPkg) installSplitApkFiles(apkFiles, context) else installRootMusic(apkFiles, context)
|
||||
}
|
||||
|
@ -544,13 +545,13 @@ object PackageHelper {
|
|||
|
||||
//install stock youtube matching vanced version
|
||||
private fun installStock(baseApkFiles: ArrayList<FileInfo>, pkg: String, context: Context): Boolean {
|
||||
Log.d(INSTALLER_TAG, "Installing stock")
|
||||
log(INSTALLER_TAG, "Installing stock")
|
||||
return if (pkg == vancedRootPkg) installSplitApkFiles(baseApkFiles, context) else installRootMusic(baseApkFiles, context)
|
||||
}
|
||||
|
||||
//set chcon to apk_data_file
|
||||
private fun chConV(apkFPath: String, context: Context): Boolean {
|
||||
Log.d(INSTALLER_TAG, "Running chcon")
|
||||
log(INSTALLER_TAG, "Running chcon")
|
||||
val response = Shell.su("chcon u:object_r:apk_data_file:s0 $apkFPath").exec()
|
||||
//val response = Shell.su("chcon -R u:object_r:system_file:s0 $path").exec()
|
||||
return if (response.isSuccess) {
|
||||
|
@ -564,7 +565,7 @@ object PackageHelper {
|
|||
|
||||
//move patch to data/app
|
||||
private fun moveAPK(apkFile: String, path: String, pkg: String, context: Context) : Boolean {
|
||||
Log.d(INSTALLER_TAG, "Moving app")
|
||||
log(INSTALLER_TAG, "Moving app")
|
||||
val apkinF = SuFile.open(apkFile)
|
||||
val apkoutF = SuFile.open(path)
|
||||
|
||||
|
@ -601,7 +602,7 @@ object PackageHelper {
|
|||
@Throws(IOException::class)
|
||||
fun copy(src: File, dst: File) {
|
||||
val cmd = Shell.su("mv ${src.absolutePath} ${dst.absolutePath}").exec().isSuccess
|
||||
Log.d("ZLog", cmd.toString())
|
||||
log("ZLog", cmd.toString())
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
|
@ -655,16 +656,16 @@ object PackageHelper {
|
|||
private fun setInstallerPackage(context: Context, target: String, installer: String) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) return
|
||||
try {
|
||||
Log.d(INSTALLER_TAG, "Setting installer package to $installer for $target")
|
||||
log(INSTALLER_TAG, "Setting installer package to $installer for $target")
|
||||
val installerUid = context.packageManager.getPackageUid(installer, 0)
|
||||
val res = Shell.su("""su $installerUid -c 'pm set-installer $target $installer'""").exec()
|
||||
if (res.out.any { line -> line.contains("Success") }) {
|
||||
Log.d(INSTALLER_TAG, "Installer package successfully set")
|
||||
log(INSTALLER_TAG, "Installer package successfully set")
|
||||
return
|
||||
}
|
||||
Log.d(INSTALLER_TAG, "Failed setting installer package")
|
||||
log(INSTALLER_TAG, "Failed setting installer package")
|
||||
} catch (e: PackageManager.NameNotFoundException) {
|
||||
Log.d(INSTALLER_TAG, "Installer package $installer not found. Skipping setting installer")
|
||||
log(INSTALLER_TAG, "Installer package $installer not found. Skipping setting installer")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
5
app/src/main/res/drawable/ic_baseline_save_24.xml
Normal file
5
app/src/main/res/drawable/ic_baseline_save_24.xml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M17,3L5,3c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,7l-4,-4zM12,19c-1.66,0 -3,-1.34 -3,-3s1.34,-3 3,-3 3,1.34 3,3 -1.34,3 -3,3zM15,9L5,9L5,5h10v4z"/>
|
||||
</vector>
|
37
app/src/main/res/layout/fragment_log.xml
Normal file
37
app/src/main/res/layout/fragment_log.xml
Normal file
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/log_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="16dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/log_save"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:backgroundTint="?colorPrimary"
|
||||
android:src="@drawable/ic_baseline_save_24"
|
||||
android:layout_marginBottom="8dp"
|
||||
app:elevation="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:maxImageSize="32dp"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -19,4 +19,10 @@
|
|||
android:icon="@drawable/ic_info_black_24dp"
|
||||
app:showAsAction="withText" />
|
||||
|
||||
<item
|
||||
android:id="@+id/toolbar_log"
|
||||
android:title="@string/title_logs"
|
||||
android:icon="@drawable/ic_info_black_24dp"
|
||||
app:showAsAction="withText" />
|
||||
|
||||
</menu>
|
|
@ -28,6 +28,14 @@
|
|||
app:popEnterAnim="@animator/fragment_enter_pop"
|
||||
app:popExitAnim="@animator/fragment_exit_pop" />
|
||||
|
||||
<action
|
||||
android:id="@+id/toLogFragment"
|
||||
app:destination="@id/log_fragment"
|
||||
app:enterAnim="@animator/fragment_enter"
|
||||
app:exitAnim="@animator/fragment_exit"
|
||||
app:popEnterAnim="@animator/fragment_enter_pop"
|
||||
app:popExitAnim="@animator/fragment_exit_pop" />
|
||||
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
|
@ -57,6 +65,14 @@
|
|||
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
android:id="@+id/log_fragment"
|
||||
android:name="com.vanced.manager.ui.fragments.LogFragment"
|
||||
android:label="@string/title_logs"
|
||||
tools:layout="@layout/fragment_log">
|
||||
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
android:id="@+id/dev_settings_fragment"
|
||||
android:name="com.vanced.manager.ui.fragments.DevSettingsFragment"
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
<!-- Main Activity -->
|
||||
<string name="title_about">About</string>
|
||||
<string name="title_logs">Logs</string>
|
||||
<string name="title_home">Manager</string>
|
||||
<string name="title_settings">Settings</string>
|
||||
<string name="update_manager">Update Manager</string>
|
||||
|
@ -64,6 +65,10 @@
|
|||
<string name="update_not_found">No new updates</string>
|
||||
<string name="variant">Variant</string>
|
||||
|
||||
<!-- Logs -->
|
||||
<string name="logs_saved">Successfully saved logs</string>
|
||||
<string name="logs_not_saved">Could not save logs</string>
|
||||
|
||||
<!-- Dialogs -->
|
||||
<string name="advanced">Advanced</string>
|
||||
<string name="app_install_files_detected">%1$s installation files detected!</string>
|
||||
|
|
Loading…
Reference in a new issue