diff --git a/CHANGELOG.md b/CHANGELOG.md
index 81f323037..d0fe67ae1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,37 @@
+# [2.159.0-dev.4](https://github.com/revanced/revanced-patches/compare/v2.159.0-dev.3...v2.159.0-dev.4) (2023-02-03)
+
+
+### Features
+
+* **netguard:** `remove-broadcasts-restriction` patch ([#1581](https://github.com/revanced/revanced-patches/issues/1581)) ([73132e3](https://github.com/revanced/revanced-patches/commit/73132e37cf83f4c1f05cf6a184dfd8e454f7456e))
+
+# [2.159.0-dev.3](https://github.com/revanced/revanced-patches/compare/v2.159.0-dev.2...v2.159.0-dev.3) (2023-02-03)
+
+
+### Features
+
+* **youtube:** `hide-player-buttons` patch ([3469d37](https://github.com/revanced/revanced-patches/commit/3469d37bcedfd2dfbe46231b17cd098b591810c1))
+
+# [2.159.0-dev.2](https://github.com/revanced/revanced-patches/compare/v2.159.0-dev.1...v2.159.0-dev.2) (2023-02-01)
+
+
+### Features
+
+* `spoof-wifi-connection` patch ([#1527](https://github.com/revanced/revanced-patches/issues/1527)) ([adce206](https://github.com/revanced/revanced-patches/commit/adce206d66e1f7017328fe68a5818d424f70e588))
+
+# [2.159.0-dev.1](https://github.com/revanced/revanced-patches/compare/v2.158.0...v2.159.0-dev.1) (2023-02-01)
+
+
+### Bug Fixes
+
+* **youtube/custom-branding:** correct scaling, margin and images ([#1580](https://github.com/revanced/revanced-patches/issues/1580)) ([491c413](https://github.com/revanced/revanced-patches/commit/491c4138f0185664a9c5d3db9ebdf026ff4594e8))
+
+
+### Features
+
+* **music:** bump patches compatibility to v5.41.50 ([#1551](https://github.com/revanced/revanced-patches/issues/1551)) ([0b1024a](https://github.com/revanced/revanced-patches/commit/0b1024ab754a3e2ce798a54cccda6f41f97069a5))
+* **spotify-lite:** enable on-demand patch ([9f0de4f](https://github.com/revanced/revanced-patches/commit/9f0de4f5678e9f57baaf6ec788821641d75defdc))
+
# [2.158.0](https://github.com/revanced/revanced-patches/compare/v2.157.0...v2.158.0) (2023-01-29)
diff --git a/README.md b/README.md
index ffef3c48d..9f6ea51a6 100644
--- a/README.md
+++ b/README.md
@@ -38,15 +38,16 @@ The official Patch bundle provided by ReVanced and the community.
| `hide-endscreen-cards` | Hides the suggested video cards at the end of a video in fullscreen. | 18.03.36 |
| `hide-info-cards` | Hides info-cards in videos. | 18.03.36 |
| `hide-my-mix` | Hides mix playlists. | 18.03.36 |
+| `hide-player-buttons` | Adds the option to hide video player previous and next buttons. | all |
| `hide-shorts-button` | Hides the shorts button on the navigation bar. | 18.03.36 |
| `hide-time-and-seekbar` | Hides progress bar and time counter on videos. | 18.03.36 |
-| `hide-video-buttons` | Adds options to hide action buttons under a video. | 18.03.36 |
+| `hide-video-action-buttons` | Adds the options to hide action buttons under a video. | 18.03.36 |
| `hide-watch-in-vr` | Hides the Watch in VR option in the player settings flyout panel. | 18.03.36 |
| `hide-watermark` | Hides creator's watermarks on videos. | 18.03.36 |
| `microg-support` | Allows YouTube ReVanced to run without root and under a different package name with Vanced MicroG. | 18.03.36 |
| `minimized-playback` | Enables minimized and background playback. | 18.03.36 |
| `old-quality-layout` | Enables the original video quality flyout in the video player settings | 18.03.36 |
-| `open-links-directly` | Bypasses https://youtube.com/redirect URLs. | 18.03.36 |
+| `open-links-directly` | Skips over redirection URLs to external links. | 18.03.36 |
| `open-links-externally` | Open links outside of the app directly in your browser. | 18.03.36 |
| `premium-heading` | Shows premium branding on the home screen. | all |
| `remember-playback-rate` | Adds the ability to remember the playback rate you chose in the video playback rate flyout. | 18.03.36 |
@@ -54,7 +55,7 @@ The official Patch bundle provided by ReVanced and the community.
| `remove-player-button-background` | Removes the background from the video player buttons. | 18.03.36 |
| `return-youtube-dislike` | Shows the dislike count of videos using the Return YouTube Dislike API. | 18.03.36 |
| `seekbar-tapping` | Enables tap-to-seek on the seekbar of the video player. | 18.03.36 |
-| `sponsorblock` | Integrate SponsorBlock. | 18.03.36 |
+| `sponsorblock` | Integrates SponsorBlock which allows skipping video segments such as sponsored content. | 18.03.36 |
| `spoof-app-version` | Tricks YouTube into thinking, you are running an older version of the app. One of the side effects also includes restoring the old UI. | 18.03.36 |
| `swipe-controls` | Adds volume and brightness swipe controls. | 18.03.36 |
| `tablet-mini-player` | Enables the tablet mini player layout. | 18.03.36 |
@@ -160,7 +161,7 @@ The official Patch bundle provided by ReVanced and the community.
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
| `remove-bootloader-detection` | Removes the check for an unlocked bootloader. | 2.2.0 |
-| `remove-root-detection` | Removes the check for root permissions | 2.2.0 |
+| `remove-root-detection` | Removes the check for root permissions. | 2.2.0 |
### [📦 `at.gv.oe.app`](https://play.google.com/store/apps/details?id=at.gv.oe.app)
@@ -188,6 +189,14 @@ The official Patch bundle provided by ReVanced and the community.
| `disable-ads` | Disables ads in HexEditor. | all |
+### [📦 `com.spotify.lite`](https://play.google.com/store/apps/details?id=com.spotify.lite)
+
+
+| 💊 Patch | 📜 Description | 🏹 Target Version |
+|:--------:|:--------------:|:-----------------:|
+| `enable-on-demand` | Enables listening to songs on-demand, allowing to play any song from playlists, albums or artists without limitations. This does not remove ads. | all |
+
+
### [📦 `org.citra.citra_emu`](https://play.google.com/store/apps/details?id=org.citra.citra_emu)
@@ -228,6 +237,14 @@ The official Patch bundle provided by ReVanced and the community.
| `remove-ads` | Removes all ads from the app. | all |
+### [📦 `eu.faircode.netguard`](https://play.google.com/store/apps/details?id=eu.faircode.netguard)
+
+
+| 💊 Patch | 📜 Description | 🏹 Target Version |
+|:--------:|:--------------:|:-----------------:|
+| `remove-broadcasts-restriction` | Enables starting/stopping NetGuard via broadcasts. | all |
+
+
### [📦 `com.teslacoilsw.launcher`](https://play.google.com/store/apps/details?id=com.teslacoilsw.launcher)
diff --git a/gradle.properties b/gradle.properties
index 68098c7ee..7e4db9fbf 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,2 +1,2 @@
kotlin.code.style = official
-version = 2.158.0
+version = 2.159.0-dev.4
diff --git a/patches.json b/patches.json
index 5f2b2ae6e..61411d1fd 100644
--- a/patches.json
+++ b/patches.json
@@ -1 +1 @@
-[{"name":"always-autorepeat","description":"Always repeats the playing video again.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"background-play","description":"Enables playing music in the background.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":["5.14.53","5.16.51","5.17.51","5.21.52","5.22.54","5.23.50","5.25.51","5.25.52","5.26.52","5.27.51","5.28.52","5.29.52","5.31.50","5.34.51","5.36.51","5.38.53","5.39.52","5.40.51"]}]},{"name":"block-audio-ads","description":"Blocks audio ads in streams and VODs.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":[]}]},{"name":"block-embedded-ads","description":"Blocks embedded steam ads using services like TTV.lol or PurpleAdBlocker.","version":"0.0.1","excluded":false,"options":[],"dependencies":["block-video-ads","integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":[]}]},{"name":"block-video-ads","description":"Blocks video ads in streams and VODs.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":[]}]},{"name":"client-spoof","description":"Spoofs the YouTube or Vanced client to prevent playback issues.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]},{"name":"com.vanced.android.youtube","versions":[]}]},{"name":"codecs-unlock","description":"Adds more audio codec options. The new audio codecs usually result in better audio quality.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":["5.14.53","5.16.51","5.17.51","5.21.52","5.22.54","5.23.50","5.25.51","5.25.52","5.26.52","5.27.51","5.28.52","5.29.52","5.31.50","5.34.51","5.36.51","5.38.53","5.39.52","5.40.51"]}]},{"name":"comments","description":"Hides components related to comments.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","comments-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"compact-header","description":"Hides the music category bar at the top of the homepage.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":["5.14.53","5.16.51","5.21.52","5.22.54","5.23.50","5.25.51","5.25.52","5.26.52","5.27.51","5.28.52","5.29.52","5.31.50","5.34.51","5.36.51","5.38.53","5.39.52","5.40.51"]}]},{"name":"copy-video-url","description":"Adds buttons in player to copy video links.","version":"0.0.1","excluded":false,"options":[],"dependencies":["copy-video-url-resource","player-controls-bytecode-patch","video-information"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"custom-branding","description":"Changes the YouTube launcher icon and name to your choice (defaults to ReVanced).","version":"0.0.1","excluded":false,"options":[{"key":"appName","title":"Application Name","description":"The name of the application it will show on your home screen.","required":true,"choices":null},{"key":"iconPath","title":"App Icon Path","description":"A path containing mipmap resource folders with icons.","required":false,"choices":null}],"dependencies":["locale-config-fix"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"custom-video-buffer","description":"Lets you change the buffers of videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":["settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"custom-video-speed","description":"Adds more video speed options.","version":"0.0.1","excluded":false,"options":[{"key":"granularity","title":"Video speed granularity","description":"The granularity of the video speeds. The higher the value, the more speeds will be available.","required":true,"choices":null},{"key":"min","title":"Minimum video speed","description":"The minimum video speed.","required":true,"choices":null},{"key":"max","title":"Maximum video speed","description":"The maximum video speed. Must be greater than the minimum video speed and smaller than 5.","required":true,"choices":null}],"dependencies":["integrations"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"debug-mode","description":"Enables Twitch\u0027s internal debugging mode.","version":"0.0.1","excluded":true,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":[]}]},{"name":"debugging","description":"Adds debugging options.","version":"0.0.1","excluded":false,"options":[{"key":"debuggable","title":"App debugging","description":"Whether to make the app debuggable on Android.","required":false,"choices":null}],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"disable-ads","description":"Disables ads in HexEditor.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.myprog.hexedit","versions":[]}]},{"name":"disable-auto-captions","description":"Disable forced captions from being automatically enabled.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"disable-auto-player-popup-panels","description":"Disable automatic popup panels (playlist or live chat) on video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"disable-capture-restriction","description":"Allows capturing Spotify\u0027s audio output while screen sharing or screen recording.","version":"0.0.2","excluded":false,"options":[],"dependencies":["disable-capture-restriction-resource-patch"],"compatiblePackages":[{"name":"com.spotify.music","versions":[]}]},{"name":"disable-fullscreen-panels","description":"Disables video description and comments panel in fullscreen view.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"disable-login-requirement","description":"Do not force login.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"disable-startup-shorts-player","description":"Disables playing YouTube Shorts when launching YouTube.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"disable-zoom-haptics","description":"Disables haptics when zooming.","version":"0.0.1","excluded":false,"options":[],"dependencies":["settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"downloads","description":"Removes download restrictions and changes the default path to download to.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":["27.8.3"]},{"name":"com.zhiliaoapp.musically","versions":["27.8.3"]}]},{"name":"downloads","description":"Enables downloading music and videos from YouTube.","version":"0.0.1","excluded":false,"options":[],"dependencies":["downloads-resource-patch","player-controls-bytecode-patch","video-information"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"dynamic-color","description":"Replaces the default Twitter Blue with the users Material You palette.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.twitter.android","versions":[]}]},{"name":"enable-wide-searchbar","description":"Replaces the search icon with a wide search bar. This will hide the YouTube logo when active.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"exclusive-audio-playback","description":"Enables the option to play music without video.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":["5.14.53","5.16.51","5.17.51","5.21.52","5.22.54","5.23.50","5.25.51","5.25.52","5.26.52","5.27.51","5.28.52","5.29.52","5.31.50","5.34.51","5.36.51","5.38.53","5.39.52","5.40.51"]}]},{"name":"feed-filter","description":"Filters tiktok videos: removing ads, removing livestreams.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":["27.8.3"]},{"name":"com.zhiliaoapp.musically","versions":["27.8.3"]}]},{"name":"fix-google-login","description":"Allows logging in with a Google account.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"general-ads","description":"Removes general ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["GeneralAdsResourcePatch","VerticalScrollPatch","FixBackToExitGesturePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"general-reddit-ads","description":"Removes general ads from the Reddit frontpage and subreddits.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":["2022.43.0"]}]},{"name":"hdr-auto-brightness","description":"Makes the brightness of HDR videos follow the system default.","version":"0.0.2","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"hide-ads","description":"Removes ads from TikTok.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"hide-album-cards","description":"Hides the album cards below the artist description.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","hide-album-cards-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"hide-artist-card","description":"Hides the artist card below the searchbar.","version":"0.0.1","excluded":false,"options":[],"dependencies":["resource-mapping","LithoFilterPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"hide-autoplay-button","description":"Hides the autoplay button in the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings","resource-mapping"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"hide-breaking-news-shelf","description":"Hides the breaking news shelf on the homepage tab.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","breaking-news-shelf-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"hide-captions-button","description":"Hides the captions button on video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"hide-cast-button","description":"Hides the cast button in the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"hide-create-button","description":"Hides the create button in the navigation bar.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","resource-mapping","settings","ResolvePivotBarFingerprintsPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"hide-crowdfunding-box","description":"Hides the crowdfunding box between the player and video description.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","crowdfunding-box-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"hide-email-address","description":"Hides the email address in the account switcher.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","hide-email-address-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"hide-endscreen-cards","description":"Hides the suggested video cards at the end of a video in fullscreen.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","hide-endscreen-cards-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"hide-get-premium","description":"Removes all \"Get Premium\" evidences from the avatar menu.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":["5.14.53","5.16.51","5.17.51","5.21.52","5.22.54","5.23.50","5.25.51","5.25.52","5.26.52","5.27.51","5.28.52","5.29.52","5.31.50","5.34.51","5.36.51","5.38.53","5.39.52"]}]},{"name":"hide-info-cards","description":"Hides info-cards in videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","HideInfocardsResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"hide-my-mix","description":"Hides mix playlists.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"hide-premium-navbar","description":"Removes the premium tab from the navbar.","version":"0.0.1","excluded":false,"options":[],"dependencies":["resource-mapping"],"compatiblePackages":[{"name":"com.spotify.music","versions":[]}]},{"name":"hide-shorts-button","description":"Hides the shorts button on the navigation bar.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings","ResolvePivotBarFingerprintsPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"hide-time-and-seekbar","description":"Hides progress bar and time counter on videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"hide-video-buttons","description":"Adds options to hide action buttons under a video.","version":"0.0.1","excluded":false,"options":[],"dependencies":["resource-mapping","LithoFilterPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"hide-views-stats","description":"Hides the view stats under tweets.","version":"0.0.1","excluded":false,"options":[],"dependencies":["HideViewsBytecodePatch"],"compatiblePackages":[{"name":"com.twitter.android","versions":["9.69.1-release.0"]}]},{"name":"hide-watch-in-vr","description":"Hides the Watch in VR option in the player settings flyout panel.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"hide-watermark","description":"Hides creator\u0027s watermarks on videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"microg-support","description":"Allows YouTube ReVanced to run without root and under a different package name with Vanced MicroG.","version":"0.0.1","excluded":false,"options":[],"dependencies":["microg-resource-patch","hide-cast-button","client-spoof"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"minimized-playback","description":"Enables minimized and background playback.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"minimized-playback-music","description":"Enables minimized playback on Kids music.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":["5.14.53","5.16.51","5.17.51","5.21.52","5.22.54","5.23.50","5.25.51","5.25.52","5.26.52","5.27.51","5.28.52","5.29.52","5.31.50","5.34.51","5.36.51","5.38.53","5.39.52","5.40.51"]}]},{"name":"monochrome-icon","description":"Adds a monochrome icon.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.twitter.android","versions":[]}]},{"name":"music-microg-support","description":"Allows YouTube Music ReVanced to run without root and under a different package name.","version":"0.0.2","excluded":false,"options":[],"dependencies":["music-microg-resource-patch"],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":["5.14.53","5.16.51","5.17.51","5.21.52","5.22.54","5.23.50","5.25.51","5.25.52","5.26.52","5.27.51","5.28.52","5.29.52","5.31.50","5.34.51","5.36.51","5.38.53","5.39.52","5.40.51"]}]},{"name":"music-video-ads","description":"Removes ads in the music player.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":["5.14.53","5.16.51","5.17.51","5.21.52","5.22.54","5.23.50","5.25.51","5.25.52","5.26.52","5.27.51","5.28.52","5.29.52","5.31.50","5.34.51","5.36.51","5.38.53","5.39.52","5.40.51"]}]},{"name":"old-quality-layout","description":"Enables the original video quality flyout in the video player settings","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"open-links-directly","description":"Bypasses https://youtube.com/redirect URLs.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"open-links-externally","description":"Open links outside of the app directly in your browser.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"playback-speed","description":"Enables the playback speed option for all videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"predictive-back-gesture","description":"Enables the predictive back gesture introduced on Android 13.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"premium-heading","description":"Shows premium branding on the home screen.","version":"0.0.1","excluded":false,"options":[],"dependencies":["locale-config-fix"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"premium-icon-reddit","description":"Unlocks premium Reddit app icons.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"premium-unlock","description":"Unlocks premium functions.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"org.citra.citra_emu","versions":[]},{"name":"org.citra.citra_emu.canary","versions":[]}]},{"name":"pro-unlock","description":"Unlocks pro-only functions.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.backdrops.wallpapers","versions":[]}]},{"name":"promo-code-unlock","description":"Disables the validation of promo code. Any code will work to unlock all features.","version":"0.0.1","excluded":false,"options":[],"dependencies":["spoof-cert-patch"],"compatiblePackages":[{"name":"de.dwd.warnapp","versions":[]}]},{"name":"remember-playback-rate","description":"Adds the ability to remember the playback rate you chose in the video playback rate flyout.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"remember-video-quality","description":"Adds the ability to remember the video quality you chose in the video quality flyout.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","video-id-hook","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"remove-ads","description":"Removes all ads from the app.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"net.binarymode.android.irplus","versions":[]}]},{"name":"remove-bootloader-detection","description":"Removes the check for an unlocked bootloader.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.bmf.bmf2go","versions":["2.2.0"]}]},{"name":"remove-player-button-background","description":"Removes the background from the video player buttons.","version":"0.0.1","excluded":false,"options":[],"dependencies":["locale-config-fix"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"remove-root-detection","description":"Removes the check for root permissions","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.bmf.bmf2go","versions":["2.2.0"]}]},{"name":"remove-root-detection","description":"Removes the check for root permissions and unlocked bootloader.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.oe.app","versions":["2.5.2"]}]},{"name":"remove-screenshot-restriction","description":"Removes the restriction of making screenshots.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"return-youtube-dislike","description":"Shows the dislike count of videos using the Return YouTube Dislike API.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","video-id-hook","return-youtube-dislike-resource-patch","player-type-hook"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"seekbar-tapping","description":"Enables tap-to-seek on the seekbar of the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"settings","description":"Adds ReVanced settings to TikTok.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":["27.8.3"]},{"name":"com.zhiliaoapp.musically","versions":["27.8.3"]}]},{"name":"settings","description":"Adds settings menu to Twitch.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings-resource-patch"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":[]}]},{"name":"show-deleted-messages","description":"Shows deleted chat messages behind a clickable spoiler.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":[]}]},{"name":"show-seekbar","description":"Shows progress bar for all video.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"sim-spoof","description":"Spoofs the information which is retrieved from the sim-card.","version":"0.0.1","excluded":true,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":["27.8.3"]},{"name":"com.zhiliaoapp.musically","versions":["27.8.3"]}]},{"name":"sponsorblock","description":"Integrate SponsorBlock.","version":"0.0.1","excluded":false,"options":[],"dependencies":["video-information","player-controls-bytecode-patch","player-type-hook","integrations","sponsorblock-resource-patch","video-id-hook"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"spoof-app-version","description":"Tricks YouTube into thinking, you are running an older version of the app. One of the side effects also includes restoring the old UI.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"spoof-signature","description":"Spoofs the signature of the app.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.oe.app","versions":["2.5.2"]}]},{"name":"spotify-theme","description":"Applies a custom theme.","version":"0.0.1","excluded":false,"options":[{"key":"backgroundColor","title":"Background color","description":"The background color. Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"accentColor","title":"Accent color","description":"The accent color (\u0027spotify green\u0027 by default). Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"accentPressedColor","title":"Pressed accent for the dark theme","description":"The color when accented buttons are pressed, by default slightly darker than accent. Can be a hex color or a resource reference.","required":false,"choices":null}],"dependencies":["locale-config-fix"],"compatiblePackages":[{"name":"com.spotify.music","versions":[]}]},{"name":"swipe-controls","description":"Adds volume and brightness swipe controls.","version":"0.0.3","excluded":false,"options":[],"dependencies":["integrations","player-type-hook","swipe-controls-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"tablet-mini-player","description":"Enables the tablet mini player layout.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"tasteBuilder-remover","description":"Removes the \"Tell us which artists you like\" card from the home screen.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":["5.21.52","5.22.54","5.23.50","5.25.51","5.25.52","5.26.52","5.27.51","5.28.52","5.29.52","5.31.50","5.34.51","5.36.51","5.38.53","5.39.52","5.40.51"]}]},{"name":"theme","description":"Applies a custom theme.","version":"0.0.1","excluded":false,"options":[{"key":"darkThemeBackgroundColor","title":"Background color for the dark theme","description":"The background color of the dark theme. Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"lightThemeBackgroundColor","title":"Background color for the light theme","description":"The background color of the light theme. Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"darkThemeSeekbarColor","title":"Dark theme seekbar color","description":"The background color of the seekbar of the dark theme. Leave empty for default color.","required":false,"choices":null}],"dependencies":["litho-components-theme","locale-config-fix"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"timeline-ads","description":"Removes ads from the Twitter timeline. Might require clearing app data to remove already cached ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.twitter.android","versions":[]}]},{"name":"unlock-prime","description":"Unlocks Nova Prime and all functions of the app.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.teslacoilsw.launcher","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"co.windyapp.android","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.awedea.nyx","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"ginlemon.iconpackstudio","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all professional features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"org.totschnig.myexpenses","versions":[]}]},{"name":"unlock-pro","description":"Unlocks pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ithebk.expensemanager","versions":[]}]},{"name":"unlock-themes","description":"Unlocks all themes.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ticktick.task","versions":[]}]},{"name":"unlock-trial","description":"Unlocks the trial version.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"net.dinglisch.android.taskerm","versions":[]}]},{"name":"upgrade-button-remover","description":"Removes the upgrade tab from the pivot bar.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":["5.14.53","5.16.51","5.17.51","5.21.52","5.22.54","5.23.50","5.25.51","5.25.52","5.26.52","5.27.51","5.28.52","5.29.52","5.31.50","5.34.51","5.36.51","5.38.53","5.39.52","5.40.51"]}]},{"name":"video-ads","description":"Removes ads in the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]}]
\ No newline at end of file
+[{"name":"always-autorepeat","description":"Always repeats the playing video again.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"background-play","description":"Enables playing music in the background.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":["5.14.53","5.16.51","5.17.51","5.21.52","5.22.54","5.23.50","5.25.51","5.25.52","5.26.52","5.27.51","5.28.52","5.29.52","5.31.50","5.34.51","5.36.51","5.38.53","5.39.52","5.40.51","5.41.50"]}]},{"name":"block-audio-ads","description":"Blocks audio ads in streams and VODs.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":[]}]},{"name":"block-embedded-ads","description":"Blocks embedded steam ads using services like TTV.lol or PurpleAdBlocker.","version":"0.0.1","excluded":false,"options":[],"dependencies":["block-video-ads","integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":[]}]},{"name":"block-video-ads","description":"Blocks video ads in streams and VODs.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":[]}]},{"name":"client-spoof","description":"Spoofs the YouTube or Vanced client to prevent playback issues.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]},{"name":"com.vanced.android.youtube","versions":[]}]},{"name":"codecs-unlock","description":"Adds more audio codec options. The new audio codecs usually result in better audio quality.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":["5.14.53","5.16.51","5.17.51","5.21.52","5.22.54","5.23.50","5.25.51","5.25.52","5.26.52","5.27.51","5.28.52","5.29.52","5.31.50","5.34.51","5.36.51","5.38.53","5.39.52","5.40.51","5.41.50"]}]},{"name":"comments","description":"Hides components related to comments.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","comments-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"compact-header","description":"Hides the music category bar at the top of the homepage.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":["5.14.53","5.16.51","5.21.52","5.22.54","5.23.50","5.25.51","5.25.52","5.26.52","5.27.51","5.28.52","5.29.52","5.31.50","5.34.51","5.36.51","5.38.53","5.39.52","5.40.51","5.41.50"]}]},{"name":"copy-video-url","description":"Adds buttons in player to copy video links.","version":"0.0.1","excluded":false,"options":[],"dependencies":["copy-video-url-resource","player-controls-bytecode-patch","video-information"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"custom-branding","description":"Changes the YouTube launcher icon and name to your choice (defaults to ReVanced).","version":"0.0.1","excluded":false,"options":[{"key":"appName","title":"Application Name","description":"The name of the application it will show on your home screen.","required":true,"choices":null},{"key":"iconPath","title":"App Icon Path","description":"A path containing mipmap resource folders with icons.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"custom-video-buffer","description":"Lets you change the buffers of videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":["settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"custom-video-speed","description":"Adds more video speed options.","version":"0.0.1","excluded":false,"options":[{"key":"granularity","title":"Video speed granularity","description":"The granularity of the video speeds. The higher the value, the more speeds will be available.","required":true,"choices":null},{"key":"min","title":"Minimum video speed","description":"The minimum video speed.","required":true,"choices":null},{"key":"max","title":"Maximum video speed","description":"The maximum video speed. Must be greater than the minimum video speed and smaller than 5.","required":true,"choices":null}],"dependencies":["integrations"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"debug-mode","description":"Enables Twitch\u0027s internal debugging mode.","version":"0.0.1","excluded":true,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":[]}]},{"name":"debugging","description":"Adds debugging options.","version":"0.0.1","excluded":false,"options":[{"key":"debuggable","title":"App debugging","description":"Whether to make the app debuggable on Android.","required":false,"choices":null}],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"disable-ads","description":"Disables ads in HexEditor.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.myprog.hexedit","versions":[]}]},{"name":"disable-auto-captions","description":"Disable forced captions from being automatically enabled.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"disable-auto-player-popup-panels","description":"Disable automatic popup panels (playlist or live chat) on video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"disable-capture-restriction","description":"Allows capturing Spotify\u0027s audio output while screen sharing or screen recording.","version":"0.0.2","excluded":false,"options":[],"dependencies":["disable-capture-restriction-resource-patch"],"compatiblePackages":[{"name":"com.spotify.music","versions":[]}]},{"name":"disable-fullscreen-panels","description":"Disables video description and comments panel in fullscreen view.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"disable-login-requirement","description":"Do not force login.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"disable-startup-shorts-player","description":"Disables playing YouTube Shorts when launching YouTube.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"disable-zoom-haptics","description":"Disables haptics when zooming.","version":"0.0.1","excluded":false,"options":[],"dependencies":["settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"downloads","description":"Removes download restrictions and changes the default path to download to.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":["27.8.3"]},{"name":"com.zhiliaoapp.musically","versions":["27.8.3"]}]},{"name":"downloads","description":"Enables downloading music and videos from YouTube.","version":"0.0.1","excluded":false,"options":[],"dependencies":["downloads-resource-patch","player-controls-bytecode-patch","video-information"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"dynamic-color","description":"Replaces the default Twitter Blue with the users Material You palette.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.twitter.android","versions":[]}]},{"name":"enable-on-demand","description":"Enables listening to songs on-demand, allowing to play any song from playlists, albums or artists without limitations. This does not remove ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.spotify.lite","versions":[]}]},{"name":"enable-wide-searchbar","description":"Replaces the search icon with a wide search bar. This will hide the YouTube logo when active.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"exclusive-audio-playback","description":"Enables the option to play music without video.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":["5.14.53","5.16.51","5.17.51","5.21.52","5.22.54","5.23.50","5.25.51","5.25.52","5.26.52","5.27.51","5.28.52","5.29.52","5.31.50","5.34.51","5.36.51","5.38.53","5.39.52","5.40.51","5.41.50"]}]},{"name":"feed-filter","description":"Filters tiktok videos: removing ads, removing livestreams.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":["27.8.3"]},{"name":"com.zhiliaoapp.musically","versions":["27.8.3"]}]},{"name":"fix-google-login","description":"Allows logging in with a Google account.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"general-ads","description":"Removes general ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["GeneralAdsResourcePatch","VerticalScrollPatch","FixBackToExitGesturePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"general-reddit-ads","description":"Removes general ads from the Reddit frontpage and subreddits.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":["2022.43.0"]}]},{"name":"hdr-auto-brightness","description":"Makes the brightness of HDR videos follow the system default.","version":"0.0.2","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"hide-ads","description":"Removes ads from TikTok.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"hide-album-cards","description":"Hides the album cards below the artist description.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","hide-album-cards-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"hide-artist-card","description":"Hides the artist card below the searchbar.","version":"0.0.1","excluded":false,"options":[],"dependencies":["resource-mapping","LithoFilterPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"hide-autoplay-button","description":"Hides the autoplay button in the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings","resource-mapping"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"hide-breaking-news-shelf","description":"Hides the breaking news shelf on the homepage tab.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","breaking-news-shelf-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"hide-captions-button","description":"Hides the captions button on video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"hide-cast-button","description":"Hides the cast button in the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"hide-create-button","description":"Hides the create button in the navigation bar.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","resource-mapping","settings","ResolvePivotBarFingerprintsPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"hide-crowdfunding-box","description":"Hides the crowdfunding box between the player and video description.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","crowdfunding-box-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"hide-email-address","description":"Hides the email address in the account switcher.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","hide-email-address-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"hide-endscreen-cards","description":"Hides the suggested video cards at the end of a video in fullscreen.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","hide-endscreen-cards-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"hide-get-premium","description":"Removes all \"Get Premium\" evidences from the avatar menu.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":["5.14.53","5.16.51","5.17.51","5.21.52","5.22.54","5.23.50","5.25.51","5.25.52","5.26.52","5.27.51","5.28.52","5.29.52","5.31.50","5.34.51","5.36.51","5.38.53","5.39.52"]}]},{"name":"hide-info-cards","description":"Hides info-cards in videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","HideInfocardsResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"hide-my-mix","description":"Hides mix playlists.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"hide-player-buttons","description":"Adds the option to hide video player previous and next buttons.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"hide-premium-navbar","description":"Removes the premium tab from the navbar.","version":"0.0.1","excluded":false,"options":[],"dependencies":["resource-mapping"],"compatiblePackages":[{"name":"com.spotify.music","versions":[]}]},{"name":"hide-shorts-button","description":"Hides the shorts button on the navigation bar.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings","ResolvePivotBarFingerprintsPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"hide-time-and-seekbar","description":"Hides progress bar and time counter on videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"hide-video-action-buttons","description":"Adds the options to hide action buttons under a video.","version":"0.0.1","excluded":false,"options":[],"dependencies":["resource-mapping","LithoFilterPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"hide-views-stats","description":"Hides the view stats under tweets.","version":"0.0.1","excluded":false,"options":[],"dependencies":["HideViewsBytecodePatch"],"compatiblePackages":[{"name":"com.twitter.android","versions":["9.69.1-release.0"]}]},{"name":"hide-watch-in-vr","description":"Hides the Watch in VR option in the player settings flyout panel.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"hide-watermark","description":"Hides creator\u0027s watermarks on videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"microg-support","description":"Allows YouTube ReVanced to run without root and under a different package name with Vanced MicroG.","version":"0.0.1","excluded":false,"options":[],"dependencies":["microg-resource-patch","hide-cast-button","client-spoof"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"minimized-playback","description":"Enables minimized and background playback.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"minimized-playback-music","description":"Enables minimized playback on Kids music.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":["5.14.53","5.16.51","5.17.51","5.21.52","5.22.54","5.23.50","5.25.51","5.25.52","5.26.52","5.27.51","5.28.52","5.29.52","5.31.50","5.34.51","5.36.51","5.38.53","5.39.52","5.40.51","5.41.50"]}]},{"name":"monochrome-icon","description":"Adds a monochrome icon.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.twitter.android","versions":[]}]},{"name":"music-microg-support","description":"Allows YouTube Music ReVanced to run without root and under a different package name.","version":"0.0.2","excluded":false,"options":[],"dependencies":["music-microg-resource-patch"],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":["5.14.53","5.16.51","5.17.51","5.21.52","5.22.54","5.23.50","5.25.51","5.25.52","5.26.52","5.27.51","5.28.52","5.29.52","5.31.50","5.34.51","5.36.51","5.38.53","5.39.52","5.40.51","5.41.50"]}]},{"name":"music-video-ads","description":"Removes ads in the music player.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":["5.14.53","5.16.51","5.17.51","5.21.52","5.22.54","5.23.50","5.25.51","5.25.52","5.26.52","5.27.51","5.28.52","5.29.52","5.31.50","5.34.51","5.36.51","5.38.53","5.39.52","5.40.51","5.41.50"]}]},{"name":"old-quality-layout","description":"Enables the original video quality flyout in the video player settings","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"open-links-directly","description":"Skips over redirection URLs to external links.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"open-links-externally","description":"Open links outside of the app directly in your browser.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"playback-speed","description":"Enables the playback speed option for all videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"predictive-back-gesture","description":"Enables the predictive back gesture introduced on Android 13.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"premium-heading","description":"Shows premium branding on the home screen.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"premium-icon-reddit","description":"Unlocks premium Reddit app icons.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"premium-unlock","description":"Unlocks premium functions.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"org.citra.citra_emu","versions":[]},{"name":"org.citra.citra_emu.canary","versions":[]}]},{"name":"pro-unlock","description":"Unlocks pro-only functions.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.backdrops.wallpapers","versions":[]}]},{"name":"promo-code-unlock","description":"Disables the validation of promo code. Any code will work to unlock all features.","version":"0.0.1","excluded":false,"options":[],"dependencies":["spoof-cert-patch"],"compatiblePackages":[{"name":"de.dwd.warnapp","versions":[]}]},{"name":"remember-playback-rate","description":"Adds the ability to remember the playback rate you chose in the video playback rate flyout.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"remember-video-quality","description":"Adds the ability to remember the video quality you chose in the video quality flyout.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","video-id-hook","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"remove-ads","description":"Removes all ads from the app.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"net.binarymode.android.irplus","versions":[]}]},{"name":"remove-bootloader-detection","description":"Removes the check for an unlocked bootloader.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.bmf.bmf2go","versions":["2.2.0"]}]},{"name":"remove-broadcasts-restriction","description":"Enables starting/stopping NetGuard via broadcasts.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"eu.faircode.netguard","versions":[]}]},{"name":"remove-player-button-background","description":"Removes the background from the video player buttons.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"remove-root-detection","description":"Removes the check for root permissions.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.bmf.bmf2go","versions":["2.2.0"]}]},{"name":"remove-root-detection","description":"Removes the check for root permissions and unlocked bootloader.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.oe.app","versions":["2.5.2"]}]},{"name":"remove-screenshot-restriction","description":"Removes the restriction of taking screenshots in apps that normally wouldn\u0027t allow it.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"return-youtube-dislike","description":"Shows the dislike count of videos using the Return YouTube Dislike API.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","video-id-hook","return-youtube-dislike-resource-patch","player-type-hook"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"seekbar-tapping","description":"Enables tap-to-seek on the seekbar of the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"settings","description":"Adds ReVanced settings to TikTok.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":["27.8.3"]},{"name":"com.zhiliaoapp.musically","versions":["27.8.3"]}]},{"name":"settings","description":"Adds settings menu to Twitch.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings-resource-patch"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":[]}]},{"name":"show-deleted-messages","description":"Shows deleted chat messages behind a clickable spoiler.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":[]}]},{"name":"show-seekbar","description":"Shows progress bar for all video.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"sim-spoof","description":"Spoofs the information which is retrieved from the sim-card.","version":"0.0.1","excluded":true,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":["27.8.3"]},{"name":"com.zhiliaoapp.musically","versions":["27.8.3"]}]},{"name":"sponsorblock","description":"Integrates SponsorBlock which allows skipping video segments such as sponsored content.","version":"0.0.1","excluded":false,"options":[],"dependencies":["video-information","player-controls-bytecode-patch","player-type-hook","integrations","sponsorblock-resource-patch","video-id-hook"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"spoof-app-version","description":"Tricks YouTube into thinking, you are running an older version of the app. One of the side effects also includes restoring the old UI.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"spoof-signature","description":"Spoofs the signature of the app.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.oe.app","versions":["2.5.2"]}]},{"name":"spoof-wifi-connection","description":"Spoofs an existing Wi-Fi connection.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"spotify-theme","description":"Applies a custom theme.","version":"0.0.1","excluded":false,"options":[{"key":"backgroundColor","title":"Background color","description":"The background color. Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"accentColor","title":"Accent color","description":"The accent color (\u0027spotify green\u0027 by default). Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"accentPressedColor","title":"Pressed accent for the dark theme","description":"The color when accented buttons are pressed, by default slightly darker than accent. Can be a hex color or a resource reference.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.spotify.music","versions":[]}]},{"name":"swipe-controls","description":"Adds volume and brightness swipe controls.","version":"0.0.3","excluded":false,"options":[],"dependencies":["integrations","player-type-hook","swipe-controls-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"tablet-mini-player","description":"Enables the tablet mini player layout.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]},{"name":"tasteBuilder-remover","description":"Removes the \"Tell us which artists you like\" card from the home screen.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":["5.21.52","5.22.54","5.23.50","5.25.51","5.25.52","5.26.52","5.27.51","5.28.52","5.29.52","5.31.50","5.34.51","5.36.51","5.38.53","5.39.52","5.40.51","5.41.50"]}]},{"name":"theme","description":"Applies a custom theme.","version":"0.0.1","excluded":false,"options":[{"key":"darkThemeBackgroundColor","title":"Background color for the dark theme","description":"The background color of the dark theme. Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"lightThemeBackgroundColor","title":"Background color for the light theme","description":"The background color of the light theme. Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"darkThemeSeekbarColor","title":"Dark theme seekbar color","description":"The background color of the seekbar of the dark theme. Leave empty for default color.","required":false,"choices":null}],"dependencies":["litho-components-theme"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"timeline-ads","description":"Removes ads from the Twitter timeline. Might require clearing app data to remove already cached ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.twitter.android","versions":[]}]},{"name":"unlock-prime","description":"Unlocks Nova Prime and all functions of the app.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.teslacoilsw.launcher","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"co.windyapp.android","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.awedea.nyx","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"ginlemon.iconpackstudio","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all professional features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"org.totschnig.myexpenses","versions":[]}]},{"name":"unlock-pro","description":"Unlocks pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ithebk.expensemanager","versions":[]}]},{"name":"unlock-themes","description":"Unlocks all themes.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ticktick.task","versions":[]}]},{"name":"unlock-trial","description":"Unlocks the trial version.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"net.dinglisch.android.taskerm","versions":[]}]},{"name":"upgrade-button-remover","description":"Removes the upgrade tab from the pivot bar.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":["5.14.53","5.16.51","5.17.51","5.21.52","5.22.54","5.23.50","5.25.51","5.25.52","5.26.52","5.27.51","5.28.52","5.29.52","5.31.50","5.34.51","5.36.51","5.38.53","5.39.52","5.40.51","5.41.50"]}]},{"name":"video-ads","description":"Removes ads in the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36"]}]}]
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/all/connectivity/wifi/spoof/patch/SpoofWifiPatch.kt b/src/main/kotlin/app/revanced/patches/all/connectivity/wifi/spoof/patch/SpoofWifiPatch.kt
new file mode 100644
index 000000000..0c6bdeae8
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/all/connectivity/wifi/spoof/patch/SpoofWifiPatch.kt
@@ -0,0 +1,206 @@
+package app.revanced.patches.all.connectivity.wifi.spoof.patch
+
+import app.revanced.patcher.annotation.Description
+import app.revanced.patcher.annotation.Name
+import app.revanced.patcher.annotation.Version
+import app.revanced.patcher.patch.annotations.Patch
+import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
+import app.revanced.util.patch.*
+import org.jf.dexlib2.iface.ClassDef
+import org.jf.dexlib2.iface.Method
+import org.jf.dexlib2.iface.instruction.Instruction
+import java.util.*
+
+@Patch(false)
+@Name("spoof-wifi-connection")
+@Description("Spoofs an existing Wi-Fi connection.")
+@Version("0.0.1")
+internal class SpoofWifiPatch : AbstractTransformInstructionsPatch() {
+
+ private companion object {
+ const val INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX = "Lapp/revanced/all/connectivity/wifi/spoof/SpoofWifiPatch"
+ const val INTEGRATIONS_CLASS_DESCRIPTOR = "${INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX};"
+ }
+
+ // Information about method calls we want to replace
+ enum class MethodCall(
+ override val definedClassName: String,
+ override val methodName: String,
+ override val methodParams: Array,
+ override val returnType: String,
+ ): IMethodCall {
+ GetSystemService1(
+ "Landroid/content/Context;",
+ "getSystemService",
+ arrayOf("Ljava/lang/String;"),
+ "Ljava/lang/Object;",
+ ),
+ GetSystemService2(
+ "Landroid/content/Context;",
+ "getSystemService",
+ arrayOf("Ljava/lang/Class;"),
+ "Ljava/lang/Object;",
+ ),
+ GetActiveNetworkInfo(
+ "Landroid/net/ConnectivityManager;",
+ "getActiveNetworkInfo",
+ arrayOf(),
+ "Landroid/net/NetworkInfo;",
+ ),
+ IsConnected(
+ "Landroid/net/NetworkInfo;",
+ "isConnected",
+ arrayOf(),
+ "Z",
+ ),
+ IsConnectedOrConnecting(
+ "Landroid/net/NetworkInfo;",
+ "isConnectedOrConnecting",
+ arrayOf(),
+ "Z",
+ ),
+ IsAvailable(
+ "Landroid/net/NetworkInfo;",
+ "isAvailable",
+ arrayOf(),
+ "Z",
+ ),
+ GetState(
+ "Landroid/net/NetworkInfo;",
+ "getState",
+ arrayOf(),
+ "Landroid/net/NetworkInfo\$State;",
+ ),
+ GetDetailedState(
+ "Landroid/net/NetworkInfo;",
+ "getDetailedState",
+ arrayOf(),
+ "Landroid/net/NetworkInfo\$DetailedState;",
+ ),
+ IsActiveNetworkMetered(
+ "Landroid/net/ConnectivityManager;",
+ "isActiveNetworkMetered",
+ arrayOf(),
+ "Z",
+ ),
+ GetActiveNetwork(
+ "Landroid/net/ConnectivityManager;",
+ "getActiveNetwork",
+ arrayOf(),
+ "Landroid/net/Network;",
+ ),
+ GetNetworkInfo(
+ "Landroid/net/ConnectivityManager;",
+ "getNetworkInfo",
+ arrayOf("Landroid/net/Network;"),
+ "Landroid/net/NetworkInfo;",
+ ),
+ HasTransport(
+ "Landroid/net/NetworkCapabilities;",
+ "hasTransport",
+ arrayOf("I"),
+ "Z",
+ ),
+ HasCapability(
+ "Landroid/net/NetworkCapabilities;",
+ "hasCapability",
+ arrayOf("I"),
+ "Z",
+ ),
+ RegisterBestMatchingNetworkCallback(
+ "Landroid/net/ConnectivityManager;",
+ "registerBestMatchingNetworkCallback",
+ arrayOf("Landroid/net/NetworkRequest;", "Landroid/net/ConnectivityManager\$NetworkCallback;", "Landroid/os/Handler;"),
+ "V",
+ ),
+ RegisterDefaultNetworkCallback1(
+ "Landroid/net/ConnectivityManager;",
+ "registerDefaultNetworkCallback",
+ arrayOf("Landroid/net/ConnectivityManager\$NetworkCallback;"),
+ "V",
+ ),
+ RegisterDefaultNetworkCallback2(
+ "Landroid/net/ConnectivityManager;",
+ "registerDefaultNetworkCallback",
+ arrayOf("Landroid/net/ConnectivityManager\$NetworkCallback;", "Landroid/os/Handler;"),
+ "V",
+ ),
+ RegisterNetworkCallback1(
+ "Landroid/net/ConnectivityManager;",
+ "registerNetworkCallback",
+ arrayOf("Landroid/net/NetworkRequest;", "Landroid/net/ConnectivityManager\$NetworkCallback;"),
+ "V",
+ ),
+ RegisterNetworkCallback2(
+ "Landroid/net/ConnectivityManager;",
+ "registerNetworkCallback",
+ arrayOf("Landroid/net/NetworkRequest;", "Landroid/app/PendingIntent;"),
+ "V",
+ ),
+ RegisterNetworkCallback3(
+ "Landroid/net/ConnectivityManager;",
+ "registerNetworkCallback",
+ arrayOf("Landroid/net/NetworkRequest;", "Landroid/net/ConnectivityManager\$NetworkCallback;", "Landroid/os/Handler;"),
+ "V",
+ ),
+ RequestNetwork1(
+ "Landroid/net/ConnectivityManager;",
+ "requestNetwork",
+ arrayOf("Landroid/net/NetworkRequest;", "Landroid/net/ConnectivityManager\$NetworkCallback;"),
+ "V",
+ ),
+ RequestNetwork2(
+ "Landroid/net/ConnectivityManager;",
+ "requestNetwork",
+ arrayOf("Landroid/net/NetworkRequest;", "Landroid/net/ConnectivityManager\$NetworkCallback;", "I"),
+ "V",
+ ),
+ RequestNetwork3(
+ "Landroid/net/ConnectivityManager;",
+ "requestNetwork",
+ arrayOf("Landroid/net/NetworkRequest;", "Landroid/net/ConnectivityManager\$NetworkCallback;", "Landroid/os/Handler;"),
+ "V",
+ ),
+ RequestNetwork4(
+ "Landroid/net/ConnectivityManager;",
+ "requestNetwork",
+ arrayOf("Landroid/net/NetworkRequest;", "Landroid/app/PendingIntent;"),
+ "V",
+ ),
+ RequestNetwork5(
+ "Landroid/net/ConnectivityManager;",
+ "requestNetwork",
+ arrayOf("Landroid/net/NetworkRequest;", "Landroid/net/ConnectivityManager\$NetworkCallback;", "Landroid/os/Handler;", "I"),
+ "V",
+ ),
+ UnregisterNetworkCallback1(
+ "Landroid/net/ConnectivityManager;",
+ "unregisterNetworkCallback",
+ arrayOf("Landroid/net/ConnectivityManager\$NetworkCallback;"),
+ "V",
+ ),
+ UnregisterNetworkCallback2(
+ "Landroid/net/ConnectivityManager;",
+ "unregisterNetworkCallback",
+ arrayOf("Landroid/app/PendingIntent;"),
+ "V",
+ );
+ }
+
+ override fun filterMap(
+ classDef: ClassDef,
+ method: Method,
+ instruction: Instruction,
+ instructionIndex: Int
+ ) = filterMapInstruction35c(
+ INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX,
+ classDef,
+ instruction,
+ instructionIndex
+ )
+
+ override fun transform(mutableMethod: MutableMethod, entry: Instruction35cInfo) {
+ val (methodType, instruction, instructionIndex) = entry
+ methodType.replaceInvokeVirtualWithIntegrations(INTEGRATIONS_CLASS_DESCRIPTOR, mutableMethod, instruction, instructionIndex)
+ }
+}
diff --git a/src/main/kotlin/app/revanced/patches/all/screenshot/removerestriction/patch/RemoveScreenshotRestrictionPatch.kt b/src/main/kotlin/app/revanced/patches/all/screenshot/removerestriction/patch/RemoveScreenshotRestrictionPatch.kt
index c3d2f86ec..b9f26c99b 100644
--- a/src/main/kotlin/app/revanced/patches/all/screenshot/removerestriction/patch/RemoveScreenshotRestrictionPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/all/screenshot/removerestriction/patch/RemoveScreenshotRestrictionPatch.kt
@@ -1,106 +1,57 @@
package app.revanced.patches.all.screenshot.removerestriction.patch
-import app.revanced.extensions.findMutableMethodOf
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
-import app.revanced.patcher.data.BytecodeContext
-import app.revanced.patcher.extensions.replaceInstruction
-import app.revanced.patcher.patch.BytecodePatch
-import app.revanced.patcher.patch.PatchResult
-import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
-import org.jf.dexlib2.Opcode
-import org.jf.dexlib2.iface.instruction.formats.Instruction35c
-import org.jf.dexlib2.iface.reference.MethodReference
+import app.revanced.util.patch.*
+import org.jf.dexlib2.iface.ClassDef
+import org.jf.dexlib2.iface.Method
+import org.jf.dexlib2.iface.instruction.Instruction
+import java.util.*
@Patch(false)
@Name("remove-screenshot-restriction")
-@Description("Removes the restriction of making screenshots.")
+@Description("Removes the restriction of taking screenshots in apps that normally wouldn't allow it.")
@Version("0.0.1")
-class RemoveScreenshotRestrictionPatch : BytecodePatch() {
+internal class RemoveScreenshotRestrictionPatch : AbstractTransformInstructionsPatch() {
private companion object {
- const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/all/screenshot/removerestriction/RemoveScreenshotRestrictionPatch;"
+ const val INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX =
+ "Lapp/revanced/all/screenshot/removerestriction/RemoveScreenshotRestrictionPatch"
+ const val INTEGRATIONS_CLASS_DESCRIPTOR = "$INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX;"
}
// Information about method calls we want to replace
- private enum class MethodCall(
- val definedClassName: String,
- val methodName: String,
- val replacementMethodDefinition: String
- ) {
+ enum class MethodCall(
+ override val definedClassName: String,
+ override val methodName: String,
+ override val methodParams: Array,
+ override val returnType: String
+ ): IMethodCall {
SetFlags(
"Landroid/view/Window;",
"setFlags",
- "setFlags(Landroid/view/Window;II)V",
+ arrayOf("I", "I"),
+ "V",
);
-
- fun replaceInstruction(method: MutableMethod, instruction: Instruction35c, instructionIndex: Int) {
- when (this) {
- SetFlags -> {
- method.replaceInstruction(
- instructionIndex,
- "invoke-static { v${instruction.registerC}, v${instruction.registerD}, v${instruction.registerE} }, ${INTEGRATIONS_CLASS_DESCRIPTOR}->${replacementMethodDefinition}"
- )
- }
- }
- }
-
- companion object {
- fun fromMethodReference(methodReference: MethodReference) = values().firstOrNull { search ->
- search.definedClassName == methodReference.definingClass && search.methodName == methodReference.name
- }
- }
}
- override fun execute(context: BytecodeContext): PatchResult {
- // Find all instructions where one of the methods is called
- buildMap {
- context.classes.forEach { classDef ->
- if (classDef.type == INTEGRATIONS_CLASS_DESCRIPTOR) {
- // avoid infinite recursion
- return@forEach
- }
+ override fun filterMap(
+ classDef: ClassDef,
+ method: Method,
+ instruction: Instruction,
+ instructionIndex: Int
+ ) = filterMapInstruction35c(
+ INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX,
+ classDef,
+ instruction,
+ instructionIndex
+ )
- classDef.methods.let { methods ->
- buildMap methodList@{
- methods.forEach methods@{ method ->
- with(method.implementation?.instructions ?: return@methods) {
- ArrayDeque>().also { patchIndices ->
- this.forEachIndexed { index, instruction ->
- if (instruction.opcode != Opcode.INVOKE_VIRTUAL) return@forEachIndexed
-
- val invokeInstruction = instruction as Instruction35c
- val methodRef = invokeInstruction.reference as MethodReference
- val methodCall = MethodCall.fromMethodReference(methodRef) ?: return@forEachIndexed
-
- patchIndices.add(Triple(methodCall, invokeInstruction, index))
- }
- }.also { if (it.isEmpty()) return@methods }.let { patches ->
- put(method, patches)
- }
- }
- }
- }
- }.also { if (it.isEmpty()) return@forEach }.let { methodPatches ->
- put(classDef, methodPatches)
- }
- }
- }.forEach { (classDef, methods) ->
- // And finally replace the instructions...
- with(context.proxy(classDef).mutableClass) {
- methods.forEach { (method, patches) ->
- val mutableMethod = findMutableMethodOf(method)
- while (!patches.isEmpty()) {
- val (methodType, instruction, instructionIndex) = patches.removeLast()
- methodType.replaceInstruction(mutableMethod, instruction, instructionIndex)
- }
- }
- }
- }
-
- return PatchResultSuccess()
+ override fun transform(mutableMethod: MutableMethod, entry: Instruction35cInfo) {
+ val (methodType, instruction, instructionIndex) = entry
+ methodType.replaceInvokeVirtualWithIntegrations(INTEGRATIONS_CLASS_DESCRIPTOR, mutableMethod, instruction, instructionIndex)
}
}
diff --git a/src/main/kotlin/app/revanced/patches/finanzonline/detection/root/patch/RootDetectionPatch.kt b/src/main/kotlin/app/revanced/patches/finanzonline/detection/root/patch/RootDetectionPatch.kt
index 216ba2cd9..4995e0705 100644
--- a/src/main/kotlin/app/revanced/patches/finanzonline/detection/root/patch/RootDetectionPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/finanzonline/detection/root/patch/RootDetectionPatch.kt
@@ -15,7 +15,7 @@ import app.revanced.patches.finanzonline.detection.shared.annotations.DetectionC
@Patch
@Name("remove-root-detection")
-@Description("Removes the check for root permissions")
+@Description("Removes the check for root permissions.")
@DetectionCompatibility
@Version("0.0.1")
class RootDetectionPatch : BytecodePatch(
diff --git a/src/main/kotlin/app/revanced/patches/music/ad/video/annotations/MusicVideoAdsCompatibility.kt b/src/main/kotlin/app/revanced/patches/music/ad/video/annotations/MusicVideoAdsCompatibility.kt
index 674d91125..46380e541 100644
--- a/src/main/kotlin/app/revanced/patches/music/ad/video/annotations/MusicVideoAdsCompatibility.kt
+++ b/src/main/kotlin/app/revanced/patches/music/ad/video/annotations/MusicVideoAdsCompatibility.kt
@@ -24,7 +24,8 @@ import app.revanced.patcher.annotation.Package
"5.36.51",
"5.38.53",
"5.39.52",
- "5.40.51"
+ "5.40.51",
+ "5.41.50"
)
)]
)
diff --git a/src/main/kotlin/app/revanced/patches/music/audio/codecs/annotations/CodecsUnlockCompatibility.kt b/src/main/kotlin/app/revanced/patches/music/audio/codecs/annotations/CodecsUnlockCompatibility.kt
index f7845cbe1..9d12ae272 100644
--- a/src/main/kotlin/app/revanced/patches/music/audio/codecs/annotations/CodecsUnlockCompatibility.kt
+++ b/src/main/kotlin/app/revanced/patches/music/audio/codecs/annotations/CodecsUnlockCompatibility.kt
@@ -24,7 +24,8 @@ import app.revanced.patcher.annotation.Package
"5.36.51",
"5.38.53",
"5.39.52",
- "5.40.51"
+ "5.40.51",
+ "5.41.50"
)
)]
)
diff --git a/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/annotations/ExclusiveAudioCompatibility.kt b/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/annotations/ExclusiveAudioCompatibility.kt
index e2209b599..812629141 100644
--- a/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/annotations/ExclusiveAudioCompatibility.kt
+++ b/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/annotations/ExclusiveAudioCompatibility.kt
@@ -24,7 +24,8 @@ import app.revanced.patcher.annotation.Package
"5.36.51",
"5.38.53",
"5.39.52",
- "5.40.51"
+ "5.40.51",
+ "5.41.50"
)
)]
)
diff --git a/src/main/kotlin/app/revanced/patches/music/layout/compactheader/annotations/CompactHeaderCompatibility.kt b/src/main/kotlin/app/revanced/patches/music/layout/compactheader/annotations/CompactHeaderCompatibility.kt
index ec3539ed3..800125659 100644
--- a/src/main/kotlin/app/revanced/patches/music/layout/compactheader/annotations/CompactHeaderCompatibility.kt
+++ b/src/main/kotlin/app/revanced/patches/music/layout/compactheader/annotations/CompactHeaderCompatibility.kt
@@ -23,7 +23,8 @@ import app.revanced.patcher.annotation.Package
"5.36.51",
"5.38.53",
"5.39.52",
- "5.40.51"
+ "5.40.51",
+ "5.41.50"
)
)]
)
diff --git a/src/main/kotlin/app/revanced/patches/music/layout/minimizedplayback/annotations/MinimizedPlaybackCompatibility.kt b/src/main/kotlin/app/revanced/patches/music/layout/minimizedplayback/annotations/MinimizedPlaybackCompatibility.kt
index 7216851b0..691da1563 100644
--- a/src/main/kotlin/app/revanced/patches/music/layout/minimizedplayback/annotations/MinimizedPlaybackCompatibility.kt
+++ b/src/main/kotlin/app/revanced/patches/music/layout/minimizedplayback/annotations/MinimizedPlaybackCompatibility.kt
@@ -24,7 +24,8 @@ import app.revanced.patcher.annotation.Package
"5.36.51",
"5.38.53",
"5.39.52",
- "5.40.51"
+ "5.40.51",
+ "5.41.50"
)
)]
)
diff --git a/src/main/kotlin/app/revanced/patches/music/layout/tastebuilder/annotations/RemoveTasteBuilderCompatibility.kt b/src/main/kotlin/app/revanced/patches/music/layout/tastebuilder/annotations/RemoveTasteBuilderCompatibility.kt
index 650674b25..d5f2bd0b7 100644
--- a/src/main/kotlin/app/revanced/patches/music/layout/tastebuilder/annotations/RemoveTasteBuilderCompatibility.kt
+++ b/src/main/kotlin/app/revanced/patches/music/layout/tastebuilder/annotations/RemoveTasteBuilderCompatibility.kt
@@ -26,7 +26,8 @@ import app.revanced.patcher.annotation.Package
"5.36.51",
"5.38.53",
"5.39.52",
- "5.40.51"
+ "5.40.51",
+ "5.41.50"
)
)]
)
diff --git a/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/annotations/RemoveUpgradeButtonCompatibility.kt b/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/annotations/RemoveUpgradeButtonCompatibility.kt
index e6aca8dff..73efd97bf 100644
--- a/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/annotations/RemoveUpgradeButtonCompatibility.kt
+++ b/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/annotations/RemoveUpgradeButtonCompatibility.kt
@@ -24,7 +24,8 @@ import app.revanced.patcher.annotation.Package
"5.36.51",
"5.38.53",
"5.39.52",
- "5.40.51"
+ "5.40.51",
+ "5.41.50"
)
)]
)
diff --git a/src/main/kotlin/app/revanced/patches/music/misc/microg/annotations/MusicMicroGPatchCompatibility.kt b/src/main/kotlin/app/revanced/patches/music/misc/microg/annotations/MusicMicroGPatchCompatibility.kt
index 571ac001c..c80a24836 100644
--- a/src/main/kotlin/app/revanced/patches/music/misc/microg/annotations/MusicMicroGPatchCompatibility.kt
+++ b/src/main/kotlin/app/revanced/patches/music/misc/microg/annotations/MusicMicroGPatchCompatibility.kt
@@ -22,9 +22,10 @@ import app.revanced.patcher.annotation.Package
"5.31.50",
"5.34.51",
"5.36.51",
- "5.38.53",
- "5.39.52",
- "5.40.51"
+ "5.38.53",
+ "5.39.52",
+ "5.40.51",
+ "5.41.50"
)
)]
)
diff --git a/src/main/kotlin/app/revanced/patches/music/premium/backgroundplay/annotations/BackgroundPlayCompatibility.kt b/src/main/kotlin/app/revanced/patches/music/premium/backgroundplay/annotations/BackgroundPlayCompatibility.kt
index 3dd028e21..c857e828a 100644
--- a/src/main/kotlin/app/revanced/patches/music/premium/backgroundplay/annotations/BackgroundPlayCompatibility.kt
+++ b/src/main/kotlin/app/revanced/patches/music/premium/backgroundplay/annotations/BackgroundPlayCompatibility.kt
@@ -24,7 +24,8 @@ import app.revanced.patcher.annotation.Package
"5.36.51",
"5.38.53",
"5.39.52",
- "5.40.51"
+ "5.40.51",
+ "5.41.50"
)
)]
)
diff --git a/src/main/kotlin/app/revanced/patches/netguard/broadcasts/removerestriction/resource/annotations/RemoveBroadcastsRestrictionCompatibility.kt b/src/main/kotlin/app/revanced/patches/netguard/broadcasts/removerestriction/resource/annotations/RemoveBroadcastsRestrictionCompatibility.kt
new file mode 100644
index 000000000..0a8a7e56a
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/netguard/broadcasts/removerestriction/resource/annotations/RemoveBroadcastsRestrictionCompatibility.kt
@@ -0,0 +1,9 @@
+package app.revanced.patches.netguard.broadcasts.removerestriction.resource.annotations
+
+import app.revanced.patcher.annotation.Compatibility
+import app.revanced.patcher.annotation.Package
+
+@Compatibility([Package("eu.faircode.netguard")])
+@Target(AnnotationTarget.CLASS)
+@Retention(AnnotationRetention.RUNTIME)
+annotation class RemoveBroadcastsRestrictionCompatibility
diff --git a/src/main/kotlin/app/revanced/patches/netguard/broadcasts/removerestriction/resource/patch/RemoveBroadcastsRestrictionPatch.kt b/src/main/kotlin/app/revanced/patches/netguard/broadcasts/removerestriction/resource/patch/RemoveBroadcastsRestrictionPatch.kt
new file mode 100644
index 000000000..728e44813
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/netguard/broadcasts/removerestriction/resource/patch/RemoveBroadcastsRestrictionPatch.kt
@@ -0,0 +1,40 @@
+package app.revanced.patches.netguard.broadcasts.removerestriction.resource.patch
+
+import app.revanced.patcher.annotation.Description
+import app.revanced.patcher.annotation.Name
+import app.revanced.patcher.annotation.Version
+import app.revanced.patcher.data.ResourceContext
+import app.revanced.patcher.patch.PatchResult
+import app.revanced.patcher.patch.PatchResultSuccess
+import app.revanced.patcher.patch.ResourcePatch
+import app.revanced.patcher.patch.annotations.Patch
+import app.revanced.patches.netguard.broadcasts.removerestriction.resource.annotations.RemoveBroadcastsRestrictionCompatibility
+import org.w3c.dom.Element
+
+@Patch(false)
+@Name("remove-broadcasts-restriction")
+@Description("Enables starting/stopping NetGuard via broadcasts.")
+@RemoveBroadcastsRestrictionCompatibility
+@Version("0.0.1")
+class RemoveBroadcastsRestrictionPatch : ResourcePatch {
+ override fun execute(context: ResourceContext): PatchResult {
+ context.xmlEditor["AndroidManifest.xml"].use { dom ->
+ val applicationNode = dom
+ .file
+ .getElementsByTagName("application")
+ .item(0) as Element
+
+ applicationNode.getElementsByTagName("receiver").also { list ->
+ for (i in 0 until list.length) {
+ val element = list.item(i) as? Element ?: continue
+ if (element.getAttribute("android:name") == "eu.faircode.netguard.WidgetAdmin") {
+ element.removeAttribute("android:permission")
+ break
+ }
+ }
+ }
+ }
+
+ return PatchResultSuccess()
+ }
+}
diff --git a/src/main/kotlin/app/revanced/patches/spotify/layout/theme/patch/ThemePatch.kt b/src/main/kotlin/app/revanced/patches/spotify/layout/theme/patch/ThemePatch.kt
index dfbc7fd17..731f1b3d1 100644
--- a/src/main/kotlin/app/revanced/patches/spotify/layout/theme/patch/ThemePatch.kt
+++ b/src/main/kotlin/app/revanced/patches/spotify/layout/theme/patch/ThemePatch.kt
@@ -5,14 +5,11 @@ import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.*
-import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.spotify.layout.theme.annotations.ThemeCompatibility
-import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch
import org.w3c.dom.Element
@Patch
-@DependsOn([FixLocaleConfigErrorPatch::class])
@Name("spotify-theme")
@Description("Applies a custom theme.")
@ThemeCompatibility
diff --git a/src/main/kotlin/app/revanced/patches/spotify/lite/ondemand/annotations/OnDemandCompatibility.kt b/src/main/kotlin/app/revanced/patches/spotify/lite/ondemand/annotations/OnDemandCompatibility.kt
new file mode 100644
index 000000000..741e23b86
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/spotify/lite/ondemand/annotations/OnDemandCompatibility.kt
@@ -0,0 +1,11 @@
+package app.revanced.patches.spotify.lite.ondemand.annotations
+
+import app.revanced.patcher.annotation.Compatibility
+import app.revanced.patcher.annotation.Package
+
+@Compatibility(
+ [Package("com.spotify.lite")]
+)
+@Target(AnnotationTarget.CLASS)
+@Retention(AnnotationRetention.RUNTIME)
+internal annotation class OnDemandCompatibility
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/spotify/lite/ondemand/fingerprints/OnDemandFingerprint.kt b/src/main/kotlin/app/revanced/patches/spotify/lite/ondemand/fingerprints/OnDemandFingerprint.kt
new file mode 100644
index 000000000..099eaa438
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/spotify/lite/ondemand/fingerprints/OnDemandFingerprint.kt
@@ -0,0 +1,25 @@
+package app.revanced.patches.spotify.lite.ondemand.fingerprints
+
+import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
+import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
+import org.jf.dexlib2.Opcode
+
+@FuzzyPatternScanMethod(2)
+object OnDemandFingerprint : MethodFingerprint(
+ "L",
+ parameters = listOf(),
+ opcodes = listOf(
+ Opcode.INVOKE_STATIC,
+ Opcode.MOVE_RESULT,
+ Opcode.INVOKE_STATIC,
+ Opcode.MOVE_RESULT_OBJECT,
+ Opcode.IF_EQZ,
+ Opcode.SGET_OBJECT,
+ Opcode.GOTO,
+ Opcode.SGET_OBJECT,
+ Opcode.INVOKE_VIRTUAL,
+ Opcode.MOVE_RESULT,
+ Opcode.IPUT,
+ Opcode.RETURN_OBJECT
+ )
+)
diff --git a/src/main/kotlin/app/revanced/patches/spotify/lite/ondemand/patch/OnDemandPatch.kt b/src/main/kotlin/app/revanced/patches/spotify/lite/ondemand/patch/OnDemandPatch.kt
new file mode 100644
index 000000000..bbb5159ef
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/spotify/lite/ondemand/patch/OnDemandPatch.kt
@@ -0,0 +1,34 @@
+package app.revanced.patches.spotify.lite.ondemand.patch
+
+import app.revanced.extensions.toErrorResult
+import app.revanced.patcher.annotation.Description
+import app.revanced.patcher.annotation.Name
+import app.revanced.patcher.annotation.Version
+import app.revanced.patcher.data.BytecodeContext
+import app.revanced.patcher.extensions.addInstruction
+import app.revanced.patcher.patch.BytecodePatch
+import app.revanced.patcher.patch.PatchResult
+import app.revanced.patcher.patch.PatchResultSuccess
+import app.revanced.patcher.patch.annotations.Patch
+import app.revanced.patches.spotify.lite.ondemand.annotations.OnDemandCompatibility
+import app.revanced.patches.spotify.lite.ondemand.fingerprints.OnDemandFingerprint
+
+@Patch
+@Name("enable-on-demand")
+@Description("Enables listening to songs on-demand, allowing to play any song from playlists, albums or artists without limitations. This does not remove ads.")
+@OnDemandCompatibility
+@Version("0.0.1")
+class OnDemandPatch : BytecodePatch(
+ listOf(
+ OnDemandFingerprint
+ )
+) {
+ override fun execute(context: BytecodeContext): PatchResult {
+ OnDemandFingerprint.result?.apply {
+ val insertIndex = scanResult.patternScanResult!!.endIndex - 1
+ // Spoof a premium account
+ mutableMethod.addInstruction(insertIndex, "const/4 v0, 0x2")
+ } ?: return OnDemandFingerprint.toErrorResult()
+ return PatchResultSuccess()
+ }
+}
diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/general/resource/patch/GeneralAdsResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/general/resource/patch/GeneralAdsResourcePatch.kt
index bfbf411b0..734869dcf 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/ad/general/resource/patch/GeneralAdsResourcePatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/ad/general/resource/patch/GeneralAdsResourcePatch.kt
@@ -10,13 +10,11 @@ import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
import app.revanced.patches.shared.settings.preference.impl.*
import app.revanced.patches.youtube.ad.general.annotation.GeneralAdsCompatibility
import app.revanced.patches.youtube.misc.litho.filter.patch.LithoFilterPatch
-import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch.PreferenceScreen
@DependsOn(
dependencies = [
- FixLocaleConfigErrorPatch::class,
LithoFilterPatch::class,
SettingsPatch::class,
ResourceMappingPatch::class
diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/resource/patch/CopyVideoUrlResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/resource/patch/CopyVideoUrlResourcePatch.kt
index de4a3c522..6e60282cd 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/resource/patch/CopyVideoUrlResourcePatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/resource/patch/CopyVideoUrlResourcePatch.kt
@@ -12,7 +12,6 @@ import app.revanced.patches.shared.settings.preference.impl.PreferenceScreen
import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
import app.revanced.patches.youtube.interaction.copyvideourl.annotation.CopyVideoUrlCompatibility
-import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch
import app.revanced.patches.youtube.misc.playercontrols.resource.patch.BottomControlsResourcePatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.util.resources.ResourceUtils
@@ -20,7 +19,7 @@ import app.revanced.util.resources.ResourceUtils.copyResources
@Name("copy-video-url-resource")
@Description("Makes necessary changes to resources for copy video link buttons.")
-@DependsOn([BottomControlsResourcePatch::class, FixLocaleConfigErrorPatch::class, SettingsPatch::class])
+@DependsOn([BottomControlsResourcePatch::class, SettingsPatch::class])
@CopyVideoUrlCompatibility
@Version("0.0.1")
class CopyVideoUrlResourcePatch : ResourcePatch {
diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/resource/patch/DownloadsResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/resource/patch/DownloadsResourcePatch.kt
index 9589c4c74..f628f4d0c 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/resource/patch/DownloadsResourcePatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/resource/patch/DownloadsResourcePatch.kt
@@ -10,7 +10,6 @@ import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patches.shared.settings.preference.impl.*
import app.revanced.patches.youtube.interaction.downloads.annotation.DownloadsCompatibility
-import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch
import app.revanced.patches.youtube.misc.playercontrols.resource.patch.BottomControlsResourcePatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.util.resources.ResourceUtils
@@ -18,7 +17,7 @@ import app.revanced.util.resources.ResourceUtils.copyResources
import app.revanced.util.resources.ResourceUtils.mergeStrings
@Name("downloads-resource-patch")
-@DependsOn([BottomControlsResourcePatch::class, FixLocaleConfigErrorPatch::class, SettingsPatch::class])
+@DependsOn([BottomControlsResourcePatch::class, SettingsPatch::class])
@Description("Makes necessary changes to resources for the download button.")
@DownloadsCompatibility
@Version("0.0.1")
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/branding/header/patch/PremiumHeadingPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/branding/header/patch/PremiumHeadingPatch.kt
index 83eca468f..2d358f79c 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/branding/header/patch/PremiumHeadingPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/branding/header/patch/PremiumHeadingPatch.kt
@@ -8,16 +8,13 @@ import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.ResourcePatch
-import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.youtube.layout.branding.header.annotations.PremiumHeadingCompatibility
-import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch
import java.nio.file.Files
import java.nio.file.StandardCopyOption
import kotlin.io.path.exists
@Patch
-@DependsOn([FixLocaleConfigErrorPatch::class])
@Name("premium-heading")
@Description("Shows premium branding on the home screen.")
@PremiumHeadingCompatibility
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/branding/icon/patch/CustomBrandingPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/branding/icon/patch/CustomBrandingPatch.kt
index f373fd6c0..f9d93d4cd 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/branding/icon/patch/CustomBrandingPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/branding/icon/patch/CustomBrandingPatch.kt
@@ -5,17 +5,14 @@ import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.*
-import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.youtube.layout.branding.icon.annotations.CustomBrandingCompatibility
-import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch
import app.revanced.util.resources.ResourceUtils
import app.revanced.util.resources.ResourceUtils.copyResources
import java.io.File
import java.nio.file.Files
@Patch
-@DependsOn([FixLocaleConfigErrorPatch::class])
@Name("custom-branding")
@Description("Changes the YouTube launcher icon and name to your choice (defaults to ReVanced).")
@CustomBrandingCompatibility
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/patch/HideButtonsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/patch/HideButtonsPatch.kt
index bd82e1dda..3de828654 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/patch/HideButtonsPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/patch/HideButtonsPatch.kt
@@ -9,18 +9,18 @@ import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
-import app.revanced.patches.youtube.misc.litho.filter.patch.LithoFilterPatch
-import app.revanced.patches.youtube.layout.buttons.annotations.HideButtonsCompatibility
import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
-import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.shared.settings.preference.impl.PreferenceScreen
import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
+import app.revanced.patches.youtube.layout.buttons.annotations.HideButtonsCompatibility
+import app.revanced.patches.youtube.misc.litho.filter.patch.LithoFilterPatch
+import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
@Patch
@DependsOn([ResourceMappingPatch::class, LithoFilterPatch::class])
-@Name("hide-video-buttons")
-@Description("Adds options to hide action buttons under a video.")
+@Name("hide-video-action-buttons")
+@Description("Adds the options to hide action buttons under a video.")
@HideButtonsCompatibility
@Version("0.0.1")
class HideButtonsPatch : ResourcePatch {
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/player/buttons/annotations/HidePlayerButtonsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/player/buttons/annotations/HidePlayerButtonsCompatibility.kt
new file mode 100644
index 000000000..bfce8a065
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/player/buttons/annotations/HidePlayerButtonsCompatibility.kt
@@ -0,0 +1,13 @@
+package app.revanced.patches.youtube.layout.player.buttons.annotations
+
+import app.revanced.patcher.annotation.Compatibility
+import app.revanced.patcher.annotation.Package
+
+@Compatibility(
+ [Package(
+ "com.google.android.youtube", arrayOf()
+ )]
+)
+@Target(AnnotationTarget.CLASS)
+@Retention(AnnotationRetention.RUNTIME)
+internal annotation class HidePlayerButtonsCompatibility
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/player/buttons/fingerprints/PlayerControlsVisibilityModelFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/player/buttons/fingerprints/PlayerControlsVisibilityModelFingerprint.kt
new file mode 100644
index 000000000..d8e45c03b
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/player/buttons/fingerprints/PlayerControlsVisibilityModelFingerprint.kt
@@ -0,0 +1,9 @@
+package app.revanced.patches.youtube.layout.player.buttons.fingerprints
+
+import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
+import org.jf.dexlib2.Opcode
+
+object PlayerControlsVisibilityModelFingerprint : MethodFingerprint(
+ opcodes = listOf(Opcode.INVOKE_DIRECT_RANGE),
+ strings = listOf("hasNext", "hasPrevious", "Missing required properties:")
+)
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/player/buttons/patch/HidePlayerButtonsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/player/buttons/patch/HidePlayerButtonsPatch.kt
new file mode 100644
index 000000000..bd12a8558
--- /dev/null
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/player/buttons/patch/HidePlayerButtonsPatch.kt
@@ -0,0 +1,74 @@
+package app.revanced.patches.youtube.layout.player.buttons.patch
+
+import app.revanced.extensions.toErrorResult
+import app.revanced.patcher.annotation.Description
+import app.revanced.patcher.annotation.Name
+import app.revanced.patcher.annotation.Version
+import app.revanced.patcher.data.BytecodeContext
+import app.revanced.patcher.extensions.addInstructions
+import app.revanced.patcher.extensions.instruction
+import app.revanced.patcher.patch.BytecodePatch
+import app.revanced.patcher.patch.PatchResult
+import app.revanced.patcher.patch.PatchResultSuccess
+import app.revanced.patcher.patch.annotations.DependsOn
+import app.revanced.patcher.patch.annotations.Patch
+import app.revanced.patches.shared.settings.preference.impl.StringResource
+import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
+import app.revanced.patches.youtube.layout.player.buttons.annotations.HidePlayerButtonsCompatibility
+import app.revanced.patches.youtube.layout.player.buttons.fingerprints.PlayerControlsVisibilityModelFingerprint
+import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
+import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
+import org.jf.dexlib2.iface.instruction.formats.Instruction3rc
+
+@Patch
+@DependsOn([IntegrationsPatch::class, SettingsPatch::class])
+@Name("hide-player-buttons")
+@Description("Adds the option to hide video player previous and next buttons.")
+@HidePlayerButtonsCompatibility
+@Version("0.0.1")
+class HidePlayerButtonsPatch : BytecodePatch(
+ listOf(PlayerControlsVisibilityModelFingerprint)
+) {
+ private object ParameterOffsets {
+ const val HAS_NEXT = 5
+ }
+
+ override fun execute(context: BytecodeContext): PatchResult {
+ SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
+ SwitchPreference(
+ "revanced_hide_player_buttons",
+ StringResource(
+ "revanced_hide_player_buttons_title",
+ "Hide previous & next video buttons"
+ ),
+ false,
+ StringResource(
+ "revanced_hide_player_buttons_summary_on",
+ "The buttons are hidden"
+ ),
+ StringResource(
+ "revanced_hide_player_buttons_summary_off",
+ "The buttons are shown"
+ )
+ )
+ )
+
+ PlayerControlsVisibilityModelFingerprint.result?.apply {
+ val callIndex = scanResult.patternScanResult!!.endIndex
+ val callInstruction = mutableMethod.instruction(callIndex) as Instruction3rc
+
+ // overriding this parameter register hides the previous and next buttons
+ val hasNextParameterRegister = callInstruction.startRegister + ParameterOffsets.HAS_NEXT
+
+ mutableMethod.addInstructions(
+ callIndex,
+ """
+ invoke-static { }, Lapp/revanced/integrations/patches/HidePlayerButtonsPatch;->hideButtons()Z
+ move-result v$hasNextParameterRegister
+ xor-int/lit8 v$hasNextParameterRegister, v$hasNextParameterRegister, 1
+ """
+ )
+ } ?: return PlayerControlsVisibilityModelFingerprint.toErrorResult()
+ return PatchResultSuccess()
+ }
+}
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/playerbuttonbackground/patch/PlayerButtonBackgroundPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/playerbuttonbackground/patch/PlayerButtonBackgroundPatch.kt
index c99615d93..32a7baa3d 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/playerbuttonbackground/patch/PlayerButtonBackgroundPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/playerbuttonbackground/patch/PlayerButtonBackgroundPatch.kt
@@ -7,15 +7,12 @@ import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
-import app.revanced.patcher.patch.annotations.DependsOn
-import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.ResourcePatch
+import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.youtube.layout.playerbuttonbackground.annotations.PlayerButtonBackgroundCompatibility
-import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch
import org.w3c.dom.Element
@Patch
-@DependsOn([FixLocaleConfigErrorPatch::class])
@Name("remove-player-button-background")
@Description("Removes the background from the video player buttons.")
@PlayerButtonBackgroundCompatibility
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/resource/patch/ReturnYouTubeDislikeResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/resource/patch/ReturnYouTubeDislikeResourcePatch.kt
index 35dd0af7c..16eaf3a26 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/resource/patch/ReturnYouTubeDislikeResourcePatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/resource/patch/ReturnYouTubeDislikeResourcePatch.kt
@@ -11,11 +11,10 @@ import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patches.shared.settings.preference.impl.Preference
import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.youtube.layout.returnyoutubedislike.annotations.ReturnYouTubeDislikeCompatibility
-import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.util.resources.ResourceUtils.mergeStrings
-@DependsOn([FixLocaleConfigErrorPatch::class, SettingsPatch::class])
+@DependsOn([SettingsPatch::class])
@Name("return-youtube-dislike-resource-patch")
@Description("Adds the preferences for Return YouTube Dislike.")
@ReturnYouTubeDislikeCompatibility
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/bytecode/patch/SponsorBlockBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/bytecode/patch/SponsorBlockBytecodePatch.kt
index 8ca1ab12e..0a75529e3 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/bytecode/patch/SponsorBlockBytecodePatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/bytecode/patch/SponsorBlockBytecodePatch.kt
@@ -46,7 +46,7 @@ import org.jf.dexlib2.iface.reference.StringReference
]
)
@Name("sponsorblock")
-@Description("Integrate SponsorBlock.")
+@Description("Integrates SponsorBlock which allows skipping video segments such as sponsored content.")
@SponsorBlockCompatibility
@Version("0.0.1")
class SponsorBlockBytecodePatch : BytecodePatch(
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/resource/patch/SponsorBlockResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/resource/patch/SponsorBlockResourcePatch.kt
index 4f85e378a..fb6f903cd 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/resource/patch/SponsorBlockResourcePatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/resource/patch/SponsorBlockResourcePatch.kt
@@ -11,7 +11,6 @@ import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
import app.revanced.patches.shared.settings.preference.impl.Preference
import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.youtube.layout.sponsorblock.annotations.SponsorBlockCompatibility
-import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.util.resources.ResourceUtils
import app.revanced.util.resources.ResourceUtils.copyResources
@@ -20,7 +19,7 @@ import app.revanced.util.resources.ResourceUtils.mergeStrings
@Name("sponsorblock-resource-patch")
@SponsorBlockCompatibility
-@DependsOn([FixLocaleConfigErrorPatch::class, SettingsPatch::class, ResourceMappingPatch::class])
+@DependsOn([SettingsPatch::class, ResourceMappingPatch::class])
@Version("0.0.1")
class SponsorBlockResourcePatch : ResourcePatch {
diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/theme/patch/ThemePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/theme/patch/ThemePatch.kt
index 7b50a3609..8bc9c1c1c 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/layout/theme/patch/ThemePatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/layout/theme/patch/ThemePatch.kt
@@ -8,13 +8,12 @@ import app.revanced.patcher.patch.*
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.youtube.layout.theme.annotations.ThemeCompatibility
-import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch
import app.revanced.util.resources.ResourceUtils
import app.revanced.util.resources.ResourceUtils.copyResources
import org.w3c.dom.Element
@Patch
-@DependsOn([LithoThemePatch::class, FixLocaleConfigErrorPatch::class])
+@DependsOn([LithoThemePatch::class])
@Name("theme")
@Description("Applies a custom theme.")
@ThemeCompatibility
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/manifest/annotations/FixLocaleConfigErrorCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/manifest/annotations/FixLocaleConfigErrorCompatibility.kt
deleted file mode 100644
index a304b71f0..000000000
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/manifest/annotations/FixLocaleConfigErrorCompatibility.kt
+++ /dev/null
@@ -1,9 +0,0 @@
-package app.revanced.patches.youtube.misc.manifest.annotations
-
-import app.revanced.patcher.annotation.Compatibility
-import app.revanced.patcher.annotation.Package
-
-@Compatibility([Package("com.google.android.youtube")])
-@Target(AnnotationTarget.CLASS)
-@Retention(AnnotationRetention.RUNTIME)
-internal annotation class FixLocaleConfigErrorCompatibility
\ No newline at end of file
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/manifest/patch/FixLocaleConfigErrorPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/manifest/patch/FixLocaleConfigErrorPatch.kt
deleted file mode 100644
index 801e444d3..000000000
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/manifest/patch/FixLocaleConfigErrorPatch.kt
+++ /dev/null
@@ -1,36 +0,0 @@
-package app.revanced.patches.youtube.misc.manifest.patch
-
-import app.revanced.patcher.annotation.Description
-import app.revanced.patcher.annotation.Name
-import app.revanced.patcher.annotation.Version
-import app.revanced.patcher.data.ResourceContext
-import app.revanced.patcher.patch.PatchResult
-import app.revanced.patcher.patch.PatchResultSuccess
-import app.revanced.patcher.patch.ResourcePatch
-import app.revanced.patches.youtube.misc.manifest.annotations.FixLocaleConfigErrorCompatibility
-import org.w3c.dom.Element
-
-@Name("locale-config-fix")
-@Description("Fixes an error when building the resources by patching the manifest file.")
-@FixLocaleConfigErrorCompatibility
-@Version("0.0.1")
-class FixLocaleConfigErrorPatch : ResourcePatch {
- override fun execute(context: ResourceContext): PatchResult {
- // create an xml editor instance
- context.xmlEditor["AndroidManifest.xml"].use {
- // edit the application nodes attribute...
- val applicationNode = it
- .file
- .getElementsByTagName("application")
- .item(0) as Element
-
-
- // by replacing the attributes name
- val attribute = "android:localeConfig"
- applicationNode.setAttribute("localeConfig", applicationNode.getAttribute(attribute))
- applicationNode.removeAttribute(attribute)
- }
-
- return PatchResultSuccess()
- }
-}
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/microg/patch/resource/MicroGResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/microg/patch/resource/MicroGResourcePatch.kt
index 1cdc47f49..257f779e2 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/microg/patch/resource/MicroGResourcePatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/microg/patch/resource/MicroGResourcePatch.kt
@@ -8,7 +8,8 @@ import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotations.DependsOn
-import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch
+import app.revanced.patches.shared.settings.preference.impl.Preference
+import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.youtube.misc.microg.annotations.MicroGPatchCompatibility
import app.revanced.patches.youtube.misc.microg.shared.Constants.PACKAGE_NAME
import app.revanced.patches.youtube.misc.microg.shared.Constants.REVANCED_APP_NAME
@@ -16,15 +17,13 @@ import app.revanced.patches.youtube.misc.microg.shared.Constants.REVANCED_PACKAG
import app.revanced.patches.youtube.misc.microg.shared.Constants.SPOOFED_PACKAGE_NAME
import app.revanced.patches.youtube.misc.microg.shared.Constants.SPOOFED_PACKAGE_SIGNATURE
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
-import app.revanced.patches.shared.settings.preference.impl.Preference
-import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.youtube.misc.settings.resource.patch.SettingsResourcePatch
import app.revanced.util.microg.Constants.MICROG_VENDOR
import app.revanced.util.microg.MicroGManifestHelper
import app.revanced.util.microg.MicroGResourceHelper
@Name("microg-resource-patch")
-@DependsOn([FixLocaleConfigErrorPatch::class, SettingsResourcePatch::class])
+@DependsOn([SettingsResourcePatch::class])
@Description("Resource patch to allow YouTube ReVanced to run without root and under a different package name.")
@MicroGPatchCompatibility
@Version("0.0.1")
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/openlinksdirectly/patch/OpenLinksDirectlyPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/openlinksdirectly/patch/OpenLinksDirectlyPatch.kt
index 8cae83e9c..ef4dc9363 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/openlinksdirectly/patch/OpenLinksDirectlyPatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/openlinksdirectly/patch/OpenLinksDirectlyPatch.kt
@@ -25,7 +25,7 @@ import org.jf.dexlib2.iface.instruction.formats.Instruction35c
@Patch
@DependsOn([IntegrationsPatch::class, SettingsPatch::class])
@Name("open-links-directly")
-@Description("Bypasses https://youtube.com/redirect URLs.")
+@Description("Skips over redirection URLs to external links.")
@OpenLinksDirectlyCompatibility
@Version("0.0.1")
class OpenLinksDirectlyPatch : BytecodePatch(
diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/resource/patch/BottomControlsResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/resource/patch/BottomControlsResourcePatch.kt
index e569e56aa..d6fb1889c 100644
--- a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/resource/patch/BottomControlsResourcePatch.kt
+++ b/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/resource/patch/BottomControlsResourcePatch.kt
@@ -8,12 +8,9 @@ import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.ResourcePatch
-import app.revanced.patcher.patch.annotations.DependsOn
-import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch
import app.revanced.patches.youtube.misc.playercontrols.annotation.PlayerControlsCompatibility
@Name("bottom-controls-resource-patch")
-@DependsOn([FixLocaleConfigErrorPatch::class])
@Description("Manages the resources for the bottom controls of the YouTube player.")
@PlayerControlsCompatibility
@Version("0.0.1")
diff --git a/src/main/kotlin/app/revanced/util/patch/AbstractTransformInstructionsPatch.kt b/src/main/kotlin/app/revanced/util/patch/AbstractTransformInstructionsPatch.kt
new file mode 100644
index 000000000..3a1b8f23b
--- /dev/null
+++ b/src/main/kotlin/app/revanced/util/patch/AbstractTransformInstructionsPatch.kt
@@ -0,0 +1,63 @@
+package app.revanced.util.patch
+
+import app.revanced.extensions.findMutableMethodOf
+import app.revanced.patcher.data.BytecodeContext
+import app.revanced.patcher.patch.BytecodePatch
+import app.revanced.patcher.patch.PatchResult
+import app.revanced.patcher.patch.PatchResultSuccess
+import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
+import org.jf.dexlib2.iface.ClassDef
+import org.jf.dexlib2.iface.Method
+import org.jf.dexlib2.iface.instruction.Instruction
+
+internal abstract class AbstractTransformInstructionsPatch : BytecodePatch() {
+
+ abstract fun filterMap(
+ classDef: ClassDef,
+ method: Method,
+ instruction: Instruction,
+ instructionIndex: Int
+ ): T?
+
+ abstract fun transform(mutableMethod: MutableMethod, entry: T)
+
+ override fun execute(context: BytecodeContext): PatchResult {
+ // Find all instructions
+ buildMap {
+ context.classes.forEach { classDef ->
+ classDef.methods.let { methods ->
+ buildMap methodList@{
+ methods.forEach methods@{ method ->
+ with(method.implementation?.instructions ?: return@methods) {
+ ArrayDeque().also { patchIndices ->
+ this.forEachIndexed { index, instruction ->
+ val result = filterMap(classDef, method, instruction, index)
+ if (result != null) {
+ patchIndices.add(result)
+ }
+ }
+ }.also { if (it.isEmpty()) return@methods }.let { patches ->
+ put(method, patches)
+ }
+ }
+ }
+ }
+ }.also { if (it.isEmpty()) return@forEach }.let { methodPatches ->
+ put(classDef, methodPatches)
+ }
+ }
+ }.forEach { (classDef, methods) ->
+ // And finally transform the instructions...
+ with(context.proxy(classDef).mutableClass) {
+ methods.forEach { (method, patches) ->
+ val mutableMethod = findMutableMethodOf(method)
+ while (!patches.isEmpty()) {
+ transform(mutableMethod, patches.removeLast())
+ }
+ }
+ }
+ }
+
+ return PatchResultSuccess()
+ }
+}
diff --git a/src/main/kotlin/app/revanced/util/patch/MethodCall.kt b/src/main/kotlin/app/revanced/util/patch/MethodCall.kt
new file mode 100644
index 000000000..fe21f4fc1
--- /dev/null
+++ b/src/main/kotlin/app/revanced/util/patch/MethodCall.kt
@@ -0,0 +1,92 @@
+package app.revanced.util.patch
+
+import app.revanced.patcher.extensions.replaceInstruction
+import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
+import org.jf.dexlib2.Opcode
+import org.jf.dexlib2.iface.ClassDef
+import org.jf.dexlib2.iface.instruction.Instruction
+import org.jf.dexlib2.iface.instruction.formats.Instruction35c
+import org.jf.dexlib2.iface.reference.MethodReference
+
+internal typealias Instruction35cInfo = Triple
+
+internal interface IMethodCall {
+ val definedClassName: String
+ val methodName: String
+ val methodParams: Array
+ val returnType: String
+
+ /**
+ * Replaces an invoke-virtual instruction with an invoke-static instruction,
+ * which calls a static replacement method in the respective integrations class.
+ * The method definition in the integrations class is expected to be the same,
+ * except that the method should be static and take as a first parameter
+ * an instance of the class, in which the original method was defined in.
+ *
+ * Example:
+ *
+ * original method: Window#setFlags(int, int)
+ *
+ * replacement method: Integrations#setFlags(Window, int, int)
+ */
+ fun replaceInvokeVirtualWithIntegrations(
+ definingClassDescriptor: String,
+ method: MutableMethod,
+ instruction: Instruction35c,
+ instructionIndex: Int
+ ) {
+ val registers = arrayOf(
+ instruction.registerC,
+ instruction.registerD,
+ instruction.registerE,
+ instruction.registerF,
+ instruction.registerG
+ )
+ val argsNum = methodParams.size + 1 // + 1 for instance of definedClassName
+ if (argsNum > registers.size) {
+ // should never happen, but just to be sure (also for the future) a safety check
+ throw RuntimeException(
+ "Not enough registers for ${definedClassName}#${methodName}: " +
+ "Required $argsNum registers, but only got ${registers.size}."
+ )
+ }
+
+ val args = registers.take(argsNum).joinToString(separator = ", ") { reg -> "v${reg}" }
+ val replacementMethodDefinition =
+ "${methodName}(${definedClassName}${methodParams.joinToString(separator = "")})${returnType}"
+
+ method.replaceInstruction(
+ instructionIndex,
+ "invoke-static { $args }, ${definingClassDescriptor}->${replacementMethodDefinition}"
+ )
+ }
+}
+
+internal inline fun fromMethodReference(methodReference: MethodReference)
+ where E : Enum, E : IMethodCall = enumValues().firstOrNull { search ->
+ search.definedClassName == methodReference.definingClass
+ && search.methodName == methodReference.name
+ && methodReference.parameterTypes.toTypedArray().contentEquals(search.methodParams)
+}
+
+internal inline fun filterMapInstruction35c(
+ integrationsClassDescriptorPrefix: String,
+ classDef: ClassDef,
+ instruction: Instruction,
+ instructionIndex: Int
+): Instruction35cInfo? where E : Enum, E : IMethodCall {
+ if (classDef.type.startsWith(integrationsClassDescriptorPrefix)) {
+ // avoid infinite recursion
+ return null
+ }
+
+ if (instruction.opcode != Opcode.INVOKE_VIRTUAL) {
+ return null
+ }
+
+ val invokeInstruction = instruction as Instruction35c
+ val methodRef = invokeInstruction.reference as MethodReference
+ val methodCall = fromMethodReference(methodRef) ?: return null
+
+ return Instruction35cInfo(methodCall, invokeInstruction, instructionIndex)
+}
diff --git a/src/main/resources/branding/mipmap-hdpi/adaptiveproduct_youtube_background_color_108.png b/src/main/resources/branding/mipmap-hdpi/adaptiveproduct_youtube_background_color_108.png
index e2dc8a53f..473330fee 100644
Binary files a/src/main/resources/branding/mipmap-hdpi/adaptiveproduct_youtube_background_color_108.png and b/src/main/resources/branding/mipmap-hdpi/adaptiveproduct_youtube_background_color_108.png differ
diff --git a/src/main/resources/branding/mipmap-hdpi/adaptiveproduct_youtube_foreground_color_108.png b/src/main/resources/branding/mipmap-hdpi/adaptiveproduct_youtube_foreground_color_108.png
index e5a73b561..0616301e7 100644
Binary files a/src/main/resources/branding/mipmap-hdpi/adaptiveproduct_youtube_foreground_color_108.png and b/src/main/resources/branding/mipmap-hdpi/adaptiveproduct_youtube_foreground_color_108.png differ
diff --git a/src/main/resources/branding/mipmap-hdpi/ic_launcher.png b/src/main/resources/branding/mipmap-hdpi/ic_launcher.png
index dc967b770..333f5c3f8 100644
Binary files a/src/main/resources/branding/mipmap-hdpi/ic_launcher.png and b/src/main/resources/branding/mipmap-hdpi/ic_launcher.png differ
diff --git a/src/main/resources/branding/mipmap-hdpi/ic_launcher_round.png b/src/main/resources/branding/mipmap-hdpi/ic_launcher_round.png
index dc967b770..333f5c3f8 100644
Binary files a/src/main/resources/branding/mipmap-hdpi/ic_launcher_round.png and b/src/main/resources/branding/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/src/main/resources/branding/mipmap-mdpi/adaptiveproduct_youtube_background_color_108.png b/src/main/resources/branding/mipmap-mdpi/adaptiveproduct_youtube_background_color_108.png
index 4dee1752a..f2e714894 100644
Binary files a/src/main/resources/branding/mipmap-mdpi/adaptiveproduct_youtube_background_color_108.png and b/src/main/resources/branding/mipmap-mdpi/adaptiveproduct_youtube_background_color_108.png differ
diff --git a/src/main/resources/branding/mipmap-mdpi/adaptiveproduct_youtube_foreground_color_108.png b/src/main/resources/branding/mipmap-mdpi/adaptiveproduct_youtube_foreground_color_108.png
index 3d26f5b2b..4a454727f 100644
Binary files a/src/main/resources/branding/mipmap-mdpi/adaptiveproduct_youtube_foreground_color_108.png and b/src/main/resources/branding/mipmap-mdpi/adaptiveproduct_youtube_foreground_color_108.png differ
diff --git a/src/main/resources/branding/mipmap-mdpi/ic_launcher.png b/src/main/resources/branding/mipmap-mdpi/ic_launcher.png
index 4e3735d01..947dca925 100644
Binary files a/src/main/resources/branding/mipmap-mdpi/ic_launcher.png and b/src/main/resources/branding/mipmap-mdpi/ic_launcher.png differ
diff --git a/src/main/resources/branding/mipmap-mdpi/ic_launcher_round.png b/src/main/resources/branding/mipmap-mdpi/ic_launcher_round.png
index 4e3735d01..947dca925 100644
Binary files a/src/main/resources/branding/mipmap-mdpi/ic_launcher_round.png and b/src/main/resources/branding/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/src/main/resources/branding/mipmap-xhdpi/adaptiveproduct_youtube_background_color_108.png b/src/main/resources/branding/mipmap-xhdpi/adaptiveproduct_youtube_background_color_108.png
index 49d5f450c..5ebd9b9b0 100644
Binary files a/src/main/resources/branding/mipmap-xhdpi/adaptiveproduct_youtube_background_color_108.png and b/src/main/resources/branding/mipmap-xhdpi/adaptiveproduct_youtube_background_color_108.png differ
diff --git a/src/main/resources/branding/mipmap-xhdpi/adaptiveproduct_youtube_foreground_color_108.png b/src/main/resources/branding/mipmap-xhdpi/adaptiveproduct_youtube_foreground_color_108.png
index 4f66f60a3..af465feb9 100644
Binary files a/src/main/resources/branding/mipmap-xhdpi/adaptiveproduct_youtube_foreground_color_108.png and b/src/main/resources/branding/mipmap-xhdpi/adaptiveproduct_youtube_foreground_color_108.png differ
diff --git a/src/main/resources/branding/mipmap-xhdpi/ic_launcher.png b/src/main/resources/branding/mipmap-xhdpi/ic_launcher.png
index 471c9779e..811c31f28 100644
Binary files a/src/main/resources/branding/mipmap-xhdpi/ic_launcher.png and b/src/main/resources/branding/mipmap-xhdpi/ic_launcher.png differ
diff --git a/src/main/resources/branding/mipmap-xhdpi/ic_launcher_round.png b/src/main/resources/branding/mipmap-xhdpi/ic_launcher_round.png
index 471c9779e..811c31f28 100644
Binary files a/src/main/resources/branding/mipmap-xhdpi/ic_launcher_round.png and b/src/main/resources/branding/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/src/main/resources/branding/mipmap-xxhdpi/adaptiveproduct_youtube_background_color_108.png b/src/main/resources/branding/mipmap-xxhdpi/adaptiveproduct_youtube_background_color_108.png
index 1a92bea23..fbeb03fcb 100644
Binary files a/src/main/resources/branding/mipmap-xxhdpi/adaptiveproduct_youtube_background_color_108.png and b/src/main/resources/branding/mipmap-xxhdpi/adaptiveproduct_youtube_background_color_108.png differ
diff --git a/src/main/resources/branding/mipmap-xxhdpi/adaptiveproduct_youtube_foreground_color_108.png b/src/main/resources/branding/mipmap-xxhdpi/adaptiveproduct_youtube_foreground_color_108.png
index 777daea51..0c8936281 100644
Binary files a/src/main/resources/branding/mipmap-xxhdpi/adaptiveproduct_youtube_foreground_color_108.png and b/src/main/resources/branding/mipmap-xxhdpi/adaptiveproduct_youtube_foreground_color_108.png differ
diff --git a/src/main/resources/branding/mipmap-xxhdpi/ic_launcher.png b/src/main/resources/branding/mipmap-xxhdpi/ic_launcher.png
index 6e2178566..7eca70426 100644
Binary files a/src/main/resources/branding/mipmap-xxhdpi/ic_launcher.png and b/src/main/resources/branding/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/src/main/resources/branding/mipmap-xxhdpi/ic_launcher_round.png b/src/main/resources/branding/mipmap-xxhdpi/ic_launcher_round.png
index 6e2178566..7eca70426 100644
Binary files a/src/main/resources/branding/mipmap-xxhdpi/ic_launcher_round.png and b/src/main/resources/branding/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/src/main/resources/branding/mipmap-xxxhdpi/adaptiveproduct_youtube_background_color_108.png b/src/main/resources/branding/mipmap-xxxhdpi/adaptiveproduct_youtube_background_color_108.png
index 9c4462f86..b7b84772f 100644
Binary files a/src/main/resources/branding/mipmap-xxxhdpi/adaptiveproduct_youtube_background_color_108.png and b/src/main/resources/branding/mipmap-xxxhdpi/adaptiveproduct_youtube_background_color_108.png differ
diff --git a/src/main/resources/branding/mipmap-xxxhdpi/adaptiveproduct_youtube_foreground_color_108.png b/src/main/resources/branding/mipmap-xxxhdpi/adaptiveproduct_youtube_foreground_color_108.png
index 0abe542a1..bc688ad36 100644
Binary files a/src/main/resources/branding/mipmap-xxxhdpi/adaptiveproduct_youtube_foreground_color_108.png and b/src/main/resources/branding/mipmap-xxxhdpi/adaptiveproduct_youtube_foreground_color_108.png differ
diff --git a/src/main/resources/branding/mipmap-xxxhdpi/ic_launcher.png b/src/main/resources/branding/mipmap-xxxhdpi/ic_launcher.png
index c0505bf87..e0fd48914 100644
Binary files a/src/main/resources/branding/mipmap-xxxhdpi/ic_launcher.png and b/src/main/resources/branding/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/src/main/resources/branding/mipmap-xxxhdpi/ic_launcher_round.png b/src/main/resources/branding/mipmap-xxxhdpi/ic_launcher_round.png
index c0505bf87..e0fd48914 100644
Binary files a/src/main/resources/branding/mipmap-xxxhdpi/ic_launcher_round.png and b/src/main/resources/branding/mipmap-xxxhdpi/ic_launcher_round.png differ