commit 0688c276bb990cf77cc16a7acbde22a232cee943
parent a633f913d3a77add7259eea6ea4dd3a08e3315f6
Author: rhunk <101876869+rhunk@users.noreply.github.com>
Date:   Wed,  5 Jun 2024 18:57:21 +0200

fix(better_location): suspend location updates

Signed-off-by: rhunk <101876869+rhunk@users.noreply.github.com>

Diffstat:
Mapp/src/main/kotlin/me/rhunk/snapenhance/ui/manager/pages/location/BetterLocationRoot.kt | 53++++++++++++++++++++++++++++++++++++-----------------
Mcommon/src/main/assets/lang/en_US.json | 8+++-----
Mcommon/src/main/kotlin/me/rhunk/snapenhance/common/bridge/BridgeFiles.kt | 1-
Mcommon/src/main/kotlin/me/rhunk/snapenhance/common/config/impl/Global.kt | 4++--
Mcore/src/main/kotlin/me/rhunk/snapenhance/core/features/FeatureManager.kt | 1-
Mcore/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/experiments/BetterLocation.kt | 32++++++++++++++------------------
Dcore/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/global/SuspendLocationUpdates.kt | 47-----------------------------------------------
7 files changed, 55 insertions(+), 91 deletions(-)

diff --git a/app/src/main/kotlin/me/rhunk/snapenhance/ui/manager/pages/location/BetterLocationRoot.kt b/app/src/main/kotlin/me/rhunk/snapenhance/ui/manager/pages/location/BetterLocationRoot.kt @@ -255,6 +255,42 @@ class BetterLocationRoot : Routes.Route() { .fillMaxSize() .clipToBounds() ) { + + item { + @Composable + fun ConfigToggle( + text: String, + state: MutableState<Boolean>, + onCheckedChange: (Boolean) -> Unit + ) { + Row( + modifier = Modifier.padding(start = 16.dp, end = 16.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Text(text = text) + Spacer(modifier = Modifier.weight(1f)) + Switch( + checked = state.value, + onCheckedChange = { + state.value = it + onCheckedChange(it) + } + ) + } + } + ConfigToggle( + translation["spoof_location_toggle"], + remember { mutableStateOf(context.config.root.global.betterLocation.spoofLocation.get()) } + ) { + context.config.root.global.betterLocation.spoofLocation.set(it) + } + ConfigToggle( + translation["suspend_location_updates"], + remember { mutableStateOf(context.config.root.global.betterLocation.suspendLocationUpdates.get()) } + ) { + context.config.root.global.betterLocation.suspendLocationUpdates.set(it) + } + } item { Row( modifier = Modifier @@ -273,23 +309,6 @@ class BetterLocationRoot : Routes.Route() { } item { Row( - modifier = Modifier.padding(start = 16.dp, end = 16.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Text(text = translation["spoof_location_toggle"]) - Spacer(modifier = Modifier.weight(1f)) - var isSpoofing by remember { mutableStateOf(context.config.root.global.betterLocation.spoofLocation.get()) } - Switch( - checked = isSpoofing, - onCheckedChange = { - isSpoofing = it - context.config.root.global.betterLocation.spoofLocation.set(it) - } - ) - } - } - item { - Row( modifier = Modifier .fillMaxWidth() .padding(start = 12.dp, end = 12.dp), diff --git a/common/src/main/assets/lang/en_US.json b/common/src/main/assets/lang/en_US.json @@ -150,7 +150,7 @@ "no_files_hint": "Here you can import files for use in Snapchat. Press the button below to import a file." }, "better_location": { - "spoofed_coordinates_title": "Spoofed Coordinates\nLat {latitude}, Lng {longitude}", + "spoofed_coordinates_title": "Lat {latitude}, Lng {longitude}", "save_coordinates_dialog_title": "Save Coordinates", "saved_name_dialog_hint": "Saved Name", "latitude_dialog_hint": "Latitude", @@ -159,6 +159,7 @@ "choose_location_button": "Choose Location", "teleport_to_friend_button": "Teleport to Friend", "spoof_location_toggle": "Spoof Location", + "suspend_location_updates": "Suspend Location Updates", "saved_coordinates_title": "Saved Coordinates", "no_saved_coordinates_hint": "No saved coordinates", "delete_dialog_title": "Delete Saved Coordinate", @@ -778,7 +779,7 @@ }, "suspend_location_updates": { "name": "Suspend Location Updates", - "description": "Adds a button in map settings to suspend location updates" + "description": "Prevents your location from being updated" }, "spoof_battery_level": { "name": "Spoof Battery Level", @@ -1624,9 +1625,6 @@ "bitmoji_scene_changed": "{username} has changed their Bitmoji scene" }, - "suspend_location_updates": { - "switch_text": "Suspend Location Updates" - }, "material3_strings": { "date_range_picker_start_headline": "From", "date_range_picker_end_headline": "To", diff --git a/common/src/main/kotlin/me/rhunk/snapenhance/common/bridge/BridgeFiles.kt b/common/src/main/kotlin/me/rhunk/snapenhance/common/bridge/BridgeFiles.kt @@ -30,7 +30,6 @@ enum class InternalFileHandleType( CONFIG("config", "config.json"), MAPPINGS("mappings", "mappings.json"), MESSAGE_LOGGER("message_logger", "message_logger.db", isDatabase = true), - SUSPEND_LOCATION_STATE("suspend_location_state", "suspend_location_state.txt"), PINNED_BEST_FRIEND("pinned_best_friend", "pinned_best_friend.txt"); diff --git a/common/src/main/kotlin/me/rhunk/snapenhance/common/config/impl/Global.kt b/common/src/main/kotlin/me/rhunk/snapenhance/common/config/impl/Global.kt @@ -20,11 +20,11 @@ class Global : ConfigContainer() { } inner class BetterLocationConfig : ConfigContainer(hasGlobalState = true) { - val spoofLocation = boolean("spoof_location") { requireRestart() } + val spoofLocation = boolean("spoof_location") val coordinates = mapCoordinates("coordinates", 0.0 to 0.0) { addFlags(ConfigFlag.SENSITIVE) } // lat, long val walkRadius = string("walk_radius") { requireRestart(); inputCheck = { it.toDoubleOrNull()?.isFinite() == true && it.toDouble() >= 0.0 } } val alwaysUpdateLocation = boolean("always_update_location") { requireRestart() } - val suspendLocationUpdates = boolean("suspend_location_updates") { requireRestart() } + val suspendLocationUpdates = boolean("suspend_location_updates") val spoofBatteryLevel = string("spoof_battery_level") { requireRestart(); inputCheck = { it.isEmpty() || it.toIntOrNull() in 0..100 } } val spoofHeadphones = boolean("spoof_headphones") { requireRestart() } } diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/features/FeatureManager.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/features/FeatureManager.kt @@ -107,7 +107,6 @@ class FeatureManager( MessageIndicators(), EditTextOverride(), PreventForcedLogout(), - SuspendLocationUpdates(), ConversationToolbox(), SpotlightCommentsUsername(), OperaViewerParamsOverride(), diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/experiments/BetterLocation.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/experiments/BetterLocation.kt @@ -26,7 +26,6 @@ import me.rhunk.snapenhance.core.event.events.impl.AddViewEvent import me.rhunk.snapenhance.core.event.events.impl.UnaryCallEvent import me.rhunk.snapenhance.core.features.Feature import me.rhunk.snapenhance.core.features.FeatureLoadParams -import me.rhunk.snapenhance.core.features.impl.global.SuspendLocationUpdates import me.rhunk.snapenhance.core.util.RandomWalking import me.rhunk.snapenhance.core.util.hook.HookStage import me.rhunk.snapenhance.core.util.hook.hook @@ -35,7 +34,6 @@ import me.rhunk.snapenhance.core.util.ktx.isDarkTheme import me.rhunk.snapenhance.mapper.impl.CallbackMapper import java.nio.ByteBuffer import java.util.UUID -import kotlin.time.Duration.Companion.days data class FriendLocation( val userId: String, @@ -91,11 +89,10 @@ class BetterLocation : Feature("Better Location", loadParams = FeatureLoadParams remove(7) addVarInt(7, System.currentTimeMillis()) // timestamp } + } - if (context.feature(SuspendLocationUpdates::class).isSuspended()) { - remove(7) - addVarInt(7, System.currentTimeMillis() - 15.days.inWholeMilliseconds) - } + if (context.config.global.betterLocation.suspendLocationUpdates.get()) { + remove(1) } // SCVSDeviceData @@ -172,19 +169,18 @@ class BetterLocation : Feature("Better Location", loadParams = FeatureLoadParams override fun init() { if (context.config.global.betterLocation.globalState != true) return - if (context.config.global.betterLocation.spoofLocation.get()) { - LocationManager::class.java.apply { - hook("isProviderEnabled", HookStage.BEFORE) { it.setResult(true) } - hook("isProviderEnabledForUser", HookStage.BEFORE) { it.setResult(true) } - } - Location::class.java.apply { - hook("getLatitude", HookStage.BEFORE) { it.setResult(getLat()) } - hook("getLongitude", HookStage.BEFORE) { it.setResult(getLong()) } - } + val canSpoofLocation = { context.config.global.betterLocation.spoofLocation.get() } + + LocationManager::class.java.apply { + hook("isProviderEnabled", HookStage.BEFORE, { canSpoofLocation() }) { it.setResult(true) } + hook("isProviderEnabledForUser", HookStage.BEFORE, { canSpoofLocation() }) { it.setResult(true) } + } + Location::class.java.apply { + hook("getLatitude", HookStage.BEFORE, { canSpoofLocation() }) { it.setResult(getLat()) } + hook("getLongitude", HookStage.BEFORE, { canSpoofLocation() }) { it.setResult(getLong()) } } val mapFeaturesRootId = context.resources.getId("map_features_root") - val mapLayerSelectorId = context.resources.getId("map_layer_selector") context.event.subscribe(AddViewEvent::class) { event -> if (event.view.id != mapFeaturesRootId) return@subscribe @@ -234,10 +230,10 @@ class BetterLocation : Feature("Better Location", loadParams = FeatureLoadParams context.mappings.useMapper(CallbackMapper::class) { callbacks.getClass("ServerStreamingEventHandler")?.hook("onEvent", HookStage.BEFORE) { param -> - val buffer = param.arg<ByteBuffer>(1).let { + val buffer = param.argNullable<ByteBuffer>(1)?.let { it.position(0) ByteArray(it.capacity()).also { buffer -> it.get(buffer); it.position(0) } - } + } ?: return@hook onLocationEvent(ProtoReader(buffer)) } } diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/global/SuspendLocationUpdates.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/global/SuspendLocationUpdates.kt @@ -1,46 +0,0 @@ -package me.rhunk.snapenhance.core.features.impl.global - -import android.view.ViewGroup -import android.widget.Switch -import me.rhunk.snapenhance.common.bridge.InternalFileHandleType -import me.rhunk.snapenhance.core.event.events.impl.LayoutInflateEvent -import me.rhunk.snapenhance.core.features.BridgeFileFeature -import me.rhunk.snapenhance.core.features.FeatureLoadParams -import me.rhunk.snapenhance.core.ui.ViewAppearanceHelper -import me.rhunk.snapenhance.core.util.ktx.getId -import me.rhunk.snapenhance.core.util.ktx.getLayoutId - -class SuspendLocationUpdates : BridgeFileFeature( - "Suspend Location Updates", - loadParams = FeatureLoadParams.ACTIVITY_CREATE_SYNC, bridgeFileType = InternalFileHandleType.SUSPEND_LOCATION_STATE) { - fun isSuspended() = exists("true") - private fun setSuspended(suspended: Boolean) = setState("true", suspended) - - override fun onActivityCreate() { - if (context.config.global.betterLocation.takeIf { it.globalState == true }?.suspendLocationUpdates?.get() != true) return - reload() - - val locationSharingSettingsContainerId = context.resources.getLayoutId("v3_screen_location_sharing_settings") - val recyclerViewContainerId = context.resources.getId("recycler_view_container") - - context.event.subscribe(LayoutInflateEvent::class) { event -> - if (event.layoutId != locationSharingSettingsContainerId) return@subscribe - val viewGroup = event.view as? ViewGroup ?: return@subscribe - viewGroup.post { - val container = viewGroup.findViewById<ViewGroup>(recyclerViewContainerId) - container.addView(Switch(event.view.context).apply { - isChecked = isSuspended() - ViewAppearanceHelper.applyTheme(this) - text = this@SuspendLocationUpdates.context.translation["suspend_location_updates.switch_text"] - layoutParams = ViewGroup.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.WRAP_CONTENT - ) - setOnCheckedChangeListener { _, isChecked -> - setSuspended(isChecked) - } - }) - } - } - } -}- \ No newline at end of file