fix(core): force upload source quality

- fix app experiment crash
- fix vertical story viewer
This commit is contained in:
rhunk 2023-11-24 22:20:06 +01:00
parent 571c2e6c4f
commit a5d63f96ca
5 changed files with 23 additions and 25 deletions

View File

@ -298,9 +298,9 @@
"name": "Hide Settings Gear", "name": "Hide Settings Gear",
"description": "Hides the SnapEnhance Settings Gear in friend feed" "description": "Hides the SnapEnhance Settings Gear in friend feed"
}, },
"story_viewer_override": { "vertical_story_viewer": {
"name": "Story Viewer Override", "name": "Vertical Story Viewer",
"description": "Turns on certain features which Snapchat hid" "description": "Enables the vertical story viewer for all stories"
}, },
"friend_feed_menu_buttons": { "friend_feed_menu_buttons": {
"name": "Friend Feed Menu Buttons", "name": "Friend Feed Menu Buttons",
@ -444,9 +444,9 @@
"name": "Disable Google Play Services Dialogs", "name": "Disable Google Play Services Dialogs",
"description": "Prevent Google Play Services availability dialogs from being shown" "description": "Prevent Google Play Services availability dialogs from being shown"
}, },
"force_media_source_quality": { "force_upload_source_quality": {
"name": "Force Media Source Quality", "name": "Force Upload Source Quality",
"description": "Forces Snapchat's Media Quality to the specified value" "description": "Forces Snapchat to upload media in the original quality\nPlease note that this may not remove metadata from media"
}, },
"disable_snap_splitting": { "disable_snap_splitting": {
"name": "Disable Snap Splitting", "name": "Disable Snap Splitting",
@ -714,11 +714,6 @@
"hide_stickers_button": "Remove Stickers Button", "hide_stickers_button": "Remove Stickers Button",
"hide_voice_record_button": "Remove Voice Record Button" "hide_voice_record_button": "Remove Voice Record Button"
}, },
"story_viewer_override": {
"OFF": "Off",
"DISCOVER_PLAYBACK_SEEKBAR": "Enable Discover Playback Seekbar",
"VERTICAL_STORY_VIEWER": "Enable Vertical Story Viewer"
},
"hide_story_sections": { "hide_story_sections": {
"hide_friend_suggestions": "Hide friend suggestions", "hide_friend_suggestions": "Hide friend suggestions",
"hide_friends": "Hide friends section", "hide_friends": "Hide friends section",

View File

@ -16,6 +16,6 @@ class Global : ConfigContainer() {
val bypassVideoLengthRestriction = unique("bypass_video_length_restriction", "split", "single") { addNotices( val bypassVideoLengthRestriction = unique("bypass_video_length_restriction", "split", "single") { addNotices(
FeatureNotice.BAN_RISK); requireRestart(); nativeHooks() } FeatureNotice.BAN_RISK); requireRestart(); nativeHooks() }
val disableGooglePlayDialogs = boolean("disable_google_play_dialogs") { requireRestart() } val disableGooglePlayDialogs = boolean("disable_google_play_dialogs") { requireRestart() }
val forceMediaSourceQuality = boolean("force_media_source_quality") val forceUploadSourceQuality = boolean("force_upload_source_quality") { requireRestart() }
val disableSnapSplitting = boolean("disable_snap_splitting") { addNotices(FeatureNotice.INTERNAL_BEHAVIOR) } val disableSnapSplitting = boolean("disable_snap_splitting") { addNotices(FeatureNotice.INTERNAL_BEHAVIOR) }
} }

View File

@ -46,5 +46,5 @@ class UserInterfaceTweaks : ConfigContainer() {
val oldBitmojiSelfie = unique("old_bitmoji_selfie", "2d", "3d") { requireCleanCache() } val oldBitmojiSelfie = unique("old_bitmoji_selfie", "2d", "3d") { requireCleanCache() }
val disableSpotlight = boolean("disable_spotlight") { requireRestart() } val disableSpotlight = boolean("disable_spotlight") { requireRestart() }
val hideSettingsGear = boolean("hide_settings_gear") { requireRestart() } val hideSettingsGear = boolean("hide_settings_gear") { requireRestart() }
val storyViewerOverride = unique("story_viewer_override", "DISCOVER_PLAYBACK_SEEKBAR", "VERTICAL_STORY_VIEWER") { requireRestart() } val verticalStoryViewer = boolean("vertical_story_viewer") { requireRestart() }
} }

View File

