mirror of
https://github.com/revanced/revanced-patches.git
synced 2025-05-01 07:04:35 +02:00
feat(YouTube): Add Open Shorts in regular player
patch (#4153)
This commit is contained in:
parent
a4db3f1df7
commit
c7c5e5b2b9
@ -0,0 +1,94 @@
|
|||||||
|
package app.revanced.extension.youtube.patches;
|
||||||
|
|
||||||
|
import static app.revanced.extension.youtube.shared.NavigationBar.NavigationButton;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
|
import app.revanced.extension.shared.Logger;
|
||||||
|
import app.revanced.extension.youtube.settings.Settings;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public class OpenShortsInRegularPlayerPatch {
|
||||||
|
|
||||||
|
public enum ShortsPlayerType {
|
||||||
|
SHORTS_PLAYER,
|
||||||
|
REGULAR_PLAYER,
|
||||||
|
REGULAR_PLAYER_FULLSCREEN
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
if (!VersionCheckPatch.IS_19_46_OR_GREATER
|
||||||
|
&& Settings.SHORTS_PLAYER_TYPE.get() == ShortsPlayerType.REGULAR_PLAYER_FULLSCREEN) {
|
||||||
|
// User imported newer settings to an older app target.
|
||||||
|
Logger.printInfo(() -> "Resetting " + Settings.SHORTS_PLAYER_TYPE);
|
||||||
|
Settings.SHORTS_PLAYER_TYPE.resetToDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static WeakReference<Activity> mainActivityRef = new WeakReference<>(null);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injection point.
|
||||||
|
*/
|
||||||
|
public static void setMainActivity(Activity activity) {
|
||||||
|
mainActivityRef = new WeakReference<>(activity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injection point.
|
||||||
|
*/
|
||||||
|
public static boolean openShort(String videoID) {
|
||||||
|
try {
|
||||||
|
ShortsPlayerType type = Settings.SHORTS_PLAYER_TYPE.get();
|
||||||
|
if (type == ShortsPlayerType.SHORTS_PLAYER) {
|
||||||
|
return false; // Default unpatched behavior.
|
||||||
|
}
|
||||||
|
|
||||||
|
if (videoID.isEmpty()) {
|
||||||
|
// Shorts was opened using launcher app shortcut.
|
||||||
|
//
|
||||||
|
// This check will not detect if the Shorts app shortcut is used
|
||||||
|
// while the app is running in the background (instead the regular player is opened).
|
||||||
|
// To detect that the hooked method map parameter can be checked
|
||||||
|
// if integer key 'com.google.android.apps.youtube.app.endpoint.flags'
|
||||||
|
// has bitmask 16 set.
|
||||||
|
//
|
||||||
|
// This use case seems unlikely if the user has the Shorts
|
||||||
|
// set to open in the regular player, so it's ignored as
|
||||||
|
// checking the map makes the patch more complicated.
|
||||||
|
Logger.printDebug(() -> "Ignoring Short with no videoId");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NavigationButton.getSelectedNavigationButton() == NavigationButton.SHORTS) {
|
||||||
|
return false; // Always use Shorts player for the Shorts nav button.
|
||||||
|
}
|
||||||
|
|
||||||
|
final boolean forceFullScreen = (type == ShortsPlayerType.REGULAR_PLAYER_FULLSCREEN);
|
||||||
|
OpenVideosFullscreenHookPatch.setOpenNextVideoFullscreen(forceFullScreen);
|
||||||
|
|
||||||
|
// Can use the application context and add intent flags of
|
||||||
|
// FLAG_ACTIVITY_NEW_TASK and FLAG_ACTIVITY_CLEAR_TOP
|
||||||
|
// But the activity context seems to fix random app crashes
|
||||||
|
// if Shorts urls are opened outside the app.
|
||||||
|
var context = mainActivityRef.get();
|
||||||
|
|
||||||
|
Intent videoPlayerIntent = new Intent(
|
||||||
|
Intent.ACTION_VIEW,
|
||||||
|
Uri.parse("https://youtube.com/watch?v=" + videoID)
|
||||||
|
);
|
||||||
|
videoPlayerIntent.setPackage(context.getPackageName());
|
||||||
|
|
||||||
|
context.startActivity(videoPlayerIntent);
|
||||||
|
return true;
|
||||||
|
} catch (Exception ex) {
|
||||||
|
OpenVideosFullscreenHookPatch.setOpenNextVideoFullscreen(null);
|
||||||
|
Logger.printException(() -> "openShort failure", ex);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,14 +0,0 @@
|
|||||||
package app.revanced.extension.youtube.patches;
|
|
||||||
|
|
||||||
import app.revanced.extension.youtube.settings.Settings;
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public class OpenVideosFullscreen {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Injection point.
|
|
||||||
*/
|
|
||||||
public static boolean openVideoFullscreenPortrait(boolean original) {
|
|
||||||
return Settings.OPEN_VIDEOS_FULLSCREEN_PORTRAIT.get();
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,41 @@
|
|||||||
|
package app.revanced.extension.youtube.patches;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import app.revanced.extension.youtube.settings.Settings;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public class OpenVideosFullscreenHookPatch {
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private static volatile Boolean openNextVideoFullscreen;
|
||||||
|
|
||||||
|
public static void setOpenNextVideoFullscreen(@Nullable Boolean forceFullScreen) {
|
||||||
|
openNextVideoFullscreen = forceFullScreen;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changed during patching since this class is also
|
||||||
|
* used by {@link OpenVideosFullscreenHookPatch}.
|
||||||
|
*/
|
||||||
|
private static boolean isFullScreenPatchIncluded() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injection point.
|
||||||
|
*/
|
||||||
|
public static boolean openVideoFullscreenPortrait(boolean original) {
|
||||||
|
Boolean openFullscreen = openNextVideoFullscreen;
|
||||||
|
if (openFullscreen != null) {
|
||||||
|
openNextVideoFullscreen = null;
|
||||||
|
return openFullscreen;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isFullScreenPatchIncluded()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Settings.OPEN_VIDEOS_FULLSCREEN_PORTRAIT.get();
|
||||||
|
}
|
||||||
|
}
|
@ -9,4 +9,5 @@ public class VersionCheckPatch {
|
|||||||
public static final boolean IS_19_26_OR_GREATER = Utils.getAppVersionName().compareTo("19.26.00") >= 0;
|
public static final boolean IS_19_26_OR_GREATER = Utils.getAppVersionName().compareTo("19.26.00") >= 0;
|
||||||
public static final boolean IS_19_29_OR_GREATER = Utils.getAppVersionName().compareTo("19.29.00") >= 0;
|
public static final boolean IS_19_29_OR_GREATER = Utils.getAppVersionName().compareTo("19.29.00") >= 0;
|
||||||
public static final boolean IS_19_34_OR_GREATER = Utils.getAppVersionName().compareTo("19.34.00") >= 0;
|
public static final boolean IS_19_34_OR_GREATER = Utils.getAppVersionName().compareTo("19.34.00") >= 0;
|
||||||
|
public static final boolean IS_19_46_OR_GREATER = Utils.getAppVersionName().compareTo("19.46.00") >= 0;
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerT
|
|||||||
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType.MODERN_2;
|
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType.MODERN_2;
|
||||||
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType.MODERN_3;
|
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType.MODERN_3;
|
||||||
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType.MODERN_4;
|
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType.MODERN_4;
|
||||||
|
import static app.revanced.extension.youtube.patches.OpenShortsInRegularPlayerPatch.ShortsPlayerType;
|
||||||
import static app.revanced.extension.youtube.patches.SeekbarThumbnailsPatch.SeekbarThumbnailsHighQualityAvailability;
|
import static app.revanced.extension.youtube.patches.SeekbarThumbnailsPatch.SeekbarThumbnailsHighQualityAvailability;
|
||||||
import static app.revanced.extension.youtube.patches.VersionCheckPatch.IS_19_17_OR_GREATER;
|
import static app.revanced.extension.youtube.patches.VersionCheckPatch.IS_19_17_OR_GREATER;
|
||||||
import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.IGNORE;
|
import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.IGNORE;
|
||||||
@ -224,6 +225,7 @@ public class Settings extends BaseSettings {
|
|||||||
// Shorts
|
// Shorts
|
||||||
public static final BooleanSetting DISABLE_RESUMING_SHORTS_PLAYER = new BooleanSetting("revanced_disable_resuming_shorts_player", FALSE);
|
public static final BooleanSetting DISABLE_RESUMING_SHORTS_PLAYER = new BooleanSetting("revanced_disable_resuming_shorts_player", FALSE);
|
||||||
public static final BooleanSetting DISABLE_SHORTS_BACKGROUND_PLAYBACK = new BooleanSetting("revanced_shorts_disable_background_playback", FALSE);
|
public static final BooleanSetting DISABLE_SHORTS_BACKGROUND_PLAYBACK = new BooleanSetting("revanced_shorts_disable_background_playback", FALSE);
|
||||||
|
public static final EnumSetting<ShortsPlayerType> SHORTS_PLAYER_TYPE = new EnumSetting<>("revanced_shorts_player_type", ShortsPlayerType.SHORTS_PLAYER);
|
||||||
public static final BooleanSetting HIDE_SHORTS_CHANNEL_BAR = new BooleanSetting("revanced_hide_shorts_channel_bar", FALSE);
|
public static final BooleanSetting HIDE_SHORTS_CHANNEL_BAR = new BooleanSetting("revanced_hide_shorts_channel_bar", FALSE);
|
||||||
public static final BooleanSetting HIDE_SHORTS_COMMENTS_BUTTON = new BooleanSetting("revanced_hide_shorts_comments_button", FALSE);
|
public static final BooleanSetting HIDE_SHORTS_COMMENTS_BUTTON = new BooleanSetting("revanced_hide_shorts_comments_button", FALSE);
|
||||||
public static final BooleanSetting HIDE_SHORTS_DISLIKE_BUTTON = new BooleanSetting("revanced_hide_shorts_dislike_button", FALSE);
|
public static final BooleanSetting HIDE_SHORTS_DISLIKE_BUTTON = new BooleanSetting("revanced_hide_shorts_dislike_button", FALSE);
|
||||||
|
@ -1177,6 +1177,10 @@ public final class app/revanced/patches/youtube/layout/player/background/PlayerC
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/youtube/layout/player/fullscreen/OpenVideosFullscreenKt {
|
public final class app/revanced/patches/youtube/layout/player/fullscreen/OpenVideosFullscreenKt {
|
||||||
|
public static final fun getOpenVideosFullscreen ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class app/revanced/patches/youtube/layout/player/fullscreen/OpenVideosFullscreenPatchKt {
|
||||||
public static final fun getOpenVideosFullscreenPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getOpenVideosFullscreenPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1210,6 +1214,10 @@ public final class app/revanced/patches/youtube/layout/shortsautoplay/ShortsAuto
|
|||||||
public static final fun getShortsAutoplayPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getShortsAutoplayPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final class app/revanced/patches/youtube/layout/shortsplayer/OpenShortsInRegularPlayerPatchKt {
|
||||||
|
public static final fun getOpenShortsInRegularPlayerPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockPatchKt {
|
public final class app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockPatchKt {
|
||||||
public static final fun getSponsorBlockPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getSponsorBlockPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ package app.revanced.patches.shared.misc.checks
|
|||||||
|
|
||||||
import android.os.Build.*
|
import android.os.Build.*
|
||||||
import app.revanced.patcher.Fingerprint
|
import app.revanced.patcher.Fingerprint
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||||
import app.revanced.patcher.patch.Patch
|
import app.revanced.patcher.patch.Patch
|
||||||
import app.revanced.patcher.patch.bytecodePatch
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
import app.revanced.patcher.util.proxy.mutableTypes.encodedValue.MutableEncodedValue
|
import app.revanced.patcher.util.proxy.mutableTypes.encodedValue.MutableEncodedValue
|
||||||
@ -82,7 +82,7 @@ fun checkEnvironmentPatch(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun invokeCheck() = mainActivityOnCreateFingerprint.method.addInstructions(
|
fun invokeCheck() = mainActivityOnCreateFingerprint.method.addInstruction(
|
||||||
0,
|
0,
|
||||||
"invoke-static/range { p0 .. p0 },$EXTENSION_CLASS_DESCRIPTOR->check(Landroid/app/Activity;)V",
|
"invoke-static/range { p0 .. p0 },$EXTENSION_CLASS_DESCRIPTOR->check(Landroid/app/Activity;)V",
|
||||||
)
|
)
|
||||||
|
@ -14,3 +14,15 @@ internal val openVideosFullscreenPortraitFingerprint = fingerprint {
|
|||||||
OPEN_VIDEOS_FULLSCREEN_PORTRAIT_FEATURE_FLAG
|
OPEN_VIDEOS_FULLSCREEN_PORTRAIT_FEATURE_FLAG
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to enable opening regular videos fullscreen.
|
||||||
|
*/
|
||||||
|
internal val openVideosFullscreenHookPatchExtensionFingerprint = fingerprint {
|
||||||
|
accessFlags(AccessFlags.PRIVATE, AccessFlags.STATIC)
|
||||||
|
returns("Z")
|
||||||
|
parameters()
|
||||||
|
custom { methodDef, classDef ->
|
||||||
|
methodDef.name == "isFullScreenPatchIncluded" && classDef.type == EXTENSION_CLASS_DESCRIPTOR
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,46 +1,9 @@
|
|||||||
package app.revanced.patches.youtube.layout.player.fullscreen
|
package app.revanced.patches.youtube.layout.player.fullscreen
|
||||||
|
|
||||||
import app.revanced.patcher.patch.bytecodePatch
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
import app.revanced.patches.all.misc.resources.addResources
|
|
||||||
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
|
||||||
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
|
||||||
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
|
||||||
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
|
||||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
|
||||||
import app.revanced.util.insertFeatureFlagBooleanOverride
|
|
||||||
|
|
||||||
private const val EXTENSION_CLASS_DESCRIPTOR =
|
|
||||||
"Lapp/revanced/extension/youtube/patches/OpenVideosFullscreen;"
|
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
val openVideosFullscreenPatch = bytecodePatch(
|
@Deprecated("Renamed to openVideosFullscreenPatch", ReplaceWith("openVideosFullscreenPatch"))
|
||||||
name = "Open videos fullscreen",
|
val openVideosFullscreen = bytecodePatch{
|
||||||
description = "Adds an option to open videos in full screen portrait mode.",
|
dependsOn(openVideosFullscreenPatch)
|
||||||
) {
|
}
|
||||||
dependsOn(
|
|
||||||
sharedExtensionPatch,
|
|
||||||
settingsPatch,
|
|
||||||
addResourcesPatch,
|
|
||||||
)
|
|
||||||
|
|
||||||
compatibleWith(
|
|
||||||
"com.google.android.youtube"(
|
|
||||||
"19.46.42",
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
execute {
|
|
||||||
openVideosFullscreenPortraitFingerprint.method.insertFeatureFlagBooleanOverride(
|
|
||||||
OPEN_VIDEOS_FULLSCREEN_PORTRAIT_FEATURE_FLAG,
|
|
||||||
"$EXTENSION_CLASS_DESCRIPTOR->openVideoFullscreenPortrait(Z)Z"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Add resources and setting last, in case the user force patches an old incompatible version.
|
|
||||||
|
|
||||||
addResources("youtube", "layout.player.fullscreen.openVideosFullscreen")
|
|
||||||
|
|
||||||
PreferenceScreen.PLAYER.addPreferences(
|
|
||||||
SwitchPreference("revanced_open_videos_fullscreen_portrait")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,32 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.player.fullscreen
|
||||||
|
|
||||||
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
|
import app.revanced.patches.youtube.layout.shortsplayer.openShortsInRegularPlayerPatch
|
||||||
|
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||||
|
import app.revanced.patches.youtube.misc.playservice.is_19_46_or_greater
|
||||||
|
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
|
||||||
|
import app.revanced.util.insertFeatureFlagBooleanOverride
|
||||||
|
|
||||||
|
internal const val EXTENSION_CLASS_DESCRIPTOR =
|
||||||
|
"Lapp/revanced/extension/youtube/patches/OpenVideosFullscreenHookPatch;"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used by both [openVideosFullscreenPatch] and [openShortsInRegularPlayerPatch].
|
||||||
|
*/
|
||||||
|
internal val openVideosFullscreenHookPatch = bytecodePatch {
|
||||||
|
dependsOn(
|
||||||
|
sharedExtensionPatch,
|
||||||
|
versionCheckPatch
|
||||||
|
)
|
||||||
|
|
||||||
|
execute {
|
||||||
|
if (!is_19_46_or_greater) {
|
||||||
|
return@execute
|
||||||
|
}
|
||||||
|
|
||||||
|
openVideosFullscreenPortraitFingerprint.method.insertFeatureFlagBooleanOverride(
|
||||||
|
OPEN_VIDEOS_FULLSCREEN_PORTRAIT_FEATURE_FLAG,
|
||||||
|
"$EXTENSION_CLASS_DESCRIPTOR->openVideoFullscreenPortrait(Z)Z"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.player.fullscreen
|
||||||
|
|
||||||
|
import app.revanced.patcher.patch.PatchException
|
||||||
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
|
import app.revanced.patches.all.misc.resources.addResources
|
||||||
|
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||||
|
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
||||||
|
import app.revanced.patches.youtube.misc.playservice.is_19_46_or_greater
|
||||||
|
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
|
||||||
|
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||||
|
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||||
|
import app.revanced.util.returnEarly
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
val openVideosFullscreenPatch = bytecodePatch(
|
||||||
|
name = "Open videos fullscreen",
|
||||||
|
description = "Adds an option to open videos in full screen portrait mode.",
|
||||||
|
) {
|
||||||
|
dependsOn(
|
||||||
|
openVideosFullscreenHookPatch,
|
||||||
|
settingsPatch,
|
||||||
|
addResourcesPatch,
|
||||||
|
versionCheckPatch
|
||||||
|
)
|
||||||
|
|
||||||
|
compatibleWith(
|
||||||
|
"com.google.android.youtube"(
|
||||||
|
"19.46.42",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
execute {
|
||||||
|
if (!is_19_46_or_greater) {
|
||||||
|
throw PatchException("'Open videos fullscreen' requires 19.46.42 or greater")
|
||||||
|
}
|
||||||
|
|
||||||
|
addResources("youtube", "layout.player.fullscreen.openVideosFullscreen")
|
||||||
|
|
||||||
|
PreferenceScreen.PLAYER.addPreferences(
|
||||||
|
SwitchPreference("revanced_open_videos_fullscreen_portrait")
|
||||||
|
)
|
||||||
|
|
||||||
|
// Enable the logic for the user Setting to open regular videos fullscreen.
|
||||||
|
openVideosFullscreenHookPatchExtensionFingerprint.method.returnEarly(true)
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package app.revanced.patches.youtube.layout.shortsautoplay
|
package app.revanced.patches.youtube.layout.shortsautoplay
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
import app.revanced.patcher.patch.bytecodePatch
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
@ -56,7 +57,7 @@ val shortsAutoplayPatch = bytecodePatch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Main activity is used to check if app is in pip mode.
|
// Main activity is used to check if app is in pip mode.
|
||||||
mainActivityOnCreateFingerprint.method.addInstructions(
|
mainActivityOnCreateFingerprint.method.addInstruction(
|
||||||
1,
|
1,
|
||||||
"invoke-static/range { p0 .. p0 }, $EXTENSION_CLASS_DESCRIPTOR->" +
|
"invoke-static/range { p0 .. p0 }, $EXTENSION_CLASS_DESCRIPTOR->" +
|
||||||
"setMainActivity(Landroid/app/Activity;)V",
|
"setMainActivity(Landroid/app/Activity;)V",
|
||||||
|
@ -0,0 +1,56 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.shortsplayer
|
||||||
|
|
||||||
|
import app.revanced.patcher.fingerprint
|
||||||
|
import app.revanced.util.literal
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Purpose of this method is not clear, and it's only used to identify
|
||||||
|
* the obfuscated name of the videoId() method in PlaybackStartDescriptor.
|
||||||
|
*/
|
||||||
|
internal val playbackStartFeatureFlagFingerprint = fingerprint {
|
||||||
|
returns("Z")
|
||||||
|
parameters(
|
||||||
|
"Lcom/google/android/libraries/youtube/player/model/PlaybackStartDescriptor;",
|
||||||
|
)
|
||||||
|
literal {
|
||||||
|
45380134L
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pre 19.25
|
||||||
|
internal val shortsPlaybackIntentLegacyFingerprint = fingerprint {
|
||||||
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||||
|
returns("V")
|
||||||
|
parameters(
|
||||||
|
"L",
|
||||||
|
"Ljava/util/Map;",
|
||||||
|
"J",
|
||||||
|
"Ljava/lang/String;",
|
||||||
|
"Z",
|
||||||
|
"Ljava/util/Map;"
|
||||||
|
)
|
||||||
|
strings(
|
||||||
|
// None of these strings are unique.
|
||||||
|
"com.google.android.apps.youtube.app.endpoint.flags",
|
||||||
|
"ReelWatchFragmentArgs",
|
||||||
|
"reels_fragment_descriptor"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal val shortsPlaybackIntentFingerprint = fingerprint {
|
||||||
|
accessFlags(AccessFlags.PROTECTED, AccessFlags.FINAL)
|
||||||
|
returns("V")
|
||||||
|
parameters(
|
||||||
|
"Lcom/google/android/libraries/youtube/player/model/PlaybackStartDescriptor;",
|
||||||
|
"Ljava/util/Map;",
|
||||||
|
"J",
|
||||||
|
"Ljava/lang/String;"
|
||||||
|
)
|
||||||
|
strings(
|
||||||
|
// None of these strings are unique.
|
||||||
|
"com.google.android.apps.youtube.app.endpoint.flags",
|
||||||
|
"ReelWatchFragmentArgs",
|
||||||
|
"reels_fragment_descriptor"
|
||||||
|
)
|
||||||
|
}
|
@ -0,0 +1,131 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.shortsplayer
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
|
import app.revanced.patches.all.misc.resources.addResources
|
||||||
|
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||||
|
import app.revanced.patches.shared.misc.settings.preference.ListPreference
|
||||||
|
import app.revanced.patches.youtube.layout.player.fullscreen.openVideosFullscreenHookPatch
|
||||||
|
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||||
|
import app.revanced.patches.youtube.misc.navigation.navigationBarHookPatch
|
||||||
|
import app.revanced.patches.youtube.misc.playservice.is_19_25_or_greater
|
||||||
|
import app.revanced.patches.youtube.misc.playservice.is_19_46_or_greater
|
||||||
|
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
|
||||||
|
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||||
|
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||||
|
import app.revanced.patches.youtube.shared.mainActivityOnCreateFingerprint
|
||||||
|
import app.revanced.util.getReference
|
||||||
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
|
|
||||||
|
private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||||
|
"Lapp/revanced/extension/youtube/patches/OpenShortsInRegularPlayerPatch;"
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
val openShortsInRegularPlayerPatch = bytecodePatch(
|
||||||
|
name = "Open Shorts in regular player",
|
||||||
|
description = "Adds options to open Shorts in the regular video player.",
|
||||||
|
) {
|
||||||
|
dependsOn(
|
||||||
|
sharedExtensionPatch,
|
||||||
|
settingsPatch,
|
||||||
|
addResourcesPatch,
|
||||||
|
openVideosFullscreenHookPatch,
|
||||||
|
navigationBarHookPatch,
|
||||||
|
versionCheckPatch
|
||||||
|
)
|
||||||
|
|
||||||
|
compatibleWith(
|
||||||
|
"com.google.android.youtube"(
|
||||||
|
"18.38.44",
|
||||||
|
"18.49.37",
|
||||||
|
"19.16.39",
|
||||||
|
"19.25.37",
|
||||||
|
"19.34.42",
|
||||||
|
"19.43.41",
|
||||||
|
"19.45.38",
|
||||||
|
"19.46.42",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
execute {
|
||||||
|
addResources("youtube", "layout.shortsplayer.shortsPlayerTypePatch")
|
||||||
|
|
||||||
|
PreferenceScreen.SHORTS.addPreferences(
|
||||||
|
if (is_19_46_or_greater) {
|
||||||
|
ListPreference(
|
||||||
|
key = "revanced_shorts_player_type",
|
||||||
|
summaryKey = null,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
ListPreference(
|
||||||
|
key = "revanced_shorts_player_type",
|
||||||
|
summaryKey = null,
|
||||||
|
entriesKey = "revanced_shorts_player_type_legacy_entries",
|
||||||
|
entryValuesKey = "revanced_shorts_player_type_legacy_entry_values"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// Activity is used as the context to launch an Intent.
|
||||||
|
mainActivityOnCreateFingerprint.method.addInstruction(
|
||||||
|
1,
|
||||||
|
"invoke-static/range { p0 .. p0 }, ${EXTENSION_CLASS_DESCRIPTOR}->" +
|
||||||
|
"setMainActivity(Landroid/app/Activity;)V",
|
||||||
|
)
|
||||||
|
|
||||||
|
// Find the obfuscated method name for PlaybackStartDescriptor.videoId()
|
||||||
|
val playbackStartVideoIdMethodName = playbackStartFeatureFlagFingerprint.method.let {
|
||||||
|
val stringMethodIndex = it.indexOfFirstInstructionOrThrow {
|
||||||
|
val reference = getReference<MethodReference>()
|
||||||
|
reference?.definingClass == "Lcom/google/android/libraries/youtube/player/model/PlaybackStartDescriptor;"
|
||||||
|
&& reference.returnType == "Ljava/lang/String;"
|
||||||
|
}
|
||||||
|
|
||||||
|
navigate(it).to(stringMethodIndex).stop().name
|
||||||
|
}
|
||||||
|
|
||||||
|
fun extensionInstructions(playbackStartRegister: Int, freeRegister: Int) =
|
||||||
|
"""
|
||||||
|
invoke-virtual { v$playbackStartRegister }, Lcom/google/android/libraries/youtube/player/model/PlaybackStartDescriptor;->$playbackStartVideoIdMethodName()Ljava/lang/String;
|
||||||
|
move-result-object v$freeRegister
|
||||||
|
invoke-static { v$freeRegister }, $EXTENSION_CLASS_DESCRIPTOR->openShort(Ljava/lang/String;)Z
|
||||||
|
move-result v$freeRegister
|
||||||
|
if-eqz v$freeRegister, :disabled
|
||||||
|
return-void
|
||||||
|
|
||||||
|
:disabled
|
||||||
|
nop
|
||||||
|
"""
|
||||||
|
|
||||||
|
if (!is_19_25_or_greater) {
|
||||||
|
shortsPlaybackIntentLegacyFingerprint.method.apply {
|
||||||
|
val index = indexOfFirstInstructionOrThrow {
|
||||||
|
getReference<MethodReference>()?.returnType ==
|
||||||
|
"Lcom/google/android/libraries/youtube/player/model/PlaybackStartDescriptor;"
|
||||||
|
}
|
||||||
|
val freeRegister = getInstruction<FiveRegisterInstruction>(index).registerC
|
||||||
|
val playbackStartRegister = getInstruction<OneRegisterInstruction>(index + 1).registerA
|
||||||
|
|
||||||
|
addInstructionsWithLabels(
|
||||||
|
index + 2,
|
||||||
|
extensionInstructions(playbackStartRegister, freeRegister)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return@execute
|
||||||
|
}
|
||||||
|
|
||||||
|
shortsPlaybackIntentFingerprint.method.addInstructionsWithLabels(
|
||||||
|
0,
|
||||||
|
"""
|
||||||
|
move-object/from16 v0, p1
|
||||||
|
${extensionInstructions(0, 1)}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
package app.revanced.patches.youtube.misc.announcements
|
package app.revanced.patches.youtube.misc.announcements
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||||
import app.revanced.patcher.patch.bytecodePatch
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
import app.revanced.patches.all.misc.resources.addResources
|
import app.revanced.patches.all.misc.resources.addResources
|
||||||
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||||
@ -41,7 +41,7 @@ val announcementsPatch = bytecodePatch(
|
|||||||
SwitchPreference("revanced_announcements"),
|
SwitchPreference("revanced_announcements"),
|
||||||
)
|
)
|
||||||
|
|
||||||
mainActivityOnCreateFingerprint.method.addInstructions(
|
mainActivityOnCreateFingerprint.method.addInstruction(
|
||||||
// Insert index must be greater than the insert index used by GmsCoreSupport,
|
// Insert index must be greater than the insert index used by GmsCoreSupport,
|
||||||
// as both patch the same method and GmsCore check should be first.
|
// as both patch the same method and GmsCore check should be first.
|
||||||
1,
|
1,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package app.revanced.patches.youtube.misc.dns
|
package app.revanced.patches.youtube.misc.dns
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||||
import app.revanced.patcher.patch.bytecodePatch
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
import app.revanced.patches.all.misc.resources.addResources
|
import app.revanced.patches.all.misc.resources.addResources
|
||||||
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||||
@ -31,7 +31,7 @@ val checkWatchHistoryDomainNameResolutionPatch = bytecodePatch(
|
|||||||
execute {
|
execute {
|
||||||
addResources("youtube", "misc.dns.checkWatchHistoryDomainNameResolutionPatch")
|
addResources("youtube", "misc.dns.checkWatchHistoryDomainNameResolutionPatch")
|
||||||
|
|
||||||
mainActivityOnCreateFingerprint.method.addInstructions(
|
mainActivityOnCreateFingerprint.method.addInstruction(
|
||||||
// FIXME: Insert index must be greater than the insert index used by GmsCoreSupport,
|
// FIXME: Insert index must be greater than the insert index used by GmsCoreSupport,
|
||||||
// as both patch the same method and GmsCoreSupport check should be first,
|
// as both patch the same method and GmsCoreSupport check should be first,
|
||||||
// but the patch does not depend on GmsCoreSupport, so it should not be possible to enforce this
|
// but the patch does not depend on GmsCoreSupport, so it should not be possible to enforce this
|
||||||
|
@ -221,6 +221,28 @@
|
|||||||
<item>BROWSE</item>
|
<item>BROWSE</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
</patch>
|
</patch>
|
||||||
|
<patch id="layout.shortsplayer.shortsPlayerTypePatch">
|
||||||
|
<string-array name="revanced_shorts_player_type_legacy_entries">
|
||||||
|
<item>@string/revanced_shorts_player_type_shorts</item>
|
||||||
|
<item>@string/revanced_shorts_player_type_regular_player</item>
|
||||||
|
</string-array>
|
||||||
|
<string-array name="revanced_shorts_player_type_legacy_entry_values">
|
||||||
|
<!-- Enum names from extension -->
|
||||||
|
<item>SHORTS_PLAYER</item>
|
||||||
|
<item>REGULAR_PLAYER</item>
|
||||||
|
</string-array>
|
||||||
|
<string-array name="revanced_shorts_player_type_entries">
|
||||||
|
<item>@string/revanced_shorts_player_type_shorts</item>
|
||||||
|
<item>@string/revanced_shorts_player_type_regular_player</item>
|
||||||
|
<item>@string/revanced_shorts_player_type_regular_player_fullscreen</item>
|
||||||
|
</string-array>
|
||||||
|
<string-array name="revanced_shorts_player_type_entry_values">
|
||||||
|
<!-- Enum names from extension -->
|
||||||
|
<item>SHORTS_PLAYER</item>
|
||||||
|
<item>REGULAR_PLAYER</item>
|
||||||
|
<item>REGULAR_PLAYER_FULLSCREEN</item>
|
||||||
|
</string-array>
|
||||||
|
</patch>
|
||||||
<patch id="layout.thumbnails.alternativeThumbnailsPatch">
|
<patch id="layout.thumbnails.alternativeThumbnailsPatch">
|
||||||
<string-array name="revanced_alt_thumbnail_options_entries">
|
<string-array name="revanced_alt_thumbnail_options_entries">
|
||||||
<item>@string/revanced_alt_thumbnail_options_entry_1</item>
|
<item>@string/revanced_alt_thumbnail_options_entry_1</item>
|
||||||
|
@ -1058,6 +1058,12 @@ If later turned off, it is recommended to clear the app data to prevent UI bugs.
|
|||||||
<string name="revanced_disable_resuming_shorts_player_summary_on">Shorts player will not resume on app startup</string>
|
<string name="revanced_disable_resuming_shorts_player_summary_on">Shorts player will not resume on app startup</string>
|
||||||
<string name="revanced_disable_resuming_shorts_player_summary_off">Shorts player will resume on app startup</string>
|
<string name="revanced_disable_resuming_shorts_player_summary_off">Shorts player will resume on app startup</string>
|
||||||
</patch>
|
</patch>
|
||||||
|
<patch id="layout.shortsplayer.shortsPlayerTypePatch">
|
||||||
|
<string name="revanced_shorts_player_type_title">Open Shorts with</string>
|
||||||
|
<string name="revanced_shorts_player_type_shorts">Shorts player</string>
|
||||||
|
<string name="revanced_shorts_player_type_regular_player">Regular player</string>
|
||||||
|
<string name="revanced_shorts_player_type_regular_player_fullscreen">Regular player fullscreen</string>
|
||||||
|
</patch>
|
||||||
<patch id="layout.shortsautoplay.shortsAutoplayPatch">
|
<patch id="layout.shortsautoplay.shortsAutoplayPatch">
|
||||||
<string name="revanced_shorts_autoplay_title">Autoplay Shorts</string>
|
<string name="revanced_shorts_autoplay_title">Autoplay Shorts</string>
|
||||||
<string name="revanced_shorts_autoplay_summary_on">Shorts will autoplay</string>
|
<string name="revanced_shorts_autoplay_summary_on">Shorts will autoplay</string>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user