Compare commits

...

32 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
semantic-release-bot
426f405407 chore(release): 4.7.0-dev.7 [skip ci]
# [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)

### Features

* **YouTube - Hide layout components:** Hide playables ([f85f518](f85f518fc9))
2024-04-14 00:09:07 +00:00
oSumAtrIX
f85f518fc9 feat(YouTube - Hide layout components): Hide playables 2024-04-14 02:06:41 +02:00
LisoUseInAIKyrios
f3972d313f chore: fix typo 2024-04-12 23:52:21 +04:00
111 changed files with 1393 additions and 438 deletions

View File

@@ -1,3 +1,124 @@
# [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)
### Features
* **YouTube - Hide layout components:** Hide playables ([8423515](https://github.com/ReVanced/revanced-patches/commit/842351548baa33737db09be1cbca9f87c1951341))
# [4.7.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.5...v4.7.0-dev.6) (2024-04-12)

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 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 static final field INSTANCE Lapp/revanced/patches/all/misc/network/OverrideCertificatePinningPatch;
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;
}
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 fun <init> (Ljava/lang/String;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 synthetic fun execute (Lapp/revanced/patcher/data/Context;)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 {
@@ -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 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 synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V
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 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 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 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 resultOrThrow (Lapp/revanced/patcher/fingerprint/MethodFingerprint;)Lapp/revanced/patcher/fingerprint/MethodFingerprintResult;
public static final fun returnEarly (Ljava/util/List;Z)V

View File

@@ -1,4 +1,4 @@
org.gradle.parallel = true
org.gradle.caching = true
kotlin.code.style = official
version = 4.7.0-dev.6
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.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.layout.premium.fingerprints.HideGetPremiumFingerprint
import app.revanced.patches.music.layout.premium.fingerprints.MembershipSettingsFingerprint
import app.revanced.util.exception
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
@Patch(
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")],
)
@Suppress("unused")
object HideGetPremiumPatch : BytecodePatch(
setOf(HideGetPremiumFingerprint),
setOf(
HideGetPremiumFingerprint,
MembershipSettingsFingerprint,
),
) {
override fun execute(context: BytecodeContext) {
HideGetPremiumFingerprint.result?.let {
@@ -41,5 +46,13 @@ object HideGetPremiumPatch : BytecodePatch(
)
}
} ?: 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(
Opcode.IF_NEZ,
Opcode.CONST_16,
Opcode.GOTO,
Opcode.NOP,
Opcode.INVOKE_VIRTUAL,
),
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.INVOKE_INTERFACE,
Opcode.GOTO,
Opcode.NOP,
Opcode.IPUT_OBJECT,
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.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchException
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.iface.ClassDef
import com.android.tools.smali.dexlib2.iface.Method
import java.util.jar.JarFile
abstract class BaseIntegrationsPatch(
private val hooks: Set<IntegrationsFingerprint>,
) : BytecodePatch(hooks) {
) : BytecodePatch(hooks + setOf(ReVancedUtilsPatchesVersionFingerprint)) {
@Deprecated(
"Use the constructor without the integrationsDescriptor parameter",
@@ -34,6 +38,46 @@ abstract class BaseIntegrationsPatch(
hooks.forEach { hook ->
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,
customFingerprint: ((methodDef: Method, classDef: ClassDef) -> Boolean)? = null,
private val insertIndexResolver: ((Method) -> Int) = object : IHookInsertIndexResolver {},
private val contextRegisterResolver: (Method) -> Int = object : IRegisterResolver {}
private val contextRegisterResolver: (Method) -> Int = object : IRegisterResolver {},
) : MethodFingerprint(
returnType,
accessFlags,
@@ -59,9 +103,11 @@ abstract class BaseIntegrationsPatch(
strings,
customFingerprint,
) {
@Deprecated("Previous constructor that is missing the insert index." +
@Deprecated(
"Previous constructor that is missing the insert index." +
"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(
returnType: String? = null,
accessFlags: Int? = null,
@@ -69,7 +115,7 @@ abstract class BaseIntegrationsPatch(
opcodes: Iterable<Opcode?>? = null,
strings: Iterable<String>? = null,
customFingerprint: ((methodDef: Method, classDef: ClassDef) -> Boolean)? = null,
contextRegisterResolver: (Method) -> Int = object : IRegisterResolver {}
contextRegisterResolver: (Method) -> Int = object : IRegisterResolver {},
) : this(
returnType,
accessFlags,
@@ -78,7 +124,7 @@ abstract class BaseIntegrationsPatch(
strings,
customFingerprint,
object : IHookInsertIndexResolver {},
contextRegisterResolver
contextRegisterResolver,
)
fun invoke(integrationsDescriptor: String) {
@@ -103,7 +149,7 @@ abstract class BaseIntegrationsPatch(
}
}
private companion object {
private const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/shared/Utils;"
internal companion object {
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
object ResourceMappingPatch : ResourcePatch() {
internal lateinit var resourceMappings: List<ResourceElement>
private set
private val resourceMappings = Collections.synchronizedList(mutableListOf<ResourceElement>())
private val THREAD_COUNT = Runtime.getRuntime().availableProcessors()
private val threadPoolExecutor = Executors.newFixedThreadPool(THREAD_COUNT)
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()
// create a synchronized list to store the resource mappings
val mappings = Collections.synchronizedList(mutableListOf<ResourceElement>())
for (threadIndex in 0 until THREAD_COUNT) {
threadPoolExecutor.execute thread@{
context.xmlEditor[resourceXmlFile.inputStream()].use { editor ->
@@ -33,7 +29,7 @@ object ResourceMappingPatch : ResourcePatch() {
val batchStart = jobSize * threadIndex
val batchEnd = jobSize * (threadIndex + 1)
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
val node = resources.item(i)
@@ -46,18 +42,18 @@ object ResourceMappingPatch : ResourcePatch() {
val id = node.getAttribute("id").substring(2).toLong(16)
mappings.add(ResourceElement(typeAttribute, nameAttribute, id))
resourceMappings.add(ResourceElement(typeAttribute, nameAttribute, id))
}
}
}
}
threadPoolExecutor
.also { it.shutdown() }
.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS)
resourceMappings = mappings
threadPoolExecutor.also { it.shutdown() }.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS)
}
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)
}

View File

@@ -16,10 +16,19 @@ import org.w3c.dom.Document
@Suppress("MemberVisibilityCanBePrivate")
class NonInteractivePreference(
key: String,
titleKey: String = "${key}_title",
summaryKey: String? = "${key}_summary",
tag: String = "Preference",
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) =
super.serialize(ownerDocument, resourceCallback).apply {

View File

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

View File

@@ -62,7 +62,17 @@ object SettingsPatch : BytecodePatch(
AddResourcesPatch(this::class)
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

View File

@@ -42,7 +42,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
"19.06.39",
"19.07.40",
"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,
SettingsPatch::class,
ResourceMappingPatch::class,
AddResourcesPatch::class
]
AddResourcesPatch::class,
],
)
object HideAdsResourcePatch : ResourcePatch() {
private const val FILTER_CLASS_DESCRIPTOR =
@@ -30,16 +30,16 @@ object HideAdsResourcePatch : ResourcePatch() {
SwitchPreference("revanced_hide_general_ads"),
SwitchPreference("revanced_hide_fullscreen_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_products_banner"),
SwitchPreference("revanced_hide_shopping_links"),
SwitchPreference("revanced_hide_web_search_results"),
SwitchPreference("revanced_hide_merchandise_banners")
SwitchPreference("revanced_hide_merchandise_banners"),
)
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.07.40",
"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.07.40",
"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.07.40",
"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.07.40",
"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.07.40",
"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.07.40",
"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.07.40",
"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.07.40",
"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 = [
IntegrationsPatch::class,
PlayerTypeHookPatch::class,
SwipeControlsResourcePatch::class
SwipeControlsResourcePatch::class,
],
compatiblePackages = [
CompatiblePackage(
@@ -42,17 +42,22 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
"19.06.39",
"19.07.40",
"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")
object SwipeControlsBytecodePatch : BytecodePatch(
setOf(
MainActivityFingerprint,
SwipeControlsHostActivityFingerprint
)
SwipeControlsHostActivityFingerprint,
),
) {
override fun execute(context: BytecodeContext) {
val wrapperClass = SwipeControlsHostActivityFingerprint.result!!.mutableClass
@@ -74,9 +79,9 @@ object SwipeControlsBytecodePatch : BytecodePatch(
accessFlags and AccessFlags.FINAL.value.inv(),
annotations,
hiddenApiRestrictions,
implementation
implementation,
).toMutable()
}
}
}
}
}

View File

@@ -24,6 +24,7 @@ internal object SwipeControlsResourcePatch : ResourcePatch() {
SwitchPreference("revanced_swipe_press_to_engage"),
SwitchPreference("revanced_swipe_haptic_feedback"),
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_text_overlay_size", 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.07.40",
"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.07.40",
"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_thanks_button"),
SwitchPreference("revanced_hide_clip_button"),
SwitchPreference("revanced_hide_playlist_button"),
SwitchPreference("revanced_hide_shop_button")
SwitchPreference("revanced_hide_playlist_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.shared.fingerprints.LayoutConstructorFingerprint
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.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
@@ -27,7 +27,7 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
IntegrationsPatch::class,
SettingsPatch::class,
ResourceMappingPatch::class,
AddResourcesPatch::class
AddResourcesPatch::class,
],
compatiblePackages = [
CompatiblePackage(
@@ -49,27 +49,29 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
]
)
]
"19.09.38",
"19.10.39",
"19.11.43",
],
),
],
)
@Suppress("unused")
object HideAutoplayButtonPatch : BytecodePatch(
setOf(LayoutConstructorFingerprint)
setOf(LayoutConstructorFingerprint),
) {
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_hide_autoplay_button")
SwitchPreference("revanced_hide_autoplay_button"),
)
LayoutConstructorFingerprint.result?.mutableMethod?.apply {
val layoutGenMethodInstructions = implementation!!.instructions
// 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
val branchIndex =
@@ -90,8 +92,8 @@ object HideAutoplayButtonPatch : BytecodePatch(
move-result v$clobberRegister
if-eqz v$clobberRegister, :hidden
""",
ExternalLabel("hidden", jumpInstruction)
ExternalLabel("hidden", jumpInstruction),
)
} ?: throw LayoutConstructorFingerprint.exception
}
}
}

View File

@@ -40,7 +40,9 @@ import com.android.tools.smali.dexlib2.Opcode
"19.06.39",
"19.07.40",
"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.07.40",
"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.07.40",
"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.07.40",
"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 = [
SettingsPatch::class,
ResourceMappingPatch::class,
AddResourcesPatch::class
AddResourcesPatch::class,
],
)
internal object AlbumCardsResourcePatch : ResourcePatch() {
@@ -22,11 +22,9 @@ internal object AlbumCardsResourcePatch : ResourcePatch() {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.FEED.addPreferences(
SwitchPreference("revanced_hide_album_cards")
SwitchPreference("revanced_hide_album_cards"),
)
albumCardId = ResourceMappingPatch.resourceMappings.single {
it.type == "layout" && it.name == "album_card"
}.id
albumCardId = ResourceMappingPatch["layout", "album_card"]
}
}
}

View File

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

View File

@@ -41,7 +41,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction21c
"19.06.39",
"19.07.40",
"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 = [
SettingsPatch::class,
ResourceMappingPatch::class,
AddResourcesPatch::class
AddResourcesPatch::class,
],
)
internal object HideEndscreenCardsResourcePatch : ResourcePatch() {
@@ -24,15 +24,13 @@ internal object HideEndscreenCardsResourcePatch : ResourcePatch() {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_hide_endscreen_cards")
SwitchPreference("revanced_hide_endscreen_cards"),
)
fun findEndscreenResourceId(name: String) = ResourceMappingPatch.resourceMappings.single {
it.type == "layout" && it.name == "endscreen_element_layout_$name"
}.id
fun idOf(name: String) = ResourceMappingPatch["layout", "endscreen_element_layout_$name"]
layoutCircle = findEndscreenResourceId("circle")
layoutIcon = findEndscreenResourceId("icon")
layoutVideo = findEndscreenResourceId("video")
layoutCircle = idOf("circle")
layoutIcon = idOf("icon")
layoutVideo = idOf("video")
}
}
}

View File

@@ -38,7 +38,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
"19.06.39",
"19.07.40",
"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_search"),
SwitchPreference("revanced_hide_filter_bar_feed_in_related_videos"),
)
)
),
),
)
relatedChipCloudMarginId = "related_chip_cloud_reduced_margins".layoutResourceId("layout")
filterBarHeightId = "filter_bar_height".layoutResourceId()
barContainerHeightId = "bar_container_height".layoutResourceId()
relatedChipCloudMarginId = ResourceMappingPatch["layout", "related_chip_cloud_reduced_margins"]
filterBarHeightId = ResourceMappingPatch["dimen", "filter_bar_height"]
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.07.40",
"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
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.all.misc.resources.AddResourcesPatch
@@ -13,8 +12,8 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
dependencies = [
SettingsPatch::class,
ResourceMappingPatch::class,
AddResourcesPatch::class
]
AddResourcesPatch::class,
],
)
internal object HideFloatingMicrophoneButtonResourcePatch : ResourcePatch() {
internal var fabButtonId: Long = -1
@@ -23,10 +22,9 @@ internal object HideFloatingMicrophoneButtonResourcePatch : ResourcePatch() {
AddResourcesPatch(this::class)
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
?: throw PatchException("Can not find required fab button resource id")
fabButtonId = ResourceMappingPatch["id", "fab"]
}
}

View File

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

View File

@@ -12,12 +12,8 @@ import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.all.misc.resources.AddResourcesPatch
import app.revanced.patches.shared.misc.settings.preference.InputType
import app.revanced.patches.shared.misc.settings.preference.NonInteractivePreference
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen
import app.revanced.patches.shared.misc.settings.preference.*
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen.Sorting
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.shared.misc.settings.preference.TextPreference
import app.revanced.patches.youtube.layout.hide.general.fingerprints.HideShowMoreButtonFingerprint
import app.revanced.patches.youtube.layout.hide.general.fingerprints.ParseElementFromBufferFingerprint
import app.revanced.patches.youtube.layout.hide.general.fingerprints.PlayerOverlayFingerprint
@@ -61,7 +57,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37",
"19.09.38",
"19.10.39",
"19.11.43"
],
),
],
@@ -123,6 +121,7 @@ object HideLayoutComponentsPatch : BytecodePatch(
SwitchPreference("revanced_hide_mix_playlists"),
SwitchPreference("revanced_hide_movies_section"),
SwitchPreference("revanced_hide_notify_me_button"),
SwitchPreference("revanced_hide_playables"),
SwitchPreference("revanced_hide_search_result_recommendations"),
SwitchPreference("revanced_hide_search_result_shelf_header"),
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.patches.all.misc.resources.AddResourcesPatch
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
@Patch(
dependencies = [
SettingsPatch::class,
ResourceMappingPatch::class,
AddResourcesPatch::class
]
AddResourcesPatch::class,
],
)
internal object HideLayoutComponentsResourcePatch : ResourcePatch() {
internal var expandButtonDownId: Long = -1
override fun execute(context: ResourceContext) {
expandButtonDownId = ResourceMappingPatch.resourceMappings.single {
it.type == "layout" && it.name == "expand_button_down"
}.id
expandButtonDownId = ResourceMappingPatch[
"layout",
"expand_button_down",
]
}
}
}

View File

@@ -45,7 +45,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
"19.06.39",
"19.07.40",
"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 = [
SettingsPatch::class,
ResourceMappingPatch::class,
AddResourcesPatch::class
AddResourcesPatch::class,
],
)
object HideInfocardsResourcePatch : ResourcePatch() {
@@ -22,11 +22,12 @@ object HideInfocardsResourcePatch : ResourcePatch() {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_hide_info_cards")
SwitchPreference("revanced_hide_info_cards"),
)
drawerResourceId = ResourceMappingPatch.resourceMappings.single {
it.type == "id" && it.name == "info_cards_drawer_header"
}.id
drawerResourceId = ResourceMappingPatch[
"id",
"info_cards_drawer_header",
]
}
}
}

View File

@@ -39,7 +39,9 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
"19.06.39",
"19.07.40",
"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.07.40",
"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.07.40",
"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
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.extensions.InstructionExtensions.addInstruction
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.litho.filter.LithoFilterPatch
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.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
@Patch(
name = "Hide Shorts components",
@@ -27,11 +30,12 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
LithoFilterPatch::class,
HideShortsComponentsResourcePatch::class,
ResourceMappingPatch::class,
NavigationBarHookPatch::class
NavigationBarHookPatch::class,
],
compatiblePackages = [
CompatiblePackage(
"com.google.android.youtube", [
"com.google.android.youtube",
[
"18.32.39",
"18.37.36",
"18.38.44",
@@ -48,10 +52,12 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
]
)
]
"19.09.38",
"19.10.39",
"19.11.43",
],
),
],
)
@Suppress("unused")
object HideShortsComponentsPatch : BytecodePatch(
@@ -60,8 +66,8 @@ object HideShortsComponentsPatch : BytecodePatch(
ReelConstructorFingerprint,
BottomNavigationBarFingerprint,
RenderBottomNavigationBarParentFingerprint,
SetPivotBarVisibilityParentFingerprint
)
SetPivotBarVisibilityParentFingerprint,
),
) {
private const val FILTER_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/youtube/patches/components/ShortsFilter;"
@@ -79,7 +85,7 @@ object HideShortsComponentsPatch : BytecodePatch(
insertIndex,
viewRegister,
FILTER_CLASS_DESCRIPTOR,
"hideShortsShelf"
"hideShortsShelf",
)
}
} // Do not throw an exception if not resolved.
@@ -93,7 +99,6 @@ object HideShortsComponentsPatch : BytecodePatch(
ShortsButtons.entries.forEach { button -> button.injectHideCall(it.mutableMethod) }
} ?: throw CreateShortsButtonsFingerprint.exception
// endregion
// region Hide the Shorts buttons in newer versions of YouTube.
@@ -106,8 +111,9 @@ object HideShortsComponentsPatch : BytecodePatch(
// Hook to get the pivotBar view.
SetPivotBarVisibilityParentFingerprint.result?.let {
if (!SetPivotBarVisibilityFingerprint.resolve(context, it.classDef))
if (!SetPivotBarVisibilityFingerprint.resolve(context, it.classDef)) {
throw SetPivotBarVisibilityFingerprint.exception
}
SetPivotBarVisibilityFingerprint.result!!.let { result ->
result.mutableMethod.apply {
@@ -116,7 +122,7 @@ object HideShortsComponentsPatch : BytecodePatch(
addInstruction(
insertIndex,
"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.
RenderBottomNavigationBarParentFingerprint.result?.let {
if (!RenderBottomNavigationBarFingerprint.resolve(context, it.classDef))
if (!RenderBottomNavigationBarFingerprint.resolve(context, it.classDef)) {
throw RenderBottomNavigationBarFingerprint.exception
}
RenderBottomNavigationBarFingerprint.result!!.mutableMethod.apply {
addInstruction(0, "invoke-static { }, $FILTER_CLASS_DESCRIPTOR->hideNavigationBar()V")
@@ -142,7 +149,7 @@ object HideShortsComponentsPatch : BytecodePatch(
addInstruction(
insertIndex,
"invoke-static { v$viewRegister }, $FILTER_CLASS_DESCRIPTOR->" +
"hideNavigationBar(Landroid/view/View;)Landroid/view/View;"
"hideNavigationBar(Landroid/view/View;)Landroid/view/View;",
)
}
} ?: throw BottomNavigationBarFingerprint.exception
@@ -150,18 +157,25 @@ object HideShortsComponentsPatch : BytecodePatch(
// endregion
}
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"),
REMIX("reel_dyn_remix", "hideShortsRemixButton"),
SHARE("reel_dyn_share", "hideShortsShareButton");
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
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"),
// 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_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_info_panel"),
SwitchPreference("revanced_hide_shorts_full_video_link_label"),
@@ -49,15 +50,19 @@ object HideShortsComponentsResourcePatch : ResourcePatch() {
SwitchPreference("revanced_hide_shorts_navigation_bar"),
)
ResourceMappingPatch.resourceMappings.find {
it.type == "layout" && it.name == "reel_multiple_items_shelf"
}?.also {
reelMultipleItemShelfId = it.id
}
reelPlayerRightCellButtonHeight = ResourceMappingPatch[
"dimen",
"reel_player_right_cell_button_height",
]
reelPlayerRightCellButtonHeight =
ResourceMappingPatch.resourceMappings.single {
it.type == "dimen" && it.name == "reel_player_right_cell_button_height"
}.id
// Resource not present in new versions of the app.
try {
ResourceMappingPatch[
"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
import app.revanced.patcher.extensions.or
import app.revanced.patches.youtube.layout.hide.shorts.HideShortsComponentsResourcePatch
import app.revanced.util.patch.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
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",
parameters = listOf("Z", "Z", "L"),
literalSupplier = { HideShortsComponentsResourcePatch.reelPlayerRightCellButtonHeight }
)

View File

@@ -33,7 +33,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
"19.06.39",
"19.07.40",
"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 = [
SettingsPatch::class,
ResourceMappingPatch::class,
AddResourcesPatch::class
AddResourcesPatch::class,
],
)
internal object DisableSuggestedVideoEndScreenResourcePatch : ResourcePatch() {
@@ -22,11 +22,12 @@ internal object DisableSuggestedVideoEndScreenResourcePatch : ResourcePatch() {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
SwitchPreference("revanced_disable_suggested_video_end_screen")
SwitchPreference("revanced_disable_suggested_video_end_screen"),
)
sizeAdjustableLiteAutoNavOverlay = ResourceMappingPatch.resourceMappings.single {
it.type == "layout" && it.name == "size_adjustable_lite_autonav_overlay"
}.id
sizeAdjustableLiteAutoNavOverlay = ResourceMappingPatch[
"layout",
"size_adjustable_lite_autonav_overlay",
]
}
}
}

View File

@@ -34,7 +34,9 @@ import app.revanced.util.exception
"19.06.39",
"19.07.40",
"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.07.40",
"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.07.40",
"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
@Patch(
dependencies = [SettingsPatch::class, ResourceMappingPatch::class, AddResourcesPatch::class]
dependencies = [SettingsPatch::class, ResourceMappingPatch::class, AddResourcesPatch::class],
)
internal object CustomPlayerOverlayOpacityResourcePatch : ResourcePatch() {
internal var scrimOverlayId = -1L
@@ -19,11 +19,12 @@ internal object CustomPlayerOverlayOpacityResourcePatch : ResourcePatch() {
AddResourcesPatch(this::class)
SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
TextPreference("revanced_player_overlay_opacity", inputType = InputType.NUMBER)
TextPreference("revanced_player_overlay_opacity", inputType = InputType.NUMBER),
)
scrimOverlayId = ResourceMappingPatch.resourceMappings.single {
it.type == "id" && it.name == "scrim_overlay"
}.id
scrimOverlayId = ResourceMappingPatch[
"id",
"scrim_overlay",
]
}
}

View File

@@ -64,7 +64,9 @@ import com.android.tools.smali.dexlib2.iface.reference.TypeReference
"19.06.39",
"19.07.40",
"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(
dependencies = [
SettingsPatch::class,
AddResourcesPatch::class
]
AddResourcesPatch::class,
],
)
internal object ReturnYouTubeDislikeResourcePatch : ResourcePatch() {
internal var oldUIDislikeId: Long = -1
@@ -25,11 +25,12 @@ internal object ReturnYouTubeDislikeResourcePatch : ResourcePatch() {
key = "revanced_settings_screen_09",
titleKey = "revanced_ryd_settings_title",
summaryKey = null,
intent = SettingsPatch.newIntent("revanced_ryd_settings_intent")
intent = SettingsPatch.newIntent("revanced_ryd_settings_intent"),
)
oldUIDislikeId = ResourceMappingPatch.resourceMappings.single {
it.type == "id" && it.name == "dislike_button"
}.id
oldUIDislikeId = ResourceMappingPatch[
"id",
"dislike_button",
]
}
}
}

View File

@@ -39,7 +39,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"19.06.39",
"19.07.40",
"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.07.40",
"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
override fun execute(context: ResourceContext) {
fun findColorResource(resourceName: String): Long {
return ResourceMappingPatch.resourceMappings
.find { it.type == "color" && it.name == resourceName }?.id
?: throw PatchException("Could not find color resource: $resourceName")
}
reelTimeBarPlayedColorId =
findColorResource("reel_time_bar_played_color")
inlineTimeBarColorizedBarPlayedColorDarkId =
findColorResource("inline_time_bar_colorized_bar_played_color_dark")
inlineTimeBarPlayedNotHighlightedColorId =
findColorResource("inline_time_bar_played_not_highlighted_color")
reelTimeBarPlayedColorId = ResourceMappingPatch[
"color",
"reel_time_bar_played_color",
]
inlineTimeBarColorizedBarPlayedColorDarkId = ResourceMappingPatch[
"color",
"inline_time_bar_colorized_bar_played_color_dark",
]
inlineTimeBarPlayedNotHighlightedColorId = ResourceMappingPatch[
"color",
"inline_time_bar_played_not_highlighted_color",
]
// 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 ->
@@ -39,10 +39,9 @@ internal object SeekbarColorResourcePatch : ResourcePatch() {
}
val scaleNode = progressNode.getElementsByTagName("scale").item(0) as Element
val shapeNode = scaleNode.getElementsByTagName("shape").item(0) as Element
val replacementNode =
document.createElement(
"app.revanced.integrations.youtube.patches.theme.ProgressBarDrawable",
)
val replacementNode = document.createElement(
"app.revanced.integrations.youtube.patches.theme.ProgressBarDrawable",
)
scaleNode.replaceChild(replacementNode, shapeNode)
}
}

View File

@@ -1,6 +1,5 @@
package app.revanced.patches.youtube.layout.sponsorblock
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
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.video.information.VideoInformationPatch
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.iface.instruction.*
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.",
compatiblePackages = [
CompatiblePackage(
"com.google.android.youtube", [
"com.google.android.youtube",
[
"18.48.39",
"18.49.37",
"19.01.34",
@@ -48,9 +49,11 @@ import com.android.tools.smali.dexlib2.iface.reference.StringReference
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
]
)
"19.09.38",
"19.10.39",
"19.11.43",
],
),
],
dependencies = [
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.
PlayerTypeHookPatch::class,
PlayerControlsBytecodePatch::class,
SponsorBlockResourcePatch::class
]
SponsorBlockResourcePatch::class,
],
)
@Suppress("unused")
object SponsorBlockBytecodePatch : BytecodePatch(
@@ -69,8 +72,8 @@ object SponsorBlockBytecodePatch : BytecodePatch(
SeekbarFingerprint,
AppendTimeFingerprint,
LayoutConstructorFingerprint,
AutoRepeatParentFingerprint
)
AutoRepeatParentFingerprint,
),
) {
private const val INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/youtube/sponsorblock/SegmentPlaybackController;"
@@ -83,8 +86,9 @@ object SponsorBlockBytecodePatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
LayoutConstructorFingerprint.result?.let {
if (!ControlsOverlayFingerprint.resolve(context, it.classDef))
if (!ControlsOverlayFingerprint.resolve(context, it.classDef)) {
throw ControlsOverlayFingerprint.exception
}
} ?: throw LayoutConstructorFingerprint.exception
/*
@@ -93,7 +97,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
with(VideoInformationPatch) {
videoTimeHook(
INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR,
"setVideoTime"
"setVideoTime",
)
}
@@ -121,7 +125,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
seekbarMethod.addInstruction(
moveRectangleToRegisterIndex + 1,
"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()) {
@@ -136,7 +140,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
seekbarMethod.addInstruction(
insertIndex,
"invoke-static {v${invokeInstruction.registerC}}, " +
"$INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarThickness(I)V"
"$INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarThickness(I)V",
)
break
}
@@ -154,7 +158,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
}
seekbarMethod.addInstruction(
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
@@ -166,9 +170,9 @@ object SponsorBlockBytecodePatch : BytecodePatch(
val controlsMethodResult = PlayerControlsBytecodePatch.showPlayerControlsFingerprintResult
val controlsLayoutStubResourceId =
ResourceMappingPatch.resourceMappings.single { it.type == "id" && it.name == "controls_layout_stub" }.id
ResourceMappingPatch["id", "controls_layout_stub"]
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) {
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_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_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;
move-result-object v$targetRegister
"""
""",
)
// initialize the player controller
@@ -236,10 +240,10 @@ object SponsorBlockBytecodePatch : BytecodePatch(
val frameLayoutRegister = (getInstruction(startIndex + 2) as OneRegisterInstruction).registerA
addInstruction(
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
RectangleFieldInvalidatorFingerprint.resolve(context, seekbarSignatureResult.classDef)
@@ -258,7 +262,8 @@ object SponsorBlockBytecodePatch : BytecodePatch(
fun MutableMethod.replaceStringInstruction(index: Int, instruction: Instruction, with: String) {
val register = (instruction as OneRegisterInstruction).registerA
this.replaceInstruction(
index, "const-string v$register, \"$with\""
index,
"const-string v$register, \"$with\"",
)
}
for ((index, it) in method.implementation!!.instructions.withIndex()) {
@@ -268,13 +273,12 @@ object SponsorBlockBytecodePatch : BytecodePatch(
"replaceMeWithsetSponsorBarRect" -> method.replaceStringInstruction(
index,
it,
rectangleFieldName
rectangleFieldName,
)
}
}
} ?: throw PatchException("Could not find the method which contains the replaceMeWith* strings")
// 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.
// 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)
}.result?.mutableMethod?.addInstruction(
0,
"invoke-static {}, $INTEGRATIONS_SPONSORBLOCK_VIEW_CONTROLLER_CLASS_DESCRIPTOR->endOfVideoReached()V"
"invoke-static {}, $INTEGRATIONS_SPONSORBLOCK_VIEW_CONTROLLER_CLASS_DESCRIPTOR->endOfVideoReached()V",
) ?: throw AutoRepeatFingerprint.exception
// 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
"drawable",
"revanced_sb_adjust.xml",
"revanced_sb_backward.xml",
"revanced_sb_compare.xml",
"revanced_sb_edit.xml",
"revanced_sb_forward.xml",
"revanced_sb_logo.xml",
"revanced_sb_publish.xml",
"revanced_sb_voting.xml",

View File

@@ -38,7 +38,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"19.06.39",
"19.07.40",
"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.07.40",
"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.07.40",
"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(
Opcode.CONST_HIGH16,
Opcode.ADD_FLOAT_2ADDR,
Opcode.MUL_FLOAT,
null, // Opcode.MUL_FLOAT or Opcode.MUL_FLOAT_2ADDR
Opcode.CONST_4,
Opcode.INVOKE_STATIC,
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.shared.misc.settings.preference.SwitchPreference
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.misc.integrations.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.SettingsPatch
import app.revanced.util.exception
import app.revanced.util.indexOfFirstWideLiteralInstructionValue
import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Patch(
@@ -47,14 +50,20 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37"
"19.09.38",
"19.10.39",
"19.11.43"
]
)
]
)
@Suppress("unused")
object ThemeBytecodePatch : BytecodePatch(
setOf(UseGradientLoadingScreenFingerprint)
setOf(
UseGradientLoadingScreenFingerprint,
ThemeHelperLightColorFingerprint,
ThemeHelperDarkColorFingerprint
)
) {
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/youtube/patches/theme/ThemePatch;"
@@ -121,6 +130,21 @@ object ThemeBytecodePatch : BytecodePatch(
)
} ?: 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")
}
}

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.07.40",
"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.07.40",
"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(
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],
compatiblePackages = [
CompatiblePackage(
@@ -34,7 +34,9 @@ import app.revanced.util.exception
"19.06.39",
"19.07.40",
"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
override fun execute(context: ResourceContext) {
scrubbedPreviewThumbnailResourceId = ResourceMappingPatch.resourceMappings.single {
it.type == "id" && it.name == "thumbnail"
}.id
scrubbedPreviewThumbnailResourceId = ResourceMappingPatch[
"id",
"thumbnail",
]
}
}

View File

@@ -44,7 +44,9 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
"19.06.39",
"19.07.40",
"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.07.40",
"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.07.40",
"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.07.40",
"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
@Patch(
dependencies = [ResourceMappingPatch::class]
dependencies = [ResourceMappingPatch::class],
)
internal object NavigationBarHookResourcePatch : ResourcePatch() {
internal var imageOnlyTabResourceId: Long = -1
internal var actionBarSearchResultsViewMicId: Long = -1
override fun execute(context: ResourceContext) {
imageOnlyTabResourceId = ResourceMappingPatch.resourceMappings.first {
it.type == "layout" && it.name == "image_only_tab"
}.id
actionBarSearchResultsViewMicId = ResourceMappingPatch.resourceMappings.first {
it.type == "layout" && it.name == "action_bar_search_results_view_mic"
}.id
imageOnlyTabResourceId = ResourceMappingPatch["layout", "image_only_tab"]
actionBarSearchResultsViewMicId = ResourceMappingPatch["layout", "action_bar_search_results_view_mic"]
}
}
}

View File

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

View File

@@ -41,7 +41,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
"19.06.39",
"19.07.40",
"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.InputType
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.TextPreference
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 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"
override fun execute(context: BytecodeContext) {
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(
TextPreference(
key = null,
@@ -52,7 +61,7 @@ object SettingsPatch :
summaryKey = "revanced_pref_import_export_summary",
inputType = InputType.TEXT_MULTI_LINE,
tag = "app.revanced.integrations.shared.settings.preference.ImportExportPreference",
),
)
)
SetThemeFingerprint.result?.mutableMethod?.let { setThemeMethod ->
@@ -69,7 +78,7 @@ object SettingsPatch :
replaceInstruction(
returnIndex,
"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")
}

View File

@@ -31,10 +31,7 @@ object SettingsResourcePatch : BaseSettingsResourcePatch(
AddResourcesPatch(this::class)
// Used for a fingerprint from SettingsPatch.
appearanceStringId =
ResourceMappingPatch.resourceMappings.find {
it.type == "string" && it.name == "app_theme_appearance_dark"
}!!.id
appearanceStringId = ResourceMappingPatch["string", "app_theme_appearance_dark"]
arrayOf(
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.07.40",
"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.07.40",
"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
override fun execute(context: ResourceContext) {
speedUnavailableId = ResourceMappingPatch.resourceMappings.single {
it.type == "string" && it.name == "varispeed_unavailable_message"
}.id
speedUnavailableId = ResourceMappingPatch[
"string",
"varispeed_unavailable_message",
]
}
}
}

View File

@@ -41,7 +41,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
"19.06.39",
"19.07.40",
"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
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.Patch
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
@Patch(
dependencies = [SettingsPatch::class, ResourceMappingPatch::class, AddResourcesPatch::class]
dependencies = [SettingsPatch::class, ResourceMappingPatch::class, AddResourcesPatch::class],
)
object RestoreOldVideoQualityMenuResourcePatch : ResourcePatch() {
internal var videoQualityBottomSheetListFragmentTitle = -1L
@@ -19,13 +18,13 @@ object RestoreOldVideoQualityMenuResourcePatch : ResourcePatch() {
AddResourcesPatch(this::class)
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.
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.util.MethodUtil
fun MethodFingerprint.resultOrThrow() = result ?: throw exception
/**
@@ -59,24 +58,41 @@ fun MutableMethod.injectHideViewCall(
insertIndex: Int,
viewRegister: Int,
classDescriptor: String,
targetMethod: String
targetMethod: String,
) = addInstruction(
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.
* @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 getIdResourceId(resourceName: String) = ResourceMappingPatch.resourceMappings.single {
it.type == "id" && it.name == resourceName
}.id
fun Method.indexOfIdResource(resourceName: String): Int {
val resourceId = ResourceMappingPatch["id", resourceName]
return indexOfFirstWideLiteralInstructionValue(resourceId)
}
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) =
this.implementation!!.instructions.indexOfFirst(predicate)
/**
* Return the resolved methods of [MethodFingerprint]s early.
*/
fun List<MethodFingerprint>.returnEarly(bool: Boolean = false) {
val const = if (bool) "0x1" else "0x0"
this.forEach { fingerprint ->
fingerprint.result?.let { result ->
val stringInstructions = when (result.method.returnType.first()) {
'L' -> """
/**
* Return the resolved methods of [MethodFingerprint]s early.
*/
fun List<MethodFingerprint>.returnEarly(bool: Boolean = false) {
val const = if (bool) "0x1" else "0x0"
this.forEach { fingerprint ->
fingerprint.result?.let { result ->
val stringInstructions = when (result.method.returnType.first()) {
'L' ->
"""
const/4 v0, $const
return-object v0
"""
'V' -> "return-void"
'I', 'Z' -> """
'V' -> "return-void"
'I', 'Z' ->
"""
const/4 v0, $const
return v0
"""
else -> throw Exception("This case should never happen.")
}
else -> throw Exception("This case should never happen.")
}
result.mutableMethod.addInstructions(0, stringInstructions)
} ?: throw fingerprint.exception
}
result.mutableMethod.addInstructions(0, stringInstructions)
} ?: throw fingerprint.exception
}
}

View File

@@ -53,10 +53,15 @@
<app id="youtube">
<patch id="misc.settings.SettingsResourcePatch">
<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_summary">Import / Export ReVanced settings</string>
</patch>
<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_02_alt_thumbnails_title">Alternative thumbnails</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_off">Watermark is shown</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>
<!-- 'Join' should be translated using the same localized wording YouTube displays.
This appears in the video player for certain videos. -->
@@ -166,6 +171,9 @@
<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_off">Channel bar is shown</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_off">Playables are shown</string>
<string name="revanced_hide_quick_actions_title">Hide quick actions in fullscreen</string>
<string name="revanced_hide_quick_actions_summary_on">Quick actions are hidden</string>
<string name="revanced_hide_quick_actions_summary_off">Quick actions are shown</string>
@@ -241,14 +249,14 @@
<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_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_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_off">Buttoned ads are shown</string>
<string name="revanced_hide_paid_content_ads_title">Hide paid content</string>
<string name="revanced_hide_paid_content_ads_summary_on">Paid content is hidden</string>
<string name="revanced_hide_paid_content_ads_summary_off">Paid content is shown</string>
<string name="revanced_hide_paid_promotion_label_title">Hide paid promotion label</string>
<string name="revanced_hide_paid_promotion_label_summary_on">Paid promotion label is hidden</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_summary_on">Self sponsored cards are hidden</string>
<string name="revanced_hide_self_sponsor_ads_summary_off">Self sponsored cards are shown</string>
@@ -264,7 +272,7 @@
<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_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 id="ad.getpremium.HideGetPremiumPatch">
<string name="revanced_hide_get_premium_title">Hide YouTube Premium promotions</string>
@@ -332,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_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_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_summary">The amount of milliseconds the overlay is visible</string>
<string name="revanced_swipe_text_overlay_size_title">Swipe overlay text size</string>
@@ -381,11 +393,6 @@
<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_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 id="layout.buttons.autoplay.HideAutoplayButtonPatch">
<string name="revanced_hide_autoplay_button_title">Hide autoplay button</string>
@@ -568,24 +575,24 @@
<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_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_subscribe_button_paused_title">Hide subscribe button when paused</string>
<string name="revanced_hide_shorts_subscribe_button_paused_summary_on">Subscribe button is hidden</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_paused_overlay_buttons_title">Hide paused overlay buttons</string>
<string name="revanced_hide_shorts_paused_overlay_buttons_summary_on">Paused overlay buttons are hidden</string>
<string name="revanced_hide_shorts_paused_overlay_buttons_summary_off">Paused overlay buttons are shown</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_off">Shop button is shown</string>
<string name="revanced_hide_shorts_location_button_title">Hide location button</string>
<string name="revanced_hide_shorts_location_button_summary_on">Location button is hidden</string>
<string name="revanced_hide_shorts_location_button_summary_off">Location button is shown</string>
<string name="revanced_hide_shorts_tagged_products_title">Hide tagged products</string>
<string name="revanced_hide_shorts_tagged_products_summary_on">Tagged products are hidden</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_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_summary_on">Like button is hidden</string>
<string name="revanced_hide_shorts_like_button_summary_off">Like button is shown</string>
@@ -996,8 +1003,9 @@
</patch>
<patch id="misc.dimensions.spoof.SpoofDeviceDimensionsPatch">
<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_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_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\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 id="misc.gms.GmsCoreSupportResourcePatch">
<string name="microg_settings_title">GmsCore Settings</string>
@@ -1142,9 +1150,9 @@
<string name="revanced_other_category_title">Other settings</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_debug_title">Debug logging</string>
<string name="revanced_debug_summary_on">Debug logs are enabled</string>
<string name="revanced_debug_summary_off">Debug logs are disabled</string>
<string name="revanced_twitch_debug_title">Debug logging</string>
<string name="revanced_twitch_debug_summary_on">Debug logs are enabled</string>
<string name="revanced_twitch_debug_summary_off">Debug logs are disabled</string>
</patch>
</app>
</resources>

View File

@@ -1,10 +1,30 @@
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<!--
https://github.com/google/material-design-icons/blob/9beae745bb758f3ad56654fb377ea5cf62be4915/symbols/android/content_copy/materialsymbolsoutlined/content_copy_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"
android:tint="#FFFFFF"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<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="#ffffffff"/>
android:fillColor="@android:color/white"
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>

View File

@@ -1,11 +1,31 @@
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<!--
https://github.com/google/material-design-icons/blob/9beae745bb758f3ad56654fb377ea5cf62be4915/symbols/android/content_copy/materialsymbolsoutlined/content_copy_wght200gradN25_24px.xml
https://github.com/google/material-design-icons/blob/9beae745bb758f3ad56654fb377ea5cf62be4915/symbols/android/schedule/materialsymbolsoutlined/schedule_wght300_24px.xml
This icon is the result of a combination of "content copy" and "schedule" icons.
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:name="path"
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:fillColor="#ffffffff" />
android:fillColor="@android:color/white"
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"/>
</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">
<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"/>
<!--
https://github.com/google/material-design-icons/blob/9beae745bb758f3ad56654fb377ea5cf62be4915/symbols/android/download/materialsymbolsoutlined/download_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"
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>

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"
android:width="24dp"
android:height="24dp"
android:tint="#FFFFFF"
android:viewportWidth="24"
android:viewportHeight="24">
android:tint="#FFFFFF"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FFFFFF"
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:fillColor="@android:color/white"
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>

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