diff --git a/app/src/main/kotlin/me/rhunk/snapenhance/bridge/ForceStartActivity.kt b/app/src/main/kotlin/me/rhunk/snapenhance/bridge/ForceStartActivity.kt index ed99d393..4d0f7e0e 100644 --- a/app/src/main/kotlin/me/rhunk/snapenhance/bridge/ForceStartActivity.kt +++ b/app/src/main/kotlin/me/rhunk/snapenhance/bridge/ForceStartActivity.kt @@ -3,13 +3,14 @@ package me.rhunk.snapenhance.bridge import android.app.Activity import android.content.Intent import android.os.Bundle +import me.rhunk.snapenhance.Constants import me.rhunk.snapenhance.SharedContextHolder class ForceStartActivity : Activity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) if (intent.getBooleanExtra("streaks_notification_action", false)) { - packageManager.getLaunchIntentForPackage("com.snapchat.android")?.apply { + packageManager.getLaunchIntentForPackage(Constants.SNAPCHAT_PACKAGE_NAME)?.apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) startActivity(this) } diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/Constants.kt b/core/src/main/kotlin/me/rhunk/snapenhance/Constants.kt index 4c9d9e14..b20263e5 100644 --- a/core/src/main/kotlin/me/rhunk/snapenhance/Constants.kt +++ b/core/src/main/kotlin/me/rhunk/snapenhance/Constants.kt @@ -3,13 +3,8 @@ package me.rhunk.snapenhance object Constants { const val SNAPCHAT_PACKAGE_NAME = "com.snapchat.android" - const val VIEW_INJECTED_CODE = 0x7FFFFF02 - val ARROYO_MEDIA_CONTAINER_PROTO_PATH = intArrayOf(4, 4) val ARROYO_STRING_CHAT_MESSAGE_PROTO = ARROYO_MEDIA_CONTAINER_PROTO_PATH + intArrayOf(2, 1) - const val ENCRYPTION_PROTO_INDEX = 19 - const val ENCRYPTION_PROTO_INDEX_V2 = 4 - const val USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" } \ No newline at end of file diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/ModContext.kt b/core/src/main/kotlin/me/rhunk/snapenhance/ModContext.kt index 85e029c3..29fcd3d0 100644 --- a/core/src/main/kotlin/me/rhunk/snapenhance/ModContext.kt +++ b/core/src/main/kotlin/me/rhunk/snapenhance/ModContext.kt @@ -10,14 +10,14 @@ import android.os.Process import android.widget.Toast import com.google.gson.Gson import com.google.gson.GsonBuilder -import kotlinx.coroutines.asCoroutineDispatcher import me.rhunk.snapenhance.core.Logger import me.rhunk.snapenhance.core.bridge.BridgeClient import me.rhunk.snapenhance.core.bridge.wrapper.LocaleWrapper import me.rhunk.snapenhance.core.bridge.wrapper.MappingsWrapper import me.rhunk.snapenhance.core.config.ModConfig import me.rhunk.snapenhance.core.database.DatabaseAccess -import me.rhunk.snapenhance.core.eventbus.EventBus +import me.rhunk.snapenhance.core.event.EventBus +import me.rhunk.snapenhance.core.event.EventDispatcher import me.rhunk.snapenhance.core.util.download.HttpServer import me.rhunk.snapenhance.data.MessageSender import me.rhunk.snapenhance.features.Feature @@ -34,32 +34,28 @@ import kotlin.system.exitProcess class ModContext { private val executorService: ExecutorService = Executors.newCachedThreadPool() - val coroutineDispatcher by lazy { - executorService.asCoroutineDispatcher() - } - lateinit var androidContext: Context - var mainActivity: Activity? = null lateinit var bridgeClient: BridgeClient + var mainActivity: Activity? = null + val classCache get() = SnapEnhance.classCache + val resources: Resources get() = androidContext.resources val gson: Gson = GsonBuilder().create() - private val modConfig = ModConfig() - val config by modConfig + private val _config = ModConfig() + val config by _config::root val log by lazy { Logger(this.bridgeClient) } - val event = EventBus(this) - val eventDispatcher = EventDispatcher(this) - val native = NativeLib() - val translation = LocaleWrapper() + val httpServer = HttpServer() + val messageSender = MessageSender(this) + val features = FeatureManager(this) val mappings = MappingsWrapper() val actionManager = ActionManager(this) val database = DatabaseAccess(this) - val httpServer = HttpServer() - val messageSender = MessageSender(this) - val classCache get() = SnapEnhance.classCache - val resources: Resources get() = androidContext.resources + val event = EventBus(this) + val eventDispatcher = EventDispatcher(this) + val native = NativeLib() val scriptRuntime by lazy { CoreScriptRuntime(log, androidContext.classLoader) } fun feature(featureClass: KClass): T { @@ -74,7 +70,7 @@ class ModContext { } } - fun executeAsync(runnable: () -> Unit) { + fun executeAsync(runnable: ModContext.() -> Unit) { executorService.submit { runCatching { runnable() @@ -99,7 +95,7 @@ class ModContext { fun softRestartApp(saveSettings: Boolean = false) { if (saveSettings) { - modConfig.writeConfig() + _config.writeConfig() } val intent: Intent? = androidContext.packageManager.getLaunchIntentForPackage( Constants.SNAPCHAT_PACKAGE_NAME @@ -117,7 +113,7 @@ class ModContext { delayForceCloseApp(100) } - fun delayForceCloseApp(delay: Long) = Handler(Looper.getMainLooper()).postDelayed({ + private fun delayForceCloseApp(delay: Long) = Handler(Looper.getMainLooper()).postDelayed({ forceCloseApp() }, delay) @@ -128,7 +124,7 @@ class ModContext { fun reloadConfig() { log.verbose("reloading config") - modConfig.loadFromBridge(bridgeClient) + _config.loadFromBridge(bridgeClient) native.loadNativeConfig( NativeConfig( disableBitmoji = config.experimental.nativeHooks.disableBitmoji.get(), @@ -138,6 +134,6 @@ class ModContext { } fun getConfigLocale(): String { - return modConfig.locale + return _config.locale } } \ No newline at end of file diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/SnapEnhance.kt b/core/src/main/kotlin/me/rhunk/snapenhance/SnapEnhance.kt index c6a4a8c0..f1e0c134 100644 --- a/core/src/main/kotlin/me/rhunk/snapenhance/SnapEnhance.kt +++ b/core/src/main/kotlin/me/rhunk/snapenhance/SnapEnhance.kt @@ -3,118 +3,102 @@ package me.rhunk.snapenhance import android.app.Activity import android.app.Application import android.content.Context -import android.content.pm.PackageManager -import kotlinx.coroutines.runBlocking -import kotlinx.coroutines.withContext import me.rhunk.snapenhance.bridge.SyncCallback -import me.rhunk.snapenhance.core.BuildConfig import me.rhunk.snapenhance.core.Logger import me.rhunk.snapenhance.core.bridge.BridgeClient -import me.rhunk.snapenhance.core.eventbus.events.impl.SnapWidgetBroadcastReceiveEvent -import me.rhunk.snapenhance.core.eventbus.events.impl.UnaryCallEvent +import me.rhunk.snapenhance.core.event.events.impl.SnapWidgetBroadcastReceiveEvent +import me.rhunk.snapenhance.core.event.events.impl.UnaryCallEvent import me.rhunk.snapenhance.core.messaging.MessagingFriendInfo import me.rhunk.snapenhance.core.messaging.MessagingGroupInfo -import me.rhunk.snapenhance.core.util.ktx.getApplicationInfoCompat import me.rhunk.snapenhance.data.SnapClassCache -import me.rhunk.snapenhance.hook.HookAdapter import me.rhunk.snapenhance.hook.HookStage -import me.rhunk.snapenhance.hook.Hooker import me.rhunk.snapenhance.hook.hook import kotlin.time.ExperimentalTime import kotlin.time.measureTime -private fun useMainActivity(hookAdapter: HookAdapter, block: Activity.() -> Unit) { - val activity = hookAdapter.thisObject() as Activity - if (!activity.packageName.equals(Constants.SNAPCHAT_PACKAGE_NAME)) return - block(activity) -} - class SnapEnhance { companion object { lateinit var classLoader: ClassLoader - val classCache: SnapClassCache by lazy { + private set + val classCache by lazy { SnapClassCache(classLoader) } } private val appContext = ModContext() private var isBridgeInitialized = false + private fun hookMainActivity(methodName: String, stage: HookStage = HookStage.AFTER, block: Activity.() -> Unit) { + Activity::class.java.hook(methodName, stage, { isBridgeInitialized }) { param -> + val activity = param.thisObject() as Activity + if (!activity.packageName.equals(Constants.SNAPCHAT_PACKAGE_NAME)) return@hook + block(activity) + } + } + init { - Hooker.hook(Application::class.java, "attach", HookStage.BEFORE) { param -> - appContext.androidContext = param.arg(0).also { - classLoader = it.classLoader - } - appContext.bridgeClient = BridgeClient(appContext) - - //for lspatch builds, we need to check if the service is correctly installed - runCatching { - appContext.androidContext.packageManager.getApplicationInfoCompat(BuildConfig.APPLICATION_ID, PackageManager.GET_META_DATA) - }.onFailure { - appContext.crash("SnapEnhance bridge service is not installed. Please download stable version from https://github.com/rhunk/SnapEnhance/releases") - return@hook - } - - appContext.bridgeClient.apply { - start { bridgeResult -> - if (!bridgeResult) { - Logger.xposedLog("Cannot connect to bridge service") - appContext.softRestartApp() - return@start - } - runCatching { - runBlocking { - init() + Application::class.java.hook("attach", HookStage.BEFORE) { param -> + appContext.apply { + androidContext = param.arg(0).also { + classLoader = it.classLoader + } + bridgeClient = BridgeClient(appContext) + bridgeClient.apply { + connect( + timeout = { + crash("SnapEnhance bridge service is not responding. Please download stable version from https://github.com/rhunk/SnapEnhance/releases", it) + } + ) { bridgeResult -> + if (!bridgeResult) { + Logger.xposedLog("Cannot connect to bridge service") + softRestartApp() + return@connect + } + runCatching { + init() + }.onSuccess { + isBridgeInitialized = true + }.onFailure { + Logger.xposedLog("Failed to initialize", it) } - }.onSuccess { - isBridgeInitialized = true - }.onFailure { - Logger.xposedLog("Failed to initialize", it) } } } } - Activity::class.java.hook( "onCreate", HookStage.AFTER, { isBridgeInitialized }) { - useMainActivity(it) { - val isMainActivityNotNull = appContext.mainActivity != null - appContext.mainActivity = this - if (isMainActivityNotNull || !appContext.mappings.isMappingsLoaded()) return@useMainActivity - onActivityCreate() - } + hookMainActivity("onCreate") { + val isMainActivityNotNull = appContext.mainActivity != null + appContext.mainActivity = this + if (isMainActivityNotNull || !appContext.mappings.isMappingsLoaded()) return@hookMainActivity + onActivityCreate() } - Activity::class.java.hook( "onPause", HookStage.AFTER, { isBridgeInitialized }) { - useMainActivity(it) { - appContext.bridgeClient.closeSettingsOverlay() - } + hookMainActivity("onPause") { + appContext.bridgeClient.closeSettingsOverlay() } var activityWasResumed = false - //we need to reload the config when the app is resumed //FIXME: called twice at first launch - Activity::class.java.hook("onResume", HookStage.AFTER, { isBridgeInitialized }) { - useMainActivity(it) { - if (!activityWasResumed) { - activityWasResumed = true - return@useMainActivity - } - - appContext.actionManager.onNewIntent(this.intent) - appContext.reloadConfig() - syncRemote() + hookMainActivity("onResume") { + if (!activityWasResumed) { + activityWasResumed = true + return@hookMainActivity } + + appContext.actionManager.onNewIntent(this.intent) + appContext.reloadConfig() + syncRemote() } } @OptIn(ExperimentalTime::class) - private suspend fun init() { + private fun init() { measureTime { with(appContext) { reloadConfig() initNative() - withContext(appContext.coroutineDispatcher) { + executeAsync { translation.userLocale = getConfigLocale() translation.loadFromBridge(bridgeClient) } @@ -162,10 +146,8 @@ class SnapEnhance { } private fun syncRemote() { - val database = appContext.database - appContext.executeAsync { - appContext.bridgeClient.sync(object : SyncCallback.Stub() { + bridgeClient.sync(object : SyncCallback.Stub() { override fun syncFriend(uuid: String): String? { return database.getFriendInfo(uuid)?.toJson() } @@ -181,7 +163,7 @@ class SnapEnhance { } }) - appContext.event.subscribe(SnapWidgetBroadcastReceiveEvent::class) { event -> + event.subscribe(SnapWidgetBroadcastReceiveEvent::class) { event -> if (event.action != BridgeClient.BRIDGE_SYNC_ACTION) return@subscribe event.canceled = true val feedEntries = appContext.database.getFeedEntries(Int.MAX_VALUE) @@ -204,7 +186,7 @@ class SnapEnhance { ) } - appContext.bridgeClient.passGroupsAndFriends( + bridgeClient.passGroupsAndFriends( groups.map { it.toJson() }, friends.map { it.toJson() } ) diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/action/impl/OpenMap.kt b/core/src/main/kotlin/me/rhunk/snapenhance/action/impl/OpenMap.kt index bb94c6e3..70d2dc32 100644 --- a/core/src/main/kotlin/me/rhunk/snapenhance/action/impl/OpenMap.kt +++ b/core/src/main/kotlin/me/rhunk/snapenhance/action/impl/OpenMap.kt @@ -9,7 +9,7 @@ class OpenMap: AbstractAction() { override fun run() { context.runOnUiThread { val mapActivityIntent = Intent() - mapActivityIntent.setClassName(BuildConfig.APPLICATION_ID, "me.rhunk.snapenhance.ui.MapActivity") + mapActivityIntent.setClassName(BuildConfig.APPLICATION_ID, BuildConfig.APPLICATION_ID + ".ui.MapActivity") mapActivityIntent.putExtra("location", Bundle().apply { putDouble("latitude", context.config.experimental.spoof.location.latitude.get().toDouble()) putDouble("longitude", context.config.experimental.spoof.location.longitude.get().toDouble()) diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/bridge/BridgeClient.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/bridge/BridgeClient.kt index 6f5e4018..7f37f616 100644 --- a/core/src/main/kotlin/me/rhunk/snapenhance/core/bridge/BridgeClient.kt +++ b/core/src/main/kotlin/me/rhunk/snapenhance/core/bridge/BridgeClient.kt @@ -23,6 +23,7 @@ import me.rhunk.snapenhance.core.messaging.SocialScope import me.rhunk.snapenhance.data.LocalePair import java.util.concurrent.CompletableFuture import java.util.concurrent.Executors +import java.util.concurrent.TimeUnit import kotlin.system.exitProcess @@ -33,22 +34,21 @@ class BridgeClient( private lateinit var service: BridgeInterface companion object { - const val BRIDGE_SYNC_ACTION = "me.rhunk.snapenhance.core.bridge.SYNC" + const val BRIDGE_SYNC_ACTION = BuildConfig.APPLICATION_ID + ".core.bridge.SYNC" } - fun start(callback: (Boolean) -> Unit) { + fun connect(timeout: (Throwable) -> Unit, onResult: (Boolean) -> Unit) { this.future = CompletableFuture() - //TODO: randomize package name with(context.androidContext) { //ensure the remote process is running startActivity(Intent() - .setClassName(BuildConfig.APPLICATION_ID, "me.rhunk.snapenhance.bridge.ForceStartActivity") + .setClassName(BuildConfig.APPLICATION_ID, BuildConfig.APPLICATION_ID + ".bridge.ForceStartActivity") .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_MULTIPLE_TASK) ) val intent = Intent() - .setClassName(BuildConfig.APPLICATION_ID, "me.rhunk.snapenhance.bridge.BridgeService") + .setClassName(BuildConfig.APPLICATION_ID, BuildConfig.APPLICATION_ID + ".bridge.BridgeService") if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { bindService( intent, @@ -70,7 +70,11 @@ class BridgeClient( ) } } - callback(future.get()) + runCatching { + onResult(future.get(10, TimeUnit.SECONDS)) + }.onFailure { + timeout(it) + } } diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/config/ModConfig.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/config/ModConfig.kt index dfb23acc..beda67df 100644 --- a/core/src/main/kotlin/me/rhunk/snapenhance/core/config/ModConfig.kt +++ b/core/src/main/kotlin/me/rhunk/snapenhance/core/config/ModConfig.kt @@ -19,7 +19,6 @@ class ModConfig { var wasPresent by Delegates.notNull() lateinit var root: RootConfig - operator fun getValue(thisRef: Any?, property: Any?) = root private fun load() { root = RootConfig() diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/eventbus/EventBus.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/event/EventBus.kt similarity index 98% rename from core/src/main/kotlin/me/rhunk/snapenhance/core/eventbus/EventBus.kt rename to core/src/main/kotlin/me/rhunk/snapenhance/core/event/EventBus.kt index 53feb585..96bc04a5 100644 --- a/core/src/main/kotlin/me/rhunk/snapenhance/core/eventbus/EventBus.kt +++ b/core/src/main/kotlin/me/rhunk/snapenhance/core/event/EventBus.kt @@ -1,4 +1,4 @@ -package me.rhunk.snapenhance.core.eventbus +package me.rhunk.snapenhance.core.event import me.rhunk.snapenhance.ModContext import kotlin.reflect.KClass diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/EventDispatcher.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/event/EventDispatcher.kt similarity index 90% rename from core/src/main/kotlin/me/rhunk/snapenhance/EventDispatcher.kt rename to core/src/main/kotlin/me/rhunk/snapenhance/core/event/EventDispatcher.kt index f91d8b42..2e60f982 100644 --- a/core/src/main/kotlin/me/rhunk/snapenhance/EventDispatcher.kt +++ b/core/src/main/kotlin/me/rhunk/snapenhance/core/event/EventDispatcher.kt @@ -1,14 +1,15 @@ -package me.rhunk.snapenhance +package me.rhunk.snapenhance.core.event import android.content.Intent import android.view.View import android.view.ViewGroup import android.view.ViewGroup.LayoutParams -import me.rhunk.snapenhance.core.eventbus.events.impl.AddViewEvent -import me.rhunk.snapenhance.core.eventbus.events.impl.NetworkApiRequestEvent -import me.rhunk.snapenhance.core.eventbus.events.impl.OnSnapInteractionEvent -import me.rhunk.snapenhance.core.eventbus.events.impl.SendMessageWithContentEvent -import me.rhunk.snapenhance.core.eventbus.events.impl.SnapWidgetBroadcastReceiveEvent +import me.rhunk.snapenhance.ModContext +import me.rhunk.snapenhance.core.event.events.impl.AddViewEvent +import me.rhunk.snapenhance.core.event.events.impl.NetworkApiRequestEvent +import me.rhunk.snapenhance.core.event.events.impl.OnSnapInteractionEvent +import me.rhunk.snapenhance.core.event.events.impl.SendMessageWithContentEvent +import me.rhunk.snapenhance.core.event.events.impl.SnapWidgetBroadcastReceiveEvent import me.rhunk.snapenhance.core.util.ktx.getObjectField import me.rhunk.snapenhance.core.util.ktx.setObjectField import me.rhunk.snapenhance.core.util.snap.SnapWidgetBroadcastReceiverHelper diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/eventbus/events/AbstractHookEvent.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/event/events/AbstractHookEvent.kt similarity index 57% rename from core/src/main/kotlin/me/rhunk/snapenhance/core/eventbus/events/AbstractHookEvent.kt rename to core/src/main/kotlin/me/rhunk/snapenhance/core/event/events/AbstractHookEvent.kt index 41465d57..c28df4a8 100644 --- a/core/src/main/kotlin/me/rhunk/snapenhance/core/eventbus/events/AbstractHookEvent.kt +++ b/core/src/main/kotlin/me/rhunk/snapenhance/core/event/events/AbstractHookEvent.kt @@ -1,6 +1,6 @@ -package me.rhunk.snapenhance.core.eventbus.events +package me.rhunk.snapenhance.core.event.events -import me.rhunk.snapenhance.core.eventbus.Event +import me.rhunk.snapenhance.core.event.Event import me.rhunk.snapenhance.hook.HookAdapter abstract class AbstractHookEvent : Event() { diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/eventbus/events/impl/AddViewEvent.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/event/events/impl/AddViewEvent.kt similarity index 63% rename from core/src/main/kotlin/me/rhunk/snapenhance/core/eventbus/events/impl/AddViewEvent.kt rename to core/src/main/kotlin/me/rhunk/snapenhance/core/event/events/impl/AddViewEvent.kt index aff213cb..4f358844 100644 --- a/core/src/main/kotlin/me/rhunk/snapenhance/core/eventbus/events/impl/AddViewEvent.kt +++ b/core/src/main/kotlin/me/rhunk/snapenhance/core/event/events/impl/AddViewEvent.kt @@ -1,8 +1,8 @@ -package me.rhunk.snapenhance.core.eventbus.events.impl +package me.rhunk.snapenhance.core.event.events.impl import android.view.View import android.view.ViewGroup -import me.rhunk.snapenhance.core.eventbus.events.AbstractHookEvent +import me.rhunk.snapenhance.core.event.events.AbstractHookEvent class AddViewEvent( val parent: ViewGroup, diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/event/events/impl/NetworkApiRequestEvent.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/event/events/impl/NetworkApiRequestEvent.kt new file mode 100644 index 00000000..f57578c6 --- /dev/null +++ b/core/src/main/kotlin/me/rhunk/snapenhance/core/event/events/impl/NetworkApiRequestEvent.kt @@ -0,0 +1,9 @@ +package me.rhunk.snapenhance.core.event.events.impl + +import me.rhunk.snapenhance.core.event.events.AbstractHookEvent + +class NetworkApiRequestEvent( + val request: Any, + val callback: Any, + var url: String, +) : AbstractHookEvent() \ No newline at end of file diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/eventbus/events/impl/OnSnapInteractionEvent.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/event/events/impl/OnSnapInteractionEvent.kt similarity index 62% rename from core/src/main/kotlin/me/rhunk/snapenhance/core/eventbus/events/impl/OnSnapInteractionEvent.kt rename to core/src/main/kotlin/me/rhunk/snapenhance/core/event/events/impl/OnSnapInteractionEvent.kt index d942ff37..32eecc41 100644 --- a/core/src/main/kotlin/me/rhunk/snapenhance/core/eventbus/events/impl/OnSnapInteractionEvent.kt +++ b/core/src/main/kotlin/me/rhunk/snapenhance/core/event/events/impl/OnSnapInteractionEvent.kt @@ -1,6 +1,6 @@ -package me.rhunk.snapenhance.core.eventbus.events.impl +package me.rhunk.snapenhance.core.event.events.impl -import me.rhunk.snapenhance.core.eventbus.events.AbstractHookEvent +import me.rhunk.snapenhance.core.event.events.AbstractHookEvent import me.rhunk.snapenhance.data.wrapper.impl.SnapUUID class OnSnapInteractionEvent( diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/eventbus/events/impl/SendMessageWithContentEvent.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/event/events/impl/SendMessageWithContentEvent.kt similarity index 84% rename from core/src/main/kotlin/me/rhunk/snapenhance/core/eventbus/events/impl/SendMessageWithContentEvent.kt rename to core/src/main/kotlin/me/rhunk/snapenhance/core/event/events/impl/SendMessageWithContentEvent.kt index 3124fb71..3d087551 100644 --- a/core/src/main/kotlin/me/rhunk/snapenhance/core/eventbus/events/impl/SendMessageWithContentEvent.kt +++ b/core/src/main/kotlin/me/rhunk/snapenhance/core/event/events/impl/SendMessageWithContentEvent.kt @@ -1,6 +1,6 @@ -package me.rhunk.snapenhance.core.eventbus.events.impl +package me.rhunk.snapenhance.core.event.events.impl -import me.rhunk.snapenhance.core.eventbus.events.AbstractHookEvent +import me.rhunk.snapenhance.core.event.events.AbstractHookEvent import me.rhunk.snapenhance.data.wrapper.impl.MessageContent import me.rhunk.snapenhance.data.wrapper.impl.MessageDestinations import me.rhunk.snapenhance.hook.HookStage diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/eventbus/events/impl/SnapWidgetBroadcastReceiveEvent.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/event/events/impl/SnapWidgetBroadcastReceiveEvent.kt similarity index 62% rename from core/src/main/kotlin/me/rhunk/snapenhance/core/eventbus/events/impl/SnapWidgetBroadcastReceiveEvent.kt rename to core/src/main/kotlin/me/rhunk/snapenhance/core/event/events/impl/SnapWidgetBroadcastReceiveEvent.kt index e814e004..737a18e3 100644 --- a/core/src/main/kotlin/me/rhunk/snapenhance/core/eventbus/events/impl/SnapWidgetBroadcastReceiveEvent.kt +++ b/core/src/main/kotlin/me/rhunk/snapenhance/core/event/events/impl/SnapWidgetBroadcastReceiveEvent.kt @@ -1,8 +1,8 @@ -package me.rhunk.snapenhance.core.eventbus.events.impl +package me.rhunk.snapenhance.core.event.events.impl import android.content.Context import android.content.Intent -import me.rhunk.snapenhance.core.eventbus.events.AbstractHookEvent +import me.rhunk.snapenhance.core.event.events.AbstractHookEvent class SnapWidgetBroadcastReceiveEvent( val androidContext: Context, diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/event/events/impl/UnaryCallEvent.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/event/events/impl/UnaryCallEvent.kt new file mode 100644 index 00000000..da39a1de --- /dev/null +++ b/core/src/main/kotlin/me/rhunk/snapenhance/core/event/events/impl/UnaryCallEvent.kt @@ -0,0 +1,8 @@ +package me.rhunk.snapenhance.core.event.events.impl + +import me.rhunk.snapenhance.core.event.events.AbstractHookEvent + +class UnaryCallEvent( + val uri: String, + var buffer: ByteArray +) : AbstractHookEvent() \ No newline at end of file diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/eventbus/events/impl/NetworkApiRequestEvent.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/eventbus/events/impl/NetworkApiRequestEvent.kt deleted file mode 100644 index a64461c7..00000000 --- a/core/src/main/kotlin/me/rhunk/snapenhance/core/eventbus/events/impl/NetworkApiRequestEvent.kt +++ /dev/null @@ -1,9 +0,0 @@ -package me.rhunk.snapenhance.core.eventbus.events.impl - -import me.rhunk.snapenhance.core.eventbus.events.AbstractHookEvent - -class NetworkApiRequestEvent( - val request: Any, - val callback: Any, - var url: String, -) : AbstractHookEvent() \ No newline at end of file diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/eventbus/events/impl/UnaryCallEvent.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/eventbus/events/impl/UnaryCallEvent.kt deleted file mode 100644 index 8146650b..00000000 --- a/core/src/main/kotlin/me/rhunk/snapenhance/core/eventbus/events/impl/UnaryCallEvent.kt +++ /dev/null @@ -1,8 +0,0 @@ -package me.rhunk.snapenhance.core.eventbus.events.impl - -import me.rhunk.snapenhance.core.eventbus.events.AbstractHookEvent - -class UnaryCallEvent( - val uri: String, - var buffer: ByteArray -) : AbstractHookEvent() \ No newline at end of file diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/Messaging.kt b/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/Messaging.kt index 9545bc98..ea582ac3 100644 --- a/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/Messaging.kt +++ b/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/Messaging.kt @@ -1,6 +1,6 @@ package me.rhunk.snapenhance.features.impl -import me.rhunk.snapenhance.core.eventbus.events.impl.OnSnapInteractionEvent +import me.rhunk.snapenhance.core.event.events.impl.OnSnapInteractionEvent import me.rhunk.snapenhance.core.util.ktx.getObjectField import me.rhunk.snapenhance.data.wrapper.impl.SnapUUID import me.rhunk.snapenhance.features.Feature diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/ScopeSync.kt b/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/ScopeSync.kt index 798d2700..741e4974 100644 --- a/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/ScopeSync.kt +++ b/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/ScopeSync.kt @@ -1,7 +1,7 @@ package me.rhunk.snapenhance.features.impl import kotlinx.coroutines.* -import me.rhunk.snapenhance.core.eventbus.events.impl.SendMessageWithContentEvent +import me.rhunk.snapenhance.core.event.events.impl.SendMessageWithContentEvent import me.rhunk.snapenhance.core.messaging.SocialScope import me.rhunk.snapenhance.data.ContentType import me.rhunk.snapenhance.features.Feature diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/downloader/MediaDownloader.kt b/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/downloader/MediaDownloader.kt index cba3ee01..d1dc4a7d 100644 --- a/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/downloader/MediaDownloader.kt +++ b/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/downloader/MediaDownloader.kt @@ -470,11 +470,11 @@ class MediaDownloader : MessagingRuleFeature("MediaDownloader", MessagingRuleTyp if (!canAutoDownload()) return@onOperaViewStateCallback context.executeAsync { - try { + runCatching { handleOperaMedia(mediaParamMap, mediaInfoMap, false) - } catch (e: Throwable) { - context.log.error("Failed to handle opera media", e) - context.longToast(e.message) + }.onFailure { + context.log.error("Failed to handle opera media", it) + context.longToast(it.message) } } } diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/downloader/ProfilePictureDownloader.kt b/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/downloader/ProfilePictureDownloader.kt index 6e5d6cbc..5ec7f03b 100644 --- a/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/downloader/ProfilePictureDownloader.kt +++ b/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/downloader/ProfilePictureDownloader.kt @@ -3,8 +3,8 @@ package me.rhunk.snapenhance.features.impl.downloader import android.annotation.SuppressLint import android.widget.Button import android.widget.RelativeLayout -import me.rhunk.snapenhance.core.eventbus.events.impl.AddViewEvent -import me.rhunk.snapenhance.core.eventbus.events.impl.NetworkApiRequestEvent +import me.rhunk.snapenhance.core.event.events.impl.AddViewEvent +import me.rhunk.snapenhance.core.event.events.impl.NetworkApiRequestEvent import me.rhunk.snapenhance.core.util.protobuf.ProtoReader import me.rhunk.snapenhance.features.Feature import me.rhunk.snapenhance.features.FeatureLoadParams diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/privacy/DisableMetrics.kt b/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/privacy/DisableMetrics.kt index c5566e22..54339637 100644 --- a/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/privacy/DisableMetrics.kt +++ b/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/privacy/DisableMetrics.kt @@ -1,6 +1,6 @@ package me.rhunk.snapenhance.features.impl.privacy -import me.rhunk.snapenhance.core.eventbus.events.impl.NetworkApiRequestEvent +import me.rhunk.snapenhance.core.event.events.impl.NetworkApiRequestEvent import me.rhunk.snapenhance.features.Feature import me.rhunk.snapenhance.features.FeatureLoadParams import me.rhunk.snapenhance.hook.HookStage diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/privacy/PreventMessageSending.kt b/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/privacy/PreventMessageSending.kt index 5ada04dd..bb771399 100644 --- a/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/privacy/PreventMessageSending.kt +++ b/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/privacy/PreventMessageSending.kt @@ -1,6 +1,6 @@ package me.rhunk.snapenhance.features.impl.privacy -import me.rhunk.snapenhance.core.eventbus.events.impl.SendMessageWithContentEvent +import me.rhunk.snapenhance.core.event.events.impl.SendMessageWithContentEvent import me.rhunk.snapenhance.data.NotificationType import me.rhunk.snapenhance.features.Feature import me.rhunk.snapenhance.features.FeatureLoadParams diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/spying/AnonymousStoryViewing.kt b/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/spying/AnonymousStoryViewing.kt index 3891de77..7f718a53 100644 --- a/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/spying/AnonymousStoryViewing.kt +++ b/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/spying/AnonymousStoryViewing.kt @@ -1,7 +1,7 @@ package me.rhunk.snapenhance.features.impl.spying import kotlinx.coroutines.runBlocking -import me.rhunk.snapenhance.core.eventbus.events.impl.NetworkApiRequestEvent +import me.rhunk.snapenhance.core.event.events.impl.NetworkApiRequestEvent import me.rhunk.snapenhance.core.util.download.HttpServer import me.rhunk.snapenhance.features.Feature import me.rhunk.snapenhance.features.FeatureLoadParams diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/spying/PreventReadReceipts.kt b/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/spying/PreventReadReceipts.kt index aec43072..d2dfa218 100644 --- a/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/spying/PreventReadReceipts.kt +++ b/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/spying/PreventReadReceipts.kt @@ -1,6 +1,6 @@ package me.rhunk.snapenhance.features.impl.spying -import me.rhunk.snapenhance.core.eventbus.events.impl.OnSnapInteractionEvent +import me.rhunk.snapenhance.core.event.events.impl.OnSnapInteractionEvent import me.rhunk.snapenhance.data.wrapper.impl.SnapUUID import me.rhunk.snapenhance.features.Feature import me.rhunk.snapenhance.features.FeatureLoadParams diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/tweaks/DisableVideoLengthRestriction.kt b/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/tweaks/DisableVideoLengthRestriction.kt index 1d081af9..67c7ccba 100644 --- a/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/tweaks/DisableVideoLengthRestriction.kt +++ b/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/tweaks/DisableVideoLengthRestriction.kt @@ -3,7 +3,7 @@ package me.rhunk.snapenhance.features.impl.tweaks import android.os.Build import android.os.FileObserver import com.google.gson.JsonParser -import me.rhunk.snapenhance.core.eventbus.events.impl.SendMessageWithContentEvent +import me.rhunk.snapenhance.core.event.events.impl.SendMessageWithContentEvent import me.rhunk.snapenhance.features.Feature import me.rhunk.snapenhance.features.FeatureLoadParams import me.rhunk.snapenhance.hook.HookStage diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/tweaks/Notifications.kt b/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/tweaks/Notifications.kt index bf136185..885da122 100644 --- a/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/tweaks/Notifications.kt +++ b/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/tweaks/Notifications.kt @@ -14,7 +14,7 @@ import de.robv.android.xposed.XposedBridge import de.robv.android.xposed.XposedHelpers import me.rhunk.snapenhance.core.Logger import me.rhunk.snapenhance.core.download.data.SplitMediaAssetType -import me.rhunk.snapenhance.core.eventbus.events.impl.SnapWidgetBroadcastReceiveEvent +import me.rhunk.snapenhance.core.event.events.impl.SnapWidgetBroadcastReceiveEvent import me.rhunk.snapenhance.core.util.CallbackBuilder import me.rhunk.snapenhance.core.util.download.RemoteMediaResolver import me.rhunk.snapenhance.core.util.ktx.setObjectField diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/tweaks/OldBitmojiSelfie.kt b/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/tweaks/OldBitmojiSelfie.kt index d08f3718..6dea84fe 100644 --- a/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/tweaks/OldBitmojiSelfie.kt +++ b/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/tweaks/OldBitmojiSelfie.kt @@ -1,6 +1,6 @@ package me.rhunk.snapenhance.features.impl.tweaks -import me.rhunk.snapenhance.core.eventbus.events.impl.NetworkApiRequestEvent +import me.rhunk.snapenhance.core.event.events.impl.NetworkApiRequestEvent import me.rhunk.snapenhance.core.util.snap.BitmojiSelfie import me.rhunk.snapenhance.features.Feature import me.rhunk.snapenhance.features.FeatureLoadParams diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/tweaks/SendOverride.kt b/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/tweaks/SendOverride.kt index 2ebdb34c..358e9f22 100644 --- a/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/tweaks/SendOverride.kt +++ b/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/tweaks/SendOverride.kt @@ -1,8 +1,8 @@ package me.rhunk.snapenhance.features.impl.tweaks import me.rhunk.snapenhance.Constants -import me.rhunk.snapenhance.core.eventbus.events.impl.SendMessageWithContentEvent -import me.rhunk.snapenhance.core.eventbus.events.impl.UnaryCallEvent +import me.rhunk.snapenhance.core.event.events.impl.SendMessageWithContentEvent +import me.rhunk.snapenhance.core.event.events.impl.UnaryCallEvent import me.rhunk.snapenhance.core.util.protobuf.ProtoEditor import me.rhunk.snapenhance.core.util.protobuf.ProtoReader import me.rhunk.snapenhance.data.ContentType diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/ui/UITweaks.kt b/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/ui/UITweaks.kt index c957e9df..133df049 100644 --- a/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/ui/UITweaks.kt +++ b/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/ui/UITweaks.kt @@ -8,7 +8,7 @@ import android.view.View import android.view.ViewGroup import android.widget.FrameLayout import me.rhunk.snapenhance.Constants -import me.rhunk.snapenhance.core.eventbus.events.impl.AddViewEvent +import me.rhunk.snapenhance.core.event.events.impl.AddViewEvent import me.rhunk.snapenhance.features.Feature import me.rhunk.snapenhance.features.FeatureLoadParams import me.rhunk.snapenhance.hook.HookStage diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/ui/menu/impl/ChatActionMenu.kt b/core/src/main/kotlin/me/rhunk/snapenhance/ui/menu/impl/ChatActionMenu.kt index e2ec912d..3ac3f738 100644 --- a/core/src/main/kotlin/me/rhunk/snapenhance/ui/menu/impl/ChatActionMenu.kt +++ b/core/src/main/kotlin/me/rhunk/snapenhance/ui/menu/impl/ChatActionMenu.kt @@ -9,7 +9,6 @@ import android.view.ViewGroup.MarginLayoutParams import android.widget.Button import android.widget.LinearLayout import me.rhunk.snapenhance.Constants -import me.rhunk.snapenhance.Constants.VIEW_INJECTED_CODE import me.rhunk.snapenhance.features.impl.Messaging import me.rhunk.snapenhance.features.impl.downloader.MediaDownloader import me.rhunk.snapenhance.features.impl.spying.MessageLogger @@ -18,9 +17,11 @@ import me.rhunk.snapenhance.ui.menu.AbstractMenu class ChatActionMenu : AbstractMenu() { + private val viewInjectedTag = 0x7FFFFF02 + private fun wasInjectedView(view: View): Boolean { - if (view.getTag(VIEW_INJECTED_CODE) != null) return true - view.setTag(VIEW_INJECTED_CODE, true) + if (view.getTag(viewInjectedTag) != null) return true + view.setTag(viewInjectedTag, true) return false } @@ -108,7 +109,7 @@ class ChatActionMenu : AbstractMenu() { text = this@ChatActionMenu.context.translation["chat_action_menu.preview_button"] setOnClickListener { closeActionMenu() - this@ChatActionMenu.context.executeAsync { this@ChatActionMenu.context.feature(MediaDownloader::class).onMessageActionMenu(true) } + this@ChatActionMenu.context.executeAsync { feature(MediaDownloader::class).onMessageActionMenu(true) } } }) @@ -117,9 +118,7 @@ class ChatActionMenu : AbstractMenu() { setOnClickListener { closeActionMenu() this@ChatActionMenu.context.executeAsync { - this@ChatActionMenu.context.feature( - MediaDownloader::class - ).onMessageActionMenu(false) + feature(MediaDownloader::class).onMessageActionMenu(false) } } }) @@ -132,8 +131,8 @@ class ChatActionMenu : AbstractMenu() { setOnClickListener { closeActionMenu() this@ChatActionMenu.context.executeAsync { - with(this@ChatActionMenu.context.feature(Messaging::class)) { - context.feature(MessageLogger::class).deleteMessage(openedConversationUUID.toString(), lastFocusedMessageId) + feature(Messaging::class).apply { + feature(MessageLogger::class).deleteMessage(openedConversationUUID.toString(), lastFocusedMessageId) } } } diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/ui/menu/impl/FriendFeedInfoMenu.kt b/core/src/main/kotlin/me/rhunk/snapenhance/ui/menu/impl/FriendFeedInfoMenu.kt index 21a069f8..94ea8bb1 100644 --- a/core/src/main/kotlin/me/rhunk/snapenhance/ui/menu/impl/FriendFeedInfoMenu.kt +++ b/core/src/main/kotlin/me/rhunk/snapenhance/ui/menu/impl/FriendFeedInfoMenu.kt @@ -164,9 +164,7 @@ class FriendFeedInfoMenu : AbstractMenu() { ) { dialog: DialogInterface, _: Int -> dialog.dismiss() } targetPerson?.let { builder.setNegativeButton(context.translation["modal_option.profile_info"]) { _, _ -> - context.executeAsync { - showProfileInfo(it) - } + context.executeAsync { showProfileInfo(it) } } } builder.show() diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/ui/menu/impl/MenuViewInjector.kt b/core/src/main/kotlin/me/rhunk/snapenhance/ui/menu/impl/MenuViewInjector.kt index bd2002ea..89f91660 100644 --- a/core/src/main/kotlin/me/rhunk/snapenhance/ui/menu/impl/MenuViewInjector.kt +++ b/core/src/main/kotlin/me/rhunk/snapenhance/ui/menu/impl/MenuViewInjector.kt @@ -7,7 +7,7 @@ import android.view.ViewGroup import android.widget.FrameLayout import android.widget.LinearLayout import me.rhunk.snapenhance.Constants -import me.rhunk.snapenhance.core.eventbus.events.impl.AddViewEvent +import me.rhunk.snapenhance.core.event.events.impl.AddViewEvent import me.rhunk.snapenhance.features.Feature import me.rhunk.snapenhance.features.FeatureLoadParams import me.rhunk.snapenhance.features.impl.Messaging