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:
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