Skip to content

Commit c2d7a7f

Browse files
chore: Merge branch dev to main (#6090)
2 parents 52c0bb6 + a55560d commit c2d7a7f

File tree

45 files changed

+808
-507
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+808
-507
lines changed

CHANGELOG.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,52 @@
1+
# [5.43.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.43.0-dev.3...v5.43.0-dev.4) (2025-10-14)
2+
3+
4+
### Bug Fixes
5+
6+
* **YouTube - Force original audio:** Do not use translated audio if stream spoofing is off and force audio is on ([0c19dba](https://github.com/ReVanced/revanced-patches/commit/0c19dbaf30bcb95a29448d98b028ebeea54cc7d3))
7+
8+
# [5.43.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.43.0-dev.2...v5.43.0-dev.3) (2025-10-14)
9+
10+
11+
### Bug Fixes
12+
13+
* **Custom branding:** Use white notification icon for expanded status bar panel ([95eee59](https://github.com/ReVanced/revanced-patches/commit/95eee59a87a680e212a3ba06e1afefee8d91ee9d))
14+
15+
# [5.43.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.43.0-dev.1...v5.43.0-dev.2) (2025-10-14)
16+
17+
18+
### Bug Fixes
19+
20+
* **YouTube - Custom branding:** Use ReVanced icon for status bar notification icon ([#6108](https://github.com/ReVanced/revanced-patches/issues/6108)) ([10ea250](https://github.com/ReVanced/revanced-patches/commit/10ea250d4a91f8ab3b7f865612a403fc93a857b5))
21+
22+
# [5.43.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.42.2-dev.3...v5.43.0-dev.1) (2025-10-11)
23+
24+
25+
### Features
26+
27+
* **Instagram:** Add `Hide suggested content` patch ([#6075](https://github.com/ReVanced/revanced-patches/issues/6075)) ([50f0b9c](https://github.com/ReVanced/revanced-patches/commit/50f0b9c5eee95ff5f9974e344802e1d2a4aab47b))
28+
29+
## [5.42.2-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.42.2-dev.2...v5.42.2-dev.3) (2025-10-11)
30+
31+
32+
### Bug Fixes
33+
34+
* **YouTube - Custom branding:** Do not add a broken custom icon if the user provides an invalid custom icon path ([6555f6e](https://github.com/ReVanced/revanced-patches/commit/6555f6e6f8b52c2f1ddab1f52c6704cd2d8cfc12))
35+
36+
## [5.42.2-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.42.2-dev.1...v5.42.2-dev.2) (2025-10-10)
37+
38+
39+
### Bug Fixes
40+
41+
* **X / Twitter - Change Link Sharing Domain:** Change link domain of share copy action ([#6091](https://github.com/ReVanced/revanced-patches/issues/6091)) ([5484625](https://github.com/ReVanced/revanced-patches/commit/54846253d748f4e7e30b2bba427c7d2fb9c341e2))
42+
43+
## [5.42.2-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.42.1...v5.42.2-dev.1) (2025-10-09)
44+
45+
46+
### Bug Fixes
47+
48+
* **Instagram - Change sharing domain:** Display patch option ([#6089](https://github.com/ReVanced/revanced-patches/issues/6089)) ([be2b144](https://github.com/ReVanced/revanced-patches/commit/be2b144cc9c4108ec37e16f3dd20573d88ffaa2b))
49+
150
## [5.42.1](https://github.com/ReVanced/revanced-patches/compare/v5.42.0...v5.42.1) (2025-10-08)
251

352

extensions/music/src/main/java/app/revanced/extension/music/settings/preference/MusicPreferenceFragment.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
import android.widget.Toolbar;
66

77
import app.revanced.extension.music.settings.MusicActivityHook;
8+
import app.revanced.extension.shared.GmsCoreSupport;
89
import app.revanced.extension.shared.Logger;
910
import app.revanced.extension.shared.Utils;
11+
import app.revanced.extension.shared.settings.BaseSettings;
1012
import app.revanced.extension.shared.settings.preference.ToolbarPreferenceFragment;
1113

1214
/**
@@ -30,6 +32,17 @@ protected void initialize() {
3032
preferenceScreen = getPreferenceScreen();
3133
Utils.sortPreferenceGroups(preferenceScreen);
3234
setPreferenceScreenToolbar(preferenceScreen);
35+
36+
// Clunky work around until preferences are custom classes that manage themselves.
37+
// Custom branding only works with non-root install. But the preferences must be
38+
// added during patched because of difficulties detecting during patching if it's
39+
// a root install. So instead the non-functional preferences are removed during
40+
// runtime if the app is mount (root) installation.
41+
if (GmsCoreSupport.isPackageNameOriginal()) {
42+
removePreferences(
43+
BaseSettings.CUSTOM_BRANDING_ICON.key,
44+
BaseSettings.CUSTOM_BRANDING_NAME.key);
45+
}
3346
} catch (Exception ex) {
3447
Logger.printException(() -> "initialize failure", ex);
3548
}

extensions/shared/library/src/main/java/app/revanced/extension/shared/patches/CustomBrandingPatch.java

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package app.revanced.extension.shared.patches;
22

3+
import android.app.Notification;
34
import android.content.ComponentName;
45
import android.content.Context;
56
import android.content.pm.PackageManager;
7+
import android.graphics.Color;
68

79
import java.util.ArrayList;
810
import java.util.List;
11+
import java.util.Locale;
912

1013
import app.revanced.extension.shared.GmsCoreSupport;
1114
import app.revanced.extension.shared.Logger;
@@ -29,28 +32,56 @@ public class CustomBrandingPatch {
2932
// The most that can be done is to hide a theme from the UI and keep the alias with dummy data.
3033
public enum BrandingTheme {
3134
/**
32-
* Original unpatched icon. Must be first enum.
35+
* Original unpatched icon.
3336
*/
34-
ORIGINAL("revanced_original"),
35-
ROUNDED("revanced_rounded"),
36-
MINIMAL("revanced_minimal"),
37-
SCALED("revanced_scaled"),
37+
ORIGINAL,
38+
ROUNDED,
39+
MINIMAL,
40+
SCALED,
3841
/**
39-
* User provided custom icon. Must be the last enum.
42+
* User provided custom icon.
4043
*/
41-
CUSTOM("revanced_custom");
42-
43-
public final String themeAlias;
44-
45-
BrandingTheme(String themeAlias) {
46-
this.themeAlias = themeAlias;
47-
}
44+
CUSTOM;
4845

4946
private String packageAndNameIndexToClassAlias(String packageName, int appIndex) {
5047
if (appIndex <= 0) {
5148
throw new IllegalArgumentException("App index starts at index 1");
5249
}
53-
return packageName + '.' + themeAlias + '_' + appIndex;
50+
return packageName + ".revanced_" + name().toLowerCase(Locale.US) + '_' + appIndex;
51+
}
52+
}
53+
54+
private static final int notificationSmallIcon;
55+
56+
static {
57+
BrandingTheme branding = BaseSettings.CUSTOM_BRANDING_ICON.get();
58+
if (branding == BrandingTheme.ORIGINAL) {
59+
notificationSmallIcon = 0;
60+
} else {
61+
// Original icon is quantum_ic_video_youtube_white_24
62+
String iconName = "revanced_notification_icon";
63+
if (branding == BrandingTheme.CUSTOM) {
64+
iconName += "_custom";
65+
}
66+
67+
notificationSmallIcon = Utils.getResourceIdentifier(iconName, "drawable");
68+
if (notificationSmallIcon == 0) {
69+
Logger.printException(() -> "Could not load notification small icon");
70+
}
71+
}
72+
}
73+
74+
/**
75+
* Injection point.
76+
*/
77+
public static void setNotificationIcon(Notification.Builder builder) {
78+
try {
79+
if (notificationSmallIcon != 0) {
80+
builder.setSmallIcon(notificationSmallIcon)
81+
.setColor(Color.TRANSPARENT); // Remove YT red tint.
82+
}
83+
} catch (Exception ex) {
84+
Logger.printException(() -> "setNotificationIcon failure", ex);
5485
}
5586
}
5687

extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/preference/ToolbarPreferenceFragment.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import android.graphics.drawable.Drawable;
77
import android.os.Build;
88
import android.preference.Preference;
9+
import android.preference.PreferenceGroup;
910
import android.preference.PreferenceScreen;
1011
import android.util.TypedValue;
1112
import android.view.ViewGroup;
@@ -22,6 +23,24 @@
2223

2324
@SuppressWarnings({"deprecation", "NewApi"})
2425
public class ToolbarPreferenceFragment extends AbstractPreferenceFragment {
26+
27+
/**
28+
* Removes the list of preferences from this fragment, if they exist.
29+
* @param keys Preference keys.
30+
*/
31+
protected void removePreferences(String ... keys) {
32+
for (String key : keys) {
33+
Preference pref = findPreference(key);
34+
if (pref != null) {
35+
PreferenceGroup parent = pref.getParent();
36+
if (parent != null) {
37+
Logger.printDebug(() -> "Removing preference: " + key);
38+
parent.removePreference(pref);
39+
}
40+
}
41+
}
42+
}
43+
2544
/**
2645
* Sets toolbar for all nested preference screens.
2746
*/

extensions/twitter/src/main/java/app/revanced/twitter/patches/links/ChangeLinkSharingDomainPatch.java

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,19 @@
22

33
@SuppressWarnings("unused")
44
public final class ChangeLinkSharingDomainPatch {
5-
private static final String DOMAIN_NAME = "https://fxtwitter.com";
65
private static final String LINK_FORMAT = "%s/%s/status/%s";
76

87
/**
9-
* Injection point.
8+
* Method is modified during patching. Do not change.
109
*/
11-
public static String formatResourceLink(Object... formatArgs) {
12-
String username = (String) formatArgs[0];
13-
String tweetId = (String) formatArgs[1];
14-
return String.format(LINK_FORMAT, DOMAIN_NAME, username, tweetId);
10+
private static String getShareDomain() {
11+
return "";
1512
}
1613

1714
/**
1815
* Injection point.
1916
*/
2017
public static String formatLink(long tweetId, String username) {
21-
return String.format(LINK_FORMAT, DOMAIN_NAME, username, tweetId);
18+
return String.format(LINK_FORMAT, getShareDomain(), username, tweetId);
2219
}
2320
}

extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/YouTubePreferenceFragment.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44
import android.preference.PreferenceScreen;
55
import android.widget.Toolbar;
66

7+
import app.revanced.extension.shared.GmsCoreSupport;
78
import app.revanced.extension.shared.Logger;
89
import app.revanced.extension.shared.Utils;
10+
import app.revanced.extension.shared.settings.BaseSettings;
911
import app.revanced.extension.shared.settings.preference.ToolbarPreferenceFragment;
1012
import app.revanced.extension.youtube.settings.YouTubeActivityHook;
1113

@@ -30,6 +32,17 @@ protected void initialize() {
3032
preferenceScreen = getPreferenceScreen();
3133
Utils.sortPreferenceGroups(preferenceScreen);
3234
setPreferenceScreenToolbar(preferenceScreen);
35+
36+
// Clunky work around until preferences are custom classes that manage themselves.
37+
// Custom branding only works with non-root install. But the preferences must be
38+
// added during patched because of difficulties detecting during patching if it's
39+
// a root install. So instead the non-functional preferences are removed during
40+
// runtime if the app is mount (root) installation.
41+
if (GmsCoreSupport.isPackageNameOriginal()) {
42+
removePreferences(
43+
BaseSettings.CUSTOM_BRANDING_ICON.key,
44+
BaseSettings.CUSTOM_BRANDING_NAME.key);
45+
}
3346
} catch (Exception ex) {
3447
Logger.printException(() -> "initialize failure", ex);
3548
}

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ org.gradle.jvmargs = -Xms512M -Xmx2048M
33
org.gradle.parallel = true
44
android.useAndroidX = true
55
kotlin.code.style = official
6-
version = 5.42.1
6+
version = 5.43.0-dev.4

patches/api/patches.api

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ public final class app/revanced/patches/instagram/feed/LimitFeedToFollowedProfil
269269
}
270270

271271
public final class app/revanced/patches/instagram/hide/explore/HideExploreFeedKt {
272-
public static final fun getHideExportFeedPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
272+
public static final fun getHideExploreFeedPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
273273
}
274274

275275
public final class app/revanced/patches/instagram/hide/navigation/HideNavigationButtonsKt {
@@ -280,6 +280,10 @@ public final class app/revanced/patches/instagram/hide/stories/HideStoriesKt {
280280
public static final fun getHideStoriesPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
281281
}
282282

283+
public final class app/revanced/patches/instagram/hide/suggestions/HideSuggestedContentKt {
284+
public static final fun getHideSuggestedContent ()Lapp/revanced/patcher/patch/BytecodePatch;
285+
}
286+
283287
public final class app/revanced/patches/instagram/misc/devmenu/EnableDeveloperMenuPatchKt {
284288
public static final fun getEnableDeveloperMenuPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
285289
}

patches/src/main/kotlin/app/revanced/patches/instagram/hide/explore/Fingerprints.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ package app.revanced.patches.instagram.hide.explore
33

44
import app.revanced.patcher.fingerprint
55

6+
internal const val EXPLORE_KEY_TO_BE_HIDDEN = "sectional_items"
7+
68
internal val exploreResponseJsonParserFingerprint = fingerprint {
7-
strings("sectional_items", "ExploreTopicalFeedResponse")
9+
strings(EXPLORE_KEY_TO_BE_HIDDEN, "ExploreTopicalFeedResponse")
810
custom { method, _ -> method.name == "parseFromJson" }
911
}

patches/src/main/kotlin/app/revanced/patches/instagram/hide/explore/HideExploreFeed.kt

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,39 @@
11
package app.revanced.patches.instagram.hide.explore
22

3+
import app.revanced.patcher.Fingerprint
34
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
45
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
6+
import app.revanced.patcher.patch.BytecodePatchContext
57
import app.revanced.patcher.patch.bytecodePatch
68
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
79

10+
context(BytecodePatchContext)
11+
internal fun Fingerprint.replaceJsonFieldWithBogus(
12+
key: String,
13+
) {
14+
val targetStringIndex = stringMatches!!.first { match -> match.string == key }.index
15+
val targetStringRegister = method.getInstruction<OneRegisterInstruction>(targetStringIndex).registerA
16+
17+
/**
18+
* Replacing the JSON key we want to skip with a random string that is not a valid JSON key.
19+
* This way the feeds array will never be populated.
20+
* Received JSON keys that are not handled are simply ignored, so there are no side effects.
21+
*/
22+
method.replaceInstruction(
23+
targetStringIndex,
24+
"const-string v$targetStringRegister, \"BOGUS\"",
25+
)
26+
}
27+
828
@Suppress("unused")
9-
val hideExportFeedPatch = bytecodePatch(
29+
val hideExploreFeedPatch = bytecodePatch(
1030
name = "Hide explore feed",
1131
description = "Hides posts and reels from the explore/search page.",
12-
use = false
32+
use = false,
1333
) {
1434
compatibleWith("com.instagram.android")
1535

1636
execute {
17-
exploreResponseJsonParserFingerprint.method.apply {
18-
val sectionalItemStringIndex = exploreResponseJsonParserFingerprint.stringMatches!!.first().index
19-
val sectionalItemStringRegister = getInstruction<OneRegisterInstruction>(sectionalItemStringIndex).registerA
20-
21-
/**
22-
* Replacing the JSON key we want to skip with a random string that is not a valid JSON key.
23-
* This way the feeds array will never be populated.
24-
* Received JSON keys that are not handled are simply ignored, so there are no side effects.
25-
*/
26-
replaceInstruction(
27-
sectionalItemStringIndex,
28-
"const-string v$sectionalItemStringRegister, \"BOGUS\""
29-
)
30-
}
37+
exploreResponseJsonParserFingerprint.replaceJsonFieldWithBogus(EXPLORE_KEY_TO_BE_HIDDEN)
3138
}
3239
}
33-

0 commit comments

Comments
 (0)