@ -15,6 +15,12 @@ data class ConfigKeyInfo(
val defaultValue: Any? val defaultValue: Any?
) )
data class ConfigFilter(
val filter: (ConfigKeyInfo) -> Boolean,
val defaultValue: Any?,
val isAppExperiment: Boolean = false
)
class ConfigurationOverride : Feature("Configuration Override", loadParams = FeatureLoadParams.INIT_SYNC) { class ConfigurationOverride : Feature("Configuration Override", loadParams = FeatureLoadParams.INIT_SYNC) {
override fun init() { override fun init() {
val compositeConfigurationProviderMappings = context.mappings.getMappedMap("CompositeConfigurationProvider") val compositeConfigurationProviderMappings = context.mappings.getMappedMap("CompositeConfigurationProvider")
@ -32,23 +38,20 @@ class ConfigurationOverride : Feature("Configuration Override", loadParams = Fea
context.log.error("Failed to get config key info", it) context.log.error("Failed to get config key info", it)
}.getOrNull() }.getOrNull()
val propertyOverrides = mutableMapOf<String, Pair<((ConfigKeyInfo) -> Boolean), Any>>() val propertyOverrides = mutableMapOf<String, ConfigFilter>()
fun overrideProperty(key: String, filter: (ConfigKeyInfo) -> Boolean, value: Any) { fun overrideProperty(key: String, filter: (ConfigKeyInfo) -> Boolean, value: Any, isAppExperiment: Boolean = false) {
propertyOverrides[key] = Pair(filter, value) propertyOverrides[key] = ConfigFilter(filter, value, isAppExperiment)
} }
overrideProperty("STREAK_EXPIRATION_INFO", { context.config.userInterface.streakExpirationInfo.get() }, true) overrideProperty("STREAK_EXPIRATION_INFO", { context.config.userInterface.streakExpirationInfo.get() }, true)
overrideProperty("TRANSCODING_MAX_QUALITY", { context.config.global.forceUploadSourceQuality.get() }, true, isAppExperiment = true)
overrideProperty("MEDIA_RECORDER_MAX_QUALITY_LEVEL", { context.config.camera.forceCameraSourceEncoding.get() }, true) overrideProperty("MEDIA_RECORDER_MAX_QUALITY_LEVEL", { context.config.camera.forceCameraSourceEncoding.get() }, true)
overrideProperty("REDUCE_MY_PROFILE_UI_COMPLEXITY", { context.config.userInterface.mapFriendNameTags.get() }, true) overrideProperty("REDUCE_MY_PROFILE_UI_COMPLEXITY", { context.config.userInterface.mapFriendNameTags.get() }, true)
overrideProperty("ENABLE_LONG_SNAP_SENDING", { context.config.global.disableSnapSplitting.get() }, true) overrideProperty("ENABLE_LONG_SNAP_SENDING", { context.config.global.disableSnapSplitting.get() }, true)
context.config.userInterface.storyViewerOverride.getNullable()?.let { state -> overrideProperty("DF_VOPERA_FOR_STORIES", { context.config.userInterface.verticalStoryViewer.get() }, true, isAppExperiment = true)
overrideProperty("DF_ENABLE_SHOWS_PAGE_CONTROLS", { state == "DISCOVER_PLAYBACK_SEEKBAR" }, true)
overrideProperty("DF_VOPERA_FOR_STORIES", { state == "VERTICAL_STORY_VIEWER" }, true)
}
overrideProperty("SPOTLIGHT_5TH_TAB_ENABLED", { context.config.userInterface.disableSpotlight.get() }, false) overrideProperty("SPOTLIGHT_5TH_TAB_ENABLED", { context.config.userInterface.disableSpotlight.get() }, false)
overrideProperty("BYPASS_AD_FEATURE_GATE", { context.config.global.blockAds.get() }, true) overrideProperty("BYPASS_AD_FEATURE_GATE", { context.config.global.blockAds.get() }, true)
@ -96,8 +99,8 @@ class ConfigurationOverride : Feature("Configuration Override", loadParams = Fea
param.setResult(true) param.setResult(true)
return@hook return@hook
} }
propertyOverrides[keyInfo.name]?.let { (filter, value) -> propertyOverrides[keyInfo.name]?.let { (filter, value, isAppExperiment) ->
if (!filter(keyInfo)) return@let if (!isAppExperiment || !filter(keyInfo)) return@let
param.setResult(value) param.setResult(value)
} }
} }
@ -122,7 +125,7 @@ class ConfigurationOverride : Feature("Configuration Override", loadParams = Fea
} }
val propertyOverride = propertyOverrides[keyInfo.name] ?: return@hook val propertyOverride = propertyOverrides[keyInfo.name] ?: return@hook
if (propertyOverride.first(keyInfo)) param.setResult(true) if (propertyOverride.isAppExperiment && propertyOverride.filter(keyInfo)) param.setResult(true)
} }
} }

View File

@ -10,7 +10,7 @@ class MediaQualityLevelOverride : Feature("MediaQualityLevelOverride", loadParam
val enumQualityLevel = context.mappings.getMappedClass("EnumQualityLevel") val enumQualityLevel = context.mappings.getMappedClass("EnumQualityLevel")
val mediaQualityLevelProvider = context.mappings.getMappedMap("MediaQualityLevelProvider") val mediaQualityLevelProvider = context.mappings.getMappedMap("MediaQualityLevelProvider")
val forceMediaSourceQuality by context.config.global.forceMediaSourceQuality val forceMediaSourceQuality by context.config.global.forceUploadSourceQuality
context.androidContext.classLoader.loadClass(mediaQualityLevelProvider["class"].toString()).hook( context.androidContext.classLoader.loadClass(mediaQualityLevelProvider["class"].toString()).hook(
mediaQualityLevelProvider["method"].toString(), mediaQualityLevelProvider["method"].toString(),