feat: immersive camera preview

This commit is contained in:
rhunk 2023-06-11 01:04:35 +02:00
parent fd3e7e416e
commit bbfc0a8350
5 changed files with 47 additions and 11 deletions

View File

@ -61,6 +61,7 @@
"hide_ui_elements": "Hide UI Elements",
"auto_updater": "Auto Updater",
"disable_camera": "Disable Camera",
"immersive_camera_preview": "Immersive Camera Preview",
"infinite_story_boost": "Infinite Story Boost",
"enable_app_appearance": "Enable App Appearance Settings",
"disable_spotlight": "Disable Spotlight",

View File

@ -183,6 +183,12 @@ enum class ConfigProperty(
ConfigCategory.UI_TWEAKS,
ConfigStateValue(false)
),
IMMERSIVE_CAMERA_PREVIEW(
"property.immersive_camera_preview",
"description.immersive_camera_preview",
ConfigCategory.UI_TWEAKS,
ConfigStateValue(false)
),
HIDE_UI_ELEMENTS(
"property.hide_ui_elements",
"description.hide_ui_elements",

View File

@ -15,10 +15,15 @@ import me.rhunk.snapenhance.hook.hook
class UITweaks : Feature("UITweaks", loadParams = FeatureLoadParams.ACTIVITY_CREATE_SYNC) {
@SuppressLint("DiscouragedApi")
override fun onActivityCreate() {
val hiddenElements = context.config.options(ConfigProperty.HIDE_UI_ELEMENTS)
val isImmersiveCamera = context.config.bool(ConfigProperty.IMMERSIVE_CAMERA_PREVIEW)
val resources = context.resources
val capriViewfinderDefaultCornerRadius = context.resources.getIdentifier("capri_viewfinder_default_corner_radius", "dimen", Constants.SNAPCHAT_PACKAGE_NAME)
val ngsHovaNavLargerCameraButtonSize = context.resources.getIdentifier("ngs_hova_nav_larger_camera_button_size", "dimen", Constants.SNAPCHAT_PACKAGE_NAME)
val displayMetrics = context.resources.displayMetrics
val capriViewfinderDefaultCornerRadius = resources.getIdentifier("capri_viewfinder_default_corner_radius", "dimen", Constants.SNAPCHAT_PACKAGE_NAME)
val ngsHovaNavLargerCameraButtonSize = resources.getIdentifier("ngs_hova_nav_larger_camera_button_size", "dimen", Constants.SNAPCHAT_PACKAGE_NAME)
val fullScreenSurfaceView = resources.getIdentifier("full_screen_surface_view", "id", Constants.SNAPCHAT_PACKAGE_NAME)
val callButtonsStub = resources.getIdentifier("call_buttons_stub", "id", Constants.SNAPCHAT_PACKAGE_NAME)
val callButton1 = resources.getIdentifier("friend_action_button3", "id", Constants.SNAPCHAT_PACKAGE_NAME)
@ -27,11 +32,10 @@ class UITweaks : Feature("UITweaks", loadParams = FeatureLoadParams.ACTIVITY_CRE
val chatNoteRecordButton = resources.getIdentifier("chat_note_record_button", "id", Constants.SNAPCHAT_PACKAGE_NAME)
val chatInputBarSticker = resources.getIdentifier("chat_input_bar_sticker", "id", Constants.SNAPCHAT_PACKAGE_NAME)
val chatInputBarCognac = resources.getIdentifier("chat_input_bar_cognac", "id", Constants.SNAPCHAT_PACKAGE_NAME)
val hiddenElements = context.config.options(ConfigProperty.HIDE_UI_ELEMENTS)
Resources::class.java.methods.first { it.name == "getDimensionPixelSize"}.hook(HookStage.AFTER, {
hiddenElements["remove_camera_borders"] == true
}) { param ->
Resources::class.java.methods.first { it.name == "getDimensionPixelSize"}.hook(HookStage.AFTER,
{ isImmersiveCamera }
) { param ->
val id = param.arg<Int>(0)
if (id == capriViewfinderDefaultCornerRadius || id == ngsHovaNavLargerCameraButtonSize) {
param.setResult(0)
@ -49,17 +53,21 @@ class UITweaks : Feature("UITweaks", loadParams = FeatureLoadParams.ACTIVITY_CRE
}
}
//TODO: use the event bus to dispatch a addView event
val addViewMethod = ViewGroup::class.java.getMethod(
ViewGroup::class.java.getMethod(
"addView",
View::class.java,
Int::class.javaPrimitiveType,
ViewGroup.LayoutParams::class.java
)
Hooker.hook(addViewMethod, HookStage.BEFORE) { param ->
).hook(HookStage.BEFORE) { param ->
val view: View = param.arg(0)
val viewId = view.id
if (isImmersiveCamera && view.id == fullScreenSurfaceView) {
Hooker.hookObjectMethod(View::class.java, view, "layout", HookStage.BEFORE) { param ->
param.setArg(3, displayMetrics.heightPixels)
}
}
if (viewId == chatNoteRecordButton && hiddenElements["remove_voice_record_button"] == true) {
view.isEnabled = false
view.setWillNotDraw(true)

View File

@ -13,6 +13,10 @@ class HookAdapter(
return methodHookParam.thisObject as T
}
fun <T : Any> nullableThisObject(): T? {
return methodHookParam.thisObject as T?
}
fun method(): Member {
return methodHookParam.method
}

View File

@ -75,6 +75,23 @@ object Hooker {
XposedBridge.hookAllConstructors(clazz, newMethodHook(stage, consumer, filter))
}
fun hookObjectMethod(
clazz: Class<*>,
instance: Any,
methodName: String,
stage: HookStage,
hookConsumer: (HookAdapter) -> Unit
) {
val unhooks: MutableSet<XC_MethodHook.Unhook> = HashSet()
hook(clazz, methodName, stage) { param->
if (param.nullableThisObject<Any>().let {
if (it == null) unhooks.forEach { u -> u.unhook() }
it != instance
}) return@hook
hookConsumer(param)
}.also { unhooks.addAll(it) }
}
fun ephemeralHookObjectMethod(
clazz: Class<*>,
instance: Any,
@ -84,7 +101,7 @@ object Hooker {
) {
val unhooks: MutableSet<XC_MethodHook.Unhook> = HashSet()
hook(clazz, methodName, stage) { param->
if (param.thisObject<Any>() != instance) return@hook
if (param.nullableThisObject<Any>() != instance) return@hook
hookConsumer(param)
unhooks.forEach{ it.unhook() }
}.also { unhooks.addAll(it) }