mirror of
https://github.com/inotia00/revanced-patches.git
synced 2025-06-12 05:07:41 +02:00
feat(YouTube): Add Change form factor
, Remove Change layout
patch
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
package app.revanced.patches.youtube.general.layoutswitch
|
||||
package app.revanced.patches.youtube.general.formfactor
|
||||
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
@ -6,30 +6,37 @@ import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patches.shared.createPlayerRequestBodyWithModelFingerprint
|
||||
import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
||||
import app.revanced.patches.youtube.utils.extension.Constants.GENERAL_PATH
|
||||
import app.revanced.patches.youtube.utils.patch.PatchList.CHANGE_LAYOUT
|
||||
import app.revanced.patches.youtube.utils.navigation.hookNavigationButtonCreated
|
||||
import app.revanced.patches.youtube.utils.navigation.navigationBarHookPatch
|
||||
import app.revanced.patches.youtube.utils.patch.PatchList.CHANGE_FORM_FACTOR
|
||||
import app.revanced.patches.youtube.utils.playertype.playerTypeHookPatch
|
||||
import app.revanced.patches.youtube.utils.settings.ResourceUtils.addPreference
|
||||
import app.revanced.patches.youtube.utils.settings.settingsPatch
|
||||
import app.revanced.util.fingerprint.definingClassOrThrow
|
||||
import app.revanced.util.fingerprint.matchOrThrow
|
||||
import app.revanced.util.fingerprint.methodOrThrow
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||
|
||||
private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
"$GENERAL_PATH/LayoutSwitchPatch;"
|
||||
"$GENERAL_PATH/ChangeFormFactorPatch;"
|
||||
|
||||
@Suppress("unused")
|
||||
val layoutSwitchPatch = bytecodePatch(
|
||||
CHANGE_LAYOUT.title,
|
||||
CHANGE_LAYOUT.summary,
|
||||
val changeFormFactorPatch = bytecodePatch(
|
||||
CHANGE_FORM_FACTOR.title,
|
||||
CHANGE_FORM_FACTOR.summary,
|
||||
) {
|
||||
compatibleWith(COMPATIBLE_PACKAGE)
|
||||
|
||||
dependsOn(settingsPatch)
|
||||
dependsOn(
|
||||
settingsPatch,
|
||||
playerTypeHookPatch,
|
||||
navigationBarHookPatch,
|
||||
)
|
||||
|
||||
execute {
|
||||
|
||||
@ -53,27 +60,31 @@ val layoutSwitchPatch = bytecodePatch(
|
||||
)
|
||||
}
|
||||
|
||||
layoutSwitchFingerprint.methodOrThrow().apply {
|
||||
val index = indexOfFirstInstructionReversedOrThrow(Opcode.IF_NEZ)
|
||||
val register = getInstruction<OneRegisterInstruction>(index).registerA
|
||||
widthDpUIFingerprint.matchOrThrow().let {
|
||||
it.method.apply {
|
||||
val index = it.patternMatch!!.startIndex
|
||||
val register = getInstruction<OneRegisterInstruction>(index).registerA
|
||||
|
||||
addInstructions(
|
||||
index, """
|
||||
invoke-static {v$register}, $EXTENSION_CLASS_DESCRIPTOR->getWidthDp(I)I
|
||||
move-result v$register
|
||||
"""
|
||||
)
|
||||
addInstructions(
|
||||
index, """
|
||||
invoke-static {v$register}, $EXTENSION_CLASS_DESCRIPTOR->getWidthDp(I)I
|
||||
move-result v$register
|
||||
"""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
hookNavigationButtonCreated(EXTENSION_CLASS_DESCRIPTOR)
|
||||
|
||||
// region add settings
|
||||
|
||||
addPreference(
|
||||
arrayOf(
|
||||
"PREFERENCE_SCREEN: GENERAL",
|
||||
"PREFERENCE_CATEGORY: GENERAL_EXPERIMENTAL_FLAGS",
|
||||
"SETTINGS: CHANGE_LAYOUT"
|
||||
"SETTINGS: CHANGE_FORM_FACTOR"
|
||||
),
|
||||
CHANGE_LAYOUT
|
||||
CHANGE_FORM_FACTOR
|
||||
)
|
||||
|
||||
// endregion
|
@ -1,4 +1,4 @@
|
||||
package app.revanced.patches.youtube.general.layoutswitch
|
||||
package app.revanced.patches.youtube.general.formfactor
|
||||
|
||||
import app.revanced.util.fingerprint.legacyFingerprint
|
||||
import app.revanced.util.or
|
||||
@ -11,20 +11,16 @@ internal val formFactorEnumConstructorFingerprint = legacyFingerprint(
|
||||
strings = listOf(
|
||||
"UNKNOWN_FORM_FACTOR",
|
||||
"SMALL_FORM_FACTOR",
|
||||
"LARGE_FORM_FACTOR"
|
||||
"LARGE_FORM_FACTOR",
|
||||
"AUTOMOTIVE_FORM_FACTOR",
|
||||
)
|
||||
)
|
||||
|
||||
internal val layoutSwitchFingerprint = legacyFingerprint(
|
||||
name = "layoutSwitchFingerprint",
|
||||
internal val widthDpUIFingerprint = legacyFingerprint(
|
||||
name = "widthDpUIFingerprint",
|
||||
returnType = "I",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
|
||||
parameters = listOf("L"),
|
||||
opcodes = listOf(
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.INVOKE_STATIC,
|
||||
Opcode.MOVE_RESULT,
|
||||
Opcode.IF_NEZ,
|
||||
Opcode.CONST_4,
|
||||
Opcode.RETURN,
|
||||
@ -41,6 +37,11 @@ internal val layoutSwitchFingerprint = legacyFingerprint(
|
||||
Opcode.CONST_4,
|
||||
Opcode.RETURN,
|
||||
Opcode.CONST_4,
|
||||
Opcode.RETURN
|
||||
Opcode.RETURN,
|
||||
),
|
||||
literals = listOf(
|
||||
480L,
|
||||
600L,
|
||||
720L
|
||||
)
|
||||
)
|
@ -109,8 +109,7 @@ val navigationBarHookPatch = bytecodePatch(
|
||||
hookNavigationButtonCreated = { extensionClassDescriptor ->
|
||||
navigationBarHookCallbackFingerprint.methodOrThrow().addInstruction(
|
||||
0,
|
||||
"invoke-static { p0, p1 }, " +
|
||||
"$extensionClassDescriptor->navigationTabCreated" +
|
||||
"invoke-static { p0, p1 }, $extensionClassDescriptor->navigationTabCreated" +
|
||||
"(${EXTENSION_NAVIGATION_BUTTON_DESCRIPTOR}Landroid/view/View;)V",
|
||||
)
|
||||
}
|
||||
|
@ -21,9 +21,9 @@ internal enum class PatchList(
|
||||
"Bypass URL redirects",
|
||||
"Adds an option to bypass URL redirects and open the original URL directly."
|
||||
),
|
||||
CHANGE_LAYOUT(
|
||||
"Change layout",
|
||||
"Adds an option to change the dp in order to use a tablet or phone layout."
|
||||
CHANGE_FORM_FACTOR(
|
||||
"Change form factor",
|
||||
"Adds an option to change the UI appearance to a phone, tablet, or automotive device."
|
||||
),
|
||||
CHANGE_LIVE_RING_CLICK_ACTION(
|
||||
"Change live ring click action",
|
||||
|
@ -1,6 +1,7 @@
|
||||
package app.revanced.patches.youtube.utils.playertype
|
||||
|
||||
import app.revanced.patches.youtube.utils.resourceid.reelWatchPlayer
|
||||
import app.revanced.patches.youtube.utils.resourceid.toolbarContainerId
|
||||
import app.revanced.util.fingerprint.legacyFingerprint
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstruction
|
||||
@ -9,6 +10,7 @@ import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.Method
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
import com.android.tools.smali.dexlib2.iface.reference.TypeReference
|
||||
|
||||
internal val browseIdClassFingerprint = legacyFingerprint(
|
||||
name = "browseIdClassFingerprint",
|
||||
@ -61,6 +63,34 @@ internal val searchQueryClassFingerprint = legacyFingerprint(
|
||||
}
|
||||
)
|
||||
|
||||
internal val toolbarLayoutFingerprint = legacyFingerprint(
|
||||
name = "toolbarLayoutFingerprint",
|
||||
literals = listOf(toolbarContainerId),
|
||||
customFingerprint = { method, _ ->
|
||||
method.name == "<init>" &&
|
||||
indexOfMainCollapsingToolbarLayoutInstruction(method) >= 0
|
||||
}
|
||||
)
|
||||
|
||||
internal fun indexOfMainCollapsingToolbarLayoutInstruction(method: Method) =
|
||||
method.indexOfFirstInstruction {
|
||||
opcode == Opcode.CHECK_CAST &&
|
||||
getReference<TypeReference>()?.type == "Lcom/google/android/apps/youtube/app/ui/actionbar/MainCollapsingToolbarLayout;"
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches to https://android.googlesource.com/platform/frameworks/support/+/9eee6ba/v7/appcompat/src/android/support/v7/widget/Toolbar.java#963
|
||||
*/
|
||||
internal val appCompatToolbarBackButtonFingerprint = legacyFingerprint(
|
||||
name = "appCompatToolbarBackButtonFingerprint",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
returnType = "Landroid/graphics/drawable/Drawable;",
|
||||
parameters = emptyList(),
|
||||
customFingerprint = { _, classDef ->
|
||||
classDef.type == "Landroid/support/v7/widget/Toolbar;"
|
||||
},
|
||||
)
|
||||
|
||||
internal val videoStateFingerprint = legacyFingerprint(
|
||||
name = "videoStateFingerprint",
|
||||
returnType = "V",
|
||||
|
@ -5,6 +5,7 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.patch.PatchException
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
|
||||
import app.revanced.patches.shared.litho.addLithoFilter
|
||||
import app.revanced.patches.shared.litho.lithoFilterPatch
|
||||
import app.revanced.patches.youtube.utils.extension.Constants.COMPONENTS_PATH
|
||||
@ -21,10 +22,13 @@ import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstLiteralInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstStringInstructionOrThrow
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
|
||||
|
||||
private const val EXTENSION_PLAYER_TYPE_HOOK_CLASS_DESCRIPTOR =
|
||||
"$UTILS_PATH/PlayerTypeHookPatch;"
|
||||
@ -32,6 +36,9 @@ private const val EXTENSION_PLAYER_TYPE_HOOK_CLASS_DESCRIPTOR =
|
||||
private const val EXTENSION_ROOT_VIEW_HOOK_CLASS_DESCRIPTOR =
|
||||
"$SHARED_PATH/RootView;"
|
||||
|
||||
private const val EXTENSION_ROOT_VIEW_TOOLBAR_INTERFACE =
|
||||
"$SHARED_PATH/RootView${'$'}AppCompatToolbarPatchInterface;"
|
||||
|
||||
private const val FILTER_CLASS_DESCRIPTOR =
|
||||
"$COMPONENTS_PATH/RelatedVideoFilter;"
|
||||
|
||||
@ -165,6 +172,53 @@ val playerTypeHookPatch = bytecodePatch(
|
||||
|
||||
// endregion
|
||||
|
||||
// region patch for hook back button visibility
|
||||
|
||||
toolbarLayoutFingerprint.methodOrThrow().apply {
|
||||
val index = indexOfMainCollapsingToolbarLayoutInstruction(this)
|
||||
val register = getInstruction<OneRegisterInstruction>(index).registerA
|
||||
|
||||
addInstruction(
|
||||
index + 1,
|
||||
"invoke-static { v$register }, $EXTENSION_ROOT_VIEW_HOOK_CLASS_DESCRIPTOR->setToolbar(Landroid/widget/FrameLayout;)V"
|
||||
)
|
||||
}
|
||||
|
||||
// Add interface for extensions code to call obfuscated methods.
|
||||
appCompatToolbarBackButtonFingerprint.matchOrThrow().let {
|
||||
it.classDef.apply {
|
||||
interfaces.add(EXTENSION_ROOT_VIEW_TOOLBAR_INTERFACE)
|
||||
|
||||
val definingClass = type
|
||||
val obfuscatedMethodName = it.originalMethod.name
|
||||
val returnType = "Landroid/graphics/drawable/Drawable;"
|
||||
|
||||
methods.add(
|
||||
ImmutableMethod(
|
||||
definingClass,
|
||||
"patch_getToolbarIcon",
|
||||
listOf(),
|
||||
returnType,
|
||||
AccessFlags.PUBLIC.value or AccessFlags.FINAL.value,
|
||||
null,
|
||||
null,
|
||||
MutableMethodImplementation(2),
|
||||
).toMutable().apply {
|
||||
addInstructions(
|
||||
0,
|
||||
"""
|
||||
invoke-virtual { p0 }, $definingClass->$obfuscatedMethodName()$returnType
|
||||
move-result-object v0
|
||||
return-object v0
|
||||
"""
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
addLithoFilter(FILTER_CLASS_DESCRIPTOR)
|
||||
}
|
||||
}
|
||||
|
@ -213,6 +213,8 @@ var tapBloomView = -1L
|
||||
private set
|
||||
var titleAnchor = -1L
|
||||
private set
|
||||
var toolbarContainerId = -1L
|
||||
private set
|
||||
var toolTipContentView = -1L
|
||||
private set
|
||||
var totalTime = -1L
|
||||
@ -656,6 +658,10 @@ internal val sharedResourceIdPatch = resourcePatch(
|
||||
ID,
|
||||
"title_anchor"
|
||||
]
|
||||
toolbarContainerId = resourceMappings[
|
||||
ID,
|
||||
"toolbar_container"
|
||||
]
|
||||
toolTipContentView = resourceMappings[
|
||||
LAYOUT,
|
||||
"tooltip_content_view"
|
||||
|
Reference in New Issue
Block a user