Cleanup ActivityResult callbacks
This commit is contained in:
parent
333fe6da0e
commit
fc19b50290
@ -1,6 +1,5 @@
|
||||
package com.topjohnwu.magisk.arch
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.KeyEvent
|
||||
import android.view.View
|
||||
@ -41,11 +40,6 @@ abstract class BaseUIActivity<VM : BaseViewModel, Binding : ViewDataBinding> :
|
||||
AppCompatDelegate.setDefaultNightMode(theme)
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
currentFragment?.onActivityResult(requestCode, resultCode, data)
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
setTheme(themeRes)
|
||||
super.onCreate(savedInstanceState)
|
||||
|
@ -17,7 +17,7 @@ import com.topjohnwu.magisk.ktx.startAnimations
|
||||
abstract class BaseUIFragment<VM : BaseViewModel, Binding : ViewDataBinding> :
|
||||
Fragment(), BaseUIComponent<VM> {
|
||||
|
||||
protected val activity get() = requireActivity() as BaseUIActivity<*, *>
|
||||
val activity get() = requireActivity() as BaseUIActivity<*, *>
|
||||
protected lateinit var binding: Binding
|
||||
protected abstract val layoutRes: Int
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
package com.topjohnwu.magisk.arch
|
||||
|
||||
import android.content.Context
|
||||
import androidx.fragment.app.Fragment
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
|
||||
/**
|
||||
@ -23,5 +22,5 @@ interface ActivityExecutor {
|
||||
}
|
||||
|
||||
interface FragmentExecutor {
|
||||
operator fun invoke(fragment: Fragment)
|
||||
operator fun invoke(fragment: BaseUIFragment<*, *>)
|
||||
}
|
||||
|
@ -33,12 +33,12 @@ object Const {
|
||||
|
||||
object ID {
|
||||
const val FETCH_ZIP = 2
|
||||
const val SELECT_BOOT = 3
|
||||
const val SELECT_FILE = 3
|
||||
const val MAX_ACTIVITY_RESULT = 10
|
||||
|
||||
// notifications
|
||||
const val MAGISK_UPDATE_NOTIFICATION_ID = 4
|
||||
const val APK_UPDATE_NOTIFICATION_ID = 5
|
||||
const val DTBO_NOTIFICATION_ID = 7
|
||||
const val HIDE_MANAGER_NOTIFICATION_ID = 8
|
||||
const val UPDATE_NOTIFICATION_CHANNEL = "update"
|
||||
const val PROGRESS_NOTIFICATION_CHANNEL = "progress"
|
||||
|
@ -8,22 +8,24 @@ import android.content.pm.PackageManager
|
||||
import android.content.res.Configuration
|
||||
import android.os.Build
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.CallSuper
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.collection.SparseArrayCompat
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.core.Const
|
||||
import com.topjohnwu.magisk.core.utils.currentLocale
|
||||
import com.topjohnwu.magisk.core.wrap
|
||||
import com.topjohnwu.magisk.ktx.set
|
||||
import com.topjohnwu.magisk.utils.Utils
|
||||
import kotlin.random.Random
|
||||
|
||||
typealias RequestCallback = BaseActivity.(Int, Intent?) -> Unit
|
||||
typealias ActivityResultCallback = BaseActivity.(Int, Intent?) -> Unit
|
||||
|
||||
abstract class BaseActivity : AppCompatActivity() {
|
||||
|
||||
private val resultCallbacks by lazy { SparseArrayCompat<RequestCallback>() }
|
||||
private val resultCallbacks by lazy { SparseArrayCompat<ActivityResultCallback>() }
|
||||
|
||||
override fun applyOverrideConfiguration(config: Configuration?) {
|
||||
// Force applying our preferred local
|
||||
@ -38,8 +40,7 @@ abstract class BaseActivity : AppCompatActivity() {
|
||||
fun withPermission(permission: String, builder: PermissionRequestBuilder.() -> Unit) {
|
||||
val request = PermissionRequestBuilder().apply(builder).build()
|
||||
|
||||
if (permission == Manifest.permission.WRITE_EXTERNAL_STORAGE &&
|
||||
Build.VERSION.SDK_INT >= 29) {
|
||||
if (permission == Manifest.permission.WRITE_EXTERNAL_STORAGE && Build.VERSION.SDK_INT >= 29) {
|
||||
// We do not need external rw on 29+
|
||||
request.onSuccess()
|
||||
return
|
||||
@ -48,7 +49,10 @@ abstract class BaseActivity : AppCompatActivity() {
|
||||
if (ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED) {
|
||||
request.onSuccess()
|
||||
} else {
|
||||
val requestCode = Random.nextInt(256, 512)
|
||||
var requestCode: Int
|
||||
do {
|
||||
requestCode = Random.nextInt(Const.ID.MAX_ACTIVITY_RESULT + 1, 1 shl 15)
|
||||
} while (!resultCallbacks.containsKey(requestCode))
|
||||
resultCallbacks[requestCode] = { result, _ ->
|
||||
if (result > 0)
|
||||
request.onSuccess()
|
||||
@ -79,16 +83,17 @@ abstract class BaseActivity : AppCompatActivity() {
|
||||
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
resultCallbacks[requestCode]?.also {
|
||||
resultCallbacks[requestCode]?.also { callback ->
|
||||
resultCallbacks.remove(requestCode)
|
||||
it(this, resultCode, data)
|
||||
callback(this, resultCode, data)
|
||||
}
|
||||
}
|
||||
|
||||
fun startActivityForResult(intent: Intent, requestCode: Int, listener: RequestCallback) {
|
||||
resultCallbacks[requestCode] = listener
|
||||
fun startActivityForResult(intent: Intent, requestCode: Int, callback: ActivityResultCallback) {
|
||||
resultCallbacks[requestCode] = callback
|
||||
try {
|
||||
startActivityForResult(intent, requestCode)
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
|
@ -1,45 +0,0 @@
|
||||
package com.topjohnwu.magisk.events
|
||||
|
||||
import android.Manifest
|
||||
import android.app.Activity
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Intent
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.RequiresPermission
|
||||
import androidx.navigation.NavDirections
|
||||
import com.topjohnwu.magisk.MainDirections
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.arch.ActivityExecutor
|
||||
import com.topjohnwu.magisk.arch.BaseUIActivity
|
||||
import com.topjohnwu.magisk.arch.ViewEvent
|
||||
import com.topjohnwu.magisk.core.Const
|
||||
import com.topjohnwu.magisk.utils.Utils
|
||||
|
||||
class InstallExternalModuleEvent : ViewEvent(), ActivityExecutor {
|
||||
|
||||
@RequiresPermission(allOf = [Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE])
|
||||
override fun invoke(activity: BaseUIActivity<*, *>) {
|
||||
val intent = Intent(Intent.ACTION_GET_CONTENT)
|
||||
intent.type = "application/zip"
|
||||
try {
|
||||
activity.startActivityForResult(intent, Const.ID.FETCH_ZIP)
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
Utils.toast(R.string.app_not_found, Toast.LENGTH_SHORT)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?): NavDirections? {
|
||||
if (requestCode == Const.ID.FETCH_ZIP && resultCode == Activity.RESULT_OK && data != null) {
|
||||
val data = data.data
|
||||
if (data != null) {
|
||||
return MainDirections.actionFlashFragment(data, Const.Value.FLASH_ZIP)
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -6,8 +6,11 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.widget.Toast
|
||||
import androidx.navigation.NavDirections
|
||||
import com.topjohnwu.magisk.MainDirections
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.arch.*
|
||||
import com.topjohnwu.magisk.core.Const
|
||||
import com.topjohnwu.magisk.core.base.ActivityResultCallback
|
||||
import com.topjohnwu.magisk.core.base.BaseActivity
|
||||
import com.topjohnwu.magisk.core.model.module.Repo
|
||||
import com.topjohnwu.magisk.utils.Utils
|
||||
@ -67,14 +70,12 @@ class RecreateEvent : ViewEvent(), ActivityExecutor {
|
||||
}
|
||||
}
|
||||
|
||||
class RequestFileEvent : ViewEvent(), ActivityExecutor {
|
||||
class MagiskInstallFileEvent(private val callback: ActivityResultCallback)
|
||||
: ViewEvent(), ActivityExecutor {
|
||||
override fun invoke(activity: BaseUIActivity<*, *>) {
|
||||
Intent(Intent.ACTION_GET_CONTENT)
|
||||
.setType("*/*")
|
||||
.addCategory(Intent.CATEGORY_OPENABLE)
|
||||
.also {
|
||||
val intent = Intent(Intent.ACTION_GET_CONTENT).setType("*/*")
|
||||
try {
|
||||
activity.startActivityForResult(it, REQUEST_CODE)
|
||||
activity.startActivityForResult(intent, Const.ID.SELECT_FILE, callback)
|
||||
Utils.toast(R.string.patch_file_msg, Toast.LENGTH_LONG)
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
Utils.toast(R.string.app_not_found, Toast.LENGTH_SHORT)
|
||||
@ -82,15 +83,6 @@ class RequestFileEvent : ViewEvent(), ActivityExecutor {
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val REQUEST_CODE = 10
|
||||
fun resolve(requestCode: Int, resultCode: Int, data: Intent?) = data
|
||||
?.takeIf { resultCode == Activity.RESULT_OK }
|
||||
?.takeIf { requestCode == REQUEST_CODE }
|
||||
?.data
|
||||
}
|
||||
}
|
||||
|
||||
class NavigationEvent(
|
||||
private val directions: NavDirections
|
||||
) : ViewEvent(), ActivityExecutor {
|
||||
@ -106,3 +98,22 @@ class AddHomeIconEvent : ViewEvent(), ContextExecutor {
|
||||
Shortcuts.addHomeIcon(context)
|
||||
}
|
||||
}
|
||||
|
||||
class SelectModuleEvent : ViewEvent(), FragmentExecutor {
|
||||
override fun invoke(fragment: BaseUIFragment<*, *>) {
|
||||
val intent = Intent(Intent.ACTION_GET_CONTENT).setType("application/zip")
|
||||
try {
|
||||
fragment.apply {
|
||||
activity.startActivityForResult(intent, Const.ID.FETCH_ZIP) { code, intent ->
|
||||
if (code == Activity.RESULT_OK && intent != null) {
|
||||
intent.data?.also {
|
||||
MainDirections.actionFlashFragment(it, Const.Value.FLASH_ZIP).navigate()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
Utils.toast(R.string.app_not_found, Toast.LENGTH_SHORT)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,10 @@
|
||||
package com.topjohnwu.magisk.ui.install
|
||||
|
||||
import android.content.Intent
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.arch.BaseUIFragment
|
||||
import com.topjohnwu.magisk.core.download.BaseDownloader
|
||||
import com.topjohnwu.magisk.databinding.FragmentInstallMd2Binding
|
||||
import com.topjohnwu.magisk.events.RequestFileEvent
|
||||
import com.topjohnwu.magisk.ktx.coroutineScope
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
|
||||
@ -15,11 +13,6 @@ class InstallFragment : BaseUIFragment<InstallViewModel, FragmentInstallMd2Bindi
|
||||
override val layoutRes = R.layout.fragment_install_md2
|
||||
override val viewModel by viewModel<InstallViewModel>()
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
viewModel.data = RequestFileEvent.resolve(requestCode, resultCode, data)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
requireActivity().setTitle(R.string.install)
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.topjohnwu.magisk.ui.install
|
||||
|
||||
import android.app.Activity
|
||||
import android.net.Uri
|
||||
import androidx.databinding.Bindable
|
||||
import androidx.lifecycle.viewModelScope
|
||||
@ -11,7 +12,7 @@ import com.topjohnwu.magisk.core.download.Action
|
||||
import com.topjohnwu.magisk.core.download.DownloadService
|
||||
import com.topjohnwu.magisk.core.download.Subject
|
||||
import com.topjohnwu.magisk.data.repository.StringRepository
|
||||
import com.topjohnwu.magisk.events.RequestFileEvent
|
||||
import com.topjohnwu.magisk.events.MagiskInstallFileEvent
|
||||
import com.topjohnwu.magisk.events.dialog.SecondSlotWarningDialog
|
||||
import com.topjohnwu.magisk.utils.set
|
||||
import com.topjohnwu.superuser.Shell
|
||||
@ -35,7 +36,10 @@ class InstallViewModel(
|
||||
set(value) = set(value, field, { field = it }, BR.method) {
|
||||
when (it) {
|
||||
R.id.method_patch -> {
|
||||
RequestFileEvent().publish()
|
||||
MagiskInstallFileEvent { code, intent ->
|
||||
if (code == Activity.RESULT_OK)
|
||||
data = intent?.data
|
||||
}.publish()
|
||||
}
|
||||
R.id.method_inactive_slot -> {
|
||||
SecondSlotWarningDialog().publish()
|
||||
|
@ -1,6 +1,5 @@
|
||||
package com.topjohnwu.magisk.ui.module
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
@ -14,7 +13,6 @@ import com.topjohnwu.magisk.arch.ReselectionTarget
|
||||
import com.topjohnwu.magisk.arch.ViewEvent
|
||||
import com.topjohnwu.magisk.core.download.BaseDownloader
|
||||
import com.topjohnwu.magisk.databinding.FragmentModuleMd2Binding
|
||||
import com.topjohnwu.magisk.events.InstallExternalModuleEvent
|
||||
import com.topjohnwu.magisk.ktx.hideKeyboard
|
||||
import com.topjohnwu.magisk.ui.MainActivity
|
||||
import com.topjohnwu.magisk.utils.EndlessRecyclerScrollListener
|
||||
@ -40,13 +38,6 @@ class ModuleFragment : BaseUIFragment<ModuleViewModel, FragmentModuleMd2Binding>
|
||||
}
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
InstallExternalModuleEvent.onActivityResult(requestCode, resultCode, data)?.also {
|
||||
it.navigate()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
setHasOptionsMenu(true)
|
||||
|
@ -14,7 +14,7 @@ import com.topjohnwu.magisk.core.tasks.RepoUpdater
|
||||
import com.topjohnwu.magisk.data.database.RepoByNameDao
|
||||
import com.topjohnwu.magisk.data.database.RepoByUpdatedDao
|
||||
import com.topjohnwu.magisk.databinding.RvItem
|
||||
import com.topjohnwu.magisk.events.InstallExternalModuleEvent
|
||||
import com.topjohnwu.magisk.events.SelectModuleEvent
|
||||
import com.topjohnwu.magisk.events.OpenChangelogEvent
|
||||
import com.topjohnwu.magisk.events.SnackbarEvent
|
||||
import com.topjohnwu.magisk.events.dialog.ModuleInstallDialog
|
||||
@ -311,7 +311,7 @@ class ModuleViewModel(
|
||||
}
|
||||
|
||||
fun installPressed() = withExternalRW {
|
||||
InstallExternalModuleEvent().publish()
|
||||
SelectModuleEvent().publish()
|
||||
}
|
||||
|
||||
fun infoPressed(item: RepoItem) =
|
||||
|
Loading…
Reference in New Issue
Block a user