Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(YouTube): Add Open Shorts in regular player patch #4153

Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
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);
LisoUseInAIKyrios marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* 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.
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);
LisoUseInAIKyrios marked this conversation as resolved.
Show resolved Hide resolved
return true;
} catch (Exception ex) {
OpenVideosFullscreenHookPatch.setOpenNextVideoFullscreen(null);
Logger.printException(() -> "openShort failure", ex);
return false;
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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 by 'Open videos fullscreen' patch,
* as this class is also used by 'Open Shorts in regular player' patch.
*/
private static boolean isFullScreenPatchIncluded() {
return false; // Modified by patches.
}

/**
* 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();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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_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_46_OR_GREATER = Utils.getAppVersionName().compareTo("19.46.00") >= 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
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_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.VersionCheckPatch.IS_19_17_OR_GREATER;
import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.IGNORE;
Expand Down Expand Up @@ -224,6 +225,7 @@ public class Settings extends BaseSettings {
// Shorts
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 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_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);
Expand Down
8 changes: 8 additions & 0 deletions patches/api/patches.api
Original file line number Diff line number Diff line change
Expand Up @@ -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 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;
}

Expand Down Expand Up @@ -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 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 static final fun getSponsorBlockPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package app.revanced.patches.shared.misc.checks

import android.os.Build.*
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.bytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.encodedValue.MutableEncodedValue
Expand Down Expand Up @@ -82,7 +82,7 @@ fun checkEnvironmentPatch(
}
}

fun invokeCheck() = mainActivityOnCreateFingerprint.method.addInstructions(
fun invokeCheck() = mainActivityOnCreateFingerprint.method.addInstruction(
0,
"invoke-static/range { p0 .. p0 },$EXTENSION_CLASS_DESCRIPTOR->check(Landroid/app/Activity;)V",
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,15 @@ internal val openVideosFullscreenPortraitFingerprint = fingerprint {
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
}
}
Original file line number Diff line number Diff line change
@@ -1,46 +1,9 @@
package app.revanced.patches.youtube.layout.player.fullscreen

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")
val openVideosFullscreenPatch = bytecodePatch(
name = "Open videos fullscreen",
description = "Adds an option to open videos in full screen portrait mode.",
) {
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")
)
}
}
@Deprecated("Renamed to openVideosFullscreenPatch", ReplaceWith("openVideosFullscreenPatch"))
val openVideosFullscreen = bytecodePatch{
dependsOn(openVideosFullscreenPatch)
}
Original file line number Diff line number Diff line change
@@ -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"
)
}
}
Original file line number Diff line number Diff line change
@@ -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)
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
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.getInstruction
import app.revanced.patcher.patch.bytecodePatch
Expand Down Expand Up @@ -56,7 +57,7 @@ val shortsAutoplayPatch = bytecodePatch(
}

// Main activity is used to check if app is in pip mode.
mainActivityOnCreateFingerprint.method.addInstructions(
mainActivityOnCreateFingerprint.method.addInstruction(
1,
"invoke-static/range { p0 .. p0 }, $EXTENSION_CLASS_DESCRIPTOR->" +
"setMainActivity(Landroid/app/Activity;)V",
Expand Down
Loading
Loading