mirror of
https://github.com/inotia00/revanced-patches.git
synced 2025-05-09 11:04:36 +02:00
fix(YouTube): Patched app crashes after first launch or clearing data
This commit is contained in:
parent
6a9ad25d30
commit
b69a041d5d
@ -1,5 +1,6 @@
|
|||||||
package app.revanced.extension.shared.utils;
|
package app.revanced.extension.shared.utils;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.view.animation.Animation;
|
import android.view.animation.Animation;
|
||||||
@ -16,12 +17,25 @@ public class ResourceUtils extends Utils {
|
|||||||
} // utility class
|
} // utility class
|
||||||
|
|
||||||
public static int getIdentifier(@NonNull String str, @NonNull ResourceType resourceType) {
|
public static int getIdentifier(@NonNull String str, @NonNull ResourceType resourceType) {
|
||||||
return getIdentifier(str, resourceType, getContext());
|
Activity mActivity = getActivity();
|
||||||
|
Context mContext = mActivity != null
|
||||||
|
? mActivity
|
||||||
|
: getContext();
|
||||||
|
if (mContext == null) {
|
||||||
|
handleException(str, resourceType);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return getIdentifier(str, resourceType, mContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getIdentifier(@NonNull String str, @NonNull ResourceType resourceType,
|
public static int getIdentifier(@NonNull String str, @NonNull ResourceType resourceType,
|
||||||
@NonNull Context context) {
|
@NonNull Context context) {
|
||||||
return getResources().getIdentifier(str, resourceType.getType(), context.getPackageName());
|
try {
|
||||||
|
return context.getResources().getIdentifier(str, resourceType.getType(), context.getPackageName());
|
||||||
|
} catch (Exception ex) {
|
||||||
|
handleException(str, resourceType);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getAnimIdentifier(@NonNull String str) {
|
public static int getAnimIdentifier(@NonNull String str) {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package app.revanced.extension.shared.utils;
|
package app.revanced.extension.shared.utils;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
|
|
||||||
@ -104,7 +105,10 @@ public class StringRef extends Utils {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
if (!resolved) {
|
if (!resolved) {
|
||||||
try {
|
try {
|
||||||
Context context = getContext();
|
Activity mActivity = getActivity();
|
||||||
|
Context context = mActivity != null
|
||||||
|
? mActivity
|
||||||
|
: getContext();
|
||||||
if (resources == null) {
|
if (resources == null) {
|
||||||
resources = getResources();
|
resources = getResources();
|
||||||
}
|
}
|
||||||
|
@ -54,8 +54,6 @@ public class Utils {
|
|||||||
@SuppressLint("StaticFieldLeak")
|
@SuppressLint("StaticFieldLeak")
|
||||||
public static Context context;
|
public static Context context;
|
||||||
|
|
||||||
private static Resources resources;
|
|
||||||
|
|
||||||
protected Utils() {
|
protected Utils() {
|
||||||
} // utility class
|
} // utility class
|
||||||
|
|
||||||
@ -282,11 +280,15 @@ public class Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Resources getResources() {
|
public static Resources getResources() {
|
||||||
if (resources == null) {
|
Activity mActivity = activityRef.get();
|
||||||
return getLocalizedContextAndSetResources(getContext()).getResources();
|
if (mActivity != null) {
|
||||||
} else {
|
return mActivity.getResources();
|
||||||
return resources;
|
|
||||||
}
|
}
|
||||||
|
Context mContext = getContext();
|
||||||
|
if (mContext != null) {
|
||||||
|
return mContext.getResources();
|
||||||
|
}
|
||||||
|
throw new IllegalStateException("Get resources failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -304,6 +306,9 @@ public class Utils {
|
|||||||
if (mActivity == null) {
|
if (mActivity == null) {
|
||||||
return mContext;
|
return mContext;
|
||||||
}
|
}
|
||||||
|
if (mContext == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// Locale of MainActivity.
|
// Locale of MainActivity.
|
||||||
Locale applicationLocale;
|
Locale applicationLocale;
|
||||||
@ -321,7 +326,6 @@ public class Utils {
|
|||||||
|
|
||||||
// If they are identical, no need to override them.
|
// If they are identical, no need to override them.
|
||||||
if (applicationLocale == contextLocale) {
|
if (applicationLocale == contextLocale) {
|
||||||
resources = mActivity.getResources();
|
|
||||||
return mContext;
|
return mContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -329,9 +333,7 @@ public class Utils {
|
|||||||
Locale.setDefault(applicationLocale);
|
Locale.setDefault(applicationLocale);
|
||||||
Configuration configuration = new Configuration(mContext.getResources().getConfiguration());
|
Configuration configuration = new Configuration(mContext.getResources().getConfiguration());
|
||||||
configuration.setLocale(applicationLocale);
|
configuration.setLocale(applicationLocale);
|
||||||
Context localizedContext = mContext.createConfigurationContext(configuration);
|
return mContext.createConfigurationContext(configuration);
|
||||||
resources = localizedContext.getResources();
|
|
||||||
return localizedContext;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setActivity(Activity mainActivity) {
|
public static void setActivity(Activity mainActivity) {
|
||||||
|
@ -40,7 +40,6 @@ import java.util.EnumMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import app.revanced.extension.shared.utils.Logger;
|
|
||||||
import app.revanced.extension.shared.utils.ResourceUtils;
|
import app.revanced.extension.shared.utils.ResourceUtils;
|
||||||
import app.revanced.extension.shared.utils.Utils;
|
import app.revanced.extension.shared.utils.Utils;
|
||||||
import app.revanced.extension.youtube.settings.Settings;
|
import app.revanced.extension.youtube.settings.Settings;
|
||||||
@ -109,12 +108,7 @@ public class GeneralPatch {
|
|||||||
// region [Disable splash animation] patch
|
// region [Disable splash animation] patch
|
||||||
|
|
||||||
public static boolean disableSplashAnimation(boolean original) {
|
public static boolean disableSplashAnimation(boolean original) {
|
||||||
try {
|
return !Settings.DISABLE_SPLASH_ANIMATION.get() && original;
|
||||||
return !Settings.DISABLE_SPLASH_ANIMATION.get() && original;
|
|
||||||
} catch (Exception ex) {
|
|
||||||
Logger.printException(() -> "Failed to load disableSplashAnimation", ex);
|
|
||||||
}
|
|
||||||
return original;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
@ -130,12 +124,7 @@ public class GeneralPatch {
|
|||||||
// region [Hide layout components] patch
|
// region [Hide layout components] patch
|
||||||
|
|
||||||
public static boolean disableTranslucentStatusBar(boolean original) {
|
public static boolean disableTranslucentStatusBar(boolean original) {
|
||||||
try {
|
return !Settings.DISABLE_TRANSLUCENT_STATUS_BAR.get() && original;
|
||||||
return !Settings.DISABLE_TRANSLUCENT_STATUS_BAR.get() && original;
|
|
||||||
} catch (Exception ex) {
|
|
||||||
Logger.printException(() -> "Failed to load disableTranslucentStatusBar", ex);
|
|
||||||
}
|
|
||||||
return original;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String[] accountMenuBlockList;
|
private static String[] accountMenuBlockList;
|
||||||
@ -240,12 +229,7 @@ public class GeneralPatch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean switchCreateWithNotificationButton(boolean original) {
|
public static boolean switchCreateWithNotificationButton(boolean original) {
|
||||||
try {
|
return Settings.SWITCH_CREATE_WITH_NOTIFICATIONS_BUTTON.get() || original;
|
||||||
return Settings.SWITCH_CREATE_WITH_NOTIFICATIONS_BUTTON.get() || original;
|
|
||||||
} catch (Exception ex) {
|
|
||||||
Logger.printException(() -> "switchCreateWithNotificationButton Failed", ex);
|
|
||||||
}
|
|
||||||
return original;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void navigationTabCreated(NavigationButton button, View tabView) {
|
public static void navigationTabCreated(NavigationButton button, View tabView) {
|
||||||
@ -327,6 +311,9 @@ public class GeneralPatch {
|
|||||||
|
|
||||||
// region [Toolbar components] patch
|
// region [Toolbar components] patch
|
||||||
|
|
||||||
|
private static final int generalHeaderAttributeId = ResourceUtils.getAttrIdentifier("ytWordmarkHeader");
|
||||||
|
private static final int premiumHeaderAttributeId = ResourceUtils.getAttrIdentifier("ytPremiumWordmarkHeader");
|
||||||
|
|
||||||
public static void setDrawerNavigationHeader(View lithoView) {
|
public static void setDrawerNavigationHeader(View lithoView) {
|
||||||
final int headerAttributeId = getHeaderAttributeId();
|
final int headerAttributeId = getHeaderAttributeId();
|
||||||
|
|
||||||
@ -344,8 +331,8 @@ public class GeneralPatch {
|
|||||||
|
|
||||||
public static int getHeaderAttributeId() {
|
public static int getHeaderAttributeId() {
|
||||||
return Settings.CHANGE_YOUTUBE_HEADER.get()
|
return Settings.CHANGE_YOUTUBE_HEADER.get()
|
||||||
? ResourceUtils.getAttrIdentifier("ytPremiumWordmarkHeader")
|
? premiumHeaderAttributeId
|
||||||
: ResourceUtils.getAttrIdentifier("ytWordmarkHeader");
|
: generalHeaderAttributeId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean overridePremiumHeader() {
|
public static boolean overridePremiumHeader() {
|
||||||
@ -357,6 +344,11 @@ public class GeneralPatch {
|
|||||||
return ResourceUtils.getDrawable("");
|
return ResourceUtils.getDrawable("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final int searchBarId = ResourceUtils.getIdIdentifier("search_bar");
|
||||||
|
private static final int youtubeTextId = ResourceUtils.getIdIdentifier("youtube_text");
|
||||||
|
private static final int searchBoxId = ResourceUtils.getIdIdentifier("search_box");
|
||||||
|
private static final int searchIconId = ResourceUtils.getIdIdentifier("search_icon");
|
||||||
|
|
||||||
private static final boolean wideSearchbarEnabled = Settings.ENABLE_WIDE_SEARCH_BAR.get();
|
private static final boolean wideSearchbarEnabled = Settings.ENABLE_WIDE_SEARCH_BAR.get();
|
||||||
// Loads the search bar deprecated by Google.
|
// Loads the search bar deprecated by Google.
|
||||||
private static final boolean wideSearchbarWithHeaderEnabled = Settings.ENABLE_WIDE_SEARCH_BAR_WITH_HEADER.get();
|
private static final boolean wideSearchbarWithHeaderEnabled = Settings.ENABLE_WIDE_SEARCH_BAR_WITH_HEADER.get();
|
||||||
@ -396,17 +388,12 @@ public class GeneralPatch {
|
|||||||
if (!wideSearchbarEnabled)
|
if (!wideSearchbarEnabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
final int searchBarId = ResourceUtils.getIdIdentifier("search_bar");
|
|
||||||
if (!(view.findViewById(searchBarId) instanceof RelativeLayout searchBarView))
|
if (!(view.findViewById(searchBarId) instanceof RelativeLayout searchBarView))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// When the deprecated search bar is loaded, two search bars overlap.
|
// When the deprecated search bar is loaded, two search bars overlap.
|
||||||
// Manually hides another search bar.
|
// Manually hides another search bar.
|
||||||
if (wideSearchbarWithHeaderEnabled) {
|
if (wideSearchbarWithHeaderEnabled) {
|
||||||
final int youtubeTextId = ResourceUtils.getIdIdentifier("youtube_text");
|
|
||||||
final int searchBoxId = ResourceUtils.getIdIdentifier("search_box");
|
|
||||||
final int searchIconId = ResourceUtils.getIdIdentifier("search_icon");
|
|
||||||
|
|
||||||
final View searchIconView = searchBarView.findViewById(searchIconId);
|
final View searchIconView = searchBarView.findViewById(searchIconId);
|
||||||
final View searchBoxView = searchBarView.findViewById(searchBoxId);
|
final View searchBoxView = searchBarView.findViewById(searchBoxId);
|
||||||
final View textView = searchBarView.findViewById(youtubeTextId);
|
final View textView = searchBarView.findViewById(youtubeTextId);
|
||||||
@ -521,14 +508,16 @@ public class GeneralPatch {
|
|||||||
imageView.setImageDrawable(drawable);
|
imageView.setImageDrawable(drawable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final int settingsDrawableId =
|
||||||
|
ResourceUtils.getDrawableIdentifier("yt_outline_gear_black_24");
|
||||||
|
private static final int settingsCairoDrawableId =
|
||||||
|
ResourceUtils.getDrawableIdentifier("yt_outline_gear_cairo_black_24");
|
||||||
|
|
||||||
public static int getCreateButtonDrawableId(int original) {
|
public static int getCreateButtonDrawableId(int original) {
|
||||||
if (!Settings.REPLACE_TOOLBAR_CREATE_BUTTON.get()) {
|
if (!Settings.REPLACE_TOOLBAR_CREATE_BUTTON.get()) {
|
||||||
return original;
|
return original;
|
||||||
}
|
}
|
||||||
|
|
||||||
final int settingsDrawableId =
|
|
||||||
ResourceUtils.getDrawableIdentifier("yt_outline_gear_black_24");
|
|
||||||
|
|
||||||
if (settingsDrawableId == 0) {
|
if (settingsDrawableId == 0) {
|
||||||
return original;
|
return original;
|
||||||
}
|
}
|
||||||
@ -539,9 +528,6 @@ public class GeneralPatch {
|
|||||||
return settingsDrawableId;
|
return settingsDrawableId;
|
||||||
}
|
}
|
||||||
|
|
||||||
final int settingsCairoDrawableId =
|
|
||||||
ResourceUtils.getDrawableIdentifier("yt_outline_gear_cairo_black_24");
|
|
||||||
|
|
||||||
return settingsCairoDrawableId == 0
|
return settingsCairoDrawableId == 0
|
||||||
? settingsDrawableId
|
? settingsDrawableId
|
||||||
: settingsCairoDrawableId;
|
: settingsCairoDrawableId;
|
||||||
|
@ -2,8 +2,10 @@ package app.revanced.patches.youtube.utils.extension
|
|||||||
|
|
||||||
import app.revanced.patches.shared.extension.sharedExtensionPatch
|
import app.revanced.patches.shared.extension.sharedExtensionPatch
|
||||||
import app.revanced.patches.youtube.utils.extension.hooks.applicationInitHook
|
import app.revanced.patches.youtube.utils.extension.hooks.applicationInitHook
|
||||||
|
import app.revanced.patches.youtube.utils.extension.hooks.mainActivityBaseContextHook
|
||||||
|
|
||||||
// TODO: Move this to a "Hook.kt" file. Same for other extension hook patches.
|
// TODO: Move this to a "Hook.kt" file. Same for other extension hook patches.
|
||||||
val sharedExtensionPatch = sharedExtensionPatch(
|
val sharedExtensionPatch = sharedExtensionPatch(
|
||||||
applicationInitHook,
|
applicationInitHook,
|
||||||
|
mainActivityBaseContextHook,
|
||||||
)
|
)
|
||||||
|
@ -0,0 +1,35 @@
|
|||||||
|
package app.revanced.patches.youtube.utils.extension.hooks
|
||||||
|
|
||||||
|
import app.revanced.patches.shared.extension.extensionHook
|
||||||
|
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.reference.MethodReference
|
||||||
|
|
||||||
|
private var attachBaseContextIndex = -1
|
||||||
|
|
||||||
|
internal val mainActivityBaseContextHook = extensionHook(
|
||||||
|
insertIndexResolver = { method ->
|
||||||
|
attachBaseContextIndex = method.indexOfFirstInstructionOrThrow {
|
||||||
|
getReference<MethodReference>()?.name == "attachBaseContext"
|
||||||
|
}
|
||||||
|
|
||||||
|
attachBaseContextIndex + 1
|
||||||
|
},
|
||||||
|
contextRegisterResolver = { method ->
|
||||||
|
val overrideInstruction = method.implementation!!.instructions.elementAt(attachBaseContextIndex)
|
||||||
|
as FiveRegisterInstruction
|
||||||
|
"v${overrideInstruction.registerD}"
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
returns("V")
|
||||||
|
parameters("Landroid/content/Context;")
|
||||||
|
custom { method, classDef ->
|
||||||
|
method.name == "attachBaseContext" &&
|
||||||
|
(
|
||||||
|
classDef.endsWith("/MainActivity;") ||
|
||||||
|
// Old versions of YouTube called this class "WatchWhileActivity" instead.
|
||||||
|
classDef.endsWith("/WatchWhileActivity;")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -70,7 +70,7 @@ val playerResponseMethodHookPatch = bytecodePatch(
|
|||||||
"""
|
"""
|
||||||
invoke-static {$registerVideoId, $registerPlayerParameter, $registerPlaylistId, $registerIsShortAndOpeningOrPlaying}, $hook
|
invoke-static {$registerVideoId, $registerPlayerParameter, $registerPlaylistId, $registerIsShortAndOpeningOrPlaying}, $hook
|
||||||
move-result-object $registerPlayerParameter
|
move-result-object $registerPlayerParameter
|
||||||
""",
|
""",
|
||||||
)
|
)
|
||||||
numberOfInstructionsAdded += 2
|
numberOfInstructionsAdded += 2
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user