0
0
Fork 0
mirror of https://github.com/YTVanced/VancedManager synced 2024-11-26 05:05:15 +00:00

Small fixes coroutine

I could not fix everything, as there were very strange moments in the code ...

Also, not all fixes are as beautiful as we would like.
This commit is contained in:
HaliksaR 2020-11-15 07:26:07 +07:00
parent ff14e65d13
commit 32cd632506
13 changed files with 133 additions and 127 deletions

View file

@ -11,13 +11,15 @@ import com.crowdin.platform.data.remote.NetworkType
import com.downloader.PRDownloader
import com.vanced.manager.BuildConfig.*
import com.vanced.manager.utils.InternetTools.loadJson
import kotlinx.coroutines.*
open class App: Application() {
private val prefs by lazy { getDefaultSharedPreferences(this) }
private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
override fun onCreate() {
loadJson(this)
scope.launch { loadJson(this@App) }
super.onCreate()
PRDownloader.initialize(this)
@ -46,6 +48,4 @@ open class App: Application() {
super.onConfigurationChanged(newConfig)
Crowdin.onConfigurationChanged()
}
}

View file

@ -13,22 +13,21 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
object MicrogDownloader {
object MicrogDownloader : CoroutineScope by CoroutineScope(Dispatchers.IO) {
fun downloadMicrog(
context: Context,
) {
CoroutineScope(Dispatchers.IO).launch {
val url = microg.get()?.string("url")
) = launch {
val url = microg.get()?.string("url")
downloadProgress.get()?.currentDownload = PRDownloader.download(url, context.getExternalFilesDir("microg")?.path, "microg.apk")
.build()
.setOnStartOrResumeListener {
downloadProgress.get()?.downloadingFile?.set(context.getString(R.string.downloading_file, url?.let { getFileNameFromUrl(it) }))
}
.setOnProgressListener { progress ->
downloadProgress.get()?.downloadProgress?.set((progress.currentBytes * 100 / progress.totalBytes).toInt())
}
downloadProgress.get()?.currentDownload = PRDownloader.download(url, context.getExternalFilesDir("microg")?.path, "microg.apk")
.build()
.setOnStartOrResumeListener {
downloadProgress.get()?.downloadingFile?.set(context.getString(R.string.downloading_file, url?.let { getFileNameFromUrl(it) }))
}
.setOnProgressListener { progress ->
downloadProgress.get()?.downloadProgress?.set((progress.currentBytes * 100 / progress.totalBytes).toInt())
}
.start(object : OnDownloadListener {
override fun onDownloadComplete() {
startMicrogInstall(context)
@ -40,12 +39,10 @@ object MicrogDownloader {
})
}
}
fun startMicrogInstall(context: Context) {
downloadProgress.get()?.installing?.set(true)
downloadProgress.get()?.reset()
install("${context.getExternalFilesDir("microg")}/microg.apk", context)
}
}

View file

@ -1,7 +1,7 @@
package com.vanced.manager.core.downloader
import android.content.Context
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import androidx.preference.PreferenceManager.*
import com.downloader.Error
import com.downloader.OnDownloadListener
import com.downloader.PRDownloader
@ -22,8 +22,9 @@ import com.vanced.manager.utils.PackageHelper.installMusicRoot
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlin.coroutines.suspendCoroutine
object MusicDownloader {
object MusicDownloader: CoroutineScope by CoroutineScope(Dispatchers.IO) {
private var variant: String? = null
private var version: String? = null
@ -45,60 +46,56 @@ object MusicDownloader {
}
private fun downloadApk(context: Context, apk: String = "music") {
CoroutineScope(Dispatchers.IO).launch {
val url =
if (apk == "stock")
"$baseurl/stock/${getArch()}.apk"
else
"$baseurl/$variant.apk"
downloadProgress.get()?.currentDownload = PRDownloader.download(url, downloadPath, getFileNameFromUrl(url))
.build()
.setOnStartOrResumeListener {
downloadProgress.get()?.downloadingFile?.set(context.getString(R.string.downloading_file, getFileNameFromUrl(url)))
}
.setOnProgressListener { progress ->
downloadProgress.get()?.downloadProgress?.set((progress.currentBytes * 100 / progress.totalBytes).toInt())
}
.start(object : OnDownloadListener {
override fun onDownloadComplete() {
if (variant == "root" && apk != "stock") {
downloadApk(context, "stock")
return
}
when (apk) {
"music" -> {
if (variant == "root") {
if (validateTheme(downloadPath!!, "root", hashUrl!!, context)) {
if (downloadStockCheck(musicRootPkg, versionCode!!, context))
downloadApk(context, "stock")
else
startMusicInstall(context)
} else {
downloadApk(context, apk)
}
} else
startMusicInstall(context)
launch {
val url = if (apk == "stock") "$baseurl/stock/${getArch()}.apk" else "$baseurl/$variant.apk"
suspendCoroutine {
downloadProgress.get()?.currentDownload = PRDownloader.download(url, downloadPath, getFileNameFromUrl(url))
.build()
.setOnStartOrResumeListener {
downloadProgress.get()?.downloadingFile?.set(context.getString(R.string.downloading_file, getFileNameFromUrl(url)))
}
.setOnProgressListener { progress ->
downloadProgress.get()?.downloadProgress?.set((progress.currentBytes * 100 / progress.totalBytes).toInt())
}
.start(object : OnDownloadListener {
override fun onDownloadComplete() {
if (variant == "root" && apk != "stock") {
downloadApk(context, "stock") // recursive in coroutine its so bad...
return
}
when (apk) {
"music" -> {
if (variant == "root") {
if (validateTheme(downloadPath!!, "root", hashUrl!!, context)) {
if (downloadStockCheck(musicRootPkg, versionCode!!, context))
downloadApk(context, "stock")
else
startMusicInstall(context)
} else {
downloadApk(context, apk)
}
} else
startMusicInstall(context)
}
}
startMusicInstall(context)
}
startMusicInstall(context)
}
override fun onError(error: Error?) {
if (baseurl != backupUrl) {
baseurl = "$backupUrl/music/v$version"
downloadApk(context, apk)
return
}
override fun onError(error: Error?) {
if (baseurl != backupUrl) {
baseurl = "$backupUrl/music/v$version"
downloadApk(context, apk)
return
downloadProgress.get()?.downloadingFile?.set(context.getString(R.string.error_downloading, "Music"))
}
downloadProgress.get()?.downloadingFile?.set(context.getString(R.string.error_downloading, "Music"))
}
})
})
}
}
}
fun startMusicInstall(context: Context) {
@ -109,5 +106,4 @@ object MusicDownloader {
else
install("${context.getExternalFilesDir("music/nonroot")}/nonroot.apk", context)
}
}

View file

@ -28,7 +28,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.File
object VancedDownloader {
object VancedDownloader: CoroutineScope by CoroutineScope(Dispatchers.IO) {
private lateinit var prefs: SharedPreferences
private lateinit var defPrefs: SharedPreferences
@ -73,7 +73,7 @@ object VancedDownloader {
context: Context,
type: String = "theme"
) {
CoroutineScope(Dispatchers.IO).launch {
launch {
val url =
when (type) {
"theme" -> "$themePath/$theme.apk"
@ -160,8 +160,4 @@ object VancedDownloader {
else
installVanced(context)
}
}
}

View file

@ -5,6 +5,7 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.vanced.manager.R
@ -13,6 +14,7 @@ import com.vanced.manager.core.downloader.MusicDownloader.startMusicInstall
import com.vanced.manager.core.downloader.VancedDownloader.startVancedInstall
import com.vanced.manager.databinding.DialogInstallationFilesDetectedBinding
import com.vanced.manager.utils.Extensions.show
import kotlinx.coroutines.launch
class InstallationFilesDetectedDialog(private val app: String) : BottomSheetDialogFragment() {

View file

@ -12,6 +12,7 @@ import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.DialogFragment
import androidx.lifecycle.lifecycleScope
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import com.downloader.PRDownloader
import com.vanced.manager.R
@ -19,6 +20,7 @@ import com.vanced.manager.databinding.DialogManagerUpdateBinding
import com.vanced.manager.utils.DownloadHelper.downloadManager
import com.vanced.manager.utils.DownloadHelper.downloadProgress
import com.vanced.manager.utils.InternetTools.isUpdateAvailable
import kotlinx.coroutines.launch
class ManagerUpdateDialog(
private val forceUpdate: Boolean
@ -51,15 +53,18 @@ class ManagerUpdateDialog(
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
if (forceUpdate) {
binding.managerUpdatePatient.text = requireActivity().getString(R.string.please_be_patient)
downloadManager(requireActivity())
} else
checkUpdates()
lifecycleScope.launch {
if (forceUpdate) {
binding.managerUpdatePatient.text = requireActivity().getString(R.string.please_be_patient)
downloadManager(requireActivity())
} else {
checkUpdates()
}
binding.managerUpdateCancel.setOnClickListener {
PRDownloader.cancel(downloadProgress.get()!!.currentDownload)
dismiss()
binding.managerUpdateCancel.setOnClickListener {
PRDownloader.cancel(downloadProgress.get()!!.currentDownload)
dismiss()
}
}
}
@ -68,12 +73,13 @@ class ManagerUpdateDialog(
registerReceiver()
}
private fun checkUpdates() {
private suspend fun checkUpdates() {
if (isUpdateAvailable()) {
binding.managerUpdatePatient.text = requireActivity().getString(R.string.please_be_patient)
downloadManager(requireActivity())
} else
} else {
binding.managerUpdatePatient.text = requireActivity().getString(R.string.update_not_found)
}
}
private fun registerReceiver() {

View file

@ -10,11 +10,13 @@ import android.widget.EditText
import android.widget.TextView
import androidx.core.content.edit
import androidx.fragment.app.DialogFragment
import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import com.google.android.material.button.MaterialButton
import com.vanced.manager.R
import com.vanced.manager.utils.Extensions.fetchData
import com.vanced.manager.utils.InternetTools.baseUrl
import kotlinx.coroutines.launch
class URLChangeDialog : DialogFragment() {
@ -46,9 +48,10 @@ class URLChangeDialog : DialogFragment() {
}
private fun saveUrl(url: String) {
getDefaultSharedPreferences(requireActivity()).edit { putString("install_url", url) }
requireActivity().fetchData()
dismiss()
lifecycleScope.launch {
getDefaultSharedPreferences(requireActivity()).edit { putString("install_url", url) }
requireActivity().fetchData()
dismiss()
}
}
}

View file

@ -12,6 +12,8 @@ import android.widget.LinearLayout
import android.widget.Toast
import androidx.core.content.edit
import androidx.core.content.res.ResourcesCompat
import androidx.lifecycle.coroutineScope
import androidx.lifecycle.lifecycleScope
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.google.android.material.button.MaterialButton
import com.google.android.material.checkbox.MaterialCheckBox
@ -23,6 +25,7 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.util.*
import kotlin.coroutines.coroutineContext
class VancedLanguageSelectionDialog : BottomSheetDialogFragment() {
@ -36,7 +39,6 @@ class VancedLanguageSelectionDialog : BottomSheetDialogFragment() {
return inflater.inflate(R.layout.dialog_vanced_language_selection, container, false)
}
@ExperimentalStdlibApi
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
langs = vanced.get()?.array<String>("langs")?.value ?: mutableListOf("null")
@ -60,9 +62,8 @@ class VancedLanguageSelectionDialog : BottomSheetDialogFragment() {
}
}
@ExperimentalStdlibApi
private fun loadBoxes(ll: LinearLayout) {
CoroutineScope(Dispatchers.Main).launch {
lifecycleScope.launch { // default Main //// But why is it here?
val langPrefs = prefs.getString("lang", getDefaultVancedLanguages())
if (this@VancedLanguageSelectionDialog::langs.isInitialized) {
if (!langs.contains("null")) {
@ -78,8 +79,9 @@ class VancedLanguageSelectionDialog : BottomSheetDialogFragment() {
ll.addView(box, MATCH_PARENT, WRAP_CONTENT)
}
}
} else
} else {
loadBoxes(ll)
}
}
}

View file

@ -10,6 +10,7 @@ import androidx.core.content.ContextCompat.startActivity
import androidx.databinding.ObservableField
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import com.crowdin.platform.Crowdin
import com.google.android.material.button.MaterialButton
@ -35,6 +36,7 @@ import com.vanced.manager.utils.PackageHelper.musicApkExists
import com.vanced.manager.utils.PackageHelper.uninstallApk
import com.vanced.manager.utils.PackageHelper.uninstallRootApk
import com.vanced.manager.utils.PackageHelper.vancedInstallFilesExist
import kotlinx.coroutines.launch
open class HomeViewModel(private val activity: FragmentActivity): ViewModel() {
@ -48,10 +50,12 @@ open class HomeViewModel(private val activity: FragmentActivity): ViewModel() {
val manager = ObservableField<DataModel>()
fun fetchData() {
activity.setRefreshing(true)
loadJson(activity)
Crowdin.forceUpdate(activity)
activity.setRefreshing(false)
viewModelScope.launch {
activity.setRefreshing(true)
loadJson(activity)
Crowdin.forceUpdate(activity)
activity.setRefreshing(false)
}
}
private val microgToast = Toast.makeText(activity, R.string.no_microg, Toast.LENGTH_LONG)
@ -122,7 +126,13 @@ open class HomeViewModel(private val activity: FragmentActivity): ViewModel() {
}
fun uninstallPackage(pkg: String) = if (prefs.getString("vanced_variant", "nonroot") == "root" && uninstallRootApk(pkg)) activity.fetchData() else uninstallApk(pkg, activity)
fun uninstallPackage(pkg: String) {
if (prefs.getString("vanced_variant", "nonroot") == "root" && uninstallRootApk(pkg)) {
viewModelScope.launch { activity.fetchData() }
} else {
uninstallApk(pkg, activity)
}
}
init {
activity.setRefreshing(true)
@ -134,5 +144,4 @@ open class HomeViewModel(private val activity: FragmentActivity): ViewModel() {
manager.set(DataModel(InternetTools.manager, activity, managerPkg, activity.getString(R.string.app_name), ContextCompat.getDrawable(activity, R.mipmap.ic_launcher)))
activity.setRefreshing(false)
}
}

View file

@ -15,7 +15,7 @@ import java.io.File
import java.io.IOException
import java.security.MessageDigest
object AppUtils {
object AppUtils: CoroutineScope by CoroutineScope(Dispatchers.IO) {
const val vancedPkg = "com.vanced.android.youtube"
const val vancedRootPkg = "com.google.android.youtube"
@ -24,25 +24,25 @@ object AppUtils {
const val microgPkg = "com.mgoogle.android.gms"
const val managerPkg = APPLICATION_ID
fun sendRefresh(context: Context) {
CoroutineScope(Dispatchers.IO).launch {
fun sendRefresh(context: Context): Job {
return launch {
delay(700)
LocalBroadcastManager.getInstance(context).sendBroadcast(Intent(HomeFragment.REFRESH_HOME))
}
}
fun sendCloseDialog(context: Context) {
fun sendCloseDialog(context: Context): Job {
downloadProgress.get()?.installing?.set(false)
CoroutineScope(Dispatchers.IO).launch {
return launch {
delay(700)
LocalBroadcastManager.getInstance(context).sendBroadcast(Intent(AppDownloadDialog.CLOSE_DIALOG))
}
}
fun sendFailure(status: Int, context: Context) {
fun sendFailure(status: Int, context: Context): Job {
downloadProgress.get()?.installing?.set(false)
//Delay error broadcast until activity (and fragment) get back to the screen
CoroutineScope(Dispatchers.IO).launch {
return launch {
delay(700)
val intent = Intent(HomeFragment.INSTALL_FAILED)
intent.putExtra("errorMsg", getErrorMessage(status, context))
@ -50,9 +50,9 @@ object AppUtils {
}
}
fun sendFailure(error: MutableList<String>, context: Context) {
fun sendFailure(error: MutableList<String>, context: Context): Job {
downloadProgress.get()?.installing?.set(false)
CoroutineScope(Dispatchers.IO).launch {
return launch {
delay(700)
val intent = Intent(HomeFragment.INSTALL_FAILED)
intent.putExtra("errorMsg", getErrorMessage(error.joinToString(), context))
@ -134,6 +134,4 @@ object AppUtils {
context.getString(R.string.installation_failed)
}
}
}
}

View file

@ -16,9 +16,8 @@ import com.downloader.PRDownloader
import com.vanced.manager.R
import com.vanced.manager.model.ProgressModel
import com.vanced.manager.utils.AppUtils.sendCloseDialog
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File
object DownloadHelper {
@ -41,8 +40,8 @@ object DownloadHelper {
downloadProgress.set(ProgressModel())
}
fun downloadManager(context: Context) {
CoroutineScope(Dispatchers.IO).launch {
suspend fun downloadManager(context: Context) =
withContext(Dispatchers.IO) {
val url = "https://github.com/YTVanced/VancedManager/releases/latest/download/manager.apk"
downloadProgress.get()?.currentDownload = PRDownloader.download(url, context.getExternalFilesDir("manager")?.path, "manager.apk")
.build()
@ -82,6 +81,4 @@ object DownloadHelper {
})
}
}
}

View file

@ -28,7 +28,7 @@ object Extensions {
show(activity.supportFragmentManager, "")
}
fun Activity.fetchData() {
suspend fun Activity.fetchData() {
val refreshLayout = findViewById<SwipeRefreshLayout>(R.id.home_refresh)
setRefreshing(true, refreshLayout)
loadJson(this)

View file

@ -7,16 +7,15 @@ import androidx.browser.customtabs.CustomTabsIntent
import androidx.core.content.ContextCompat
import androidx.core.net.toUri
import androidx.databinding.ObservableField
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import androidx.preference.PreferenceManager.*
import com.beust.klaxon.JsonArray
import com.beust.klaxon.JsonObject
import com.vanced.manager.BuildConfig
import com.vanced.manager.R
import com.vanced.manager.utils.AppUtils.generateChecksum
import com.vanced.manager.utils.Extensions.getDefaultPrefs
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File
import java.text.SimpleDateFormat
import java.util.*
@ -49,19 +48,20 @@ object InternetTools {
context.startActivity(Intent(Intent.ACTION_VIEW, url.toUri()).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK))
}
fun getFileNameFromUrl(url: String) = url.substring(url.lastIndexOf('/')+1, url.length)
fun getFileNameFromUrl(url: String) = url.substring(url.lastIndexOf('/') + 1, url.length)
fun loadJson(context: Context) = CoroutineScope(Dispatchers.IO).launch {
val installUrl = context.getDefaultPrefs().getString("install_url", baseUrl)
val latest = JsonHelper.getJson("$installUrl/latest.json?fetchTime=${SimpleDateFormat("HHmmss", Locale.ROOT)}")
val versions = JsonHelper.getJson("$installUrl/versions.json?fetchTime=${SimpleDateFormat("HHmmss", Locale.ROOT)}")
suspend fun loadJson(context: Context) =
withContext(Dispatchers.IO) {
val installUrl = context.getDefaultPrefs().getString("install_url", baseUrl)
val latest = JsonHelper.getJson("$installUrl/latest.json?fetchTime=${SimpleDateFormat("HHmmss", Locale.ROOT)}")
val versions = JsonHelper.getJson("$installUrl/versions.json?fetchTime=${SimpleDateFormat("HHmmss", Locale.ROOT)}")
// braveTiers.apply {
// set(getJson("$installUrl/sponsor.json"))
// notifyChange()
// }
vanced.apply {
set(latest?.obj("vanced"))
vanced.apply {
set(latest?.obj("vanced"))
notifyChange()
}
vancedVersions.set(versions?.array("vanced"))