fix(YouTube - Downloads): Use new task context (#583)

Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
This commit is contained in:
LisoUseInAIKyrios 2024-03-08 09:10:06 +04:00 committed by GitHub
parent 75a494e09b
commit 468dfac054
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 117 additions and 57 deletions

View File

@ -40,7 +40,7 @@ import kotlin.text.Regex;
public class Utils {
@SuppressLint("StaticFieldLeak")
public static Context context;
private static Context context;
private static String versionName;
@ -233,6 +233,11 @@ public class Utils {
return context;
}
public static void setContext(Context appContext) {
context = appContext;
Logger.printDebug(() -> "Set context: " + appContext); // Cannot log before context is set.
}
public static void setClipboard(@NonNull String text) {
android.content.ClipboardManager clipboard = (android.content.ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
android.content.ClipData clip = android.content.ClipData.newPlainText("ReVanced", text);

View File

@ -1,27 +1,84 @@
package app.revanced.integrations.youtube.patches;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.lang.ref.WeakReference;
import app.revanced.integrations.shared.Logger;
import app.revanced.integrations.shared.StringRef;
import app.revanced.integrations.shared.Utils;
import app.revanced.integrations.youtube.patches.spoof.SpoofAppVersionPatch;
import app.revanced.integrations.youtube.settings.Settings;
@SuppressWarnings("unused")
public final class DownloadsPatch {
public static boolean inAppDownloadButtonOnClick() {
if (!Settings.USE_IN_APP_DOWNLOAD_BUTTON.get())
return false;
launchExternalDownloader();
return true;
private static WeakReference<Activity> activityRef = new WeakReference<>(null);
/**
* Injection point.
*/
public static void activityCreated(Activity mainActivity) {
activityRef = new WeakReference<>(mainActivity);
}
public static void launchExternalDownloader() {
Logger.printDebug(() -> "Launching external downloader");
/**
* Injection point.
*
* Call if download playlist is pressed, or if download button is used
* for old spoofed version (both playlists and the player action button).
*
* Downloading playlists is not supported yet,
* as the hooked code does not easily expose the playlist id.
*/
public static boolean inAppDownloadPlaylistLegacyOnClick(@Nullable String videoId) {
if (videoId == null || videoId.isEmpty()) {
// videoId is null or empty if download playlist is pressed.
Logger.printDebug(() -> "Ignoring playlist download button press");
return false;
}
return inAppDownloadButtonOnClick();
}
final var context = Utils.getContext();
/**
* Injection point.
*/
public static boolean inAppDownloadButtonOnClick() {
try {
if (!Settings.EXTERNAL_DOWNLOADER_ACTION_BUTTON.get()) {
return false;
}
// If possible, use the main activity as the context.
// Otherwise fall back on using the application context.
Context context = activityRef.get();
boolean isActivityContext = true;
if (context == null) {
// Utils context is the application context, and not an activity context.
context = Utils.getContext();
isActivityContext = false;
}
launchExternalDownloader(context, isActivityContext);
return true;
} catch (Exception ex) {
Logger.printException(() -> "inAppDownloadButtonOnClick failure", ex);
}
return false;
}
/**
* @param isActivityContext If the context parameter is for an Activity. If this is false, then
* the downloader is opened as a new task (which forces YT to minimize).
*/
public static void launchExternalDownloader(@NonNull Context context, boolean isActivityContext) {
Logger.printDebug(() -> "Launching external downloader with context: " + context);
// Trim string to avoid any accidental whitespace.
var downloaderPackageName = Settings.EXTERNAL_DOWNLOADER_PACKAGE_NAME.get().trim();
@ -47,11 +104,13 @@ public final class DownloadsPatch {
intent.setType("text/plain");
intent.setPackage(downloaderPackageName);
intent.putExtra("android.intent.extra.TEXT", content);
if (!isActivityContext) {
Logger.printDebug(() -> "Using new task intent");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
context.startActivity(intent);
Logger.printDebug(() -> "Launched the intent with the content: " + content);
} catch (Exception error) {
Logger.printException(() -> "Failed to launch the intent: " + error, error);
Logger.printException(() -> "Failed to launch intent: " + error, error);
}
}
}

View File

@ -16,7 +16,7 @@ public class HideBreakingNewsPatch {
* Breaking news does not appear to be present in these older versions anyways.
*/
private static final boolean isSpoofingOldVersionWithHorizontalCardListWatchHistory =
SpoofAppVersionPatch.isSpoofingToEqualOrLessThan("17.31.00");
SpoofAppVersionPatch.isSpoofingToLessThan("18.01.00");
/**
* Injection point.

View File

@ -6,24 +6,12 @@ import androidx.annotation.Nullable;
import app.revanced.integrations.youtube.shared.PlayerOverlays;
/**
* Hook receiver class for 'player-overlays-hook' patch
*
* @usedBy app.revanced.patches.youtube.misc.playeroverlay.patch.PlayerOverlaysHookPatch
* @smali Lapp/revanced/integrations/patches/PlayerOverlaysHookPatch;
*/
@SuppressWarnings("unused")
public class PlayerOverlaysHookPatch {
/**
* Injection point.
*
* @param thisRef reference to the view
* @smali YouTubePlayerOverlaysLayout_onFinishInflateHook(Ljava / lang / Object ;)V
*/
public static void YouTubePlayerOverlaysLayout_onFinishInflateHook(@Nullable Object thisRef) {
if (thisRef == null) return;
if (thisRef instanceof ViewGroup) {
PlayerOverlays.attach((ViewGroup) thisRef);
}
public static void playerOverlayInflated(ViewGroup group) {
PlayerOverlays.attach(group);
}
}

View File

@ -46,7 +46,7 @@ import static app.revanced.integrations.youtube.returnyoutubedislike.ReturnYouTu
public class ReturnYouTubeDislikePatch {
public static final boolean IS_SPOOFING_TO_NON_LITHO_SHORTS_PLAYER =
SpoofAppVersionPatch.isSpoofingToEqualOrLessThan("18.33.40");
SpoofAppVersionPatch.isSpoofingToLessThan("18.34.00");
/**
* RYD data for the current video on screen.

View File

@ -1,26 +1,12 @@
package app.revanced.integrations.youtube.patches.spoof;
import app.revanced.integrations.shared.Logger;
import app.revanced.integrations.youtube.settings.Settings;
@SuppressWarnings("unused")
public class SpoofAppVersionPatch {
private static final boolean SPOOF_APP_VERSION_ENABLED;
private static final String SPOOF_APP_VERSION_TARGET;
static {
// TODO: remove this migration code
// Spoof targets below 17.33 that no longer reliably work.
if (Settings.SPOOF_APP_VERSION_TARGET.get().compareTo("17.33.01") < 0) {
Logger.printInfo(() -> "Resetting spoof app version target");
Settings.SPOOF_APP_VERSION_TARGET.resetToDefault();
}
// End migration
SPOOF_APP_VERSION_ENABLED = Settings.SPOOF_APP_VERSION.get();
SPOOF_APP_VERSION_TARGET = Settings.SPOOF_APP_VERSION_TARGET.get();
}
private static final boolean SPOOF_APP_VERSION_ENABLED = Settings.SPOOF_APP_VERSION.get();
private static final String SPOOF_APP_VERSION_TARGET = Settings.SPOOF_APP_VERSION_TARGET.get();
/**
* Injection point
@ -30,8 +16,8 @@ public class SpoofAppVersionPatch {
return version;
}
public static boolean isSpoofingToEqualOrLessThan(String version) {
return SPOOF_APP_VERSION_ENABLED && SPOOF_APP_VERSION_TARGET.compareTo(version) <= 0;
public static boolean isSpoofingToLessThan(String version) {
return SPOOF_APP_VERSION_ENABLED && SPOOF_APP_VERSION_TARGET.compareTo(version) < 0;
}
}

View File

@ -91,7 +91,7 @@ public class ReturnYouTubeDislike {
private static final char MIDDLE_SEPARATOR_CHARACTER = '◎'; // 'bullseye'
private static final boolean IS_SPOOFING_TO_OLD_SEPARATOR_COLOR
= SpoofAppVersionPatch.isSpoofingToEqualOrLessThan("18.09.39");
= SpoofAppVersionPatch.isSpoofingToLessThan("18.10.00");
/**
* Cached lookup of all video ids.

View File

@ -1,7 +1,9 @@
package app.revanced.integrations.youtube.settings;
import app.revanced.integrations.shared.Logger;
import app.revanced.integrations.shared.settings.*;
import app.revanced.integrations.shared.settings.preference.SharedPrefCategory;
import app.revanced.integrations.youtube.patches.spoof.SpoofAppVersionPatch;
import app.revanced.integrations.youtube.sponsorblock.SponsorBlockSettings;
import java.util.Arrays;
@ -16,9 +18,9 @@ import static java.lang.Boolean.TRUE;
public class Settings extends BaseSettings {
// External downloader
public static final BooleanSetting EXTERNAL_DOWNLOADER = new BooleanSetting("revanced_external_downloader", FALSE);
public static final BooleanSetting EXTERNAL_DOWNLOADER_ACTION_BUTTON = new BooleanSetting("revanced_external_downloader_action_button", FALSE);
public static final StringSetting EXTERNAL_DOWNLOADER_PACKAGE_NAME = new StringSetting("revanced_external_downloader_name",
"org.schabi.newpipe" /* NewPipe */, parent(EXTERNAL_DOWNLOADER));
public static final BooleanSetting USE_IN_APP_DOWNLOAD_BUTTON = new BooleanSetting("revanced_use_in_app_download_button", TRUE);
"org.schabi.newpipe" /* NewPipe */, parentsAny(EXTERNAL_DOWNLOADER, EXTERNAL_DOWNLOADER_ACTION_BUTTON));
// Copy video URL
public static final BooleanSetting COPY_VIDEO_URL = new BooleanSetting("revanced_copy_video_url", FALSE);
@ -335,6 +337,14 @@ public class Settings extends BaseSettings {
// and more time should be given for users who rarely upgrade.
migrateOldSettingToNew(DEPRECATED_SB_UUID_OLD_MIGRATION_SETTING, SB_PRIVATE_USER_ID);
// Old spoof versions that no longer work reliably.
if (SpoofAppVersionPatch.isSpoofingToLessThan("17.33.00")) {
Logger.printInfo(() -> "Resetting spoof app version target");
Settings.SPOOF_APP_VERSION_TARGET.resetToDefault();
}
// endregion
}
}

View File

@ -1,8 +1,15 @@
package app.revanced.integrations.youtube.settings.preference;
import android.os.Build;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceGroup;
import androidx.annotation.RequiresApi;
import app.revanced.integrations.shared.Logger;
import app.revanced.integrations.shared.settings.preference.AbstractPreferenceFragment;
import app.revanced.integrations.youtube.patches.DownloadsPatch;
import app.revanced.integrations.youtube.patches.playback.speed.CustomPlaybackSpeedPatch;
import app.revanced.integrations.youtube.settings.Settings;
@ -12,14 +19,20 @@ import app.revanced.integrations.youtube.settings.Settings;
* @noinspection deprecation
*/
public class ReVancedPreferenceFragment extends AbstractPreferenceFragment {
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
protected void initialize() {
super.initialize();
// If the preference was included, then initialize it based on the available playback speed
Preference defaultSpeedPreference = findPreference(Settings.PLAYBACK_SPEED_DEFAULT.key);
if (defaultSpeedPreference instanceof ListPreference) {
CustomPlaybackSpeedPatch.initializeListPreference((ListPreference) defaultSpeedPreference);
try {
// If the preference was included, then initialize it based on the available playback speed.
Preference defaultSpeedPreference = findPreference(Settings.PLAYBACK_SPEED_DEFAULT.key);
if (defaultSpeedPreference instanceof ListPreference) {
CustomPlaybackSpeedPatch.initializeListPreference((ListPreference) defaultSpeedPreference);
}
} catch (Exception ex) {
Logger.printException(() -> "initialize failure", ex);
}
}
}

View File

@ -5,10 +5,9 @@ import android.view.ViewGroup;
import androidx.annotation.Nullable;
import app.revanced.integrations.youtube.patches.DownloadsPatch;
import app.revanced.integrations.youtube.patches.VideoInformation;
import app.revanced.integrations.youtube.settings.Settings;
import app.revanced.integrations.shared.Logger;
import app.revanced.integrations.youtube.patches.DownloadsPatch;
import app.revanced.integrations.youtube.settings.Settings;
@SuppressWarnings("unused")
public class ExternalDownloadButton extends BottomControlButton {
@ -44,7 +43,7 @@ public class ExternalDownloadButton extends BottomControlButton {
}
private static void onDownloadClick(View view) {
DownloadsPatch.launchExternalDownloader();
DownloadsPatch.launchExternalDownloader(view.getContext(), true);
}
}