refactor: activity result event

This commit is contained in:
rhunk
2024-03-17 16:55:21 +01:00
parent 5d35550cc5
commit b5a3b13172
3 changed files with 75 additions and 42 deletions

View File

@ -1,5 +1,6 @@
package me.rhunk.snapenhance.core.event
import android.app.Activity
import android.content.Intent
import android.view.View
import android.view.ViewGroup
@ -222,6 +223,32 @@ class EventDispatcher(
}
}
arrayOf(
"com.snap.mushroom.MainActivity",
"com.snap.identity.loginsignup.ui.LoginSignupActivity"
).forEach {
context.androidContext.classLoader.loadClass(it).hook("onActivityResult", HookStage.BEFORE) { param ->
val instance = param.thisObject<Activity>()
val requestCode = param.arg<Int>(0)
val resultCode = param.arg<Int>(1)
val intent = param.arg<Intent>(2)
context.event.post(
ActivityResultEvent(
activity = instance,
requestCode = requestCode,
resultCode = resultCode,
intent = intent
).apply {
adapter = param
}
) {
if (canceled) param.setResult(null)
postHookEvent()
}
}
}
hookViewBinder()
}
}

View File

@ -0,0 +1,12 @@
package me.rhunk.snapenhance.core.event.events.impl
import android.app.Activity
import android.content.Intent
import me.rhunk.snapenhance.core.event.events.AbstractHookEvent
class ActivityResultEvent(
val activity: Activity,
val requestCode: Int,
val resultCode: Int,
val intent: Intent
): AbstractHookEvent()

View File

@ -32,6 +32,7 @@ import me.rhunk.snapenhance.common.data.FileType
import me.rhunk.snapenhance.common.ui.AppMaterialTheme
import me.rhunk.snapenhance.common.ui.createComposeAlertDialog
import me.rhunk.snapenhance.common.util.snap.MediaDownloaderHelper
import me.rhunk.snapenhance.core.event.events.impl.ActivityResultEvent
import me.rhunk.snapenhance.core.event.events.impl.AddViewEvent
import me.rhunk.snapenhance.core.features.Feature
import me.rhunk.snapenhance.core.features.FeatureLoadParams
@ -425,51 +426,10 @@ class AccountSwitcher: Feature("Account Switcher", loadParams = FeatureLoadParam
mainDbShmFile?.delete()
}
private fun hookActivityResult(activityClass: Class<*>) {
activityClass.hook("onActivityResult", HookStage.BEFORE) { param ->
val requestCode = param.arg<Int>(0)
val resultCode = param.arg<Int>(1)
val intent = param.arg<Intent>(2)
if (importRequestCode == requestCode) {
importRequestCode = null
if (resultCode != Activity.RESULT_OK) return@hook
val uri = intent.data ?: return@hook
context.coroutineScope.launch { importAccount(uri) }
}
if (exportCallback?.first == requestCode) {
val userId = exportCallback?.second
exportCallback = null
param.setResult(null)
if (resultCode != Activity.RESULT_OK) return@hook
context.coroutineScope.launch {
runCatching {
intent.data?.let { uri ->
val accountDataPfd = context.bridgeClient.getAccountStorage().getAccountData(userId) ?: throw Exception("Account data not found")
context.androidContext.contentResolver.openOutputStream(uri)?.use { outputStream ->
ParcelFileDescriptor.AutoCloseInputStream(accountDataPfd).use {
it.copyTo(outputStream)
}
}
context.shortToast("Account exported!")
}
}.onFailure {
context.shortToast("Failed to export account. Check logs for more info.")
context.log.error("Failed to export account", it)
}
}
}
}
}
override fun onActivityCreate() {
if (context.config.experimental.accountSwitcher.globalState != true) return
activity = context.mainActivity!!
hookActivityResult(activity!!::class.java)
val hovaHeaderSearchIcon = activity!!.resources.getId("hova_header_search_icon")
context.event.subscribe(AddViewEvent::class) { event ->
@ -487,6 +447,41 @@ class AccountSwitcher: Feature("Account Switcher", loadParams = FeatureLoadParam
override fun init() {
if (context.config.experimental.accountSwitcher.globalState != true) return
context.event.subscribe(ActivityResultEvent::class) { event ->
if (importRequestCode == event.requestCode) {
importRequestCode = null
if (event.resultCode != Activity.RESULT_OK) return@subscribe
event.canceled = true
val uri = event.intent.data ?: return@subscribe
context.coroutineScope.launch { importAccount(uri) }
}
if (exportCallback?.first == event.requestCode) {
val userId = exportCallback?.second
exportCallback = null
event.canceled = true
if (event.resultCode != Activity.RESULT_OK) return@subscribe
context.coroutineScope.launch {
runCatching {
event.intent.data?.let { uri ->
val accountDataPfd = context.bridgeClient.getAccountStorage().getAccountData(userId) ?: throw Exception("Account data not found")
context.androidContext.contentResolver.openOutputStream(uri)?.use { outputStream ->
ParcelFileDescriptor.AutoCloseInputStream(accountDataPfd).use {
it.copyTo(outputStream)
}
}
context.shortToast("Account exported!")
}
}.onFailure {
context.shortToast("Failed to export account. Check logs for more info.")
context.log.error("Failed to export account", it)
}
}
}
}
findClass("com.snap.identity.service.ForcedLogoutBroadcastReceiver").hook("onReceive", HookStage.BEFORE) { param ->
val intent = param.arg<Intent>(1)
if (isLoginActivity) return@hook
@ -508,7 +503,6 @@ class AccountSwitcher: Feature("Account Switcher", loadParams = FeatureLoadParam
}
findClass("com.snap.identity.loginsignup.ui.LoginSignupActivity").apply {
hookActivityResult(this)
hook("onCreate", HookStage.AFTER) { param ->
activity = param.thisObject()
activity!!.findViewById<FrameLayout>(android.R.id.content).addView(Button(activity).apply {