Compare commits

...

29 Commits

Author SHA1 Message Date
semantic-release-bot
49db0cee1b chore(release): 4.8.0-dev.2 [skip ci]
# [4.8.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v4.8.0-dev.1...v4.8.0-dev.2) (2024-04-21)

### Bug Fixes

* Case patch option title correctly ([531955a](531955a111))
2024-04-21 23:39:44 +00:00
oSumAtrIX
531955a111 fix: Case patch option title correctly 2024-04-22 01:37:36 +02:00
semantic-release-bot
e53cc9bba9 chore(release): 4.8.0-dev.1 [skip ci]
# [4.8.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v4.7.0...v4.8.0-dev.1) (2024-04-21)

### Bug Fixes

* **YouTube - Hide video action buttons:** Remove obsolete `hide Shop button` ([#3057](https://github.com/ReVanced/revanced-patches/issues/3057)) ([fc43dd7](fc43dd709f))

### Features

* **YouTube - Hide Shorts components:** Hide like / dislike button in video ads ([#3062](https://github.com/ReVanced/revanced-patches/issues/3062)) ([3a018ff](3a018ff002))
2024-04-21 14:59:47 +00:00
LisoUseInAIKyrios
fc43dd709f fix(YouTube - Hide video action buttons): Remove obsolete hide Shop button (#3057) 2024-04-21 18:57:35 +04:00
LisoUseInAIKyrios
3a018ff002 feat(YouTube - Hide Shorts components): Hide like / dislike button in video ads (#3062) 2024-04-21 18:55:26 +04:00
LisoUseInAIKyrios
86f11480e7 chore: Fix duplicate strings that is confusing Crowdin 2024-04-21 08:03:11 +04:00
LisoUseInAIKyrios
0190d5a5c9 chore: Adjust hide fullscreen ads toast text, move hide Playables to feed menu 2024-04-21 06:06:16 +04:00
semantic-release-bot
50735fabbc chore(release): 4.7.0 [skip ci]
# [4.7.0](https://github.com/ReVanced/revanced-patches/compare/v4.6.0...v4.7.0) (2024-04-21)

### Bug Fixes

* **Tumblr - Fix old versions:** Improve reliability by removing remnances of Tumblr Live  ([#2988](https://github.com/ReVanced/revanced-patches/issues/2988)) ([1ac6127](1ac612798b))
* **YouTube - GmsCore support:** Prompt to disable battery optimizations, if not done already ([#2958](https://github.com/ReVanced/revanced-patches/issues/2958)) ([b80bb89](b80bb8969c))
* **YouTube - Hide ads:** rename `Hide paid content` to `Hide paid promotion label` ([#3026](https://github.com/ReVanced/revanced-patches/issues/3026)) ([58ce37b](58ce37b0d3))
* **YouTube - Hide load more button:** Include patch with `Hide layout components`, and hide button only in search feed  ([#2959](https://github.com/ReVanced/revanced-patches/issues/2959)) ([0e88306](0e88306f3f))
* **YouTube - Hide Shorts components:** Correctly hide Shorts if navigation tab is changed using device back button ([#3007](https://github.com/ReVanced/revanced-patches/issues/3007)) ([e97aaf4](e97aaf4aae))
* **YouTube - Player flyout menu:** Add hide Lock screen menu ([#2985](https://github.com/ReVanced/revanced-patches/issues/2985)) ([6175841](61758414c2))
* **YouTube - Spoof device dimensions:** Warn about potential performance issues ([#3039](https://github.com/ReVanced/revanced-patches/issues/3039)) ([cc7f79d](cc7f79d903))
* **YouTube Music - Remove upgrade button:** Fix compatibility with latest versions ([#3045](https://github.com/ReVanced/revanced-patches/issues/3045)) ([e329e1d](e329e1dd1a))

### Features

* Add `Hex` patch ([#3034](https://github.com/ReVanced/revanced-patches/issues/3034)) ([6fd46ad](6fd46ad9b6))
* **Amazon:** Add `Always allow deep-linking` patch ([#3000](https://github.com/ReVanced/revanced-patches/issues/3000)) ([f2fe0d5](f2fe0d5c6f))
* **Strava - Unlock subscription:** Remove compatible version constraint ([e798341](e7983411a7))
* **Twitter:** Add `Sanitize sharing links` patch ([#3003](https://github.com/ReVanced/revanced-patches/issues/3003)) ([b4e8beb](b4e8beb8ec))
* **YouTube - Hide layout components:** Add option to hide horizontal shelves ([#2951](https://github.com/ReVanced/revanced-patches/issues/2951)) ([122f042](122f04219f))
* **YouTube - Hide layout components:** Hide playables ([f85f518](f85f518fc9))
* **YouTube - Hide Shorts components:** Hide `Shop`, `Location` and `Save sound to playlist` buttons ([#3018](https://github.com/ReVanced/revanced-patches/issues/3018)) ([be76e49](be76e49a8b))
* **YouTube - Hide Shorts components:** Hide tagged products, hide search suggestions ([#3019](https://github.com/ReVanced/revanced-patches/issues/3019)) ([2e59965](2e59965bb5))
* **YouTube - Swipe controls:** Save and restore brightness and add auto-brightness toggle ([#2996](https://github.com/ReVanced/revanced-patches/issues/2996)) ([533f9a9](533f9a964d))
* **YouTube:** Add 'About' preference to settings menu ([#2981](https://github.com/ReVanced/revanced-patches/issues/2981)) ([c272333](c272333adb))
* **YouTube:** Match overlay icons style to YouTube ([#3023](https://github.com/ReVanced/revanced-patches/issues/3023)) ([366f754](366f754a6a))
* **YouTube:** Support version `19.09.38`, `19.10.39` and `19.11.43` ([#2971](https://github.com/ReVanced/revanced-patches/issues/2971)) ([96e17cf](96e17cf4de))
* **YT Music - Hide 'Get Music Premium' label:** Remove occurences of label in settings ([#3046](https://github.com/ReVanced/revanced-patches/issues/3046)) ([7ecd992](7ecd992def))
2024-04-21 01:49:13 +00:00
oSumAtrIX
653631703c chore: Merge branch dev to main (#2982) 2024-04-21 03:47:03 +02:00
semantic-release-bot
2587508944 chore(release): 4.7.0-dev.16 [skip ci]
# [4.7.0-dev.16](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.15...v4.7.0-dev.16) (2024-04-21)

### Features

* **YouTube - Swipe controls:** Save and restore brightness and add auto-brightness toggle ([#2996](https://github.com/ReVanced/revanced-patches/issues/2996)) ([533f9a9](533f9a964d))
2024-04-21 00:00:57 +00:00
MarcaD
533f9a964d feat(YouTube - Swipe controls): Save and restore brightness and add auto-brightness toggle (#2996)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2024-04-21 01:58:56 +02:00
semantic-release-bot
fb0b3bd673 chore(release): 4.7.0-dev.15 [skip ci]
# [4.7.0-dev.15](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.14...v4.7.0-dev.15) (2024-04-20)

### Features

* **YouTube:** Support version `19.09.38`, `19.10.39` and `19.11.43` ([#2971](https://github.com/ReVanced/revanced-patches/issues/2971)) ([96e17cf](96e17cf4de))
2024-04-20 23:17:38 +00:00
LisoUseInAIKyrios
96e17cf4de feat(YouTube): Support version 19.09.38, 19.10.39 and 19.11.43 (#2971)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2024-04-21 01:15:31 +02:00
semantic-release-bot
a7bd0b111e chore(release): 4.7.0-dev.14 [skip ci]
# [4.7.0-dev.14](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.13...v4.7.0-dev.14) (2024-04-20)

### Features

* **YT Music - Hide 'Get Music Premium' label:** Remove occurences of label in settings ([#3046](https://github.com/ReVanced/revanced-patches/issues/3046)) ([7ecd992](7ecd992def))
2024-04-20 22:39:55 +00:00
Alberto Ponces
7ecd992def feat(YT Music - Hide 'Get Music Premium' label): Remove occurences of label in settings (#3046)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2024-04-21 00:37:51 +02:00
semantic-release-bot
217d3c69ba chore(release): 4.7.0-dev.13 [skip ci]
# [4.7.0-dev.13](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.12...v4.7.0-dev.13) (2024-04-18)

### Bug Fixes

* **YouTube Music - Remove upgrade button:** Fix compatibility with latest versions ([#3045](https://github.com/ReVanced/revanced-patches/issues/3045)) ([e329e1d](e329e1dd1a))
2024-04-18 23:18:22 +00:00
Alberto Ponces
e329e1dd1a fix(YouTube Music - Remove upgrade button): Fix compatibility with latest versions (#3045) 2024-04-19 01:16:25 +02:00
semantic-release-bot
6a8b669ba2 chore(release): 4.7.0-dev.12 [skip ci]
# [4.7.0-dev.12](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.11...v4.7.0-dev.12) (2024-04-18)

### Features

* Add `Hex` patch ([#3034](https://github.com/ReVanced/revanced-patches/issues/3034)) ([6fd46ad](6fd46ad9b6))
2024-04-18 22:50:02 +00:00
oSumAtrIX
6fd46ad9b6 feat: Add Hex patch (#3034) 2024-04-18 21:37:46 +02:00
semantic-release-bot
50ddb680ed chore(release): 4.7.0-dev.11 [skip ci]
# [4.7.0-dev.11](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.10...v4.7.0-dev.11) (2024-04-18)

### Bug Fixes

* **YouTube - Spoof device dimensions:** Warn about potential performance issues ([#3039](https://github.com/ReVanced/revanced-patches/issues/3039)) ([cc7f79d](cc7f79d903))
2024-04-18 13:21:16 +00:00
LisoUseInAIKyrios
cc7f79d903 fix(YouTube - Spoof device dimensions): Warn about potential performance issues (#3039) 2024-04-18 17:19:04 +04:00
LisoUseInAIKyrios
57274b5435 chore: Fix typo 2024-04-18 12:41:48 +04:00
semantic-release-bot
8295b7a22e chore(release): 4.7.0-dev.10 [skip ci]
# [4.7.0-dev.10](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.9...v4.7.0-dev.10) (2024-04-17)

### Features

* **YouTube:** Add 'About' preference to settings menu ([#2981](https://github.com/ReVanced/revanced-patches/issues/2981)) ([c272333](c272333adb))
* **YouTube:** Match overlay icons style to YouTube ([#3023](https://github.com/ReVanced/revanced-patches/issues/3023)) ([366f754](366f754a6a))
2024-04-17 16:04:01 +00:00
MarcaD
366f754a6a feat(YouTube): Match overlay icons style to YouTube (#3023) 2024-04-17 18:01:47 +02:00
LisoUseInAIKyrios
c272333adb feat(YouTube): Add 'About' preference to settings menu (#2981)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2024-04-17 20:01:17 +04:00
semantic-release-bot
ef6c00a520 chore(release): 4.7.0-dev.9 [skip ci]
# [4.7.0-dev.9](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.8...v4.7.0-dev.9) (2024-04-15)

### Bug Fixes

* **YouTube - Hide ads:** rename `Hide paid content` to `Hide paid promotion label` ([#3026](https://github.com/ReVanced/revanced-patches/issues/3026)) ([58ce37b](58ce37b0d3))
2024-04-15 15:21:08 +00:00
LisoUseInAIKyrios
58ce37b0d3 fix(YouTube - Hide ads): rename Hide paid content to Hide paid promotion label (#3026) 2024-04-15 19:18:57 +04:00
semantic-release-bot
4b7e12f995 chore(release): 4.7.0-dev.8 [skip ci]
# [4.7.0-dev.8](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.7...v4.7.0-dev.8) (2024-04-14)

### Features

* **YouTube - Hide Shorts components:** Hide tagged products, hide search suggestions ([#3019](https://github.com/ReVanced/revanced-patches/issues/3019)) ([2e59965](2e59965bb5))
2024-04-14 14:56:15 +00:00
LisoUseInAIKyrios
2e59965bb5 feat(YouTube - Hide Shorts components): Hide tagged products, hide search suggestions (#3019) 2024-04-14 18:54:00 +04:00
111 changed files with 1382 additions and 434 deletions

View File

@@ -1,3 +1,117 @@
# [4.8.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v4.8.0-dev.1...v4.8.0-dev.2) (2024-04-21)
### Bug Fixes
* Case patch option title correctly ([259c8b4](https://github.com/ReVanced/revanced-patches/commit/259c8b4e58df51d92d7e19417e13afa3848afc73))
# [4.8.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v4.7.0...v4.8.0-dev.1) (2024-04-21)
### Bug Fixes
* **YouTube - Hide video action buttons:** Remove obsolete `hide Shop button` ([#3057](https://github.com/ReVanced/revanced-patches/issues/3057)) ([b5e34f3](https://github.com/ReVanced/revanced-patches/commit/b5e34f3aabc1d9df8c41f92251618243caecdc9f))
### Features
* **YouTube - Hide Shorts components:** Hide like / dislike button in video ads ([#3062](https://github.com/ReVanced/revanced-patches/issues/3062)) ([1296985](https://github.com/ReVanced/revanced-patches/commit/12969853adfe530eb6006df38e1a5aa30b28fdf9))
# [4.7.0](https://github.com/ReVanced/revanced-patches/compare/v4.6.0...v4.7.0) (2024-04-21)
### Bug Fixes
* **Tumblr - Fix old versions:** Improve reliability by removing remnances of Tumblr Live ([#2988](https://github.com/ReVanced/revanced-patches/issues/2988)) ([897b4db](https://github.com/ReVanced/revanced-patches/commit/897b4dbce984270ae1fd7de5bd30bd05153e45f2))
* **YouTube - GmsCore support:** Prompt to disable battery optimizations, if not done already ([#2958](https://github.com/ReVanced/revanced-patches/issues/2958)) ([82acb84](https://github.com/ReVanced/revanced-patches/commit/82acb84b5f6ff0722a2eb080b53da9dd3622502f))
* **YouTube - Hide ads:** rename `Hide paid content` to `Hide paid promotion label` ([#3026](https://github.com/ReVanced/revanced-patches/issues/3026)) ([17e4ac9](https://github.com/ReVanced/revanced-patches/commit/17e4ac978a2f109fd62469a3163b636cd63c55ae))
* **YouTube - Hide load more button:** Include patch with `Hide layout components`, and hide button only in search feed ([#2959](https://github.com/ReVanced/revanced-patches/issues/2959)) ([b007e8e](https://github.com/ReVanced/revanced-patches/commit/b007e8e06a3afad79b40bec1c6a14604f059049c))
* **YouTube - Hide Shorts components:** Correctly hide Shorts if navigation tab is changed using device back button ([#3007](https://github.com/ReVanced/revanced-patches/issues/3007)) ([e5848e9](https://github.com/ReVanced/revanced-patches/commit/e5848e99c4cc838595164ef673a77fe60d28086b))
* **YouTube - Player flyout menu:** Add hide Lock screen menu ([#2985](https://github.com/ReVanced/revanced-patches/issues/2985)) ([308de4a](https://github.com/ReVanced/revanced-patches/commit/308de4a63ca99b8d30d6b3242f98d6f0e2aefb37))
* **YouTube - Spoof device dimensions:** Warn about potential performance issues ([#3039](https://github.com/ReVanced/revanced-patches/issues/3039)) ([9d6f305](https://github.com/ReVanced/revanced-patches/commit/9d6f305b7c923e62b89581d221fedbe1e3f81835))
* **YouTube Music - Remove upgrade button:** Fix compatibility with latest versions ([#3045](https://github.com/ReVanced/revanced-patches/issues/3045)) ([80de996](https://github.com/ReVanced/revanced-patches/commit/80de99666555694670529bbfe2e0be7a14d66555))
### Features
* Add `Hex` patch ([#3034](https://github.com/ReVanced/revanced-patches/issues/3034)) ([3c95aac](https://github.com/ReVanced/revanced-patches/commit/3c95aac838693b354d3a7b0e3dc57c6da5adfa9e))
* **Amazon:** Add `Always allow deep-linking` patch ([#3000](https://github.com/ReVanced/revanced-patches/issues/3000)) ([a92b7fb](https://github.com/ReVanced/revanced-patches/commit/a92b7fb43c8b1b45577360cdc6d883fe2815c2f2))
* **Strava - Unlock subscription:** Remove compatible version constraint ([80a5599](https://github.com/ReVanced/revanced-patches/commit/80a55991683d7b22626224fa2935a5bf9bfcbfee))
* **Twitter:** Add `Sanitize sharing links` patch ([#3003](https://github.com/ReVanced/revanced-patches/issues/3003)) ([186b887](https://github.com/ReVanced/revanced-patches/commit/186b8874157eef1b882b05d491ba1d4ca2809535))
* **YouTube - Hide layout components:** Add option to hide horizontal shelves ([#2951](https://github.com/ReVanced/revanced-patches/issues/2951)) ([9ae0650](https://github.com/ReVanced/revanced-patches/commit/9ae0650c0005d882299996aa442410bab4261395))
* **YouTube - Hide layout components:** Hide playables ([8423515](https://github.com/ReVanced/revanced-patches/commit/842351548baa33737db09be1cbca9f87c1951341))
* **YouTube - Hide Shorts components:** Hide `Shop`, `Location` and `Save sound to playlist` buttons ([#3018](https://github.com/ReVanced/revanced-patches/issues/3018)) ([5210ac4](https://github.com/ReVanced/revanced-patches/commit/5210ac431c191987264865bf8e789ea9f3fdd360))
* **YouTube - Hide Shorts components:** Hide tagged products, hide search suggestions ([#3019](https://github.com/ReVanced/revanced-patches/issues/3019)) ([e0d2fe5](https://github.com/ReVanced/revanced-patches/commit/e0d2fe5bd2e681b9a5252a8e4ad582cc019b1606))
* **YouTube - Swipe controls:** Save and restore brightness and add auto-brightness toggle ([#2996](https://github.com/ReVanced/revanced-patches/issues/2996)) ([f6c3bc4](https://github.com/ReVanced/revanced-patches/commit/f6c3bc43190d33e06f49b74fc056d26da1bb014a))
* **YouTube:** Add 'About' preference to settings menu ([#2981](https://github.com/ReVanced/revanced-patches/issues/2981)) ([5abf894](https://github.com/ReVanced/revanced-patches/commit/5abf89444a3e6a211ec03c242eb9a7847542b08c))
* **YouTube:** Match overlay icons style to YouTube ([#3023](https://github.com/ReVanced/revanced-patches/issues/3023)) ([6849393](https://github.com/ReVanced/revanced-patches/commit/684939314be3d0d43482f229b2adb033e7aa492a))
* **YouTube:** Support version `19.09.38`, `19.10.39` and `19.11.43` ([#2971](https://github.com/ReVanced/revanced-patches/issues/2971)) ([730f3e3](https://github.com/ReVanced/revanced-patches/commit/730f3e3a7e058b60f9a8130980ecb0a747fa0a8a))
* **YT Music - Hide 'Get Music Premium' label:** Remove occurences of label in settings ([#3046](https://github.com/ReVanced/revanced-patches/issues/3046)) ([10e170a](https://github.com/ReVanced/revanced-patches/commit/10e170a7302fdb585efee663ca13c814aea46c54))
# [4.7.0-dev.16](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.15...v4.7.0-dev.16) (2024-04-21)
### Features
* **YouTube - Swipe controls:** Save and restore brightness and add auto-brightness toggle ([#2996](https://github.com/ReVanced/revanced-patches/issues/2996)) ([f6c3bc4](https://github.com/ReVanced/revanced-patches/commit/f6c3bc43190d33e06f49b74fc056d26da1bb014a))
# [4.7.0-dev.15](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.14...v4.7.0-dev.15) (2024-04-20)
### Features
* **YouTube:** Support version `19.09.38`, `19.10.39` and `19.11.43` ([#2971](https://github.com/ReVanced/revanced-patches/issues/2971)) ([730f3e3](https://github.com/ReVanced/revanced-patches/commit/730f3e3a7e058b60f9a8130980ecb0a747fa0a8a))
# [4.7.0-dev.14](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.13...v4.7.0-dev.14) (2024-04-20)
### Features
* **YT Music - Hide 'Get Music Premium' label:** Remove occurences of label in settings ([#3046](https://github.com/ReVanced/revanced-patches/issues/3046)) ([10e170a](https://github.com/ReVanced/revanced-patches/commit/10e170a7302fdb585efee663ca13c814aea46c54))
# [4.7.0-dev.13](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.12...v4.7.0-dev.13) (2024-04-18)
### Bug Fixes
* **YouTube Music - Remove upgrade button:** Fix compatibility with latest versions ([#3045](https://github.com/ReVanced/revanced-patches/issues/3045)) ([80de996](https://github.com/ReVanced/revanced-patches/commit/80de99666555694670529bbfe2e0be7a14d66555))
# [4.7.0-dev.12](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.11...v4.7.0-dev.12) (2024-04-18)
### Features
* Add `Hex` patch ([#3034](https://github.com/ReVanced/revanced-patches/issues/3034)) ([3c95aac](https://github.com/ReVanced/revanced-patches/commit/3c95aac838693b354d3a7b0e3dc57c6da5adfa9e))
# [4.7.0-dev.11](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.10...v4.7.0-dev.11) (2024-04-18)
### Bug Fixes
* **YouTube - Spoof device dimensions:** Warn about potential performance issues ([#3039](https://github.com/ReVanced/revanced-patches/issues/3039)) ([9d6f305](https://github.com/ReVanced/revanced-patches/commit/9d6f305b7c923e62b89581d221fedbe1e3f81835))
# [4.7.0-dev.10](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.9...v4.7.0-dev.10) (2024-04-17)
### Features
* **YouTube:** Add 'About' preference to settings menu ([#2981](https://github.com/ReVanced/revanced-patches/issues/2981)) ([5abf894](https://github.com/ReVanced/revanced-patches/commit/5abf89444a3e6a211ec03c242eb9a7847542b08c))
* **YouTube:** Match overlay icons style to YouTube ([#3023](https://github.com/ReVanced/revanced-patches/issues/3023)) ([6849393](https://github.com/ReVanced/revanced-patches/commit/684939314be3d0d43482f229b2adb033e7aa492a))
# [4.7.0-dev.9](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.8...v4.7.0-dev.9) (2024-04-15)
### Bug Fixes
* **YouTube - Hide ads:** rename `Hide paid content` to `Hide paid promotion label` ([#3026](https://github.com/ReVanced/revanced-patches/issues/3026)) ([17e4ac9](https://github.com/ReVanced/revanced-patches/commit/17e4ac978a2f109fd62469a3163b636cd63c55ae))
# [4.7.0-dev.8](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.7...v4.7.0-dev.8) (2024-04-14)
### Features
* **YouTube - Hide Shorts components:** Hide tagged products, hide search suggestions ([#3019](https://github.com/ReVanced/revanced-patches/issues/3019)) ([e0d2fe5](https://github.com/ReVanced/revanced-patches/commit/e0d2fe5bd2e681b9a5252a8e4ad582cc019b1606))
# [4.7.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.6...v4.7.0-dev.7) (2024-04-14) # [4.7.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.6...v4.7.0-dev.7) (2024-04-14)

View File

@@ -28,6 +28,10 @@ public final class app/revanced/patches/all/misc/debugging/EnableAndroidDebuggin
public fun execute (Lapp/revanced/patcher/data/ResourceContext;)V public fun execute (Lapp/revanced/patcher/data/ResourceContext;)V
} }
public final class app/revanced/patches/all/misc/hex/HexPatch : app/revanced/patches/shared/misc/hex/BaseHexPatch {
public fun <init> ()V
}
public final class app/revanced/patches/all/misc/network/OverrideCertificatePinningPatch : app/revanced/patcher/patch/ResourcePatch { public final class app/revanced/patches/all/misc/network/OverrideCertificatePinningPatch : app/revanced/patcher/patch/ResourcePatch {
public static final field INSTANCE Lapp/revanced/patches/all/misc/network/OverrideCertificatePinningPatch; public static final field INSTANCE Lapp/revanced/patches/all/misc/network/OverrideCertificatePinningPatch;
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
@@ -669,6 +673,21 @@ public abstract class app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportRes
protected final fun getGmsCoreVendorGroupId ()Ljava/lang/String; protected final fun getGmsCoreVendorGroupId ()Ljava/lang/String;
} }
public abstract class app/revanced/patches/shared/misc/hex/BaseHexPatch : app/revanced/patcher/patch/RawResourcePatch {
public fun <init> ()V
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
public fun execute (Lapp/revanced/patcher/data/ResourceContext;)V
}
public final class app/revanced/patches/shared/misc/hex/BaseHexPatch$Replacement {
public static final field Companion Lapp/revanced/patches/shared/misc/hex/BaseHexPatch$Replacement$Companion;
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
public final fun replacePattern ([B)V
}
public final class app/revanced/patches/shared/misc/hex/BaseHexPatch$Replacement$Companion {
}
public abstract class app/revanced/patches/shared/misc/integrations/BaseIntegrationsPatch : app/revanced/patcher/patch/BytecodePatch { public abstract class app/revanced/patches/shared/misc/integrations/BaseIntegrationsPatch : app/revanced/patcher/patch/BytecodePatch {
public fun <init> (Ljava/lang/String;Ljava/util/Set;)V public fun <init> (Ljava/lang/String;Ljava/util/Set;)V
public fun <init> (Ljava/util/Set;)V public fun <init> (Ljava/util/Set;)V
@@ -705,6 +724,7 @@ public final class app/revanced/patches/shared/misc/mapping/ResourceMappingPatch
public static final field INSTANCE Lapp/revanced/patches/shared/misc/mapping/ResourceMappingPatch; public static final field INSTANCE Lapp/revanced/patches/shared/misc/mapping/ResourceMappingPatch;
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
public fun execute (Lapp/revanced/patcher/data/ResourceContext;)V public fun execute (Lapp/revanced/patcher/data/ResourceContext;)V
public final fun get (Ljava/lang/String;Ljava/lang/String;)J
} }
public final class app/revanced/patches/shared/misc/mapping/ResourceMappingPatch$ResourceElement { public final class app/revanced/patches/shared/misc/mapping/ResourceMappingPatch$ResourceElement {
@@ -844,6 +864,8 @@ public final class app/revanced/patches/shared/misc/settings/preference/ListPref
} }
public final class app/revanced/patches/shared/misc/settings/preference/NonInteractivePreference : app/revanced/patches/shared/misc/settings/preference/BasePreference { public final class app/revanced/patches/shared/misc/settings/preference/NonInteractivePreference : app/revanced/patches/shared/misc/settings/preference/BasePreference {
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun getSelectable ()Z public final fun getSelectable ()Z
@@ -1825,11 +1847,12 @@ public final class app/revanced/patches/yuka/misc/unlockpremium/UnlockPremiumPat
public final class app/revanced/util/BytecodeUtilsKt { public final class app/revanced/util/BytecodeUtilsKt {
public static final fun containsWideLiteralInstructionValue (Lcom/android/tools/smali/dexlib2/iface/Method;J)Z public static final fun containsWideLiteralInstructionValue (Lcom/android/tools/smali/dexlib2/iface/Method;J)Z
public static final fun findIndexForIdResource (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/String;)I
public static final fun findMutableMethodOf (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;Lcom/android/tools/smali/dexlib2/iface/Method;)Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod; public static final fun findMutableMethodOf (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;Lcom/android/tools/smali/dexlib2/iface/Method;)Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;
public static final fun getException (Lapp/revanced/patcher/fingerprint/MethodFingerprint;)Lapp/revanced/patcher/patch/PatchException; public static final fun getException (Lapp/revanced/patcher/fingerprint/MethodFingerprint;)Lapp/revanced/patcher/patch/PatchException;
public static final fun indexOfFirstInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;Lkotlin/jvm/functions/Function1;)I public static final fun indexOfFirstInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;Lkotlin/jvm/functions/Function1;)I
public static final fun indexOfFirstWideLiteralInstructionValue (Lcom/android/tools/smali/dexlib2/iface/Method;J)I public static final fun indexOfFirstWideLiteralInstructionValue (Lcom/android/tools/smali/dexlib2/iface/Method;J)I
public static final fun indexOfIdResource (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/String;)I
public static final fun indexOfIdResourceOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/String;)I
public static final fun injectHideViewCall (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;IILjava/lang/String;Ljava/lang/String;)V public static final fun injectHideViewCall (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;IILjava/lang/String;Ljava/lang/String;)V
public static final fun resultOrThrow (Lapp/revanced/patcher/fingerprint/MethodFingerprint;)Lapp/revanced/patcher/fingerprint/MethodFingerprintResult; public static final fun resultOrThrow (Lapp/revanced/patcher/fingerprint/MethodFingerprint;)Lapp/revanced/patcher/fingerprint/MethodFingerprintResult;
public static final fun returnEarly (Ljava/util/List;Z)V public static final fun returnEarly (Ljava/util/List;Z)V

View File

@@ -1,4 +1,4 @@
org.gradle.parallel = true org.gradle.parallel = true
org.gradle.caching = true org.gradle.caching = true
kotlin.code.style = official kotlin.code.style = official
version = 4.7.0-dev.7 version = 4.8.0-dev.2

View File

@@ -0,0 +1,55 @@
package app.revanced.patches.all.misc.hex
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.registerNewPatchOption
import app.revanced.patches.shared.misc.hex.BaseHexPatch
import app.revanced.util.Utils.trimIndentMultiline
import app.revanced.patcher.patch.Patch as PatchClass
@Patch(
name = "Hex",
description = "Replaces a hexadecimal patterns of bytes of files in an APK.",
use = false,
)
@Suppress("unused")
class HexPatch : BaseHexPatch() {
// TODO: Instead of stringArrayOption, use a custom option type to work around
// https://github.com/ReVanced/revanced-library/issues/48.
// Replace the custom option type with a stringArrayOption once the issue is resolved.
private val replacementsOption by registerNewPatchOption<PatchClass<*>, List<String>>(
key = "replacements",
title = "Replacements",
description = """
Hexadecimal patterns to search for and replace with another in a target file.
A pattern is a sequence of case insensitive strings, each representing hexadecimal bytes, separated by spaces.
An example pattern is 'aa 01 02 FF'.
Every pattern must be followed by a pipe ('|'), the replacement pattern,
another pipe ('|'), and the path to the file to make the changes in relative to the APK root.
The replacement pattern must have the same length as the original pattern.
Full example of a valid input:
'aa 01 02 FF|00 00 00 00|path/to/file'
""".trimIndentMultiline(),
required = true,
valueType = "StringArray",
)
override val replacements
get() = replacementsOption!!.map { from ->
val (pattern, replacementPattern, targetFilePath) = try {
from.split("|", limit = 3)
} catch (e: Exception) {
throw PatchException(
"Invalid input: $from.\n" +
"Every pattern must be followed by a pipe ('|'), " +
"the replacement pattern, another pipe ('|'), " +
"and the path to the file to make the changes in relative to the APK root. ",
)
}
Replacement(pattern, replacementPattern, targetFilePath)
}
}

View File

@@ -2,23 +2,28 @@ package app.revanced.patches.music.layout.premium
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.layout.premium.fingerprints.HideGetPremiumFingerprint import app.revanced.patches.music.layout.premium.fingerprints.HideGetPremiumFingerprint
import app.revanced.patches.music.layout.premium.fingerprints.MembershipSettingsFingerprint
import app.revanced.util.exception import app.revanced.util.exception
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
@Patch( @Patch(
name = "Hide 'Get Music Premium' label", name = "Hide 'Get Music Premium' label",
description = "Hides the red \"Get Music Premium\" label from the account menu.", description = "Hides the \"Get Music Premium\" label from the account menu and settings.",
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")], compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
) )
@Suppress("unused") @Suppress("unused")
object HideGetPremiumPatch : BytecodePatch( object HideGetPremiumPatch : BytecodePatch(
setOf(HideGetPremiumFingerprint), setOf(
HideGetPremiumFingerprint,
MembershipSettingsFingerprint,
),
) { ) {
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
HideGetPremiumFingerprint.result?.let { HideGetPremiumFingerprint.result?.let {
@@ -41,5 +46,13 @@ object HideGetPremiumPatch : BytecodePatch(
) )
} }
} ?: throw HideGetPremiumFingerprint.exception } ?: throw HideGetPremiumFingerprint.exception
MembershipSettingsFingerprint.result?.mutableMethod?.addInstructions(
0,
"""
const/4 v0, 0x0
return-object v0
""",
) ?: throw MembershipSettingsFingerprint.exception
} }
} }

View File

@@ -12,6 +12,8 @@ internal object HideGetPremiumFingerprint : MethodFingerprint(
listOf( listOf(
Opcode.IF_NEZ, Opcode.IF_NEZ,
Opcode.CONST_16, Opcode.CONST_16,
Opcode.GOTO,
Opcode.NOP,
Opcode.INVOKE_VIRTUAL, Opcode.INVOKE_VIRTUAL,
), ),
listOf("FEmusic_history", "FEmusic_offline"), listOf("FEmusic_history", "FEmusic_offline"),

View File

@@ -0,0 +1,20 @@
package app.revanced.patches.music.layout.premium.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
internal object MembershipSettingsFingerprint : MethodFingerprint(
returnType = "Ljava/lang/CharSequence;",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
opcodes = listOf(
Opcode.IGET_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IF_EQZ,
Opcode.IGET_OBJECT
)
)

View File

@@ -13,6 +13,7 @@ internal object PivotBarConstructorFingerprint : MethodFingerprint(
Opcode.CHECK_CAST, Opcode.CHECK_CAST,
Opcode.INVOKE_INTERFACE, Opcode.INVOKE_INTERFACE,
Opcode.GOTO, Opcode.GOTO,
Opcode.NOP,
Opcode.IPUT_OBJECT, Opcode.IPUT_OBJECT,
Opcode.RETURN_VOID, Opcode.RETURN_VOID,
), ),

View File

@@ -0,0 +1,120 @@
package app.revanced.patches.shared.misc.hex
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.RawResourcePatch
import kotlin.math.max
abstract class BaseHexPatch : RawResourcePatch() {
internal abstract val replacements: List<Replacement>
override fun execute(context: ResourceContext) {
replacements.groupBy { it.targetFilePath }.forEach { (targetFilePath, replacements) ->
val targetFile = try {
context[targetFilePath, true]
} catch (e: Exception) {
throw PatchException("Could not find target file: $targetFilePath")
}
// TODO: Use a file channel to read and write the file instead of reading the whole file into memory,
// in order to reduce memory usage.
val targetFileBytes = targetFile.readBytes()
replacements.forEach { replacement ->
replacement.replacePattern(targetFileBytes)
}
targetFile.writeBytes(targetFileBytes)
}
}
/**
* Represents a pattern to search for and its replacement pattern.
*
* @property pattern The pattern to search for.
* @property replacementPattern The pattern to replace the [pattern] with.
* @property targetFilePath The path to the file to make the changes in relative to the APK root.
*/
class Replacement(
private val pattern: String,
replacementPattern: String,
internal val targetFilePath: String,
) {
private val patternBytes = pattern.toByteArrayPattern()
private val replacementPattern = replacementPattern.toByteArrayPattern()
init {
if (this.patternBytes.size != this.replacementPattern.size) {
throw PatchException("Pattern and replacement pattern must have the same length: $pattern")
}
}
/**
* Replaces the [patternBytes] with the [replacementPattern] in the [targetFileBytes].
*
* @param targetFileBytes The bytes of the file to make the changes in.
*/
fun replacePattern(targetFileBytes: ByteArray) {
val startIndex = indexOfPatternIn(targetFileBytes)
if (startIndex == -1) {
throw PatchException("Pattern not found in target file: $pattern")
}
replacementPattern.copyInto(targetFileBytes, startIndex)
}
// TODO: Allow searching in a file channel instead of a byte array to reduce memory usage.
/**
* Returns the index of the first occurrence of [patternBytes] in the haystack
* using the Boyer-Moore algorithm.
*
* @param haystack The array to search in.
*
* @return The index of the first occurrence of the [patternBytes] in the haystack or -1
* if the [patternBytes] is not found.
*/
private fun indexOfPatternIn(haystack: ByteArray): Int {
val needle = patternBytes
val haystackLength = haystack.size - 1
val needleLength = needle.size - 1
val right = IntArray(256) { -1 }
for (i in 0 until needleLength) right[needle[i].toInt().and(0xFF)] = i
var skip: Int
for (i in 0..haystackLength - needleLength) {
skip = 0
for (j in needleLength - 1 downTo 0)
if (needle[j] != haystack[i + j]) {
skip = max(1, j - right[haystack[i + j].toInt().and(0xFF)])
break
}
if (skip == 0) return i
}
return -1
}
companion object {
/**
* Convert a string representing a pattern of hexadecimal bytes to a byte array.
*
* @return The byte array representing the pattern.
* @throws PatchException If the pattern is invalid.
*/
private fun String.toByteArrayPattern() = try {
split(" ").map { it.toInt(16).toByte() }.toByteArray()
} catch (e: NumberFormatException) {
throw PatchException(
"Could not parse pattern: $this. A pattern is a sequence of case insensitive strings " +
"representing hexadecimal bytes separated by spaces",
e,
)
}
}
}
}

View File

@@ -2,17 +2,21 @@ package app.revanced.patches.shared.misc.integrations
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.PatchException
import app.revanced.patches.shared.misc.integrations.BaseIntegrationsPatch.IntegrationsFingerprint.IRegisterResolver import app.revanced.patches.shared.misc.integrations.BaseIntegrationsPatch.IntegrationsFingerprint.IRegisterResolver
import app.revanced.patches.shared.misc.integrations.fingerprints.ReVancedUtilsPatchesVersionFingerprint
import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.ClassDef import com.android.tools.smali.dexlib2.iface.ClassDef
import com.android.tools.smali.dexlib2.iface.Method import com.android.tools.smali.dexlib2.iface.Method
import java.util.jar.JarFile
abstract class BaseIntegrationsPatch( abstract class BaseIntegrationsPatch(
private val hooks: Set<IntegrationsFingerprint>, private val hooks: Set<IntegrationsFingerprint>,
) : BytecodePatch(hooks) { ) : BytecodePatch(hooks + setOf(ReVancedUtilsPatchesVersionFingerprint)) {
@Deprecated( @Deprecated(
"Use the constructor without the integrationsDescriptor parameter", "Use the constructor without the integrationsDescriptor parameter",
@@ -34,6 +38,46 @@ abstract class BaseIntegrationsPatch(
hooks.forEach { hook -> hooks.forEach { hook ->
hook.invoke(INTEGRATIONS_CLASS_DESCRIPTOR) hook.invoke(INTEGRATIONS_CLASS_DESCRIPTOR)
} }
// Modify Utils method to include the patches release version version.
ReVancedUtilsPatchesVersionFingerprint.resultOrThrow().mutableMethod.apply {
val manifestValue = getPatchesManifestEntry("Version")
addInstructions(
0,
"""
const-string v0, "$manifestValue"
return-object v0
""",
)
}
}
/**
* @return The value for the manifest entry,
* or "Unknown" if the entry does not exist or is blank.
*/
@Suppress("SameParameterValue")
private fun getPatchesManifestEntry(attributeKey: String) = JarFile(getCurrentJarFilePath()).use { jarFile ->
jarFile.manifest.mainAttributes.entries.firstOrNull { it.key.toString() == attributeKey }?.value?.toString()
?: "Unknown"
}
/**
* @return The file path for the jar this classfile is contained inside.
*/
private fun getCurrentJarFilePath(): String {
val className = object {}::class.java.enclosingClass.name.replace('.', '/') + ".class"
val classUrl = object {}::class.java.classLoader.getResource(className)
if (classUrl != null) {
val urlString = classUrl.toString()
if (urlString.startsWith("jar:file:")) {
val end = urlString.indexOf('!')
return urlString.substring("jar:file:".length, end)
}
}
throw IllegalStateException("Not running from inside a JAR file.")
} }
/** /**
@@ -50,7 +94,7 @@ abstract class BaseIntegrationsPatch(
strings: Iterable<String>? = null, strings: Iterable<String>? = null,
customFingerprint: ((methodDef: Method, classDef: ClassDef) -> Boolean)? = null, customFingerprint: ((methodDef: Method, classDef: ClassDef) -> Boolean)? = null,
private val insertIndexResolver: ((Method) -> Int) = object : IHookInsertIndexResolver {}, private val insertIndexResolver: ((Method) -> Int) = object : IHookInsertIndexResolver {},
private val contextRegisterResolver: (Method) -> Int = object : IRegisterResolver {} private val contextRegisterResolver: (Method) -> Int = object : IRegisterResolver {},
) : MethodFingerprint( ) : MethodFingerprint(
returnType, returnType,
accessFlags, accessFlags,
@@ -59,9 +103,11 @@ abstract class BaseIntegrationsPatch(
strings, strings,
customFingerprint, customFingerprint,
) { ) {
@Deprecated("Previous constructor that is missing the insert index." + @Deprecated(
"Previous constructor that is missing the insert index." +
"Here only for binary compatibility, " + "Here only for binary compatibility, " +
"and this can be removed after the next major version update.") "and this can be removed after the next major version update.",
)
constructor( constructor(
returnType: String? = null, returnType: String? = null,
accessFlags: Int? = null, accessFlags: Int? = null,
@@ -69,7 +115,7 @@ abstract class BaseIntegrationsPatch(
opcodes: Iterable<Opcode?>? = null, opcodes: Iterable<Opcode?>? = null,
strings: Iterable<String>? = null, strings: Iterable<String>? = null,
customFingerprint: ((methodDef: Method, classDef: ClassDef) -> Boolean)? = null, customFingerprint: ((methodDef: Method, classDef: ClassDef) -> Boolean)? = null,
contextRegisterResolver: (Method) -> Int = object : IRegisterResolver {} contextRegisterResolver: (Method) -> Int = object : IRegisterResolver {},
) : this( ) : this(
returnType, returnType,
accessFlags, accessFlags,
@@ -78,7 +124,7 @@ abstract class BaseIntegrationsPatch(
strings, strings,
customFingerprint, customFingerprint,
object : IHookInsertIndexResolver {}, object : IHookInsertIndexResolver {},
contextRegisterResolver contextRegisterResolver,
) )
fun invoke(integrationsDescriptor: String) { fun invoke(integrationsDescriptor: String) {
@@ -103,7 +149,7 @@ abstract class BaseIntegrationsPatch(
} }
} }
private companion object { internal companion object {
private const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/shared/Utils;" internal const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/shared/Utils;"
} }
} }

View File

@@ -0,0 +1,16 @@
package app.revanced.patches.shared.misc.integrations.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.shared.misc.integrations.BaseIntegrationsPatch
import com.android.tools.smali.dexlib2.AccessFlags
internal object ReVancedUtilsPatchesVersionFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
returnType = "Ljava/lang/String;",
parameters = listOf(),
customFingerprint = { methodDef, classDef ->
methodDef.name == "getPatchesReleaseVersion" &&
classDef.type == BaseIntegrationsPatch.INTEGRATIONS_CLASS_DESCRIPTOR
}
)

View File

@@ -8,19 +8,15 @@ import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
object ResourceMappingPatch : ResourcePatch() { object ResourceMappingPatch : ResourcePatch() {
internal lateinit var resourceMappings: List<ResourceElement> private val resourceMappings = Collections.synchronizedList(mutableListOf<ResourceElement>())
private set
private val THREAD_COUNT = Runtime.getRuntime().availableProcessors() private val THREAD_COUNT = Runtime.getRuntime().availableProcessors()
private val threadPoolExecutor = Executors.newFixedThreadPool(THREAD_COUNT) private val threadPoolExecutor = Executors.newFixedThreadPool(THREAD_COUNT)
override fun execute(context: ResourceContext) { override fun execute(context: ResourceContext) {
// save the file in memory to concurrently read from // sSve the file in memory to concurrently read from it.
val resourceXmlFile = context.get("res/values/public.xml").readBytes() val resourceXmlFile = context.get("res/values/public.xml").readBytes()
// create a synchronized list to store the resource mappings
val mappings = Collections.synchronizedList(mutableListOf<ResourceElement>())
for (threadIndex in 0 until THREAD_COUNT) { for (threadIndex in 0 until THREAD_COUNT) {
threadPoolExecutor.execute thread@{ threadPoolExecutor.execute thread@{
context.xmlEditor[resourceXmlFile.inputStream()].use { editor -> context.xmlEditor[resourceXmlFile.inputStream()].use { editor ->
@@ -33,7 +29,7 @@ object ResourceMappingPatch : ResourcePatch() {
val batchStart = jobSize * threadIndex val batchStart = jobSize * threadIndex
val batchEnd = jobSize * (threadIndex + 1) val batchEnd = jobSize * (threadIndex + 1)
element@ for (i in batchStart until batchEnd) { element@ for (i in batchStart until batchEnd) {
// make sure to not go out of bounds when rounding errors occur at calculating the jobSize // Prevent out of bounds.
if (i >= resourcesLength) return@thread if (i >= resourcesLength) return@thread
val node = resources.item(i) val node = resources.item(i)
@@ -46,18 +42,18 @@ object ResourceMappingPatch : ResourcePatch() {
val id = node.getAttribute("id").substring(2).toLong(16) val id = node.getAttribute("id").substring(2).toLong(16)
mappings.add(ResourceElement(typeAttribute, nameAttribute, id)) resourceMappings.add(ResourceElement(typeAttribute, nameAttribute, id))
} }
} }
} }
} }
threadPoolExecutor threadPoolExecutor.also { it.shutdown() }.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS)
.also { it.shutdown() }
.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS)
resourceMappings = mappings
} }
operator fun get(type: String, name: String) = resourceMappings.first {
it.type == type && it.name == name
}.id
data class ResourceElement(val type: String, val name: String, val id: Long) data class ResourceElement(val type: String, val name: String, val id: Long)
} }

View File

@@ -16,10 +16,19 @@ import org.w3c.dom.Document
@Suppress("MemberVisibilityCanBePrivate") @Suppress("MemberVisibilityCanBePrivate")
class NonInteractivePreference( class NonInteractivePreference(
key: String, key: String,
titleKey: String = "${key}_title",
summaryKey: String? = "${key}_summary", summaryKey: String? = "${key}_summary",
tag: String = "Preference", tag: String = "Preference",
val selectable: Boolean = false val selectable: Boolean = false
) : BasePreference(null, "${key}_title", summaryKey, tag) { ) : BasePreference(key, titleKey, summaryKey, tag) {
@Deprecated("Here only for binary compatibility, and should be removed after the next major version update.")
constructor(
key: String,
summaryKey: String? = "${key}_summary",
tag: String = "Preference",
selectable: Boolean = false
) : this(key, "${key}_title", summaryKey, tag, selectable)
override fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit) = override fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit) =
super.serialize(ownerDocument, resourceCallback).apply { super.serialize(ownerDocument, resourceCallback).apply {

View File

@@ -11,12 +11,11 @@ object PremiumNavbarTabResourcePatch : ResourcePatch() {
internal var premiumTabId = -1L internal var premiumTabId = -1L
override fun execute(context: ResourceContext) { override fun execute(context: ResourceContext) {
premiumTabId = ResourceMappingPatch.resourceMappings.single { premiumTabId = ResourceMappingPatch["id", "premium_tab"]
it.type == "id" && it.name == "premium_tab"
}.id
showBottomNavigationItemsTextId = ResourceMappingPatch.resourceMappings.single { showBottomNavigationItemsTextId = ResourceMappingPatch[
it.type == "bool" && it.name == "show_bottom_navigation_items_text" "bool",
}.id "show_bottom_navigation_items_text",
]
} }
} }

View File

@@ -62,7 +62,17 @@ object SettingsPatch : BytecodePatch(
AddResourcesPatch(this::class) AddResourcesPatch(this::class)
PreferenceScreen.MISC.OTHER.addPreferences( PreferenceScreen.MISC.OTHER.addPreferences(
SwitchPreference("revanced_debug") // The debug setting is shared across multiple apps and the key must be the same.
// But the title and summary must be different, otherwise when the strings file is flattened
// for Crowdin push, Crowdin gets confused by the duplicate keys.
// FIXME: Ideally the shared debug strings are extracted into a common app group
// and then both apps import that. But for now unique unique title and summary keys also works.
SwitchPreference(
key = "revanced_debug",
titleKey = "revanced_twitch_debug_title",
summaryOnKey = "revanced_twitch_debug_summary_on",
summaryOffKey = "revanced_twitch_debug_summary_off"
)
) )
// Hook onCreate to handle fragment creation // Hook onCreate to handle fragment creation

View File

@@ -42,7 +42,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
], ],
), ),
], ],

View File

@@ -14,8 +14,8 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
LithoFilterPatch::class, LithoFilterPatch::class,
SettingsPatch::class, SettingsPatch::class,
ResourceMappingPatch::class, ResourceMappingPatch::class,
AddResourcesPatch::class AddResourcesPatch::class,
] ],
) )
object HideAdsResourcePatch : ResourcePatch() { object HideAdsResourcePatch : ResourcePatch() {
private const val FILTER_CLASS_DESCRIPTOR = private const val FILTER_CLASS_DESCRIPTOR =
@@ -30,16 +30,16 @@ object HideAdsResourcePatch : ResourcePatch() {
SwitchPreference("revanced_hide_general_ads"), SwitchPreference("revanced_hide_general_ads"),
SwitchPreference("revanced_hide_fullscreen_ads"), SwitchPreference("revanced_hide_fullscreen_ads"),
SwitchPreference("revanced_hide_buttoned_ads"), SwitchPreference("revanced_hide_buttoned_ads"),
SwitchPreference("revanced_hide_paid_content_ads"), SwitchPreference("revanced_hide_paid_promotion_label"),
SwitchPreference("revanced_hide_self_sponsor_ads"), SwitchPreference("revanced_hide_self_sponsor_ads"),
SwitchPreference("revanced_hide_products_banner"), SwitchPreference("revanced_hide_products_banner"),
SwitchPreference("revanced_hide_shopping_links"), SwitchPreference("revanced_hide_shopping_links"),
SwitchPreference("revanced_hide_web_search_results"), SwitchPreference("revanced_hide_web_search_results"),
SwitchPreference("revanced_hide_merchandise_banners") SwitchPreference("revanced_hide_merchandise_banners"),
) )
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR) LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
adAttributionId = ResourceMappingPatch.resourceMappings.single { it.name == "ad_attribution" }.id adAttributionId = ResourceMappingPatch["id", "ad_attribution"]
} }
} }

View File

@@ -36,7 +36,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -41,7 +41,9 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -29,7 +29,9 @@ import app.revanced.patches.youtube.video.information.VideoInformationPatch
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
], ],
), ),
], ],

View File

@@ -38,7 +38,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -35,7 +35,9 @@ import app.revanced.util.resultOrThrow
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
], ],
), ),
], ],

View File

@@ -38,7 +38,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -40,7 +40,9 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -36,7 +36,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
], ],

View File

@@ -20,7 +20,7 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
dependencies = [ dependencies = [
IntegrationsPatch::class, IntegrationsPatch::class,
PlayerTypeHookPatch::class, PlayerTypeHookPatch::class,
SwipeControlsResourcePatch::class SwipeControlsResourcePatch::class,
], ],
compatiblePackages = [ compatiblePackages = [
CompatiblePackage( CompatiblePackage(
@@ -42,17 +42,22 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
] "19.10.39",
) "19.11.43", // 19.12.x has an issue with opening YT using external links,
] // and the app then crashes if double tap to skip forward/back is immediately used.
// The stack trace shows a call coming from integrations SwipeController,
// but it may be a bug in YT itself as other target versions do not have this issue.
],
),
],
) )
@Suppress("unused") @Suppress("unused")
object SwipeControlsBytecodePatch : BytecodePatch( object SwipeControlsBytecodePatch : BytecodePatch(
setOf( setOf(
MainActivityFingerprint, MainActivityFingerprint,
SwipeControlsHostActivityFingerprint SwipeControlsHostActivityFingerprint,
) ),
) { ) {
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
val wrapperClass = SwipeControlsHostActivityFingerprint.result!!.mutableClass val wrapperClass = SwipeControlsHostActivityFingerprint.result!!.mutableClass
@@ -74,9 +79,9 @@ object SwipeControlsBytecodePatch : BytecodePatch(
accessFlags and AccessFlags.FINAL.value.inv(), accessFlags and AccessFlags.FINAL.value.inv(),
annotations, annotations,
hiddenApiRestrictions, hiddenApiRestrictions,
implementation implementation,
).toMutable() ).toMutable()
} }
} }
} }
} }

View File

@@ -24,6 +24,7 @@ internal object SwipeControlsResourcePatch : ResourcePatch() {
SwitchPreference("revanced_swipe_press_to_engage"), SwitchPreference("revanced_swipe_press_to_engage"),
SwitchPreference("revanced_swipe_haptic_feedback"), SwitchPreference("revanced_swipe_haptic_feedback"),
SwitchPreference("revanced_swipe_save_and_restore_brightness"), SwitchPreference("revanced_swipe_save_and_restore_brightness"),
SwitchPreference("revanced_swipe_lowest_value_enable_auto_brightness"),
TextPreference("revanced_swipe_overlay_timeout", inputType = InputType.NUMBER), TextPreference("revanced_swipe_overlay_timeout", inputType = InputType.NUMBER),
TextPreference("revanced_swipe_text_overlay_size", inputType = InputType.NUMBER), TextPreference("revanced_swipe_text_overlay_size", inputType = InputType.NUMBER),
TextPreference("revanced_swipe_overlay_background_alpha", inputType = InputType.NUMBER), TextPreference("revanced_swipe_overlay_background_alpha", inputType = InputType.NUMBER),

View File

@@ -40,7 +40,9 @@ import app.revanced.util.exception
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
], ],

View File

@@ -39,7 +39,9 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]
@@ -63,8 +65,7 @@ object HideButtonsPatch : ResourcePatch() {
SwitchPreference("revanced_hide_download_button"), SwitchPreference("revanced_hide_download_button"),
SwitchPreference("revanced_hide_thanks_button"), SwitchPreference("revanced_hide_thanks_button"),
SwitchPreference("revanced_hide_clip_button"), SwitchPreference("revanced_hide_clip_button"),
SwitchPreference("revanced_hide_playlist_button"), SwitchPreference("revanced_hide_playlist_button")
SwitchPreference("revanced_hide_shop_button")
), ),
) )
) )

View File

@@ -14,7 +14,7 @@ import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.SettingsPatch import app.revanced.patches.youtube.misc.settings.SettingsPatch
import app.revanced.patches.youtube.shared.fingerprints.LayoutConstructorFingerprint import app.revanced.patches.youtube.shared.fingerprints.LayoutConstructorFingerprint
import app.revanced.util.exception import app.revanced.util.exception
import app.revanced.util.findIndexForIdResource import app.revanced.util.indexOfIdResourceOrThrow
import com.android.tools.smali.dexlib2.iface.instruction.Instruction import com.android.tools.smali.dexlib2.iface.instruction.Instruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
@@ -27,7 +27,7 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
IntegrationsPatch::class, IntegrationsPatch::class,
SettingsPatch::class, SettingsPatch::class,
ResourceMappingPatch::class, ResourceMappingPatch::class,
AddResourcesPatch::class AddResourcesPatch::class,
], ],
compatiblePackages = [ compatiblePackages = [
CompatiblePackage( CompatiblePackage(
@@ -49,27 +49,29 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
] "19.10.39",
) "19.11.43",
] ],
),
],
) )
@Suppress("unused") @Suppress("unused")
object HideAutoplayButtonPatch : BytecodePatch( object HideAutoplayButtonPatch : BytecodePatch(
setOf(LayoutConstructorFingerprint) setOf(LayoutConstructorFingerprint),
) { ) {
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class) AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.PLAYER.addPreferences( SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_hide_autoplay_button") SwitchPreference("revanced_hide_autoplay_button"),
) )
LayoutConstructorFingerprint.result?.mutableMethod?.apply { LayoutConstructorFingerprint.result?.mutableMethod?.apply {
val layoutGenMethodInstructions = implementation!!.instructions val layoutGenMethodInstructions = implementation!!.instructions
// resolve the offsets of where to insert the branch instructions and ... // resolve the offsets of where to insert the branch instructions and ...
val insertIndex = findIndexForIdResource("autonav_preview_stub") val insertIndex = indexOfIdResourceOrThrow("autonav_preview_stub")
// where to branch away // where to branch away
val branchIndex = val branchIndex =
@@ -90,8 +92,8 @@ object HideAutoplayButtonPatch : BytecodePatch(
move-result v$clobberRegister move-result v$clobberRegister
if-eqz v$clobberRegister, :hidden if-eqz v$clobberRegister, :hidden
""", """,
ExternalLabel("hidden", jumpInstruction) ExternalLabel("hidden", jumpInstruction),
) )
} ?: throw LayoutConstructorFingerprint.exception } ?: throw LayoutConstructorFingerprint.exception
} }
} }

View File

@@ -40,7 +40,9 @@ import com.android.tools.smali.dexlib2.Opcode
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -47,7 +47,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37", "19.09.38",
"19.10.39",
"19.11.43"
], ],
), ),
], ],

View File

@@ -44,7 +44,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction3rc
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -38,7 +38,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -12,7 +12,7 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
dependencies = [ dependencies = [
SettingsPatch::class, SettingsPatch::class,
ResourceMappingPatch::class, ResourceMappingPatch::class,
AddResourcesPatch::class AddResourcesPatch::class,
], ],
) )
internal object AlbumCardsResourcePatch : ResourcePatch() { internal object AlbumCardsResourcePatch : ResourcePatch() {
@@ -22,11 +22,9 @@ internal object AlbumCardsResourcePatch : ResourcePatch() {
AddResourcesPatch(this::class) AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.FEED.addPreferences( SettingsPatch.PreferenceScreen.FEED.addPreferences(
SwitchPreference("revanced_hide_album_cards") SwitchPreference("revanced_hide_album_cards"),
) )
albumCardId = ResourceMappingPatch.resourceMappings.single { albumCardId = ResourceMappingPatch["layout", "album_card"]
it.type == "layout" && it.name == "album_card"
}.id
} }
} }

View File

@@ -38,7 +38,9 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -38,7 +38,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -12,7 +12,7 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
dependencies = [ dependencies = [
SettingsPatch::class, SettingsPatch::class,
ResourceMappingPatch::class, ResourceMappingPatch::class,
AddResourcesPatch::class AddResourcesPatch::class,
], ],
) )
internal object CrowdfundingBoxResourcePatch : ResourcePatch() { internal object CrowdfundingBoxResourcePatch : ResourcePatch() {
@@ -22,11 +22,12 @@ internal object CrowdfundingBoxResourcePatch : ResourcePatch() {
AddResourcesPatch(this::class) AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.FEED.addPreferences( SettingsPatch.PreferenceScreen.FEED.addPreferences(
SwitchPreference("revanced_hide_crowdfunding_box") SwitchPreference("revanced_hide_crowdfunding_box"),
) )
crowdfundingBoxId = ResourceMappingPatch.resourceMappings.single { crowdfundingBoxId = ResourceMappingPatch[
it.type == "layout" && it.name == "donation_companion" "layout",
}.id "donation_companion",
]
} }
} }

View File

@@ -41,7 +41,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction21c
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -12,7 +12,7 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
dependencies = [ dependencies = [
SettingsPatch::class, SettingsPatch::class,
ResourceMappingPatch::class, ResourceMappingPatch::class,
AddResourcesPatch::class AddResourcesPatch::class,
], ],
) )
internal object HideEndscreenCardsResourcePatch : ResourcePatch() { internal object HideEndscreenCardsResourcePatch : ResourcePatch() {
@@ -24,15 +24,13 @@ internal object HideEndscreenCardsResourcePatch : ResourcePatch() {
AddResourcesPatch(this::class) AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.PLAYER.addPreferences( SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_hide_endscreen_cards") SwitchPreference("revanced_hide_endscreen_cards"),
) )
fun findEndscreenResourceId(name: String) = ResourceMappingPatch.resourceMappings.single { fun idOf(name: String) = ResourceMappingPatch["layout", "endscreen_element_layout_$name"]
it.type == "layout" && it.name == "endscreen_element_layout_$name"
}.id
layoutCircle = findEndscreenResourceId("circle") layoutCircle = idOf("circle")
layoutIcon = findEndscreenResourceId("icon") layoutIcon = idOf("icon")
layoutVideo = findEndscreenResourceId("video") layoutVideo = idOf("video")
} }
} }

View File

@@ -38,7 +38,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -25,15 +25,12 @@ internal object HideFilterBarResourcePatch : ResourcePatch() {
SwitchPreference("revanced_hide_filter_bar_feed_in_feed"), SwitchPreference("revanced_hide_filter_bar_feed_in_feed"),
SwitchPreference("revanced_hide_filter_bar_feed_in_search"), SwitchPreference("revanced_hide_filter_bar_feed_in_search"),
SwitchPreference("revanced_hide_filter_bar_feed_in_related_videos"), SwitchPreference("revanced_hide_filter_bar_feed_in_related_videos"),
) ),
) ),
) )
relatedChipCloudMarginId = "related_chip_cloud_reduced_margins".layoutResourceId("layout") relatedChipCloudMarginId = ResourceMappingPatch["layout", "related_chip_cloud_reduced_margins"]
filterBarHeightId = "filter_bar_height".layoutResourceId() filterBarHeightId = ResourceMappingPatch["dimen", "filter_bar_height"]
barContainerHeightId = "bar_container_height".layoutResourceId() barContainerHeightId = ResourceMappingPatch["dimen", "bar_container_height"]
} }
}
private fun String.layoutResourceId(type: String = "dimen") =
ResourceMappingPatch.resourceMappings.single { it.type == type && it.name == this }.id
}

View File

@@ -34,7 +34,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -1,7 +1,6 @@
package app.revanced.patches.youtube.layout.hide.floatingmicrophone package app.revanced.patches.youtube.layout.hide.floatingmicrophone
import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.all.misc.resources.AddResourcesPatch import app.revanced.patches.all.misc.resources.AddResourcesPatch
@@ -13,8 +12,8 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
dependencies = [ dependencies = [
SettingsPatch::class, SettingsPatch::class,
ResourceMappingPatch::class, ResourceMappingPatch::class,
AddResourcesPatch::class AddResourcesPatch::class,
] ],
) )
internal object HideFloatingMicrophoneButtonResourcePatch : ResourcePatch() { internal object HideFloatingMicrophoneButtonResourcePatch : ResourcePatch() {
internal var fabButtonId: Long = -1 internal var fabButtonId: Long = -1
@@ -23,10 +22,9 @@ internal object HideFloatingMicrophoneButtonResourcePatch : ResourcePatch() {
AddResourcesPatch(this::class) AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.GENERAL_LAYOUT.addPreferences( SettingsPatch.PreferenceScreen.GENERAL_LAYOUT.addPreferences(
SwitchPreference("revanced_hide_floating_microphone_button") SwitchPreference("revanced_hide_floating_microphone_button"),
) )
fabButtonId = ResourceMappingPatch.resourceMappings.find { it.type == "id" && it.name == "fab" }?.id fabButtonId = ResourceMappingPatch["id", "fab"]
?: throw PatchException("Can not find required fab button resource id")
} }
} }

View File

@@ -34,7 +34,9 @@ import app.revanced.util.exception
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -57,7 +57,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37", "19.09.38",
"19.10.39",
"19.11.43"
], ],
), ),
], ],
@@ -101,7 +103,6 @@ object HideLayoutComponentsPatch : BytecodePatch(
SwitchPreference("revanced_hide_info_panels"), SwitchPreference("revanced_hide_info_panels"),
SwitchPreference("revanced_hide_join_membership_button"), SwitchPreference("revanced_hide_join_membership_button"),
SwitchPreference("revanced_hide_medical_panels"), SwitchPreference("revanced_hide_medical_panels"),
SwitchPreference("revanced_hide_playables"),
SwitchPreference("revanced_hide_quick_actions"), SwitchPreference("revanced_hide_quick_actions"),
SwitchPreference("revanced_hide_related_videos"), SwitchPreference("revanced_hide_related_videos"),
SwitchPreference("revanced_hide_subscribers_community_guidelines"), SwitchPreference("revanced_hide_subscribers_community_guidelines"),
@@ -120,6 +121,7 @@ object HideLayoutComponentsPatch : BytecodePatch(
SwitchPreference("revanced_hide_mix_playlists"), SwitchPreference("revanced_hide_mix_playlists"),
SwitchPreference("revanced_hide_movies_section"), SwitchPreference("revanced_hide_movies_section"),
SwitchPreference("revanced_hide_notify_me_button"), SwitchPreference("revanced_hide_notify_me_button"),
SwitchPreference("revanced_hide_playables"),
SwitchPreference("revanced_hide_search_result_recommendations"), SwitchPreference("revanced_hide_search_result_recommendations"),
SwitchPreference("revanced_hide_search_result_shelf_header"), SwitchPreference("revanced_hide_search_result_shelf_header"),
SwitchPreference("revanced_hide_show_more_button"), SwitchPreference("revanced_hide_show_more_button"),

View File

@@ -5,22 +5,22 @@ import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.all.misc.resources.AddResourcesPatch import app.revanced.patches.all.misc.resources.AddResourcesPatch
import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.settings.SettingsPatch import app.revanced.patches.youtube.misc.settings.SettingsPatch
@Patch( @Patch(
dependencies = [ dependencies = [
SettingsPatch::class, SettingsPatch::class,
ResourceMappingPatch::class, ResourceMappingPatch::class,
AddResourcesPatch::class AddResourcesPatch::class,
] ],
) )
internal object HideLayoutComponentsResourcePatch : ResourcePatch() { internal object HideLayoutComponentsResourcePatch : ResourcePatch() {
internal var expandButtonDownId: Long = -1 internal var expandButtonDownId: Long = -1
override fun execute(context: ResourceContext) { override fun execute(context: ResourceContext) {
expandButtonDownId = ResourceMappingPatch.resourceMappings.single { expandButtonDownId = ResourceMappingPatch[
it.type == "layout" && it.name == "expand_button_down" "layout",
}.id "expand_button_down",
]
} }
} }

View File

@@ -45,7 +45,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -12,7 +12,7 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
dependencies = [ dependencies = [
SettingsPatch::class, SettingsPatch::class,
ResourceMappingPatch::class, ResourceMappingPatch::class,
AddResourcesPatch::class AddResourcesPatch::class,
], ],
) )
object HideInfocardsResourcePatch : ResourcePatch() { object HideInfocardsResourcePatch : ResourcePatch() {
@@ -22,11 +22,12 @@ object HideInfocardsResourcePatch : ResourcePatch() {
AddResourcesPatch(this::class) AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.PLAYER.addPreferences( SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_hide_info_cards") SwitchPreference("revanced_hide_info_cards"),
) )
drawerResourceId = ResourceMappingPatch.resourceMappings.single { drawerResourceId = ResourceMappingPatch[
it.type == "id" && it.name == "info_cards_drawer_header" "id",
}.id "info_cards_drawer_header",
]
} }
} }

View File

@@ -39,7 +39,9 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -36,7 +36,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -41,7 +41,9 @@ import app.revanced.patches.youtube.shared.fingerprints.SeekbarOnDrawFingerprint
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -1,8 +1,5 @@
package app.revanced.patches.youtube.layout.hide.shorts package app.revanced.patches.youtube.layout.hide.shorts
import app.revanced.util.exception
import app.revanced.util.findIndexForIdResource
import app.revanced.util.injectHideViewCall
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
@@ -15,9 +12,15 @@ import app.revanced.patches.youtube.layout.hide.shorts.fingerprints.*
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
import app.revanced.patches.youtube.misc.litho.filter.LithoFilterPatch import app.revanced.patches.youtube.misc.litho.filter.LithoFilterPatch
import app.revanced.patches.youtube.misc.navigation.NavigationBarHookPatch import app.revanced.patches.youtube.misc.navigation.NavigationBarHookPatch
import app.revanced.util.exception
import app.revanced.util.getReference
import app.revanced.util.indexOfIdResourceOrThrow
import app.revanced.util.injectHideViewCall
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
@Patch( @Patch(
name = "Hide Shorts components", name = "Hide Shorts components",
@@ -27,11 +30,12 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
LithoFilterPatch::class, LithoFilterPatch::class,
HideShortsComponentsResourcePatch::class, HideShortsComponentsResourcePatch::class,
ResourceMappingPatch::class, ResourceMappingPatch::class,
NavigationBarHookPatch::class NavigationBarHookPatch::class,
], ],
compatiblePackages = [ compatiblePackages = [
CompatiblePackage( CompatiblePackage(
"com.google.android.youtube", [ "com.google.android.youtube",
[
"18.32.39", "18.32.39",
"18.37.36", "18.37.36",
"18.38.44", "18.38.44",
@@ -48,10 +52,12 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
] "19.10.39",
) "19.11.43",
] ],
),
],
) )
@Suppress("unused") @Suppress("unused")
object HideShortsComponentsPatch : BytecodePatch( object HideShortsComponentsPatch : BytecodePatch(
@@ -60,8 +66,8 @@ object HideShortsComponentsPatch : BytecodePatch(
ReelConstructorFingerprint, ReelConstructorFingerprint,
BottomNavigationBarFingerprint, BottomNavigationBarFingerprint,
RenderBottomNavigationBarParentFingerprint, RenderBottomNavigationBarParentFingerprint,
SetPivotBarVisibilityParentFingerprint SetPivotBarVisibilityParentFingerprint,
) ),
) { ) {
private const val FILTER_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/youtube/patches/components/ShortsFilter;" private const val FILTER_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/youtube/patches/components/ShortsFilter;"
@@ -79,7 +85,7 @@ object HideShortsComponentsPatch : BytecodePatch(
insertIndex, insertIndex,
viewRegister, viewRegister,
FILTER_CLASS_DESCRIPTOR, FILTER_CLASS_DESCRIPTOR,
"hideShortsShelf" "hideShortsShelf",
) )
} }
} // Do not throw an exception if not resolved. } // Do not throw an exception if not resolved.
@@ -93,7 +99,6 @@ object HideShortsComponentsPatch : BytecodePatch(
ShortsButtons.entries.forEach { button -> button.injectHideCall(it.mutableMethod) } ShortsButtons.entries.forEach { button -> button.injectHideCall(it.mutableMethod) }
} ?: throw CreateShortsButtonsFingerprint.exception } ?: throw CreateShortsButtonsFingerprint.exception
// endregion // endregion
// region Hide the Shorts buttons in newer versions of YouTube. // region Hide the Shorts buttons in newer versions of YouTube.
@@ -106,8 +111,9 @@ object HideShortsComponentsPatch : BytecodePatch(
// Hook to get the pivotBar view. // Hook to get the pivotBar view.
SetPivotBarVisibilityParentFingerprint.result?.let { SetPivotBarVisibilityParentFingerprint.result?.let {
if (!SetPivotBarVisibilityFingerprint.resolve(context, it.classDef)) if (!SetPivotBarVisibilityFingerprint.resolve(context, it.classDef)) {
throw SetPivotBarVisibilityFingerprint.exception throw SetPivotBarVisibilityFingerprint.exception
}
SetPivotBarVisibilityFingerprint.result!!.let { result -> SetPivotBarVisibilityFingerprint.result!!.let { result ->
result.mutableMethod.apply { result.mutableMethod.apply {
@@ -116,7 +122,7 @@ object HideShortsComponentsPatch : BytecodePatch(
addInstruction( addInstruction(
insertIndex, insertIndex,
"sput-object v$viewRegister, $FILTER_CLASS_DESCRIPTOR->pivotBar:" + "sput-object v$viewRegister, $FILTER_CLASS_DESCRIPTOR->pivotBar:" +
"Lcom/google/android/libraries/youtube/rendering/ui/pivotbar/PivotBar;" "Lcom/google/android/libraries/youtube/rendering/ui/pivotbar/PivotBar;",
) )
} }
} }
@@ -124,8 +130,9 @@ object HideShortsComponentsPatch : BytecodePatch(
// Hook to hide the navigation bar when Shorts are being played. // Hook to hide the navigation bar when Shorts are being played.
RenderBottomNavigationBarParentFingerprint.result?.let { RenderBottomNavigationBarParentFingerprint.result?.let {
if (!RenderBottomNavigationBarFingerprint.resolve(context, it.classDef)) if (!RenderBottomNavigationBarFingerprint.resolve(context, it.classDef)) {
throw RenderBottomNavigationBarFingerprint.exception throw RenderBottomNavigationBarFingerprint.exception
}
RenderBottomNavigationBarFingerprint.result!!.mutableMethod.apply { RenderBottomNavigationBarFingerprint.result!!.mutableMethod.apply {
addInstruction(0, "invoke-static { }, $FILTER_CLASS_DESCRIPTOR->hideNavigationBar()V") addInstruction(0, "invoke-static { }, $FILTER_CLASS_DESCRIPTOR->hideNavigationBar()V")
@@ -142,7 +149,7 @@ object HideShortsComponentsPatch : BytecodePatch(
addInstruction( addInstruction(
insertIndex, insertIndex,
"invoke-static { v$viewRegister }, $FILTER_CLASS_DESCRIPTOR->" + "invoke-static { v$viewRegister }, $FILTER_CLASS_DESCRIPTOR->" +
"hideNavigationBar(Landroid/view/View;)Landroid/view/View;" "hideNavigationBar(Landroid/view/View;)Landroid/view/View;",
) )
} }
} ?: throw BottomNavigationBarFingerprint.exception } ?: throw BottomNavigationBarFingerprint.exception
@@ -150,18 +157,25 @@ object HideShortsComponentsPatch : BytecodePatch(
// endregion // endregion
} }
private enum class ShortsButtons(private val resourceName: String, private val methodName: String) { private enum class ShortsButtons(private val resourceName: String, private val methodName: String) {
LIKE("reel_dyn_like", "hideLikeButton"),
DISLIKE("reel_dyn_dislike", "hideDislikeButton"),
COMMENTS("reel_dyn_comment", "hideShortsCommentsButton"), COMMENTS("reel_dyn_comment", "hideShortsCommentsButton"),
REMIX("reel_dyn_remix", "hideShortsRemixButton"), REMIX("reel_dyn_remix", "hideShortsRemixButton"),
SHARE("reel_dyn_share", "hideShortsShareButton"); SHARE("reel_dyn_share", "hideShortsShareButton");
fun injectHideCall(method: MutableMethod) { fun injectHideCall(method: MutableMethod) {
val referencedIndex = method.findIndexForIdResource(resourceName) val referencedIndex = method.indexOfIdResourceOrThrow(resourceName)
val setIdIndex = referencedIndex + 1 val instruction = method.implementation!!.instructions
.subList(referencedIndex, referencedIndex + 20)
.first {
it.opcode == Opcode.INVOKE_VIRTUAL && it.getReference<MethodReference>()?.name == "setId"
}
val setIdIndex = instruction.location.index
val viewRegister = method.getInstruction<FiveRegisterInstruction>(setIdIndex).registerC val viewRegister = method.getInstruction<FiveRegisterInstruction>(setIdIndex).registerC
method.injectHideViewCall(setIdIndex, viewRegister, FILTER_CLASS_DESCRIPTOR, methodName) method.injectHideViewCall(setIdIndex + 1, viewRegister, FILTER_CLASS_DESCRIPTOR, methodName)
} }
} }
} }

View File

@@ -34,13 +34,14 @@ object HideShortsComponentsResourcePatch : ResourcePatch() {
SwitchPreference("revanced_hide_shorts_sound_button"), SwitchPreference("revanced_hide_shorts_sound_button"),
// Everything else. // Everything else.
SwitchPreference("revanced_hide_shorts_thanks_button"),
SwitchPreference("revanced_hide_shorts_shop_button"),
SwitchPreference("revanced_hide_shorts_location_button"),
SwitchPreference("revanced_hide_shorts_save_sound_button"),
SwitchPreference("revanced_hide_shorts_join_button"), SwitchPreference("revanced_hide_shorts_join_button"),
SwitchPreference("revanced_hide_shorts_subscribe_button"), SwitchPreference("revanced_hide_shorts_subscribe_button"),
SwitchPreference("revanced_hide_shorts_subscribe_button_paused"), SwitchPreference("revanced_hide_shorts_paused_overlay_buttons"),
SwitchPreference("revanced_hide_shorts_save_sound_button"),
SwitchPreference("revanced_hide_shorts_shop_button"),
SwitchPreference("revanced_hide_shorts_tagged_products"),
SwitchPreference("revanced_hide_shorts_search_suggestions"),
SwitchPreference("revanced_hide_shorts_location_label"),
SwitchPreference("revanced_hide_shorts_channel_bar"), SwitchPreference("revanced_hide_shorts_channel_bar"),
SwitchPreference("revanced_hide_shorts_info_panel"), SwitchPreference("revanced_hide_shorts_info_panel"),
SwitchPreference("revanced_hide_shorts_full_video_link_label"), SwitchPreference("revanced_hide_shorts_full_video_link_label"),
@@ -49,15 +50,19 @@ object HideShortsComponentsResourcePatch : ResourcePatch() {
SwitchPreference("revanced_hide_shorts_navigation_bar"), SwitchPreference("revanced_hide_shorts_navigation_bar"),
) )
ResourceMappingPatch.resourceMappings.find { reelPlayerRightCellButtonHeight = ResourceMappingPatch[
it.type == "layout" && it.name == "reel_multiple_items_shelf" "dimen",
}?.also { "reel_player_right_cell_button_height",
reelMultipleItemShelfId = it.id ]
}
reelPlayerRightCellButtonHeight = // Resource not present in new versions of the app.
ResourceMappingPatch.resourceMappings.single { try {
it.type == "dimen" && it.name == "reel_player_right_cell_button_height" ResourceMappingPatch[
}.id "dimen",
"reel_player_right_cell_button_height",
]
} catch (e: NoSuchElementException) {
return
}.also { reelPlayerRightCellButtonHeight = it }
} }
} }

View File

@@ -1,13 +1,10 @@
package app.revanced.patches.youtube.layout.hide.shorts.fingerprints package app.revanced.patches.youtube.layout.hide.shorts.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patches.youtube.layout.hide.shorts.HideShortsComponentsResourcePatch import app.revanced.patches.youtube.layout.hide.shorts.HideShortsComponentsResourcePatch
import app.revanced.util.patch.LiteralValueFingerprint import app.revanced.util.patch.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
internal object CreateShortsButtonsFingerprint : LiteralValueFingerprint( internal object CreateShortsButtonsFingerprint : LiteralValueFingerprint(
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL, // YT 19.12.x moved this code inside another method, and each method has different parameters.
returnType = "V", returnType = "V",
parameters = listOf("Z", "Z", "L"),
literalSupplier = { HideShortsComponentsResourcePatch.reelPlayerRightCellButtonHeight } literalSupplier = { HideShortsComponentsResourcePatch.reelPlayerRightCellButtonHeight }
) )

View File

@@ -33,7 +33,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -12,7 +12,7 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
dependencies = [ dependencies = [
SettingsPatch::class, SettingsPatch::class,
ResourceMappingPatch::class, ResourceMappingPatch::class,
AddResourcesPatch::class AddResourcesPatch::class,
], ],
) )
internal object DisableSuggestedVideoEndScreenResourcePatch : ResourcePatch() { internal object DisableSuggestedVideoEndScreenResourcePatch : ResourcePatch() {
@@ -22,11 +22,12 @@ internal object DisableSuggestedVideoEndScreenResourcePatch : ResourcePatch() {
AddResourcesPatch(this::class) AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.PLAYER.addPreferences( SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_disable_suggested_video_end_screen") SwitchPreference("revanced_disable_suggested_video_end_screen"),
) )
sizeAdjustableLiteAutoNavOverlay = ResourceMappingPatch.resourceMappings.single { sizeAdjustableLiteAutoNavOverlay = ResourceMappingPatch[
it.type == "layout" && it.name == "size_adjustable_lite_autonav_overlay" "layout",
}.id "size_adjustable_lite_autonav_overlay",
]
} }
} }

View File

@@ -34,7 +34,9 @@ import app.revanced.util.exception
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -35,7 +35,9 @@ import app.revanced.util.exception
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -30,7 +30,9 @@ import org.w3c.dom.Element
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
], ],
), ),
], ],

View File

@@ -10,7 +10,7 @@ import app.revanced.patches.shared.misc.settings.preference.TextPreference
import app.revanced.patches.youtube.misc.settings.SettingsPatch import app.revanced.patches.youtube.misc.settings.SettingsPatch
@Patch( @Patch(
dependencies = [SettingsPatch::class, ResourceMappingPatch::class, AddResourcesPatch::class] dependencies = [SettingsPatch::class, ResourceMappingPatch::class, AddResourcesPatch::class],
) )
internal object CustomPlayerOverlayOpacityResourcePatch : ResourcePatch() { internal object CustomPlayerOverlayOpacityResourcePatch : ResourcePatch() {
internal var scrimOverlayId = -1L internal var scrimOverlayId = -1L
@@ -19,11 +19,12 @@ internal object CustomPlayerOverlayOpacityResourcePatch : ResourcePatch() {
AddResourcesPatch(this::class) AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.PLAYER.addPreferences( SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
TextPreference("revanced_player_overlay_opacity", inputType = InputType.NUMBER) TextPreference("revanced_player_overlay_opacity", inputType = InputType.NUMBER),
) )
scrimOverlayId = ResourceMappingPatch.resourceMappings.single { scrimOverlayId = ResourceMappingPatch[
it.type == "id" && it.name == "scrim_overlay" "id",
}.id "scrim_overlay",
]
} }
} }

View File

@@ -64,7 +64,9 @@ import com.android.tools.smali.dexlib2.iface.reference.TypeReference
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -12,8 +12,8 @@ import app.revanced.patches.youtube.misc.settings.SettingsResourcePatch
@Patch( @Patch(
dependencies = [ dependencies = [
SettingsPatch::class, SettingsPatch::class,
AddResourcesPatch::class AddResourcesPatch::class,
] ],
) )
internal object ReturnYouTubeDislikeResourcePatch : ResourcePatch() { internal object ReturnYouTubeDislikeResourcePatch : ResourcePatch() {
internal var oldUIDislikeId: Long = -1 internal var oldUIDislikeId: Long = -1
@@ -25,11 +25,12 @@ internal object ReturnYouTubeDislikeResourcePatch : ResourcePatch() {
key = "revanced_settings_screen_09", key = "revanced_settings_screen_09",
titleKey = "revanced_ryd_settings_title", titleKey = "revanced_ryd_settings_title",
summaryKey = null, summaryKey = null,
intent = SettingsPatch.newIntent("revanced_ryd_settings_intent") intent = SettingsPatch.newIntent("revanced_ryd_settings_intent"),
) )
oldUIDislikeId = ResourceMappingPatch.resourceMappings.single { oldUIDislikeId = ResourceMappingPatch[
it.type == "id" && it.name == "dislike_button" "id",
}.id "dislike_button",
]
} }
} }

View File

@@ -39,7 +39,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -35,7 +35,9 @@ import app.revanced.util.exception
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -15,18 +15,18 @@ internal object SeekbarColorResourcePatch : ResourcePatch() {
internal var inlineTimeBarPlayedNotHighlightedColorId = -1L internal var inlineTimeBarPlayedNotHighlightedColorId = -1L
override fun execute(context: ResourceContext) { override fun execute(context: ResourceContext) {
fun findColorResource(resourceName: String): Long { reelTimeBarPlayedColorId = ResourceMappingPatch[
return ResourceMappingPatch.resourceMappings "color",
.find { it.type == "color" && it.name == resourceName }?.id "reel_time_bar_played_color",
?: throw PatchException("Could not find color resource: $resourceName") ]
} inlineTimeBarColorizedBarPlayedColorDarkId = ResourceMappingPatch[
"color",
reelTimeBarPlayedColorId = "inline_time_bar_colorized_bar_played_color_dark",
findColorResource("reel_time_bar_played_color") ]
inlineTimeBarColorizedBarPlayedColorDarkId = inlineTimeBarPlayedNotHighlightedColorId = ResourceMappingPatch[
findColorResource("inline_time_bar_colorized_bar_played_color_dark") "color",
inlineTimeBarPlayedNotHighlightedColorId = "inline_time_bar_played_not_highlighted_color",
findColorResource("inline_time_bar_played_not_highlighted_color") ]
// Edit the resume playback drawable and replace the progress bar with a custom drawable // Edit the resume playback drawable and replace the progress bar with a custom drawable
context.xmlEditor["res/drawable/resume_playback_progressbar_drawable.xml"].use { editor -> context.xmlEditor["res/drawable/resume_playback_progressbar_drawable.xml"].use { editor ->
@@ -39,10 +39,9 @@ internal object SeekbarColorResourcePatch : ResourcePatch() {
} }
val scaleNode = progressNode.getElementsByTagName("scale").item(0) as Element val scaleNode = progressNode.getElementsByTagName("scale").item(0) as Element
val shapeNode = scaleNode.getElementsByTagName("shape").item(0) as Element val shapeNode = scaleNode.getElementsByTagName("shape").item(0) as Element
val replacementNode = val replacementNode = document.createElement(
document.createElement( "app.revanced.integrations.youtube.patches.theme.ProgressBarDrawable",
"app.revanced.integrations.youtube.patches.theme.ProgressBarDrawable", )
)
scaleNode.replaceChild(replacementNode, shapeNode) scaleNode.replaceChild(replacementNode, shapeNode)
} }
} }

View File

@@ -1,6 +1,5 @@
package app.revanced.patches.youtube.layout.sponsorblock package app.revanced.patches.youtube.layout.sponsorblock
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
@@ -25,6 +24,7 @@ import app.revanced.patches.youtube.shared.fingerprints.SeekbarFingerprint
import app.revanced.patches.youtube.shared.fingerprints.SeekbarOnDrawFingerprint import app.revanced.patches.youtube.shared.fingerprints.SeekbarOnDrawFingerprint
import app.revanced.patches.youtube.video.information.VideoInformationPatch import app.revanced.patches.youtube.video.information.VideoInformationPatch
import app.revanced.patches.youtube.video.videoid.VideoIdPatch import app.revanced.patches.youtube.video.videoid.VideoIdPatch
import app.revanced.util.exception
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.* import com.android.tools.smali.dexlib2.iface.instruction.*
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
@@ -37,7 +37,8 @@ import com.android.tools.smali.dexlib2.iface.reference.StringReference
description = "Adds options to enable and configure SponsorBlock, which can skip undesired video segments such as sponsored content.", description = "Adds options to enable and configure SponsorBlock, which can skip undesired video segments such as sponsored content.",
compatiblePackages = [ compatiblePackages = [
CompatiblePackage( CompatiblePackage(
"com.google.android.youtube", [ "com.google.android.youtube",
[
"18.48.39", "18.48.39",
"18.49.37", "18.49.37",
"19.01.34", "19.01.34",
@@ -48,9 +49,11 @@ import com.android.tools.smali.dexlib2.iface.reference.StringReference
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
] "19.10.39",
) "19.11.43",
],
),
], ],
dependencies = [ dependencies = [
IntegrationsPatch::class, IntegrationsPatch::class,
@@ -60,8 +63,8 @@ import com.android.tools.smali.dexlib2.iface.reference.StringReference
// Used to prevent SponsorBlock from running on Shorts because SponsorBlock does not yet support Shorts. // Used to prevent SponsorBlock from running on Shorts because SponsorBlock does not yet support Shorts.
PlayerTypeHookPatch::class, PlayerTypeHookPatch::class,
PlayerControlsBytecodePatch::class, PlayerControlsBytecodePatch::class,
SponsorBlockResourcePatch::class SponsorBlockResourcePatch::class,
] ],
) )
@Suppress("unused") @Suppress("unused")
object SponsorBlockBytecodePatch : BytecodePatch( object SponsorBlockBytecodePatch : BytecodePatch(
@@ -69,8 +72,8 @@ object SponsorBlockBytecodePatch : BytecodePatch(
SeekbarFingerprint, SeekbarFingerprint,
AppendTimeFingerprint, AppendTimeFingerprint,
LayoutConstructorFingerprint, LayoutConstructorFingerprint,
AutoRepeatParentFingerprint AutoRepeatParentFingerprint,
) ),
) { ) {
private const val INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR = private const val INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/youtube/sponsorblock/SegmentPlaybackController;" "Lapp/revanced/integrations/youtube/sponsorblock/SegmentPlaybackController;"
@@ -83,8 +86,9 @@ object SponsorBlockBytecodePatch : BytecodePatch(
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
LayoutConstructorFingerprint.result?.let { LayoutConstructorFingerprint.result?.let {
if (!ControlsOverlayFingerprint.resolve(context, it.classDef)) if (!ControlsOverlayFingerprint.resolve(context, it.classDef)) {
throw ControlsOverlayFingerprint.exception throw ControlsOverlayFingerprint.exception
}
} ?: throw LayoutConstructorFingerprint.exception } ?: throw LayoutConstructorFingerprint.exception
/* /*
@@ -93,7 +97,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
with(VideoInformationPatch) { with(VideoInformationPatch) {
videoTimeHook( videoTimeHook(
INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR, INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR,
"setVideoTime" "setVideoTime",
) )
} }
@@ -121,7 +125,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
seekbarMethod.addInstruction( seekbarMethod.addInstruction(
moveRectangleToRegisterIndex + 1, moveRectangleToRegisterIndex + 1,
"invoke-static/range {p0 .. p0}, " + "invoke-static/range {p0 .. p0}, " +
"$INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarRect(Ljava/lang/Object;)V" "$INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarRect(Ljava/lang/Object;)V",
) )
for ((index, instruction) in seekbarMethodInstructions.withIndex()) { for ((index, instruction) in seekbarMethodInstructions.withIndex()) {
@@ -136,7 +140,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
seekbarMethod.addInstruction( seekbarMethod.addInstruction(
insertIndex, insertIndex,
"invoke-static {v${invokeInstruction.registerC}}, " + "invoke-static {v${invokeInstruction.registerC}}, " +
"$INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarThickness(I)V" "$INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarThickness(I)V",
) )
break break
} }
@@ -154,7 +158,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
} }
seekbarMethod.addInstruction( seekbarMethod.addInstruction(
i, i,
"invoke-static {v$canvasInstance, v$centerY}, $INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->drawSponsorTimeBars(Landroid/graphics/Canvas;F)V" "invoke-static {v$canvasInstance, v$centerY}, $INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->drawSponsorTimeBars(Landroid/graphics/Canvas;F)V",
) )
break break
@@ -166,9 +170,9 @@ object SponsorBlockBytecodePatch : BytecodePatch(
val controlsMethodResult = PlayerControlsBytecodePatch.showPlayerControlsFingerprintResult val controlsMethodResult = PlayerControlsBytecodePatch.showPlayerControlsFingerprintResult
val controlsLayoutStubResourceId = val controlsLayoutStubResourceId =
ResourceMappingPatch.resourceMappings.single { it.type == "id" && it.name == "controls_layout_stub" }.id ResourceMappingPatch["id", "controls_layout_stub"]
val zoomOverlayResourceId = val zoomOverlayResourceId =
ResourceMappingPatch.resourceMappings.single { it.type == "id" && it.name == "video_zoom_overlay_stub" }.id ResourceMappingPatch["id", "video_zoom_overlay_stub"]
methods@ for (method in controlsMethodResult.mutableClass.methods) { methods@ for (method in controlsMethodResult.mutableClass.methods) {
val instructions = method.implementation?.instructions!! val instructions = method.implementation?.instructions!!
@@ -188,7 +192,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
""" """
invoke-static {v$inflatedViewRegister}, $INTEGRATIONS_CREATE_SEGMENT_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->initialize(Landroid/view/View;)V invoke-static {v$inflatedViewRegister}, $INTEGRATIONS_CREATE_SEGMENT_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->initialize(Landroid/view/View;)V
invoke-static {v$inflatedViewRegister}, $INTEGRATIONS_VOTING_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->initialize(Landroid/view/View;)V invoke-static {v$inflatedViewRegister}, $INTEGRATIONS_VOTING_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->initialize(Landroid/view/View;)V
""" """,
) )
} }
@@ -201,7 +205,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
""" """
invoke-static {p1}, $INTEGRATIONS_CREATE_SEGMENT_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->changeVisibilityNegatedImmediate(Z)V invoke-static {p1}, $INTEGRATIONS_CREATE_SEGMENT_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->changeVisibilityNegatedImmediate(Z)V
invoke-static {p1}, $INTEGRATIONS_VOTING_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->changeVisibilityNegatedImmediate(Z)V invoke-static {p1}, $INTEGRATIONS_VOTING_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->changeVisibilityNegatedImmediate(Z)V
""".trimIndent() """.trimIndent(),
) )
} }
} }
@@ -223,7 +227,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
""" """
invoke-static {v$targetRegister}, $INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->appendTimeWithoutSegments(Ljava/lang/String;)Ljava/lang/String; invoke-static {v$targetRegister}, $INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->appendTimeWithoutSegments(Ljava/lang/String;)Ljava/lang/String;
move-result-object v$targetRegister move-result-object v$targetRegister
""" """,
) )
// initialize the player controller // initialize the player controller
@@ -236,10 +240,10 @@ object SponsorBlockBytecodePatch : BytecodePatch(
val frameLayoutRegister = (getInstruction(startIndex + 2) as OneRegisterInstruction).registerA val frameLayoutRegister = (getInstruction(startIndex + 2) as OneRegisterInstruction).registerA
addInstruction( addInstruction(
startIndex + 3, startIndex + 3,
"invoke-static {v$frameLayoutRegister}, $INTEGRATIONS_SPONSORBLOCK_VIEW_CONTROLLER_CLASS_DESCRIPTOR->initialize(Landroid/view/ViewGroup;)V" "invoke-static {v$frameLayoutRegister}, $INTEGRATIONS_SPONSORBLOCK_VIEW_CONTROLLER_CLASS_DESCRIPTOR->initialize(Landroid/view/ViewGroup;)V",
) )
} }
} ?: throw ControlsOverlayFingerprint.exception } ?: throw ControlsOverlayFingerprint.exception
// get rectangle field name // get rectangle field name
RectangleFieldInvalidatorFingerprint.resolve(context, seekbarSignatureResult.classDef) RectangleFieldInvalidatorFingerprint.resolve(context, seekbarSignatureResult.classDef)
@@ -258,7 +262,8 @@ object SponsorBlockBytecodePatch : BytecodePatch(
fun MutableMethod.replaceStringInstruction(index: Int, instruction: Instruction, with: String) { fun MutableMethod.replaceStringInstruction(index: Int, instruction: Instruction, with: String) {
val register = (instruction as OneRegisterInstruction).registerA val register = (instruction as OneRegisterInstruction).registerA
this.replaceInstruction( this.replaceInstruction(
index, "const-string v$register, \"$with\"" index,
"const-string v$register, \"$with\"",
) )
} }
for ((index, it) in method.implementation!!.instructions.withIndex()) { for ((index, it) in method.implementation!!.instructions.withIndex()) {
@@ -268,13 +273,12 @@ object SponsorBlockBytecodePatch : BytecodePatch(
"replaceMeWithsetSponsorBarRect" -> method.replaceStringInstruction( "replaceMeWithsetSponsorBarRect" -> method.replaceStringInstruction(
index, index,
it, it,
rectangleFieldName rectangleFieldName,
) )
} }
} }
} ?: throw PatchException("Could not find the method which contains the replaceMeWith* strings") } ?: throw PatchException("Could not find the method which contains the replaceMeWith* strings")
// The vote and create segment buttons automatically change their visibility when appropriate, // The vote and create segment buttons automatically change their visibility when appropriate,
// but if buttons are showing when the end of the video is reached then they will not automatically hide. // but if buttons are showing when the end of the video is reached then they will not automatically hide.
// Add a hook to forcefully hide when the end of the video is reached. // Add a hook to forcefully hide when the end of the video is reached.
@@ -283,7 +287,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
it.resolve(context, AutoRepeatParentFingerprint.result!!.classDef) it.resolve(context, AutoRepeatParentFingerprint.result!!.classDef)
}.result?.mutableMethod?.addInstruction( }.result?.mutableMethod?.addInstruction(
0, 0,
"invoke-static {}, $INTEGRATIONS_SPONSORBLOCK_VIEW_CONTROLLER_CLASS_DESCRIPTOR->endOfVideoReached()V" "invoke-static {}, $INTEGRATIONS_SPONSORBLOCK_VIEW_CONTROLLER_CLASS_DESCRIPTOR->endOfVideoReached()V",
) ?: throw AutoRepeatFingerprint.exception ) ?: throw AutoRepeatFingerprint.exception
// TODO: isSBChannelWhitelisting implementation // TODO: isSBChannelWhitelisting implementation

View File

@@ -43,8 +43,10 @@ internal object SponsorBlockResourcePatch : ResourcePatch() {
// required resource for back button, because when the base APK is used, this resource will not exist // required resource for back button, because when the base APK is used, this resource will not exist
"drawable", "drawable",
"revanced_sb_adjust.xml", "revanced_sb_adjust.xml",
"revanced_sb_backward.xml",
"revanced_sb_compare.xml", "revanced_sb_compare.xml",
"revanced_sb_edit.xml", "revanced_sb_edit.xml",
"revanced_sb_forward.xml",
"revanced_sb_logo.xml", "revanced_sb_logo.xml",
"revanced_sb_publish.xml", "revanced_sb_publish.xml",
"revanced_sb_voting.xml", "revanced_sb_voting.xml",

View File

@@ -38,7 +38,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -44,7 +44,9 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -43,7 +43,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
) )
) )
] ]

View File

@@ -12,7 +12,7 @@ internal object MiniPlayerDimensionsCalculatorParentFingerprint : MethodFingerpr
opcodes = listOf( opcodes = listOf(
Opcode.CONST_HIGH16, Opcode.CONST_HIGH16,
Opcode.ADD_FLOAT_2ADDR, Opcode.ADD_FLOAT_2ADDR,
Opcode.MUL_FLOAT, null, // Opcode.MUL_FLOAT or Opcode.MUL_FLOAT_2ADDR
Opcode.CONST_4, Opcode.CONST_4,
Opcode.INVOKE_STATIC, Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT, Opcode.MOVE_RESULT,

View File

@@ -10,11 +10,14 @@ import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringPatc
import app.revanced.patches.all.misc.resources.AddResourcesPatch import app.revanced.patches.all.misc.resources.AddResourcesPatch
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.layout.seekbar.SeekbarColorBytecodePatch import app.revanced.patches.youtube.layout.seekbar.SeekbarColorBytecodePatch
import app.revanced.patches.youtube.layout.theme.fingerprints.ThemeHelperDarkColorFingerprint
import app.revanced.patches.youtube.layout.theme.fingerprints.ThemeHelperLightColorFingerprint
import app.revanced.patches.youtube.layout.theme.fingerprints.UseGradientLoadingScreenFingerprint import app.revanced.patches.youtube.layout.theme.fingerprints.UseGradientLoadingScreenFingerprint
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.SettingsPatch import app.revanced.patches.youtube.misc.settings.SettingsPatch
import app.revanced.util.exception import app.revanced.util.exception
import app.revanced.util.indexOfFirstWideLiteralInstructionValue import app.revanced.util.indexOfFirstWideLiteralInstructionValue
import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Patch( @Patch(
@@ -47,14 +50,20 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]
) )
@Suppress("unused") @Suppress("unused")
object ThemeBytecodePatch : BytecodePatch( object ThemeBytecodePatch : BytecodePatch(
setOf(UseGradientLoadingScreenFingerprint) setOf(
UseGradientLoadingScreenFingerprint,
ThemeHelperLightColorFingerprint,
ThemeHelperDarkColorFingerprint
)
) { ) {
private const val INTEGRATIONS_CLASS_DESCRIPTOR = private const val INTEGRATIONS_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/youtube/patches/theme/ThemePatch;" "Lapp/revanced/integrations/youtube/patches/theme/ThemePatch;"
@@ -121,6 +130,21 @@ object ThemeBytecodePatch : BytecodePatch(
) )
} ?: throw UseGradientLoadingScreenFingerprint.exception } ?: throw UseGradientLoadingScreenFingerprint.exception
mapOf(
ThemeHelperLightColorFingerprint to lightThemeBackgroundColor,
ThemeHelperDarkColorFingerprint to darkThemeBackgroundColor
).forEach { (fingerprint, color) ->
fingerprint.resultOrThrow().mutableMethod.apply {
addInstructions(
0, """
const-string v0, "$color"
return-object v0
"""
)
}
}
LithoColorHookPatch.lithoColorOverrideHook(INTEGRATIONS_CLASS_DESCRIPTOR, "getValue") LithoColorHookPatch.lithoColorOverrideHook(INTEGRATIONS_CLASS_DESCRIPTOR, "getValue")
} }
} }

View File

@@ -0,0 +1,16 @@
package app.revanced.patches.youtube.layout.theme.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.youtube.misc.settings.SettingsPatch
import com.android.tools.smali.dexlib2.AccessFlags
internal object ThemeHelperDarkColorFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PRIVATE or AccessFlags.STATIC,
returnType = "Ljava/lang/String;",
parameters = listOf(),
customFingerprint = { methodDef, classDef ->
methodDef.name == "darkThemeResourceName" &&
classDef.type == SettingsPatch.THEME_HELPER_DESCRIPTOR
}
)

View File

@@ -0,0 +1,16 @@
package app.revanced.patches.youtube.layout.theme.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.youtube.misc.settings.SettingsPatch
import com.android.tools.smali.dexlib2.AccessFlags
internal object ThemeHelperLightColorFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PRIVATE or AccessFlags.STATIC,
returnType = "Ljava/lang/String;",
parameters = listOf(),
customFingerprint = { methodDef, classDef ->
methodDef.name == "lightThemeResourceName" &&
classDef.type == SettingsPatch.THEME_HELPER_DESCRIPTOR
}
)

View File

@@ -61,7 +61,9 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
], ],
), ),
], ],

View File

@@ -39,7 +39,9 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -14,7 +14,7 @@ import app.revanced.util.exception
@Patch( @Patch(
name = "Spoof device dimensions", name = "Spoof device dimensions",
description = "Adds an option to spoof the device dimensions which unlocks higher video qualities if they aren't available on the device.", description = "Adds an option to spoof the device dimensions which can unlock higher video qualities.",
dependencies = [IntegrationsPatch::class, SettingsPatch::class, AddResourcesPatch::class], dependencies = [IntegrationsPatch::class, SettingsPatch::class, AddResourcesPatch::class],
compatiblePackages = [ compatiblePackages = [
CompatiblePackage( CompatiblePackage(
@@ -34,7 +34,9 @@ import app.revanced.util.exception
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -11,8 +11,9 @@ object SpoofSignatureResourcePatch : ResourcePatch() {
internal var scrubbedPreviewThumbnailResourceId: Long = -1 internal var scrubbedPreviewThumbnailResourceId: Long = -1
override fun execute(context: ResourceContext) { override fun execute(context: ResourceContext) {
scrubbedPreviewThumbnailResourceId = ResourceMappingPatch.resourceMappings.single { scrubbedPreviewThumbnailResourceId = ResourceMappingPatch[
it.type == "id" && it.name == "thumbnail" "id",
}.id "thumbnail",
]
} }
} }

View File

@@ -44,7 +44,9 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37", "19.09.38",
"19.10.39",
"19.11.43"
), ),
), ),
), ),

View File

@@ -36,7 +36,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -40,7 +40,9 @@ import com.android.tools.smali.dexlib2.iface.reference.StringReference
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -45,7 +45,9 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -6,19 +6,14 @@ import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch
@Patch( @Patch(
dependencies = [ResourceMappingPatch::class] dependencies = [ResourceMappingPatch::class],
) )
internal object NavigationBarHookResourcePatch : ResourcePatch() { internal object NavigationBarHookResourcePatch : ResourcePatch() {
internal var imageOnlyTabResourceId: Long = -1 internal var imageOnlyTabResourceId: Long = -1
internal var actionBarSearchResultsViewMicId: Long = -1 internal var actionBarSearchResultsViewMicId: Long = -1
override fun execute(context: ResourceContext) { override fun execute(context: ResourceContext) {
imageOnlyTabResourceId = ResourceMappingPatch.resourceMappings.first { imageOnlyTabResourceId = ResourceMappingPatch["layout", "image_only_tab"]
it.type == "layout" && it.name == "image_only_tab" actionBarSearchResultsViewMicId = ResourceMappingPatch["layout", "action_bar_search_results_view_mic"]
}.id
actionBarSearchResultsViewMicId = ResourceMappingPatch.resourceMappings.first {
it.type == "layout" && it.name == "action_bar_search_results_view_mic"
}.id
} }
} }

View File

@@ -24,8 +24,7 @@ object BottomControlsResourcePatch : ResourcePatch(), Closeable {
resourceContext = context resourceContext = context
targetDocumentEditor = context.xmlEditor[TARGET_RESOURCE] targetDocumentEditor = context.xmlEditor[TARGET_RESOURCE]
bottomUiContainerResourceId = ResourceMappingPatch.resourceMappings bottomUiContainerResourceId = ResourceMappingPatch["id", "bottom_ui_container_stub"]
.single { it.type == "id" && it.name == "bottom_ui_container_stub" }.id
} }
/** /**

View File

@@ -41,7 +41,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -12,6 +12,7 @@ import app.revanced.patches.all.misc.resources.AddResourcesPatch
import app.revanced.patches.shared.misc.settings.preference.BasePreferenceScreen import app.revanced.patches.shared.misc.settings.preference.BasePreferenceScreen
import app.revanced.patches.shared.misc.settings.preference.InputType import app.revanced.patches.shared.misc.settings.preference.InputType
import app.revanced.patches.shared.misc.settings.preference.IntentPreference import app.revanced.patches.shared.misc.settings.preference.IntentPreference
import app.revanced.patches.shared.misc.settings.preference.NonInteractivePreference
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen.Sorting import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen.Sorting
import app.revanced.patches.shared.misc.settings.preference.TextPreference import app.revanced.patches.shared.misc.settings.preference.TextPreference
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
@@ -39,12 +40,20 @@ object SettingsPatch :
private const val INTEGRATIONS_PACKAGE = "app/revanced/integrations/youtube" private const val INTEGRATIONS_PACKAGE = "app/revanced/integrations/youtube"
private const val ACTIVITY_HOOK_CLASS_DESCRIPTOR = "L$INTEGRATIONS_PACKAGE/settings/LicenseActivityHook;" private const val ACTIVITY_HOOK_CLASS_DESCRIPTOR = "L$INTEGRATIONS_PACKAGE/settings/LicenseActivityHook;"
private const val THEME_HELPER_DESCRIPTOR = "L$INTEGRATIONS_PACKAGE/ThemeHelper;" internal const val THEME_HELPER_DESCRIPTOR = "L$INTEGRATIONS_PACKAGE/ThemeHelper;"
private const val SET_THEME_METHOD_NAME: String = "setTheme" private const val SET_THEME_METHOD_NAME: String = "setTheme"
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class) AddResourcesPatch(this::class)
// Add an about preference to the top.
SettingsResourcePatch += NonInteractivePreference(
key = "revanced_settings_screen_00_about",
summaryKey = null,
tag = "app.revanced.integrations.youtube.settings.preference.ReVancedYouTubeAboutPreference",
selectable = true,
)
PreferenceScreen.MISC.addPreferences( PreferenceScreen.MISC.addPreferences(
TextPreference( TextPreference(
key = null, key = null,
@@ -52,7 +61,7 @@ object SettingsPatch :
summaryKey = "revanced_pref_import_export_summary", summaryKey = "revanced_pref_import_export_summary",
inputType = InputType.TEXT_MULTI_LINE, inputType = InputType.TEXT_MULTI_LINE,
tag = "app.revanced.integrations.shared.settings.preference.ImportExportPreference", tag = "app.revanced.integrations.shared.settings.preference.ImportExportPreference",
), )
) )
SetThemeFingerprint.result?.mutableMethod?.let { setThemeMethod -> SetThemeFingerprint.result?.mutableMethod?.let { setThemeMethod ->
@@ -69,7 +78,7 @@ object SettingsPatch :
replaceInstruction( replaceInstruction(
returnIndex, returnIndex,
"invoke-static { v$register }, " + "invoke-static { v$register }, " +
"$THEME_HELPER_DESCRIPTOR->$SET_THEME_METHOD_NAME(Ljava/lang/Object;)V", "$THEME_HELPER_DESCRIPTOR->$SET_THEME_METHOD_NAME(Ljava/lang/Enum;)V",
) )
addInstruction(returnIndex + 1, "return-object v$register") addInstruction(returnIndex + 1, "return-object v$register")
} }

View File

@@ -31,10 +31,7 @@ object SettingsResourcePatch : BaseSettingsResourcePatch(
AddResourcesPatch(this::class) AddResourcesPatch(this::class)
// Used for a fingerprint from SettingsPatch. // Used for a fingerprint from SettingsPatch.
appearanceStringId = appearanceStringId = ResourceMappingPatch["string", "app_theme_appearance_dark"]
ResourceMappingPatch.resourceMappings.find {
it.type == "string" && it.name == "app_theme_appearance_dark"
}!!.id
arrayOf( arrayOf(
ResourceGroup("layout", "revanced_settings_with_toolbar.xml"), ResourceGroup("layout", "revanced_settings_with_toolbar.xml"),

View File

@@ -45,7 +45,9 @@ import com.android.tools.smali.dexlib2.iface.reference.FieldReference
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -25,7 +25,9 @@ import app.revanced.patches.youtube.video.speed.remember.RememberPlaybackSpeedPa
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
], ],
), ),
], ],

View File

@@ -8,8 +8,9 @@ internal object CustomPlaybackSpeedResourcePatch : ResourcePatch() {
var speedUnavailableId: Long = -1 var speedUnavailableId: Long = -1
override fun execute(context: ResourceContext) { override fun execute(context: ResourceContext) {
speedUnavailableId = ResourceMappingPatch.resourceMappings.single { speedUnavailableId = ResourceMappingPatch[
it.type == "string" && it.name == "varispeed_unavailable_message" "string",
}.id "varispeed_unavailable_message",
]
} }
} }

View File

@@ -41,7 +41,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"19.06.39", "19.06.39",
"19.07.40", "19.07.40",
"19.08.36", "19.08.36",
"19.09.37" "19.09.38",
"19.10.39",
"19.11.43"
] ]
) )
] ]

View File

@@ -1,7 +1,6 @@
package app.revanced.patches.youtube.video.videoqualitymenu package app.revanced.patches.youtube.video.videoqualitymenu
import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.all.misc.resources.AddResourcesPatch import app.revanced.patches.all.misc.resources.AddResourcesPatch
@@ -10,7 +9,7 @@ import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.settings.SettingsPatch import app.revanced.patches.youtube.misc.settings.SettingsPatch
@Patch( @Patch(
dependencies = [SettingsPatch::class, ResourceMappingPatch::class, AddResourcesPatch::class] dependencies = [SettingsPatch::class, ResourceMappingPatch::class, AddResourcesPatch::class],
) )
object RestoreOldVideoQualityMenuResourcePatch : ResourcePatch() { object RestoreOldVideoQualityMenuResourcePatch : ResourcePatch() {
internal var videoQualityBottomSheetListFragmentTitle = -1L internal var videoQualityBottomSheetListFragmentTitle = -1L
@@ -19,13 +18,13 @@ object RestoreOldVideoQualityMenuResourcePatch : ResourcePatch() {
AddResourcesPatch(this::class) AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.VIDEO.addPreferences( SettingsPatch.PreferenceScreen.VIDEO.addPreferences(
SwitchPreference("revanced_restore_old_video_quality_menu") SwitchPreference("revanced_restore_old_video_quality_menu"),
) )
fun findResource(name: String) = ResourceMappingPatch.resourceMappings.find { it.name == name }?.id
?: throw PatchException("Could not find resource")
// Used for the old type of the video quality menu. // Used for the old type of the video quality menu.
videoQualityBottomSheetListFragmentTitle = findResource("video_quality_bottom_sheet_list_fragment_title") videoQualityBottomSheetListFragmentTitle = ResourceMappingPatch[
"layout",
"video_quality_bottom_sheet_list_fragment_title",
]
} }
} }

View File

@@ -15,7 +15,6 @@ import com.android.tools.smali.dexlib2.iface.instruction.WideLiteralInstruction
import com.android.tools.smali.dexlib2.iface.reference.Reference import com.android.tools.smali.dexlib2.iface.reference.Reference
import com.android.tools.smali.dexlib2.util.MethodUtil import com.android.tools.smali.dexlib2.util.MethodUtil
fun MethodFingerprint.resultOrThrow() = result ?: throw exception fun MethodFingerprint.resultOrThrow() = result ?: throw exception
/** /**
@@ -59,24 +58,41 @@ fun MutableMethod.injectHideViewCall(
insertIndex: Int, insertIndex: Int,
viewRegister: Int, viewRegister: Int,
classDescriptor: String, classDescriptor: String,
targetMethod: String targetMethod: String,
) = addInstruction( ) = addInstruction(
insertIndex, insertIndex,
"invoke-static { v$viewRegister }, $classDescriptor->$targetMethod(Landroid/view/View;)V" "invoke-static { v$viewRegister }, $classDescriptor->$targetMethod(Landroid/view/View;)V",
) )
/** /**
* Find the index of the first instruction with the id of the given resource name. * Get the index of the first instruction with the id of the given resource name.
*
* Requires [ResourceMappingPatch] as a dependency.
* *
* @param resourceName the name of the resource to find the id for. * @param resourceName the name of the resource to find the id for.
* @return the index of the first instruction with the id of the given resource name, or -1 if not found. * @return the index of the first instruction with the id of the given resource name, or -1 if not found.
* @throws PatchException if the resource cannot be found.
* @see [indexOfIdResourceOrThrow]
*/ */
fun Method.findIndexForIdResource(resourceName: String): Int { fun Method.indexOfIdResource(resourceName: String): Int {
fun getIdResourceId(resourceName: String) = ResourceMappingPatch.resourceMappings.single { val resourceId = ResourceMappingPatch["id", resourceName]
it.type == "id" && it.name == resourceName return indexOfFirstWideLiteralInstructionValue(resourceId)
}.id }
return indexOfFirstWideLiteralInstructionValue(getIdResourceId(resourceName)) /**
* Get the index of the first instruction with the id of the given resource name or throw a [PatchException].
*
* Requires [ResourceMappingPatch] as a dependency.
*
* @throws [PatchException] if the resource is not found, or the method does not contain the resource id literal value.
*/
fun Method.indexOfIdResourceOrThrow(resourceName: String): Int {
val index = indexOfIdResource(resourceName)
if (index < 0) {
throw PatchException("Found resource id for: '$resourceName' but method does not contain the id: $this")
}
return index
} }
/** /**
@@ -130,27 +146,29 @@ inline fun <reified T : Reference> Instruction.getReference() = (this as? Refere
fun Method.indexOfFirstInstruction(predicate: Instruction.() -> Boolean) = fun Method.indexOfFirstInstruction(predicate: Instruction.() -> Boolean) =
this.implementation!!.instructions.indexOfFirst(predicate) this.implementation!!.instructions.indexOfFirst(predicate)
/** /**
* Return the resolved methods of [MethodFingerprint]s early. * Return the resolved methods of [MethodFingerprint]s early.
*/ */
fun List<MethodFingerprint>.returnEarly(bool: Boolean = false) { fun List<MethodFingerprint>.returnEarly(bool: Boolean = false) {
val const = if (bool) "0x1" else "0x0" val const = if (bool) "0x1" else "0x0"
this.forEach { fingerprint -> this.forEach { fingerprint ->
fingerprint.result?.let { result -> fingerprint.result?.let { result ->
val stringInstructions = when (result.method.returnType.first()) { val stringInstructions = when (result.method.returnType.first()) {
'L' -> """ 'L' ->
"""
const/4 v0, $const const/4 v0, $const
return-object v0 return-object v0
""" """
'V' -> "return-void" 'V' -> "return-void"
'I', 'Z' -> """ 'I', 'Z' ->
"""
const/4 v0, $const const/4 v0, $const
return v0 return v0
""" """
else -> throw Exception("This case should never happen.") else -> throw Exception("This case should never happen.")
} }
result.mutableMethod.addInstructions(0, stringInstructions) result.mutableMethod.addInstructions(0, stringInstructions)
} ?: throw fingerprint.exception } ?: throw fingerprint.exception
}
} }
}

View File

@@ -53,10 +53,15 @@
<app id="youtube"> <app id="youtube">
<patch id="misc.settings.SettingsResourcePatch"> <patch id="misc.settings.SettingsResourcePatch">
<string name="revanced_settings">ReVanced</string> <string name="revanced_settings">ReVanced</string>
<string name="revanced_settings_about_links_body">You are using ReVanced Patches version &lt;i>%s&lt;/i></string>
<string name="revanced_settings_about_links_dev_header">Note</string>
<string name="revanced_settings_about_links_dev_body">This version is a pre-release and you may experience unexpected issues</string>
<string name="revanced_settings_about_links_header">Official links</string>
<string name="revanced_pref_import_export_title">Import / Export</string> <string name="revanced_pref_import_export_title">Import / Export</string>
<string name="revanced_pref_import_export_summary">Import / Export ReVanced settings</string> <string name="revanced_pref_import_export_summary">Import / Export ReVanced settings</string>
</patch> </patch>
<patch id="misc.settings.SettingsPatch"> <patch id="misc.settings.SettingsPatch">
<string name="revanced_settings_screen_00_about_title">About</string>
<string name="revanced_settings_screen_01_ads_title">Ads</string> <string name="revanced_settings_screen_01_ads_title">Ads</string>
<string name="revanced_settings_screen_02_alt_thumbnails_title">Alternative thumbnails</string> <string name="revanced_settings_screen_02_alt_thumbnails_title">Alternative thumbnails</string>
<string name="revanced_settings_screen_03_feed_title">Feed</string> <string name="revanced_settings_screen_03_feed_title">Feed</string>
@@ -93,7 +98,7 @@
<string name="revanced_hide_channel_watermark_summary_on">Watermark is hidden</string> <string name="revanced_hide_channel_watermark_summary_on">Watermark is hidden</string>
<string name="revanced_hide_channel_watermark_summary_off">Watermark is shown</string> <string name="revanced_hide_channel_watermark_summary_off">Watermark is shown</string>
<string name="revanced_hide_horizontal_shelves_title">Hide horizontal shelves</string> <string name="revanced_hide_horizontal_shelves_title">Hide horizontal shelves</string>
<string name="revanced_hide_horizontal_shelves_summary_on">Shelves are hidden such as:\n• Breaking news\n• Continue watching\n• Explore more channels\n• Shopping\n• Watch it Again</string> <string name="revanced_hide_horizontal_shelves_summary_on">Shelves are hidden such as:\n• Breaking news\n• Continue watching\n• Explore more channels\n• Shopping\n• Watch it again</string>
<string name="revanced_hide_horizontal_shelves_summary_off">Shelves are shown</string> <string name="revanced_hide_horizontal_shelves_summary_off">Shelves are shown</string>
<!-- 'Join' should be translated using the same localized wording YouTube displays. <!-- 'Join' should be translated using the same localized wording YouTube displays.
This appears in the video player for certain videos. --> This appears in the video player for certain videos. -->
@@ -166,7 +171,7 @@
<string name="revanced_hide_channel_bar_title">Hide channel bar</string> <string name="revanced_hide_channel_bar_title">Hide channel bar</string>
<string name="revanced_hide_channel_bar_summary_on">Channel bar is hidden</string> <string name="revanced_hide_channel_bar_summary_on">Channel bar is hidden</string>
<string name="revanced_hide_channel_bar_summary_off">Channel bar is shown</string> <string name="revanced_hide_channel_bar_summary_off">Channel bar is shown</string>
<string name="revanced_hide_playables_title">Hide playables</string> <string name="revanced_hide_playables_title">Hide Playables</string>
<string name="revanced_hide_playables_summary_on">Playables are hidden</string> <string name="revanced_hide_playables_summary_on">Playables are hidden</string>
<string name="revanced_hide_playables_summary_off">Playables are shown</string> <string name="revanced_hide_playables_summary_off">Playables are shown</string>
<string name="revanced_hide_quick_actions_title">Hide quick actions in fullscreen</string> <string name="revanced_hide_quick_actions_title">Hide quick actions in fullscreen</string>
@@ -244,14 +249,14 @@
<string name="revanced_hide_general_ads_summary_on">General ads are hidden</string> <string name="revanced_hide_general_ads_summary_on">General ads are hidden</string>
<string name="revanced_hide_general_ads_summary_off">General ads are shown</string> <string name="revanced_hide_general_ads_summary_off">General ads are shown</string>
<string name="revanced_hide_fullscreen_ads_title">Hide fullscreen ads</string> <string name="revanced_hide_fullscreen_ads_title">Hide fullscreen ads</string>
<string name="revanced_hide_fullscreen_ads_summary_on">Fullscreen ads are hidden</string> <string name="revanced_hide_fullscreen_ads_summary_on">Fullscreen ads are hidden\n\nThis feature is only available for older devices</string>
<string name="revanced_hide_fullscreen_ads_summary_off">Fullscreen ads are shown</string> <string name="revanced_hide_fullscreen_ads_summary_off">Fullscreen ads are shown</string>
<string name="revanced_hide_buttoned_ads_title">Hide buttoned ads</string> <string name="revanced_hide_buttoned_ads_title">Hide buttoned ads</string>
<string name="revanced_hide_buttoned_ads_summary_on">Buttoned ads are hidden</string> <string name="revanced_hide_buttoned_ads_summary_on">Buttoned ads are hidden</string>
<string name="revanced_hide_buttoned_ads_summary_off">Buttoned ads are shown</string> <string name="revanced_hide_buttoned_ads_summary_off">Buttoned ads are shown</string>
<string name="revanced_hide_paid_content_ads_title">Hide paid content</string> <string name="revanced_hide_paid_promotion_label_title">Hide paid promotion label</string>
<string name="revanced_hide_paid_content_ads_summary_on">Paid content is hidden</string> <string name="revanced_hide_paid_promotion_label_summary_on">Paid promotion label is hidden</string>
<string name="revanced_hide_paid_content_ads_summary_off">Paid content is shown</string> <string name="revanced_hide_paid_promotion_label_summary_off">Paid promotion label is shown</string>
<string name="revanced_hide_self_sponsor_ads_title">Hide self sponsored cards</string> <string name="revanced_hide_self_sponsor_ads_title">Hide self sponsored cards</string>
<string name="revanced_hide_self_sponsor_ads_summary_on">Self sponsored cards are hidden</string> <string name="revanced_hide_self_sponsor_ads_summary_on">Self sponsored cards are hidden</string>
<string name="revanced_hide_self_sponsor_ads_summary_off">Self sponsored cards are shown</string> <string name="revanced_hide_self_sponsor_ads_summary_off">Self sponsored cards are shown</string>
@@ -267,7 +272,7 @@
<string name="revanced_hide_merchandise_banners_title">Hide merchandise banners</string> <string name="revanced_hide_merchandise_banners_title">Hide merchandise banners</string>
<string name="revanced_hide_merchandise_banners_summary_on">Merchandise banners are hidden</string> <string name="revanced_hide_merchandise_banners_summary_on">Merchandise banners are hidden</string>
<string name="revanced_hide_merchandise_banners_summary_off">Merchandise banners are shown</string> <string name="revanced_hide_merchandise_banners_summary_off">Merchandise banners are shown</string>
<string name="revanced_hide_fullscreen_ads_feature_not_available_toast">Could not hide fullscreen ad. Hide setting disabled to prevent issues.</string> <string name="revanced_hide_fullscreen_ads_feature_not_available_toast">Hide fullscreen ads only works with older devices</string>
</patch> </patch>
<patch id="ad.getpremium.HideGetPremiumPatch"> <patch id="ad.getpremium.HideGetPremiumPatch">
<string name="revanced_hide_get_premium_title">Hide YouTube Premium promotions</string> <string name="revanced_hide_get_premium_title">Hide YouTube Premium promotions</string>
@@ -335,6 +340,10 @@
<string name="revanced_swipe_save_and_restore_brightness_title">Save and restore brightness</string> <string name="revanced_swipe_save_and_restore_brightness_title">Save and restore brightness</string>
<string name="revanced_swipe_save_and_restore_brightness_summary_on">Save and restore brightness when exiting or entering fullscreen</string> <string name="revanced_swipe_save_and_restore_brightness_summary_on">Save and restore brightness when exiting or entering fullscreen</string>
<string name="revanced_swipe_save_and_restore_brightness_summary_off">Do not save and restore brightness when exiting or entering fullscreen</string> <string name="revanced_swipe_save_and_restore_brightness_summary_off">Do not save and restore brightness when exiting or entering fullscreen</string>
<string name="revanced_swipe_lowest_value_enable_auto_brightness_title">Enable auto-brightness gesture</string>
<string name="revanced_swipe_lowest_value_enable_auto_brightness_summary_on">Swiping down to the lowest value of the brightness gesture enable auto-brightness</string>
<string name="revanced_swipe_lowest_value_enable_auto_brightness_summary_off">Swiping down to the lowest value does not enable auto-brightness</string>
<string name="revanced_swipe_lowest_value_enable_auto_brightness_overlay_text">Auto</string>
<string name="revanced_swipe_overlay_timeout_title">Swipe overlay timeout</string> <string name="revanced_swipe_overlay_timeout_title">Swipe overlay timeout</string>
<string name="revanced_swipe_overlay_timeout_summary">The amount of milliseconds the overlay is visible</string> <string name="revanced_swipe_overlay_timeout_summary">The amount of milliseconds the overlay is visible</string>
<string name="revanced_swipe_text_overlay_size_title">Swipe overlay text size</string> <string name="revanced_swipe_text_overlay_size_title">Swipe overlay text size</string>
@@ -384,11 +393,6 @@
<string name="revanced_hide_playlist_button_title">Hide Save to playlist</string> <string name="revanced_hide_playlist_button_title">Hide Save to playlist</string>
<string name="revanced_hide_playlist_button_summary_on">Save to playlist button is hidden</string> <string name="revanced_hide_playlist_button_summary_on">Save to playlist button is hidden</string>
<string name="revanced_hide_playlist_button_summary_off">Save to playlist button is shown</string> <string name="revanced_hide_playlist_button_summary_off">Save to playlist button is shown</string>
<!-- 'Shop' should be translated with the same localized wording that YouTube displays.
Shop button appears only for some videos in certain regions. Translate the button name normally if this menu is never shown. -->
<string name="revanced_hide_shop_button_title">Hide Shop</string>
<string name="revanced_hide_shop_button_summary_on">Shop button is hidden</string>
<string name="revanced_hide_shop_button_summary_off">Shop button is shown</string>
</patch> </patch>
<patch id="layout.buttons.autoplay.HideAutoplayButtonPatch"> <patch id="layout.buttons.autoplay.HideAutoplayButtonPatch">
<string name="revanced_hide_autoplay_button_title">Hide autoplay button</string> <string name="revanced_hide_autoplay_button_title">Hide autoplay button</string>
@@ -571,24 +575,24 @@
<string name="revanced_hide_shorts_subscribe_button_title">Hide subscribe button</string> <string name="revanced_hide_shorts_subscribe_button_title">Hide subscribe button</string>
<string name="revanced_hide_shorts_subscribe_button_summary_on">Subscribe button is hidden</string> <string name="revanced_hide_shorts_subscribe_button_summary_on">Subscribe button is hidden</string>
<string name="revanced_hide_shorts_subscribe_button_summary_off">Subscribe button is shown</string> <string name="revanced_hide_shorts_subscribe_button_summary_off">Subscribe button is shown</string>
<!-- 'subscribe' should be translated using the same localized wording YouTube displays for the button. --> <string name="revanced_hide_shorts_paused_overlay_buttons_title">Hide paused overlay buttons</string>
<string name="revanced_hide_shorts_subscribe_button_paused_title">Hide subscribe button when paused</string> <string name="revanced_hide_shorts_paused_overlay_buttons_summary_on">Paused overlay buttons are hidden</string>
<string name="revanced_hide_shorts_subscribe_button_paused_summary_on">Subscribe button is hidden</string> <string name="revanced_hide_shorts_paused_overlay_buttons_summary_off">Paused overlay buttons are shown</string>
<string name="revanced_hide_shorts_subscribe_button_paused_summary_off">Subscribe button is shown</string>
<!-- 'thanks' should be translated using the same localized wording YouTube displays for the button.
If the button never shows up, then translate the button name normally. -->
<string name="revanced_hide_shorts_thanks_button_title">Hide thanks button</string>
<string name="revanced_hide_shorts_thanks_button_summary_on">Thanks button is hidden</string>
<string name="revanced_hide_shorts_thanks_button_summary_off">Thanks button is shown</string>
<string name="revanced_hide_shorts_shop_button_title">Hide shop button</string> <string name="revanced_hide_shorts_shop_button_title">Hide shop button</string>
<string name="revanced_hide_shorts_shop_button_summary_on">Shop button is hidden</string> <string name="revanced_hide_shorts_shop_button_summary_on">Shop button is hidden</string>
<string name="revanced_hide_shorts_shop_button_summary_off">Shop button is shown</string> <string name="revanced_hide_shorts_shop_button_summary_off">Shop button is shown</string>
<string name="revanced_hide_shorts_location_button_title">Hide location button</string> <string name="revanced_hide_shorts_tagged_products_title">Hide tagged products</string>
<string name="revanced_hide_shorts_location_button_summary_on">Location button is hidden</string> <string name="revanced_hide_shorts_tagged_products_summary_on">Tagged products are hidden</string>
<string name="revanced_hide_shorts_location_button_summary_off">Location button is shown</string> <string name="revanced_hide_shorts_tagged_products_summary_off">Tagged products are shown</string>
<string name="revanced_hide_shorts_location_label_title">Hide location label</string>
<string name="revanced_hide_shorts_location_label_summary_on">Location label is hidden</string>
<string name="revanced_hide_shorts_location_label_summary_off">Location label is shown</string>
<string name="revanced_hide_shorts_save_sound_button_title">Hide save sound to playlist button</string> <string name="revanced_hide_shorts_save_sound_button_title">Hide save sound to playlist button</string>
<string name="revanced_hide_shorts_save_sound_button_summary_on">Save sound to playlist is hidden</string> <string name="revanced_hide_shorts_save_sound_button_summary_on">Save sound to playlist is hidden</string>
<string name="revanced_hide_shorts_save_sound_button_summary_off">Save sound to playlist is shown</string> <string name="revanced_hide_shorts_save_sound_button_summary_off">Save sound to playlist is shown</string>
<string name="revanced_hide_shorts_search_suggestions_title">Hide search suggestions</string>
<string name="revanced_hide_shorts_search_suggestions_summary_on">Search suggestions are hidden</string>
<string name="revanced_hide_shorts_search_suggestions_summary_off">Search suggestions are shown</string>
<string name="revanced_hide_shorts_like_button_title">Hide like button</string> <string name="revanced_hide_shorts_like_button_title">Hide like button</string>
<string name="revanced_hide_shorts_like_button_summary_on">Like button is hidden</string> <string name="revanced_hide_shorts_like_button_summary_on">Like button is hidden</string>
<string name="revanced_hide_shorts_like_button_summary_off">Like button is shown</string> <string name="revanced_hide_shorts_like_button_summary_off">Like button is shown</string>
@@ -999,8 +1003,9 @@
</patch> </patch>
<patch id="misc.dimensions.spoof.SpoofDeviceDimensionsPatch"> <patch id="misc.dimensions.spoof.SpoofDeviceDimensionsPatch">
<string name="revanced_spoof_device_dimensions_title">Spoof device dimensions</string> <string name="revanced_spoof_device_dimensions_title">Spoof device dimensions</string>
<string name="revanced_spoof_device_dimensions_summary_on">Device dimensions spoofed</string> <string name="revanced_spoof_device_dimensions_summary_on">Device dimensions spoofed\n\nHigher video qualities might be unlocked but you may experience video playback stuttering, worse battery life, and unknown side effects</string>
<string name="revanced_spoof_device_dimensions_summary_off">Device dimensions not spoofed\n\nSpoofing the device dimensions can unlock higher video qualities but unknown side effects may occur</string> <string name="revanced_spoof_device_dimensions_summary_off">Device dimensions not spoofed\n\nEnabling this can unlock higher video qualities</string>
<string name="revanced_spoof_device_dimensions_user_dialog_message">Enabling this can cause video playback stuttering, worse battery life, and unknown side effects.</string>
</patch> </patch>
<patch id="misc.gms.GmsCoreSupportResourcePatch"> <patch id="misc.gms.GmsCoreSupportResourcePatch">
<string name="microg_settings_title">GmsCore Settings</string> <string name="microg_settings_title">GmsCore Settings</string>
@@ -1145,9 +1150,9 @@
<string name="revanced_other_category_title">Other settings</string> <string name="revanced_other_category_title">Other settings</string>
<string name="revanced_client_ads_category_title">Client-side ads</string> <string name="revanced_client_ads_category_title">Client-side ads</string>
<string name="revanced_surestream_ads_category_title">Server-side surestream ads</string> <string name="revanced_surestream_ads_category_title">Server-side surestream ads</string>
<string name="revanced_debug_title">Debug logging</string> <string name="revanced_twitch_debug_title">Debug logging</string>
<string name="revanced_debug_summary_on">Debug logs are enabled</string> <string name="revanced_twitch_debug_summary_on">Debug logs are enabled</string>
<string name="revanced_debug_summary_off">Debug logs are disabled</string> <string name="revanced_twitch_debug_summary_off">Debug logs are disabled</string>
</patch> </patch>
</app> </app>
</resources> </resources>

View File

@@ -1,10 +1,30 @@
<vector <!--
xmlns:android="http://schemas.android.com/apk/res/android" https://github.com/google/material-design-icons/blob/9beae745bb758f3ad56654fb377ea5cf62be4915/symbols/android/content_copy/materialsymbolsoutlined/content_copy_wght200gradN25_24px.xml
android:width="24dp" The icon has been resized
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"> Copyright 2022 Google
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:tint="#FFFFFF"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path <path
android:pathData="M 6.8 19.5 C 6.5 19.5 6.2 19.399 6 19.199 C 5.8 19 5.7 18.699 5.7 18.399 L 5.7 7.099 L 6.8 7.099 L 6.8 18.399 L 15.7 18.399 L 15.7 19.5 L 6.8 19.5 Z M 9 17.2 C 8.7 17.2 8.4 17.1 8.2 16.9 C 8 16.7 7.9 16.4 7.9 16.1 L 7.9 5.6 C 7.9 5.3 8 5 8.2 4.8 C 8.4 4.6 8.7 4.5 9 4.5 L 17.2 4.5 C 17.5 4.5 17.8 4.6 18 4.8 C 18.2 5 18.3 5.3 18.3 5.6 L 18.3 16.1 C 18.3 16.4 18.2 16.7 18 16.9 C 17.8 17.1 17.5 17.2 17.2 17.2 L 9 17.2 Z M 9 16.1 L 17.2 16.1 L 17.2 5.6 L 9 5.6 L 9 16.1 Z M 9 16.1 L 9 5.6 L 9 16.1 Z" android:fillColor="@android:color/white"
android:fillColor="#ffffffff"/> android:pathData="m 9.7348145,16.94238 q -0.5966913,0 -1.0062178,-0.39988 Q 8.319101,16.14259 8.319101,15.5599 V 5.88248 q 0,-0.58269 0.4094957,-0.9826 Q 9.1381232,4.5 9.7348145,4.5 h 7.1494615 q 0.596701,0 1.006218,0.39988 Q 18.3,5.29979 18.3,5.88248 v 9.67742 q 0,0.58269 -0.409506,0.9826 -0.409517,0.39988 -1.006218,0.39988 z m 0,-0.82949 h 7.1494615 q 0.212367,0 0.389322,-0.1728 0.176965,-0.17283 0.176965,-0.38019 V 5.88248 q 0,-0.20738 -0.176965,-0.38019 -0.176955,-0.1728 -0.389322,-0.1728 H 9.7348145 q -0.212336,0 -0.389322,0.1728 Q 9.1685373,5.6751 9.1685373,5.88248 v 9.67742 q 0,0.20736 0.1769552,0.38019 0.176986,0.1728 0.389322,0.1728 z M 7.1157237,19.5 Q 6.519022,19.5 6.1094957,19.10009 5.7,18.70021 5.7,18.1175 V 7.61058 H 6.5494363 V 18.1175 q 0,0.20738 0.1769552,0.38018 0.1769655,0.17281 0.3893322,0.17281 H 15.114611 V 19.5 Z M 9.1685373,16.11289 V 5.32949 Z"/>
</vector> </vector>

View File

@@ -1,11 +1,31 @@
<vector <!--
xmlns:android="http://schemas.android.com/apk/res/android" https://github.com/google/material-design-icons/blob/9beae745bb758f3ad56654fb377ea5cf62be4915/symbols/android/content_copy/materialsymbolsoutlined/content_copy_wght200gradN25_24px.xml
android:width="24dp" https://github.com/google/material-design-icons/blob/9beae745bb758f3ad56654fb377ea5cf62be4915/symbols/android/schedule/materialsymbolsoutlined/schedule_wght300_24px.xml
android:height="24dp" This icon is the result of a combination of "content copy" and "schedule" icons.
android:viewportWidth="24"
android:viewportHeight="24">
Copyright 2022 Google
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:tint="#FFFFFF"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path <path
android:name="path" android:fillColor="@android:color/white"
android:pathData="M 6.8 19.5 C 6.5 19.5 6.2 19.4 6 19.2 C 5.8 19 5.7 18.7 5.7 18.4 L 5.7 7.1 L 6.8 7.1 L 6.8 18.4 L 15.7 18.4 L 15.7 19.5 L 6.8 19.5 Z M 9 17.2 C 8.7 17.2 8.4 17.1 8.2 16.9 C 8 16.7 7.9 16.4 7.9 16.1 L 7.9 5.6 C 7.9 5.3 8 5 8.2 4.8 C 8.4 4.6 8.7 4.5 9 4.5 L 17.2 4.5 C 17.5 4.5 17.8 4.6 18 4.8 C 18.2 5 18.3 5.3 18.3 5.6 L 18.3 16.1 C 18.3 16.4 18.2 16.7 18 16.9 C 17.8 17.1 17.5 17.2 17.2 17.2 L 9 17.2 Z M 9 16.1 L 17.2 16.1 L 17.2 5.6 L 9 5.6 L 9 16.1 Z M 9 16.1 L 9 5.6 L 9 16.1 Z M 13.1 8 C 11.5 8 10.2 9.3 10.2 10.9 C 10.2 12.5 11.5 13.8 13.1 13.8 C 14.7 13.8 16 12.5 16 10.9 C 16 9.3 14.7 8 13.1 8 Z M 13.1 13.3 C 11.8 13.3 10.7 12.2 10.7 10.9 C 10.7 9.6 11.8 8.5 13.1 8.5 C 14.4 8.5 15.5 9.6 15.5 10.9 C 15.5 12.2 14.5 13.3 13.1 13.3 Z M 14.5 12 L 14.2 12.3 L 12.9 11 L 12.9 9.4 L 13.3 9.4 L 13.3 10.8 L 14.5 12 Z" android:pathData="M 9.734375 4.5 C 9.3365813 4.5 9.0015328 4.6338045 8.7285156 4.9003906 C 8.4555191 5.1669968 8.3183594 5.4943533 8.3183594 5.8828125 L 8.3183594 15.560547 C 8.3183594 15.949005 8.4555191 16.276362 8.7285156 16.542969 C 9.0015328 16.809554 9.3365813 16.941406 9.734375 16.941406 L 11.259766 16.941406 C 11.220306 16.699026 11.199219 16.450296 11.199219 16.195312 C 11.199219 16.167903 11.200672 16.140551 11.201172 16.113281 L 9.734375 16.113281 C 9.5928176 16.113281 9.4636936 16.054651 9.3457031 15.939453 C 9.2277332 15.824233 9.1679687 15.698787 9.1679688 15.560547 L 9.1679688 5.8828125 C 9.1679688 5.7445594 9.2277329 5.6171596 9.3457031 5.5019531 C 9.4636936 5.3867533 9.5928176 5.3300781 9.734375 5.3300781 L 16.884766 5.3300781 C 17.026342 5.3300781 17.155468 5.3867532 17.273438 5.5019531 C 17.391413 5.6171596 17.451172 5.7445594 17.451172 5.8828125 L 17.451172 12.052734 C 17.453072 12.053553 17.455131 12.053788 17.457031 12.054688 C 17.760014 12.185563 18.041487 12.342729 18.300781 12.525391 L 18.300781 5.8828125 C 18.300781 5.4943533 18.163629 5.1669968 17.890625 4.9003906 C 17.617573 4.6338045 17.282565 4.5 16.884766 4.5 L 9.734375 4.5 z M 5.6992188 7.6113281 L 5.6992188 18.117188 C 5.6992188 18.505659 5.8363784 18.833024 6.109375 19.099609 C 6.382392 19.366216 6.717434 19.5 7.1152344 19.5 L 12.642578 19.5 C 12.600698 19.46116 12.558138 19.42142 12.517578 19.380859 C 12.299781 19.163062 12.107686 18.926178 11.939453 18.669922 L 7.1152344 18.669922 C 6.9736568 18.669922 6.8445393 18.613252 6.7265625 18.498047 C 6.6085926 18.382847 6.5488281 18.25544 6.5488281 18.117188 L 6.5488281 7.6113281 L 5.6992188 7.6113281 z M 15.75 12.5 C 15.231251 12.5 14.743359 12.598047 14.287109 12.794922 C 13.83086 12.991797 13.435156 13.260157 13.097656 13.597656 C 12.760157 13.935156 12.491797 14.33086 12.294922 14.787109 C 12.098047 15.243359 12 15.731251 12 16.25 C 12 16.768749 12.098047 17.256641 12.294922 17.712891 C 12.491797 18.16914 12.760157 18.564844 13.097656 18.902344 C 13.435156 19.239843 13.83086 19.508203 14.287109 19.705078 C 14.743359 19.901953 15.231251 20 15.75 20 C 16.268749 20 16.756641 19.901953 17.212891 19.705078 C 17.66914 19.508203 18.064844 19.239843 18.402344 18.902344 C 18.739843 18.564844 19.008203 18.16914 19.205078 17.712891 C 19.401953 17.256641 19.5 16.768749 19.5 16.25 C 19.5 15.731251 19.401953 15.243359 19.205078 14.787109 C 19.008203 14.33086 18.739843 13.935156 18.402344 13.597656 C 18.064844 13.260157 17.66914 12.991797 17.212891 12.794922 C 16.756641 12.598047 16.268749 12.5 15.75 12.5 z M 15.75 13.25 C 16.581249 13.25 17.288672 13.542578 17.873047 14.126953 C 18.457421 14.711327 18.75 15.418751 18.75 16.25 C 18.75 17.081249 18.457421 17.788672 17.873047 18.373047 C 17.288672 18.957421 16.581249 19.25 15.75 19.25 C 14.918751 19.25 14.211327 18.957421 13.626953 18.373047 C 13.042578 17.788672 12.75 17.081249 12.75 16.25 C 12.75 15.418751 13.042578 14.711327 13.626953 14.126953 C 14.211327 13.542578 14.918751 13.25 15.75 13.25 z M 15.375 14.375 L 15.375 16.400391 L 16.988281 18.011719 L 17.511719 17.488281 L 16.125 16.099609 L 16.125 14.375 L 15.375 14.375 z"/>
android:fillColor="#ffffffff" />
</vector> </vector>

View File

@@ -1,4 +1,30 @@
<?xml version="1.0" encoding="utf-8"?> <!--
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:tint="#FFFFFF" android:height="24dp" android:width="24dp" android:viewportWidth="24" android:viewportHeight="24"> https://github.com/google/material-design-icons/blob/9beae745bb758f3ad56654fb377ea5cf62be4915/symbols/android/download/materialsymbolsoutlined/download_wght200gradN25_24px.xml
<path android:fillColor="#FFFFFF" android:pathData="M 6.0050001,16.257111 h 0.916667 v 1.666667 H 16.088333 V 16.257111 H 17.005 v 2.777778 H 6.0050001 Z M 16.5,11.4 15.8,10.7 12,14.4 V 4 h -1 v 10.4 l -3.8,-3.8 -0.7,0.7 5,5 z"/> The icon has been resized
Copyright 2022 Google
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:tint="#FFFFFF"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M 12,15.834271 8.2721019,12.095857 8.9799906,11.392186 11.499655,13.91185 V 4.5 h 1.011235 v 9.41185 l 2.519663,-2.519664 0.707862,0.703671 z M 6.1825058,19.5 Q 5.4750279,19.5 4.9875002,19.0125 4.5,18.524973 4.5,17.81607 v -2.619082 h 1.0112344 v 2.617631 q 0,0.252815 0.2106659,0.46348 0.2106658,0.210666 0.4634813,0.210666 H 17.814619 q 0.252815,0 0.46348,-0.210666 0.210666,-0.210665 0.210666,-0.46348 V 15.196988 H 19.5 v 2.619082 q 0,0.708903 -0.4875,1.19643 Q 18.524973,19.5 17.817522,19.5 Z"/>
</vector> </vector>

View File

@@ -1,10 +1,30 @@
<!--
https://github.com/google/material-design-icons/blob/9beae745bb758f3ad56654fb377ea5cf62be4915/symbols/android/adjust/materialsymbolsoutlined/adjust_wght200gradN25_24px.xml
The icon has been resized
Copyright 2022 Google
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:tint="#FFFFFF"
android:height="24dp" android:width="24dp"
android:tint="#FFFFFF" android:height="24dp"
android:viewportWidth="24" android:viewportWidth="24"
android:viewportHeight="24"> android:viewportHeight="24">
<path <path
android:fillColor="#FFFFFF" android:fillColor="@android:color/white"
android:pathData="M12,2C6.49,2 2,6.49 2,12s4.49,10 10,10 10,-4.49 10,-10S17.51,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM15,12c0,1.66 -1.34,3 -3,3s-3,-1.34 -3,-3 1.34,-3 3,-3 3,1.34 3,3z" /> android:pathData="m 12,14.156532 q 0.913052,0 1.534792,-0.62174 0.62174,-0.62174 0.62174,-1.534792 0,-0.913052 -0.62174,-1.534792 Q 12.913052,9.843468 12,9.843468 q -0.913052,0 -1.534792,0.62174 -0.62174,0.62174 -0.62174,1.534792 0,0.913052 0.62174,1.534792 0.62174,0.62174 1.534792,0.62174 z M 12.0052,22 Q 9.930936,22 8.1033049,21.211917 6.2756454,20.423835 4.9237012,19.072851 3.5717572,17.721839 2.7858786,15.899494 2,14.077147 2,12.005172 2,9.930908 2.788083,8.1032766 3.576166,6.2756454 4.9271491,4.9237012 6.2781605,3.5717572 8.100507,2.7858786 9.922853,2 11.994828,2 q 2.074264,0 3.901896,0.788083 1.827631,0.788083 3.179575,2.1390661 1.351944,1.3510114 2.137823,3.1733579 Q 22,9.922853 22,11.994828 q 0,2.074264 -0.788083,3.901896 -0.788082,1.827631 -2.139066,3.179575 -1.351012,1.351944 -3.173357,2.137823 Q 14.077147,22 12.005172,22 Z m -0.0059,-1.043476 q 3.738745,0 6.347988,-2.608508 2.609242,-2.608536 2.609242,-6.347309 0,-3.7387455 -2.608508,-6.347988 -2.608536,-2.6092425 -6.347309,-2.6092425 -3.7387453,0 -6.3479878,2.6085077 -2.6092425,2.6085359 -2.6092425,6.3473088 0,3.738746 2.6085077,6.347988 2.608536,2.609243 6.3473096,2.609243 z M 12,12 Z"/>
</vector> </vector>

View File

@@ -0,0 +1,30 @@
<!--
https://github.com/google/material-design-icons/blob/9beae745bb758f3ad56654fb377ea5cf62be4915/symbols/android/fast_forward/materialsymbolsoutlined/fast_forward_wght200gradN25_24px.xml
The icon has been mirrored and resized
Copyright 2022 Google
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:tint="#FFFFFF"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M 22,17.799197 V 6.2 l -8.689607,5.799598 z m -11.310393,0 V 6.2 L 2,11.999598 Z m 10.114551,-5.799599 z m -11.3103926,0 z m 11.3103926,3.582383 -5.351233,-3.582383 5.351233,-3.582384 z m -11.3103926,0 -5.3512316,-3.582383 5.3512316,-3.582384 z"/>
</vector>

Some files were not shown because too many files have changed in this diff Show More