From fc19b502908bad0869b079154da682c60c19c774 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Tue, 6 Oct 2020 02:04:19 -0700 Subject: [PATCH] Cleanup ActivityResult callbacks --- .../topjohnwu/magisk/arch/BaseUIActivity.kt | 6 --- .../topjohnwu/magisk/arch/BaseUIFragment.kt | 2 +- .../com/topjohnwu/magisk/arch/ViewEvent.kt | 3 +- .../java/com/topjohnwu/magisk/core/Const.kt | 4 +- .../magisk/core/base/BaseActivity.kt | 25 +++++---- .../events/InstallExternalModuleEvent.kt | 45 ---------------- .../com/topjohnwu/magisk/events/ViewEvents.kt | 51 +++++++++++-------- .../magisk/ui/install/InstallFragment.kt | 7 --- .../magisk/ui/install/InstallViewModel.kt | 8 ++- .../magisk/ui/module/ModuleFragment.kt | 9 ---- .../magisk/ui/module/ModuleViewModel.kt | 4 +- 11 files changed, 58 insertions(+), 106 deletions(-) delete mode 100644 app/src/main/java/com/topjohnwu/magisk/events/InstallExternalModuleEvent.kt diff --git a/app/src/main/java/com/topjohnwu/magisk/arch/BaseUIActivity.kt b/app/src/main/java/com/topjohnwu/magisk/arch/BaseUIActivity.kt index 010954aca..0c7a5098e 100644 --- a/app/src/main/java/com/topjohnwu/magisk/arch/BaseUIActivity.kt +++ b/app/src/main/java/com/topjohnwu/magisk/arch/BaseUIActivity.kt @@ -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 : 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) diff --git a/app/src/main/java/com/topjohnwu/magisk/arch/BaseUIFragment.kt b/app/src/main/java/com/topjohnwu/magisk/arch/BaseUIFragment.kt index ceea8cf07..3ffe64431 100644 --- a/app/src/main/java/com/topjohnwu/magisk/arch/BaseUIFragment.kt +++ b/app/src/main/java/com/topjohnwu/magisk/arch/BaseUIFragment.kt @@ -17,7 +17,7 @@ import com.topjohnwu.magisk.ktx.startAnimations abstract class BaseUIFragment : Fragment(), BaseUIComponent { - protected val activity get() = requireActivity() as BaseUIActivity<*, *> + val activity get() = requireActivity() as BaseUIActivity<*, *> protected lateinit var binding: Binding protected abstract val layoutRes: Int diff --git a/app/src/main/java/com/topjohnwu/magisk/arch/ViewEvent.kt b/app/src/main/java/com/topjohnwu/magisk/arch/ViewEvent.kt index 18ac2eb9e..050e2dc0d 100644 --- a/app/src/main/java/com/topjohnwu/magisk/arch/ViewEvent.kt +++ b/app/src/main/java/com/topjohnwu/magisk/arch/ViewEvent.kt @@ -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<*, *>) } diff --git a/app/src/main/java/com/topjohnwu/magisk/core/Const.kt b/app/src/main/java/com/topjohnwu/magisk/core/Const.kt index 8a512daf9..36903f78b 100644 --- a/app/src/main/java/com/topjohnwu/magisk/core/Const.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/Const.kt @@ -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" diff --git a/app/src/main/java/com/topjohnwu/magisk/core/base/BaseActivity.kt b/app/src/main/java/com/topjohnwu/magisk/core/base/BaseActivity.kt index acd6299cb..17c974525 100644 --- a/app/src/main/java/com/topjohnwu/magisk/core/base/BaseActivity.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/base/BaseActivity.kt @@ -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() } + private val resultCallbacks by lazy { SparseArrayCompat() } 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,8 +49,11 @@ abstract class BaseActivity : AppCompatActivity() { if (ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED) { request.onSuccess() } else { - val requestCode = Random.nextInt(256, 512) - resultCallbacks[requestCode] = { result, _ -> + 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() else @@ -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) { diff --git a/app/src/main/java/com/topjohnwu/magisk/events/InstallExternalModuleEvent.kt b/app/src/main/java/com/topjohnwu/magisk/events/InstallExternalModuleEvent.kt deleted file mode 100644 index 6d15a856b..000000000 --- a/app/src/main/java/com/topjohnwu/magisk/events/InstallExternalModuleEvent.kt +++ /dev/null @@ -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 - } - - } - -} diff --git a/app/src/main/java/com/topjohnwu/magisk/events/ViewEvents.kt b/app/src/main/java/com/topjohnwu/magisk/events/ViewEvents.kt index 217f2d26e..40835b2fe 100644 --- a/app/src/main/java/com/topjohnwu/magisk/events/ViewEvents.kt +++ b/app/src/main/java/com/topjohnwu/magisk/events/ViewEvents.kt @@ -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,27 +70,16 @@ 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 { - try { - activity.startActivityForResult(it, REQUEST_CODE) - Utils.toast(R.string.patch_file_msg, Toast.LENGTH_LONG) - } catch (e: ActivityNotFoundException) { - Utils.toast(R.string.app_not_found, Toast.LENGTH_SHORT) - } - } - } - - 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 + val intent = Intent(Intent.ACTION_GET_CONTENT).setType("*/*") + try { + 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) + } } } @@ -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) + } + } +} diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/install/InstallFragment.kt b/app/src/main/java/com/topjohnwu/magisk/ui/install/InstallFragment.kt index 08aac9cce..ab5ffbc72 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/install/InstallFragment.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/install/InstallFragment.kt @@ -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() - 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) diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/install/InstallViewModel.kt b/app/src/main/java/com/topjohnwu/magisk/ui/install/InstallViewModel.kt index d33bf1baa..b6d479e46 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/install/InstallViewModel.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/install/InstallViewModel.kt @@ -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() diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/module/ModuleFragment.kt b/app/src/main/java/com/topjohnwu/magisk/ui/module/ModuleFragment.kt index 57ece0bb3..d733fdaae 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/module/ModuleFragment.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/module/ModuleFragment.kt @@ -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 } } - 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) diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/module/ModuleViewModel.kt b/app/src/main/java/com/topjohnwu/magisk/ui/module/ModuleViewModel.kt index c83e2fbd2..2d056eb5f 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/module/ModuleViewModel.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/module/ModuleViewModel.kt @@ -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) =