From 01795e0fb4375c04f61384d4224f59ba7d952703 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Sun, 5 May 2024 00:22:51 +0900 Subject: [PATCH] refactor(YouTube Music/Settings): reorganize settings menu --- .../account/component/MenuComponentPatch.kt | 62 -- .../components/AccountComponentsPatch.kt | 145 +++ ...ntSwitcherAccessibilityLabelFingerprint.kt | 2 +- .../fingerprints/MenuEntryFingerprint.kt | 2 +- ...InactiveAccountThumbnailSizeFingerprint.kt | 2 +- .../fingerprints/TermsOfServiceFingerprint.kt | 2 +- .../music/account/handle/HandlePatch.kt | 77 -- .../music/account/tos/TermsContainerPatch.kt | 57 -- .../ActionBarComponentsPatch.kt} | 48 +- .../ActionBarComponentFingerprint.kt | 2 +- .../LikeDislikeContainerFingerprint.kt | 2 +- .../{GeneralAdsPatch.kt => AdsPatch.kt} | 104 ++- .../ads/{music => general}/MusicAdsPatch.kt | 2 +- .../AccountMenuFooterFingerprint.kt | 2 +- .../GetPremiumTextViewFingerprint.kt} | 4 +- .../MembershipSettingsFingerprint.kt | 2 +- .../MembershipSettingsParentFingerprint.kt | 2 +- .../components/FlyoutMenuComponentsPatch.kt | 420 +++++++++ .../FlyoutMenuComponentsResourcePatch.kt} | 4 +- .../fingerprints/DialogSolidFingerprint.kt | 2 +- .../EndButtonsContainerFingerprint.kt | 2 +- .../fingerprints/MenuItemFingerprint.kt | 2 +- .../fingerprints/SleepTimerFingerprint.kt | 2 +- .../fingerprints/TouchOutsideFingerprint.kt | 2 +- .../TrimSilenceConfigFingerprint.kt | 8 + .../TrimSilenceSwitchFingerprint.kt | 13 + .../compactdialog/CompactDialogPatch.kt | 44 - .../flyoutpanel/component/FlyoutPanelPatch.kt | 248 ------ .../replace/ReplaceDismissQueuePatch.kt | 38 - .../flyoutpanel/replace/ReplaceReportPatch.kt | 63 -- .../shared/FlyoutPanelMenuItemPatch.kt | 83 -- .../general/autocaptions/AutoCaptionsPatch.kt | 2 +- .../general/buttonshelf/ButtonShelfPatch.kt | 34 - .../carouselshelf/CarouselShelfPatch.kt | 34 - .../general/castbutton/CastButtonPatch.kt | 76 -- .../general/categorybar/CategoryBarPatch.kt | 47 - .../ChannelGuidelinesPatch.kt | 34 - .../components/LayoutComponentsPatch.kt | 378 ++++++++ .../fingerprints/ChipCloudFingerprint.kt | 2 +- .../fingerprints/ContentPillInFingerprint.kt | 2 +- .../fingerprints/FloatingButtonFingerprint.kt | 2 +- .../FloatingButtonParentFingerprint.kt | 2 +- .../HistoryMenuItemFingerprint.kt | 2 +- .../HistoryMenuItemOfflineTabFingerprint.kt | 2 +- .../MediaRouteButtonFingerprint.kt | 2 +- .../PlayerOverlayChipFingerprint.kt | 2 +- .../fingerprints/SearchBarFingerprint.kt | 8 + .../SearchBarParentFingerprint.kt | 8 + .../fingerprints/SoundSearchFingerprint.kt | 8 + .../TasteBuilderConstructorFingerprint.kt | 2 +- .../TasteBuilderSyntheticFingerprint.kt | 2 +- .../TooltipContentViewFingerprint.kt | 2 +- .../TopBarMenuItemImageViewFingerprint.kt | 14 + .../general/customfilter/CustomFilterPatch.kt | 39 - .../general/emojipicker/EmojiPickerPatch.kt | 34 - .../floatingbutton/FloatingButtonPatch.kt | 57 -- .../historybutton/HistoryButtonPatch.kt | 59 -- .../OldStyleLibraryShelfPatch.kt | 6 +- .../general/playlistcard/PlaylistCardPatch.kt | 34 - .../general/sampleshelf/SampleShelfPatch.kt | 34 - .../SpoofAppVersionBytecodePatch.kt | 8 + .../spoofappversion/SpoofAppVersionPatch.kt | 14 +- .../general/startpage/ChangeStartPagePatch.kt | 7 - .../taptoupdate/TapToUpdateButtonPatch.kt | 46 - .../tooltip/TooltipContentViewPatch.kt | 27 - .../voicesearch/VoiceSearchButtonPatch.kt | 23 - .../branding/name/CustomBrandingNamePatch.kt | 4 +- .../backgroundplay/BackgroundPlayPatch.kt | 31 - .../misc/bitrate/BitrateDefaultValuePatch.kt | 2 +- .../exclusiveaudio/ExclusiveAudioPatch.kt | 88 -- .../MinimizedPlaybackPatch.kt | 93 +- .../BackgroundPlaybackFingerprint.kt | 2 +- .../DataSavingSettingsFragmentFingerprint.kt | 2 +- .../MusicBrowserServiceFingerprint.kt | 2 +- .../fingerprints/PodCastConfigFingerprint.kt | 2 +- .../music/misc/premium/GetPremiumPatch.kt | 90 -- .../SpoofAppVersionBytecodePatch.kt | 8 - .../misc/tastebuilder/TasteBuilderPatch.kt | 58 -- .../black/BlackNavigationBarPatch.kt | 50 -- .../NavigationBarComponentsPatch.kt} | 66 +- .../fingerprints/TabLayoutFingerprint.kt | 2 +- .../fingerprints/TabLayoutTextFingerprint.kt | 2 +- .../colormatchplayer/ColorMatchPlayerPatch.kt | 107 --- .../components/PlayerComponentsPatch.kt | 836 ++++++++++++++++++ .../PlayerComponentsResourcePatch.kt} | 4 +- .../HandleSearchRenderedFingerprint.kt | 2 +- .../HandleSignInEventFingerprint.kt | 2 +- .../InteractionLoggingEnumFingerprint.kt | 2 +- .../MiniPlayerConstructorFingerprint.kt | 2 +- .../MiniPlayerDefaultTextFingerprint.kt | 2 +- ...iPlayerDefaultViewVisibilityFingerprint.kt | 2 +- .../MiniPlayerParentFingerprint.kt | 2 +- .../MinimizedPlayerFingerprint.kt | 2 +- .../MppWatchWhileLayoutFingerprint.kt | 2 +- .../MusicActivityWidgetFingerprint.kt | 2 +- .../MusicPlaybackControlsFingerprint.kt | 2 +- .../NextButtonVisibilityFingerprint.kt | 2 +- .../OldEngagementPanelFingerprint.kt | 9 + .../OldPlayerBackgroundFingerprint.kt | 2 +- .../OldPlayerLayoutFingerprint.kt | 2 +- .../PlayerPatchConstructorFingerprint.kt | 2 +- .../RemixGenericButtonFingerprint.kt | 2 +- .../fingerprints/RepeatTrackFingerprint.kt | 2 +- .../ShuffleClassReferenceFingerprint.kt | 2 +- .../fingerprints/SwipeToCloseFingerprint.kt | 2 +- .../SwitchToggleColorFingerprint.kt | 2 +- .../fingerprints/ZenModeFingerprint.kt | 2 +- .../minimizedplayer/MinimizedPlayerPatch.kt | 46 - .../nextprevious/MiniPlayerButtonPatch.kt | 237 ----- .../OldPlayerBackgroundPatch.kt | 36 - .../oldplayerlayout/OldPlayerLayoutPatch.kt | 36 - .../player/repeat/RememberRepeatPatch.kt | 44 - .../music/player/share/ShareButtonPatch.kt | 48 - .../player/shuffle/RememberShufflePatch.kt | 174 ---- .../SwipeToDismissMiniPlayerPatch.kt | 221 ----- .../music/player/zenmode/ZenModePatch.kt | 89 -- .../music/utils/compatibility/Constants.kt | 3 +- .../utils/flyoutmenu/FlyoutMenuHookPatch.kt | 47 + ...PlaybackRateBottomSheetClassFingerprint.kt | 13 + .../PlaybackSpeedFlyoutPanelHookPatch.kt | 99 --- ...PlaybackSpeedOnClickListenerFingerprint.kt | 19 - .../music/utils/integrations/Constants.kt | 96 +- .../utils/resourceid/SharedResourceIdPatch.kt | 6 + .../music/utils/settings/CategoryType.kt | 4 +- .../music/utils/settings/ResourceUtils.kt | 12 +- .../music/utils/settings/SettingsPatch.kt | 16 - .../sponsorblock/SponsorBlockBytecodePatch.kt | 1 - .../utils/sponsorblock/SponsorBlockPatch.kt | 6 +- .../customspeed/CustomPlaybackSpeedPatch.kt | 27 - .../information/VideoInformationPatch.kt | 112 +-- .../CustomPlaybackSpeedPatch.kt} | 6 +- .../video/playback/VideoPlaybackPatch.kt | 124 +++ .../PlaybackSpeedBottomSheetFingerprint.kt} | 4 +- .../UserQualityChangeFingerprint.kt | 2 +- .../music/video/quality/VideoQualityPatch.kt | 64 -- .../music/video/speed/PlaybackSpeedPatch.kt | 73 -- .../PlaybackSpeedBottomSheetFingerprint.kt | 16 - .../music/video/videoid/VideoIdPatch.kt | 97 +- ...ponseModelStoryboardRendererFingerprint.kt | 18 - ...ntFingerprint.kt => VideoIdFingerprint.kt} | 15 +- ...dsBytecodePatch.kt => AdsBytecodePatch.kt} | 3 +- .../{GeneralAdsPatch.kt => AdsPatch.kt} | 5 +- .../ads/{video => general}/VideoAdsPatch.kt | 2 +- .../NavigationBarComponentsPatch.kt | 4 +- .../splashanimation/SplashAnimationPatch.kt | 5 +- .../general/toolbar/ToolBarComponentsPatch.kt | 2 +- .../branding/name/CustomBrandingNamePatch.kt | 6 +- .../overlaybuttons/OverlayButtonsPatch.kt | 5 - .../kotlin/app/revanced/util/BytecodeUtils.kt | 33 +- .../music/settings/host/values/arrays.xml | 42 +- .../music/settings/host/values/strings.xml | 555 +++++++----- .../music/settings/values-v21/strings.xml | 16 - .../spoofappversion/host/values/arrays.xml | 11 - .../music/startpage/host/values/arrays.xml | 17 - .../shared/host/values/arrays.xml | 21 - .../youtube/settings/host/values/arrays.xml | 18 + .../youtube/settings/xml/revanced_prefs.xml | 2 +- 157 files changed, 2834 insertions(+), 3725 deletions(-) delete mode 100644 src/main/kotlin/app/revanced/patches/music/account/component/MenuComponentPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/music/account/components/AccountComponentsPatch.kt rename src/main/kotlin/app/revanced/patches/music/account/{handle => components}/fingerprints/AccountSwitcherAccessibilityLabelFingerprint.kt (85%) rename src/main/kotlin/app/revanced/patches/music/account/{component => components}/fingerprints/MenuEntryFingerprint.kt (80%) rename src/main/kotlin/app/revanced/patches/music/account/{handle => components}/fingerprints/NamesInactiveAccountThumbnailSizeFingerprint.kt (92%) rename src/main/kotlin/app/revanced/patches/music/account/{tos => components}/fingerprints/TermsOfServiceFingerprint.kt (81%) delete mode 100644 src/main/kotlin/app/revanced/patches/music/account/handle/HandlePatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/account/tos/TermsContainerPatch.kt rename src/main/kotlin/app/revanced/patches/music/actionbar/{component/ActionBarComponentPatch.kt => components/ActionBarComponentsPatch.kt} (94%) rename src/main/kotlin/app/revanced/patches/music/actionbar/{component => components}/fingerprints/ActionBarComponentFingerprint.kt (89%) rename src/main/kotlin/app/revanced/patches/music/actionbar/{component => components}/fingerprints/LikeDislikeContainerFingerprint.kt (86%) rename src/main/kotlin/app/revanced/patches/music/ads/general/{GeneralAdsPatch.kt => AdsPatch.kt} (68%) rename src/main/kotlin/app/revanced/patches/music/ads/{music => general}/MusicAdsPatch.kt (82%) rename src/main/kotlin/app/revanced/patches/music/{misc/premium => ads/general}/fingerprints/AccountMenuFooterFingerprint.kt (91%) rename src/main/kotlin/app/revanced/patches/music/{misc/premium/fingerprints/HideGetPremiumFingerprint.kt => ads/general/fingerprints/GetPremiumTextViewFingerprint.kt} (82%) rename src/main/kotlin/app/revanced/patches/music/{misc/premium => ads/general}/fingerprints/MembershipSettingsFingerprint.kt (85%) rename src/main/kotlin/app/revanced/patches/music/{misc/premium => ads/general}/fingerprints/MembershipSettingsParentFingerprint.kt (86%) create mode 100644 src/main/kotlin/app/revanced/patches/music/flyoutmenu/components/FlyoutMenuComponentsPatch.kt rename src/main/kotlin/app/revanced/patches/music/{flyoutpanel/replace/ReplaceReportResourcePatch.kt => flyoutmenu/components/FlyoutMenuComponentsResourcePatch.kt} (87%) rename src/main/kotlin/app/revanced/patches/music/{flyoutpanel/compactdialog => flyoutmenu/components}/fingerprints/DialogSolidFingerprint.kt (89%) rename src/main/kotlin/app/revanced/patches/music/{flyoutpanel/component => flyoutmenu/components}/fingerprints/EndButtonsContainerFingerprint.kt (82%) rename src/main/kotlin/app/revanced/patches/music/{flyoutpanel/shared => flyoutmenu/components}/fingerprints/MenuItemFingerprint.kt (88%) rename src/main/kotlin/app/revanced/patches/music/{flyoutpanel/component => flyoutmenu/components}/fingerprints/SleepTimerFingerprint.kt (77%) rename src/main/kotlin/app/revanced/patches/music/{flyoutpanel/replace => flyoutmenu/components}/fingerprints/TouchOutsideFingerprint.kt (80%) create mode 100644 src/main/kotlin/app/revanced/patches/music/flyoutmenu/components/fingerprints/TrimSilenceConfigFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/music/flyoutmenu/components/fingerprints/TrimSilenceSwitchFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/flyoutpanel/compactdialog/CompactDialogPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/flyoutpanel/component/FlyoutPanelPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/flyoutpanel/replace/ReplaceDismissQueuePatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/flyoutpanel/replace/ReplaceReportPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/flyoutpanel/shared/FlyoutPanelMenuItemPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/general/buttonshelf/ButtonShelfPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/general/carouselshelf/CarouselShelfPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/general/castbutton/CastButtonPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/general/categorybar/CategoryBarPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/general/channelguidelines/ChannelGuidelinesPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/music/general/components/LayoutComponentsPatch.kt rename src/main/kotlin/app/revanced/patches/music/general/{categorybar => components}/fingerprints/ChipCloudFingerprint.kt (87%) rename src/main/kotlin/app/revanced/patches/music/general/{taptoupdate => components}/fingerprints/ContentPillInFingerprint.kt (73%) rename src/main/kotlin/app/revanced/patches/music/general/{floatingbutton => components}/fingerprints/FloatingButtonFingerprint.kt (78%) rename src/main/kotlin/app/revanced/patches/music/general/{floatingbutton => components}/fingerprints/FloatingButtonParentFingerprint.kt (86%) rename src/main/kotlin/app/revanced/patches/music/general/{historybutton => components}/fingerprints/HistoryMenuItemFingerprint.kt (92%) rename src/main/kotlin/app/revanced/patches/music/general/{historybutton => components}/fingerprints/HistoryMenuItemOfflineTabFingerprint.kt (93%) rename src/main/kotlin/app/revanced/patches/music/general/{castbutton => components}/fingerprints/MediaRouteButtonFingerprint.kt (84%) rename src/main/kotlin/app/revanced/patches/music/general/{castbutton => components}/fingerprints/PlayerOverlayChipFingerprint.kt (87%) create mode 100644 src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/SearchBarFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/SearchBarParentFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/SoundSearchFingerprint.kt rename src/main/kotlin/app/revanced/patches/music/{misc/tastebuilder => general/components}/fingerprints/TasteBuilderConstructorFingerprint.kt (87%) rename src/main/kotlin/app/revanced/patches/music/{misc/tastebuilder => general/components}/fingerprints/TasteBuilderSyntheticFingerprint.kt (88%) rename src/main/kotlin/app/revanced/patches/music/general/{tooltip => components}/fingerprints/TooltipContentViewFingerprint.kt (87%) create mode 100644 src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/TopBarMenuItemImageViewFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/general/customfilter/CustomFilterPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/general/emojipicker/EmojiPickerPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/general/floatingbutton/FloatingButtonPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/general/historybutton/HistoryButtonPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/general/playlistcard/PlaylistCardPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/general/sampleshelf/SampleShelfPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/music/general/spoofappversion/SpoofAppVersionBytecodePatch.kt rename src/main/kotlin/app/revanced/patches/music/{misc => general}/spoofappversion/SpoofAppVersionPatch.kt (78%) delete mode 100644 src/main/kotlin/app/revanced/patches/music/general/taptoupdate/TapToUpdateButtonPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/general/tooltip/TooltipContentViewPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/general/voicesearch/VoiceSearchButtonPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/misc/backgroundplay/BackgroundPlayPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/misc/exclusiveaudio/ExclusiveAudioPatch.kt rename src/main/kotlin/app/revanced/patches/music/misc/{backgroundplay => minimizedplayback}/fingerprints/BackgroundPlaybackFingerprint.kt (84%) rename src/main/kotlin/app/revanced/patches/music/misc/{exclusiveaudio => minimizedplayback}/fingerprints/DataSavingSettingsFragmentFingerprint.kt (86%) rename src/main/kotlin/app/revanced/patches/music/misc/{exclusiveaudio => minimizedplayback}/fingerprints/MusicBrowserServiceFingerprint.kt (89%) rename src/main/kotlin/app/revanced/patches/music/misc/{exclusiveaudio => minimizedplayback}/fingerprints/PodCastConfigFingerprint.kt (83%) delete mode 100644 src/main/kotlin/app/revanced/patches/music/misc/premium/GetPremiumPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/misc/spoofappversion/SpoofAppVersionBytecodePatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/misc/tastebuilder/TasteBuilderPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/navigation/black/BlackNavigationBarPatch.kt rename src/main/kotlin/app/revanced/patches/music/navigation/{component/NavigationBarComponentPatch.kt => components/NavigationBarComponentsPatch.kt} (74%) rename src/main/kotlin/app/revanced/patches/music/navigation/{black => components}/fingerprints/TabLayoutFingerprint.kt (89%) rename src/main/kotlin/app/revanced/patches/music/navigation/{component => components}/fingerprints/TabLayoutTextFingerprint.kt (91%) delete mode 100644 src/main/kotlin/app/revanced/patches/music/player/colormatchplayer/ColorMatchPlayerPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/music/player/components/PlayerComponentsPatch.kt rename src/main/kotlin/app/revanced/patches/music/player/{nextprevious/MiniPlayerButtonResourcePatch.kt => components/PlayerComponentsResourcePatch.kt} (97%) rename src/main/kotlin/app/revanced/patches/music/player/{swipetodismiss => components}/fingerprints/HandleSearchRenderedFingerprint.kt (79%) rename src/main/kotlin/app/revanced/patches/music/player/{swipetodismiss => components}/fingerprints/HandleSignInEventFingerprint.kt (84%) rename src/main/kotlin/app/revanced/patches/music/player/{swipetodismiss => components}/fingerprints/InteractionLoggingEnumFingerprint.kt (75%) rename src/main/kotlin/app/revanced/patches/music/{utils => player/components}/fingerprints/MiniPlayerConstructorFingerprint.kt (91%) rename src/main/kotlin/app/revanced/patches/music/player/{swipetodismiss => components}/fingerprints/MiniPlayerDefaultTextFingerprint.kt (87%) rename src/main/kotlin/app/revanced/patches/music/player/{swipetodismiss => components}/fingerprints/MiniPlayerDefaultViewVisibilityFingerprint.kt (90%) rename src/main/kotlin/app/revanced/patches/music/player/{nextprevious => components}/fingerprints/MiniPlayerParentFingerprint.kt (87%) rename src/main/kotlin/app/revanced/patches/music/player/{minimizedplayer => components}/fingerprints/MinimizedPlayerFingerprint.kt (88%) rename src/main/kotlin/app/revanced/patches/music/player/{nextprevious => components}/fingerprints/MppWatchWhileLayoutFingerprint.kt (90%) rename src/main/kotlin/app/revanced/patches/music/player/{swipetodismiss => components}/fingerprints/MusicActivityWidgetFingerprint.kt (85%) rename src/main/kotlin/app/revanced/patches/music/player/{shuffle => components}/fingerprints/MusicPlaybackControlsFingerprint.kt (90%) rename src/main/kotlin/app/revanced/patches/music/player/{nextprevious => components}/fingerprints/NextButtonVisibilityFingerprint.kt (88%) create mode 100644 src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/OldEngagementPanelFingerprint.kt rename src/main/kotlin/app/revanced/patches/music/player/{oldplayerbackground => components}/fingerprints/OldPlayerBackgroundFingerprint.kt (78%) rename src/main/kotlin/app/revanced/patches/music/player/{oldplayerlayout => components}/fingerprints/OldPlayerLayoutFingerprint.kt (79%) rename src/main/kotlin/app/revanced/patches/music/player/{nextprevious => components}/fingerprints/PlayerPatchConstructorFingerprint.kt (85%) rename src/main/kotlin/app/revanced/patches/music/player/{share => components}/fingerprints/RemixGenericButtonFingerprint.kt (90%) rename src/main/kotlin/app/revanced/patches/music/player/{repeat => components}/fingerprints/RepeatTrackFingerprint.kt (90%) rename src/main/kotlin/app/revanced/patches/music/player/{shuffle => components}/fingerprints/ShuffleClassReferenceFingerprint.kt (90%) rename src/main/kotlin/app/revanced/patches/music/player/{swipetodismiss => components}/fingerprints/SwipeToCloseFingerprint.kt (75%) rename src/main/kotlin/app/revanced/patches/music/{utils => player/components}/fingerprints/SwitchToggleColorFingerprint.kt (88%) rename src/main/kotlin/app/revanced/patches/music/player/{zenmode => components}/fingerprints/ZenModeFingerprint.kt (89%) delete mode 100644 src/main/kotlin/app/revanced/patches/music/player/minimizedplayer/MinimizedPlayerPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/player/nextprevious/MiniPlayerButtonPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/player/oldplayerbackground/OldPlayerBackgroundPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/player/oldplayerlayout/OldPlayerLayoutPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/player/repeat/RememberRepeatPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/player/share/ShareButtonPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/player/shuffle/RememberShufflePatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/player/swipetodismiss/SwipeToDismissMiniPlayerPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/player/zenmode/ZenModePatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/music/utils/flyoutmenu/FlyoutMenuHookPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/music/utils/flyoutmenu/fingerprints/PlaybackRateBottomSheetClassFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/utils/flyoutpanel/PlaybackSpeedFlyoutPanelHookPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/utils/flyoutpanel/fingerprints/PlaybackSpeedOnClickListenerFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/video/customspeed/CustomPlaybackSpeedPatch.kt rename src/main/kotlin/app/revanced/patches/music/video/{customspeed/CustomPlaybackSpeedBytecodePatch.kt => playback/CustomPlaybackSpeedPatch.kt} (59%) create mode 100644 src/main/kotlin/app/revanced/patches/music/video/playback/VideoPlaybackPatch.kt rename src/main/kotlin/app/revanced/patches/music/video/{speed/fingerprints/PlaybackSpeedBottomSheetParentFingerprint.kt => playback/fingerprints/PlaybackSpeedBottomSheetFingerprint.kt} (70%) rename src/main/kotlin/app/revanced/patches/music/video/{quality => playback}/fingerprints/UserQualityChangeFingerprint.kt (87%) delete mode 100644 src/main/kotlin/app/revanced/patches/music/video/quality/VideoQualityPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/video/speed/PlaybackSpeedPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/video/speed/fingerprints/PlaybackSpeedBottomSheetFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/video/videoid/fingerprints/PlayerResponseModelStoryboardRendererFingerprint.kt rename src/main/kotlin/app/revanced/patches/music/video/videoid/fingerprints/{VideoIdParentFingerprint.kt => VideoIdFingerprint.kt} (50%) rename src/main/kotlin/app/revanced/patches/youtube/ads/general/{GeneralAdsBytecodePatch.kt => AdsBytecodePatch.kt} (99%) rename src/main/kotlin/app/revanced/patches/youtube/ads/general/{GeneralAdsPatch.kt => AdsPatch.kt} (95%) rename src/main/kotlin/app/revanced/patches/youtube/ads/{video => general}/VideoAdsPatch.kt (82%) delete mode 100644 src/main/resources/music/settings/values-v21/strings.xml delete mode 100644 src/main/resources/music/spoofappversion/host/values/arrays.xml delete mode 100644 src/main/resources/music/startpage/host/values/arrays.xml delete mode 100644 src/main/resources/youtube/overlaybuttons/shared/host/values/arrays.xml diff --git a/src/main/kotlin/app/revanced/patches/music/account/component/MenuComponentPatch.kt b/src/main/kotlin/app/revanced/patches/music/account/component/MenuComponentPatch.kt deleted file mode 100644 index abb15ca4a..000000000 --- a/src/main/kotlin/app/revanced/patches/music/account/component/MenuComponentPatch.kt +++ /dev/null @@ -1,62 +0,0 @@ -package app.revanced.patches.music.account.component - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patches.music.account.component.fingerprints.MenuEntryFingerprint -import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.music.utils.integrations.Constants.ACCOUNT_CLASS_DESCRIPTOR -import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch -import app.revanced.patches.music.utils.settings.CategoryType -import app.revanced.patches.music.utils.settings.SettingsPatch -import app.revanced.util.getTargetIndexWithMethodReferenceName -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction - -@Suppress("unused") -object MenuComponentPatch : BaseBytecodePatch( - name = "Hide account menu", - description = "Adds the ability to hide account menu elements using a custom filter.", - dependencies = setOf( - SettingsPatch::class, - SharedResourceIdPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(MenuEntryFingerprint) -) { - override fun execute(context: BytecodeContext) { - - MenuEntryFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val textIndex = getTargetIndexWithMethodReferenceName("setText") - val viewIndex = getTargetIndexWithMethodReferenceName("addView") - - val textRegister = getInstruction(textIndex).registerD - val viewRegister = getInstruction(viewIndex).registerD - - addInstruction( - textIndex + 1, - "invoke-static {v$textRegister, v$viewRegister}, $ACCOUNT_CLASS_DESCRIPTOR->hideAccountMenu(Ljava/lang/CharSequence;Landroid/view/View;)V" - ) - } - } - - SettingsPatch.addSwitchPreference( - CategoryType.ACCOUNT, - "revanced_hide_account_menu", - "false" - ) - SettingsPatch.addPreferenceWithIntent( - CategoryType.ACCOUNT, - "revanced_hide_account_menu_filter_strings", - "revanced_hide_account_menu" - ) - SettingsPatch.addSwitchPreference( - CategoryType.ACCOUNT, - "revanced_hide_account_menu_empty_component", - "false", - "revanced_hide_account_menu" - ) - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/account/components/AccountComponentsPatch.kt b/src/main/kotlin/app/revanced/patches/music/account/components/AccountComponentsPatch.kt new file mode 100644 index 000000000..51583709a --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/account/components/AccountComponentsPatch.kt @@ -0,0 +1,145 @@ +package app.revanced.patches.music.account.components + +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.patches.music.account.components.fingerprints.AccountSwitcherAccessibilityLabelFingerprint +import app.revanced.patches.music.account.components.fingerprints.MenuEntryFingerprint +import app.revanced.patches.music.account.components.fingerprints.NamesInactiveAccountThumbnailSizeFingerprint +import app.revanced.patches.music.account.components.fingerprints.TermsOfServiceFingerprint +import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE +import app.revanced.patches.music.utils.integrations.Constants.ACCOUNT_CLASS_DESCRIPTOR +import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch +import app.revanced.patches.music.utils.settings.CategoryType +import app.revanced.patches.music.utils.settings.SettingsPatch +import app.revanced.util.getTargetIndexWithMethodReferenceName +import app.revanced.util.getTargetIndexWithReference +import app.revanced.util.patch.BaseBytecodePatch +import app.revanced.util.resultOrThrow +import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction + +@Suppress("unused") +object AccountComponentsPatch : BaseBytecodePatch( + name = "Hide account components", + description = "Adds the options to hide components related to account menu.", + dependencies = setOf( + SettingsPatch::class, + SharedResourceIdPatch::class + ), + compatiblePackages = COMPATIBLE_PACKAGE, + fingerprints = setOf( + AccountSwitcherAccessibilityLabelFingerprint, + MenuEntryFingerprint, + NamesInactiveAccountThumbnailSizeFingerprint, + TermsOfServiceFingerprint, + ) +) { + override fun execute(context: BytecodeContext) { + + // region patch for hide account menu + + MenuEntryFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val textIndex = getTargetIndexWithMethodReferenceName("setText") + val viewIndex = getTargetIndexWithMethodReferenceName("addView") + + val textRegister = getInstruction(textIndex).registerD + val viewRegister = getInstruction(viewIndex).registerD + + addInstruction( + textIndex + 1, + "invoke-static {v$textRegister, v$viewRegister}, $ACCOUNT_CLASS_DESCRIPTOR->hideAccountMenu(Ljava/lang/CharSequence;Landroid/view/View;)V" + ) + } + } + + // endregion + + // region patch for hide handle + + // account menu + AccountSwitcherAccessibilityLabelFingerprint.resultOrThrow().let { result -> + result.mutableMethod.apply { + + val textColorIndex = getTargetIndexWithMethodReferenceName("setTextColor") + val setVisibilityIndex = getTargetIndexWithMethodReferenceName(textColorIndex, "setVisibility") + val textViewInstruction = getInstruction(setVisibilityIndex) + + replaceInstruction( + setVisibilityIndex, + "invoke-static {v${textViewInstruction.registerC}, v${textViewInstruction.registerD}}, $ACCOUNT_CLASS_DESCRIPTOR->hideHandle(Landroid/widget/TextView;I)V" + ) + } + } + + // account switcher + NamesInactiveAccountThumbnailSizeFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val targetIndex = it.scanResult.patternScanResult!!.startIndex + val targetRegister = getInstruction(targetIndex).registerA + + addInstructions( + targetIndex, """ + invoke-static {v$targetRegister}, $ACCOUNT_CLASS_DESCRIPTOR->hideHandle(Z)Z + move-result v$targetRegister + """ + ) + } + } + + // endregion + + // region patch for hide terms container + + TermsOfServiceFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val insertIndex = getTargetIndexWithReference("/PrivacyTosFooter;->setVisibility(I)V") + val visibilityRegister = + getInstruction(insertIndex).registerD + + addInstruction( + insertIndex + 1, + "const/4 v$visibilityRegister, 0x0" + ) + addInstructions( + insertIndex, """ + invoke-static {}, $ACCOUNT_CLASS_DESCRIPTOR->hideTermsContainer()I + move-result v$visibilityRegister + """ + ) + } + } + + // endregion + + SettingsPatch.addSwitchPreference( + CategoryType.ACCOUNT, + "revanced_hide_account_menu", + "false" + ) + SettingsPatch.addPreferenceWithIntent( + CategoryType.ACCOUNT, + "revanced_hide_account_menu_filter_strings", + "revanced_hide_account_menu" + ) + SettingsPatch.addSwitchPreference( + CategoryType.ACCOUNT, + "revanced_hide_account_menu_empty_component", + "false", + "revanced_hide_account_menu" + ) + SettingsPatch.addSwitchPreference( + CategoryType.ACCOUNT, + "revanced_hide_handle", + "true" + ) + SettingsPatch.addSwitchPreference( + CategoryType.ACCOUNT, + "revanced_hide_terms_container", + "false" + ) + } +} diff --git a/src/main/kotlin/app/revanced/patches/music/account/handle/fingerprints/AccountSwitcherAccessibilityLabelFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/account/components/fingerprints/AccountSwitcherAccessibilityLabelFingerprint.kt similarity index 85% rename from src/main/kotlin/app/revanced/patches/music/account/handle/fingerprints/AccountSwitcherAccessibilityLabelFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/account/components/fingerprints/AccountSwitcherAccessibilityLabelFingerprint.kt index 4248854c2..3c0b8a71d 100644 --- a/src/main/kotlin/app/revanced/patches/music/account/handle/fingerprints/AccountSwitcherAccessibilityLabelFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/account/components/fingerprints/AccountSwitcherAccessibilityLabelFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.account.handle.fingerprints +package app.revanced.patches.music.account.components.fingerprints import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.AccountSwitcherAccessibility import app.revanced.util.fingerprint.LiteralValueFingerprint diff --git a/src/main/kotlin/app/revanced/patches/music/account/component/fingerprints/MenuEntryFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/account/components/fingerprints/MenuEntryFingerprint.kt similarity index 80% rename from src/main/kotlin/app/revanced/patches/music/account/component/fingerprints/MenuEntryFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/account/components/fingerprints/MenuEntryFingerprint.kt index 794ee6c59..79e10550c 100644 --- a/src/main/kotlin/app/revanced/patches/music/account/component/fingerprints/MenuEntryFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/account/components/fingerprints/MenuEntryFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.account.component.fingerprints +package app.revanced.patches.music.account.components.fingerprints import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MenuEntry import app.revanced.util.fingerprint.LiteralValueFingerprint diff --git a/src/main/kotlin/app/revanced/patches/music/account/handle/fingerprints/NamesInactiveAccountThumbnailSizeFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/account/components/fingerprints/NamesInactiveAccountThumbnailSizeFingerprint.kt similarity index 92% rename from src/main/kotlin/app/revanced/patches/music/account/handle/fingerprints/NamesInactiveAccountThumbnailSizeFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/account/components/fingerprints/NamesInactiveAccountThumbnailSizeFingerprint.kt index 1f4f67d0c..52dbd3cd8 100644 --- a/src/main/kotlin/app/revanced/patches/music/account/handle/fingerprints/NamesInactiveAccountThumbnailSizeFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/account/components/fingerprints/NamesInactiveAccountThumbnailSizeFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.account.handle.fingerprints +package app.revanced.patches.music.account.components.fingerprints import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.NamesInactiveAccountThumbnailSize import app.revanced.util.fingerprint.LiteralValueFingerprint diff --git a/src/main/kotlin/app/revanced/patches/music/account/tos/fingerprints/TermsOfServiceFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/account/components/fingerprints/TermsOfServiceFingerprint.kt similarity index 81% rename from src/main/kotlin/app/revanced/patches/music/account/tos/fingerprints/TermsOfServiceFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/account/components/fingerprints/TermsOfServiceFingerprint.kt index 5f379ca9e..35743e7fe 100644 --- a/src/main/kotlin/app/revanced/patches/music/account/tos/fingerprints/TermsOfServiceFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/account/components/fingerprints/TermsOfServiceFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.account.tos.fingerprints +package app.revanced.patches.music.account.components.fingerprints import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.TosFooter import app.revanced.util.fingerprint.LiteralValueFingerprint diff --git a/src/main/kotlin/app/revanced/patches/music/account/handle/HandlePatch.kt b/src/main/kotlin/app/revanced/patches/music/account/handle/HandlePatch.kt deleted file mode 100644 index 40f9076b7..000000000 --- a/src/main/kotlin/app/revanced/patches/music/account/handle/HandlePatch.kt +++ /dev/null @@ -1,77 +0,0 @@ -package app.revanced.patches.music.account.handle - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction -import app.revanced.patches.music.account.handle.fingerprints.AccountSwitcherAccessibilityLabelFingerprint -import app.revanced.patches.music.account.handle.fingerprints.NamesInactiveAccountThumbnailSizeFingerprint -import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.music.utils.integrations.Constants.ACCOUNT_CLASS_DESCRIPTOR -import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch -import app.revanced.patches.music.utils.settings.CategoryType -import app.revanced.patches.music.utils.settings.SettingsPatch -import app.revanced.util.getTargetIndexWithMethodReferenceName -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction - -@Suppress("unused") -object HandlePatch : BaseBytecodePatch( - name = "Hide handle", - description = "Adds an option to hide the handle in the account menu.", - dependencies = setOf( - SettingsPatch::class, - SharedResourceIdPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf( - AccountSwitcherAccessibilityLabelFingerprint, - NamesInactiveAccountThumbnailSizeFingerprint - ) -) { - override fun execute(context: BytecodeContext) { - - /** - * Hide handle in account menu - */ - AccountSwitcherAccessibilityLabelFingerprint.resultOrThrow().let { result -> - result.mutableMethod.apply { - - val textColorIndex = getTargetIndexWithMethodReferenceName("setTextColor") - val setVisibilityIndex = getTargetIndexWithMethodReferenceName(textColorIndex, "setVisibility") - val textViewInstruction = getInstruction(setVisibilityIndex) - - replaceInstruction( - setVisibilityIndex, - "invoke-static {v${textViewInstruction.registerC}, v${textViewInstruction.registerD}}, $ACCOUNT_CLASS_DESCRIPTOR->hideHandle(Landroid/widget/TextView;I)V" - ) - } - } - - /** - * Hide handle in account switcher - */ - NamesInactiveAccountThumbnailSizeFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val targetIndex = it.scanResult.patternScanResult!!.startIndex - val targetRegister = getInstruction(targetIndex).registerA - - addInstructions( - targetIndex, """ - invoke-static {v$targetRegister}, $ACCOUNT_CLASS_DESCRIPTOR->hideHandle(Z)Z - move-result v$targetRegister - """ - ) - } - } - - SettingsPatch.addSwitchPreference( - CategoryType.ACCOUNT, - "revanced_hide_handle", - "true" - ) - - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/account/tos/TermsContainerPatch.kt b/src/main/kotlin/app/revanced/patches/music/account/tos/TermsContainerPatch.kt deleted file mode 100644 index 5277f305b..000000000 --- a/src/main/kotlin/app/revanced/patches/music/account/tos/TermsContainerPatch.kt +++ /dev/null @@ -1,57 +0,0 @@ -package app.revanced.patches.music.account.tos - -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.patches.music.account.tos.fingerprints.TermsOfServiceFingerprint -import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.music.utils.integrations.Constants.ACCOUNT_CLASS_DESCRIPTOR -import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch -import app.revanced.patches.music.utils.settings.CategoryType -import app.revanced.patches.music.utils.settings.SettingsPatch -import app.revanced.util.getTargetIndexWithReference -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction - -@Suppress("unused") -object TermsContainerPatch : BaseBytecodePatch( - name = "Hide terms container", - description = "Adds an option to hide the terms of service container in the account menu.", - dependencies = setOf( - SettingsPatch::class, - SharedResourceIdPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(TermsOfServiceFingerprint) -) { - override fun execute(context: BytecodeContext) { - - TermsOfServiceFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val insertIndex = getTargetIndexWithReference("/PrivacyTosFooter;->setVisibility(I)V") - val visibilityRegister = - getInstruction(insertIndex).registerD - - addInstruction( - insertIndex + 1, - "const/4 v$visibilityRegister, 0x0" - ) - addInstructions( - insertIndex, """ - invoke-static {}, $ACCOUNT_CLASS_DESCRIPTOR->hideTermsContainer()I - move-result v$visibilityRegister - """ - ) - } - } - - SettingsPatch.addSwitchPreference( - CategoryType.ACCOUNT, - "revanced_hide_terms_container", - "false" - ) - - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/actionbar/component/ActionBarComponentPatch.kt b/src/main/kotlin/app/revanced/patches/music/actionbar/components/ActionBarComponentsPatch.kt similarity index 94% rename from src/main/kotlin/app/revanced/patches/music/actionbar/component/ActionBarComponentPatch.kt rename to src/main/kotlin/app/revanced/patches/music/actionbar/components/ActionBarComponentsPatch.kt index c80c5b906..f08bcbd75 100644 --- a/src/main/kotlin/app/revanced/patches/music/actionbar/component/ActionBarComponentPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/actionbar/components/ActionBarComponentsPatch.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.actionbar.component +package app.revanced.patches.music.actionbar.components import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.extensions.InstructionExtensions.addInstruction @@ -6,8 +6,8 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWith import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.music.actionbar.component.fingerprints.ActionBarComponentFingerprint -import app.revanced.patches.music.actionbar.component.fingerprints.LikeDislikeContainerFingerprint +import app.revanced.patches.music.actionbar.components.fingerprints.ActionBarComponentFingerprint +import app.revanced.patches.music.actionbar.components.fingerprints.LikeDislikeContainerFingerprint import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.music.utils.integrations.Constants.ACTIONBAR_CLASS_DESCRIPTOR import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch @@ -29,8 +29,8 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction import kotlin.math.min @Suppress("unused") -object ActionBarComponentPatch : BaseBytecodePatch( - name = "Hide action bar component", +object ActionBarComponentsPatch : BaseBytecodePatch( + name = "Hide action bar components", description = "Adds options to hide action bar components and replace the offline download button with an external download button.", dependencies = setOf( SettingsPatch::class, @@ -53,7 +53,7 @@ object ActionBarComponentPatch : BaseBytecodePatch( addInstruction( addViewIndex + 1, - "invoke-static {v$addViewRegister}, $ACTIONBAR_CLASS_DESCRIPTOR->hookDownloadButton(Landroid/view/View;)V" + "invoke-static {v$addViewRegister}, $ACTIONBAR_CLASS_DESCRIPTOR->inAppDownloadButtonOnClick(Landroid/view/View;)V" ) // hide action button label @@ -132,7 +132,7 @@ object ActionBarComponentPatch : BaseBytecodePatch( SettingsPatch.addSwitchPreference( CategoryType.ACTION_BAR, - "revanced_hide_action_button_add_to_playlist", + "revanced_hide_action_button_like_dislike", "false" ) SettingsPatch.addSwitchPreference( @@ -140,26 +140,16 @@ object ActionBarComponentPatch : BaseBytecodePatch( "revanced_hide_action_button_comment", "false" ) + SettingsPatch.addSwitchPreference( + CategoryType.ACTION_BAR, + "revanced_hide_action_button_add_to_playlist", + "false" + ) SettingsPatch.addSwitchPreference( CategoryType.ACTION_BAR, "revanced_hide_action_button_download", "false" ) - SettingsPatch.addSwitchPreference( - CategoryType.ACTION_BAR, - "revanced_hide_action_button_label", - "false" - ) - SettingsPatch.addSwitchPreference( - CategoryType.ACTION_BAR, - "revanced_hide_action_button_like_dislike", - "false" - ) - SettingsPatch.addSwitchPreference( - CategoryType.ACTION_BAR, - "revanced_hide_action_button_radio", - "false" - ) SettingsPatch.addSwitchPreference( CategoryType.ACTION_BAR, "revanced_hide_action_button_share", @@ -167,13 +157,23 @@ object ActionBarComponentPatch : BaseBytecodePatch( ) SettingsPatch.addSwitchPreference( CategoryType.ACTION_BAR, - "revanced_hook_action_button_download", + "revanced_hide_action_button_radio", + "false" + ) + SettingsPatch.addSwitchPreference( + CategoryType.ACTION_BAR, + "revanced_hide_action_button_label", + "false" + ) + SettingsPatch.addSwitchPreference( + CategoryType.ACTION_BAR, + "revanced_external_downloader_action", "false" ) SettingsPatch.addPreferenceWithIntent( CategoryType.ACTION_BAR, "revanced_external_downloader_package_name", - "revanced_hook_action_button_download" + "revanced_external_downloader_action" ) } diff --git a/src/main/kotlin/app/revanced/patches/music/actionbar/component/fingerprints/ActionBarComponentFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/actionbar/components/fingerprints/ActionBarComponentFingerprint.kt similarity index 89% rename from src/main/kotlin/app/revanced/patches/music/actionbar/component/fingerprints/ActionBarComponentFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/actionbar/components/fingerprints/ActionBarComponentFingerprint.kt index 7978eb4b0..de2ac50ad 100644 --- a/src/main/kotlin/app/revanced/patches/music/actionbar/component/fingerprints/ActionBarComponentFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/actionbar/components/fingerprints/ActionBarComponentFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.actionbar.component.fingerprints +package app.revanced.patches.music.actionbar.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.util.fingerprint.LiteralValueFingerprint diff --git a/src/main/kotlin/app/revanced/patches/music/actionbar/component/fingerprints/LikeDislikeContainerFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/actionbar/components/fingerprints/LikeDislikeContainerFingerprint.kt similarity index 86% rename from src/main/kotlin/app/revanced/patches/music/actionbar/component/fingerprints/LikeDislikeContainerFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/actionbar/components/fingerprints/LikeDislikeContainerFingerprint.kt index 7ec66d0e8..d507f7a5b 100644 --- a/src/main/kotlin/app/revanced/patches/music/actionbar/component/fingerprints/LikeDislikeContainerFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/actionbar/components/fingerprints/LikeDislikeContainerFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.actionbar.component.fingerprints +package app.revanced.patches.music.actionbar.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.LikeDislikeContainer diff --git a/src/main/kotlin/app/revanced/patches/music/ads/general/GeneralAdsPatch.kt b/src/main/kotlin/app/revanced/patches/music/ads/general/AdsPatch.kt similarity index 68% rename from src/main/kotlin/app/revanced/patches/music/ads/general/GeneralAdsPatch.kt rename to src/main/kotlin/app/revanced/patches/music/ads/general/AdsPatch.kt index a72b2892e..0f9252c60 100644 --- a/src/main/kotlin/app/revanced/patches/music/ads/general/GeneralAdsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/ads/general/AdsPatch.kt @@ -2,14 +2,19 @@ package app.revanced.patches.music.ads.general 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.addInstructionsWithLabels import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.util.smali.ExternalLabel +import app.revanced.patches.music.ads.general.fingerprints.AccountMenuFooterFingerprint import app.revanced.patches.music.ads.general.fingerprints.FloatingLayoutFingerprint +import app.revanced.patches.music.ads.general.fingerprints.GetPremiumTextViewFingerprint import app.revanced.patches.music.ads.general.fingerprints.InterstitialsContainerFingerprint +import app.revanced.patches.music.ads.general.fingerprints.MembershipSettingsFingerprint +import app.revanced.patches.music.ads.general.fingerprints.MembershipSettingsParentFingerprint import app.revanced.patches.music.ads.general.fingerprints.NotifierShelfFingerprint import app.revanced.patches.music.ads.general.fingerprints.ShowDialogCommandFingerprint -import app.revanced.patches.music.ads.music.MusicAdsPatch +import app.revanced.patches.music.navigation.components.NavigationBarComponentsPatch import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.music.utils.integrations.Constants.ADS_PATH import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH @@ -20,25 +25,35 @@ import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.Interst import app.revanced.patches.music.utils.settings.CategoryType import app.revanced.patches.music.utils.settings.SettingsPatch import app.revanced.patches.shared.litho.LithoFilterPatch +import app.revanced.util.getTargetIndex +import app.revanced.util.getTargetIndexWithReference +import app.revanced.util.getWalkerMethod import app.revanced.util.getWideLiteralInstructionIndex import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.resultOrThrow +import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction +import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction +import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction @Suppress("unused") -object GeneralAdsPatch : BaseBytecodePatch( - name = "Hide general ads", - description = "Adds options to hide general ads.", +object AdsPatch : BaseBytecodePatch( + name = "Hide ads", + description = "Adds options to hide ads.", dependencies = setOf( LithoFilterPatch::class, MusicAdsPatch::class, + NavigationBarComponentsPatch::class, // for 'Hide upgrade button' setting SettingsPatch::class, SharedResourceIdPatch::class ), compatiblePackages = COMPATIBLE_PACKAGE, fingerprints = setOf( + AccountMenuFooterFingerprint, FloatingLayoutFingerprint, + GetPremiumTextViewFingerprint, InterstitialsContainerFingerprint, + MembershipSettingsParentFingerprint, NotifierShelfFingerprint, ShowDialogCommandFingerprint ) @@ -58,10 +73,9 @@ object GeneralAdsPatch : BaseBytecodePatch( override fun execute(context: BytecodeContext) { LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR) - /** - * Hides fullscreen ads - * Non-litho view, used in some old clients. - */ + // region patch for hide fullscreen ads + + // non-litho view, used in some old clients InterstitialsContainerFingerprint.resultOrThrow().let { it.mutableMethod.apply { val targetIndex = getWideLiteralInstructionIndex(InterstitialsContainer) + 2 @@ -74,10 +88,7 @@ object GeneralAdsPatch : BaseBytecodePatch( } } - /** - * Hides fullscreen ads - * Litho view, used in 'ShowDialogCommandOuterClass' in innertube - */ + // litho view, used in 'ShowDialogCommandOuterClass' in innertube ShowDialogCommandFingerprint.resultOrThrow().let { it.mutableMethod.apply { // In this method, custom dialog is created and shown. @@ -127,9 +138,10 @@ object GeneralAdsPatch : BaseBytecodePatch( } } - /** - * Hides premium promotion popup - */ + // endregion + + // region patch for hide premium promotion popup + FloatingLayoutFingerprint.resultOrThrow().let { it.mutableMethod.apply { val targetIndex = getWideLiteralInstructionIndex(FloatingLayout) + 2 @@ -142,9 +154,10 @@ object GeneralAdsPatch : BaseBytecodePatch( } } - /** - * Hides premium renewal banner - */ + // endregion + + // region patch for hide premium renewal banner + NotifierShelfFingerprint.resultOrThrow().let { it.mutableMethod.apply { val linearLayoutIndex = getWideLiteralInstructionIndex(ButtonContainer) + 3 @@ -158,6 +171,59 @@ object GeneralAdsPatch : BaseBytecodePatch( } } + // endregion + + // region patch for hide get premium + + // get premium button at the top of the account switching menu + GetPremiumTextViewFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val insertIndex = it.scanResult.patternScanResult!!.startIndex + val register = getInstruction(insertIndex).registerA + + addInstruction( + insertIndex + 1, + "const/4 v$register, 0x0" + ) + } + } + + // get premium button at the bottom of the account switching menu + AccountMenuFooterFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val constIndex = getWideLiteralInstructionIndex(SharedResourceIdPatch.PrivacyTosFooter) + val walkerIndex = getTargetIndex(constIndex + 2, Opcode.INVOKE_VIRTUAL) + val viewIndex = getTargetIndex(constIndex, Opcode.IGET_OBJECT) + val viewReference = getInstruction(viewIndex).reference.toString() + + val walkerMethod = getWalkerMethod(context, walkerIndex) + walkerMethod.apply { + val insertIndex = getTargetIndexWithReference(viewReference) + val nullCheckIndex = getTargetIndex(insertIndex - 1, Opcode.IF_NEZ) + val nullCheckRegister = getInstruction(nullCheckIndex).registerA + + addInstruction( + nullCheckIndex, + "const/4 v$nullCheckRegister, 0x0" + ) + } + } + } + + // premium membership menu in settings + MembershipSettingsFingerprint.resolve( + context, + MembershipSettingsParentFingerprint.resultOrThrow().classDef + ) + MembershipSettingsFingerprint.resultOrThrow().mutableMethod.addInstructions( + 0, """ + const/4 v0, 0x0 + return-object v0 + """ + ) + + // endregion + SettingsPatch.addSwitchPreference( CategoryType.ADS, "revanced_hide_fullscreen_ads", @@ -175,7 +241,7 @@ object GeneralAdsPatch : BaseBytecodePatch( ) SettingsPatch.addSwitchPreference( CategoryType.ADS, - "revanced_hide_paid_promotion", + "revanced_hide_paid_promotion_label", "true" ) SettingsPatch.addSwitchPreference( diff --git a/src/main/kotlin/app/revanced/patches/music/ads/music/MusicAdsPatch.kt b/src/main/kotlin/app/revanced/patches/music/ads/general/MusicAdsPatch.kt similarity index 82% rename from src/main/kotlin/app/revanced/patches/music/ads/music/MusicAdsPatch.kt rename to src/main/kotlin/app/revanced/patches/music/ads/general/MusicAdsPatch.kt index a193cf29b..ad8ee8fda 100644 --- a/src/main/kotlin/app/revanced/patches/music/ads/music/MusicAdsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/ads/general/MusicAdsPatch.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.ads.music +package app.revanced.patches.music.ads.general import app.revanced.patches.music.utils.integrations.Constants.ADS_PATH import app.revanced.patches.shared.ads.BaseAdsPatch diff --git a/src/main/kotlin/app/revanced/patches/music/misc/premium/fingerprints/AccountMenuFooterFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/ads/general/fingerprints/AccountMenuFooterFingerprint.kt similarity index 91% rename from src/main/kotlin/app/revanced/patches/music/misc/premium/fingerprints/AccountMenuFooterFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/ads/general/fingerprints/AccountMenuFooterFingerprint.kt index 18bb5b5de..0ddd4bf72 100644 --- a/src/main/kotlin/app/revanced/patches/music/misc/premium/fingerprints/AccountMenuFooterFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/ads/general/fingerprints/AccountMenuFooterFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.misc.premium.fingerprints +package app.revanced.patches.music.ads.general.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.PrivacyTosFooter diff --git a/src/main/kotlin/app/revanced/patches/music/misc/premium/fingerprints/HideGetPremiumFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/ads/general/fingerprints/GetPremiumTextViewFingerprint.kt similarity index 82% rename from src/main/kotlin/app/revanced/patches/music/misc/premium/fingerprints/HideGetPremiumFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/ads/general/fingerprints/GetPremiumTextViewFingerprint.kt index c5c1c7dc7..9fff52bdf 100644 --- a/src/main/kotlin/app/revanced/patches/music/misc/premium/fingerprints/HideGetPremiumFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/ads/general/fingerprints/GetPremiumTextViewFingerprint.kt @@ -1,11 +1,11 @@ -package app.revanced.patches.music.misc.premium.fingerprints +package app.revanced.patches.music.ads.general.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 HideGetPremiumFingerprint : MethodFingerprint( +internal object GetPremiumTextViewFingerprint : MethodFingerprint( returnType = "V", accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, parameters = emptyList(), diff --git a/src/main/kotlin/app/revanced/patches/music/misc/premium/fingerprints/MembershipSettingsFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/ads/general/fingerprints/MembershipSettingsFingerprint.kt similarity index 85% rename from src/main/kotlin/app/revanced/patches/music/misc/premium/fingerprints/MembershipSettingsFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/ads/general/fingerprints/MembershipSettingsFingerprint.kt index cc5a264f0..af3434c7f 100644 --- a/src/main/kotlin/app/revanced/patches/music/misc/premium/fingerprints/MembershipSettingsFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/ads/general/fingerprints/MembershipSettingsFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.misc.premium.fingerprints +package app.revanced.patches.music.ads.general.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/music/misc/premium/fingerprints/MembershipSettingsParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/ads/general/fingerprints/MembershipSettingsParentFingerprint.kt similarity index 86% rename from src/main/kotlin/app/revanced/patches/music/misc/premium/fingerprints/MembershipSettingsParentFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/ads/general/fingerprints/MembershipSettingsParentFingerprint.kt index 676ab6bb1..54f428559 100644 --- a/src/main/kotlin/app/revanced/patches/music/misc/premium/fingerprints/MembershipSettingsParentFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/ads/general/fingerprints/MembershipSettingsParentFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.misc.premium.fingerprints +package app.revanced.patches.music.ads.general.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/music/flyoutmenu/components/FlyoutMenuComponentsPatch.kt b/src/main/kotlin/app/revanced/patches/music/flyoutmenu/components/FlyoutMenuComponentsPatch.kt new file mode 100644 index 000000000..4320d7be8 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/flyoutmenu/components/FlyoutMenuComponentsPatch.kt @@ -0,0 +1,420 @@ +package app.revanced.patches.music.flyoutmenu.components + +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.addInstructionsWithLabels +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.patch.PatchException +import app.revanced.patcher.util.smali.ExternalLabel +import app.revanced.patches.music.flyoutmenu.components.fingerprints.DialogSolidFingerprint +import app.revanced.patches.music.flyoutmenu.components.fingerprints.EndButtonsContainerFingerprint +import app.revanced.patches.music.flyoutmenu.components.fingerprints.MenuItemFingerprint +import app.revanced.patches.music.flyoutmenu.components.fingerprints.SleepTimerFingerprint +import app.revanced.patches.music.flyoutmenu.components.fingerprints.TouchOutsideFingerprint +import app.revanced.patches.music.flyoutmenu.components.fingerprints.TrimSilenceConfigFingerprint +import app.revanced.patches.music.flyoutmenu.components.fingerprints.TrimSilenceSwitchFingerprint +import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE +import app.revanced.patches.music.utils.flyoutmenu.FlyoutMenuHookPatch +import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH +import app.revanced.patches.music.utils.integrations.Constants.FLYOUT_CLASS_DESCRIPTOR +import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch +import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.EndButtonsContainer +import app.revanced.patches.music.utils.settings.CategoryType +import app.revanced.patches.music.utils.settings.SettingsPatch +import app.revanced.patches.music.utils.videotype.VideoTypeHookPatch +import app.revanced.patches.music.video.information.VideoInformationPatch +import app.revanced.patches.shared.litho.LithoFilterPatch +import app.revanced.util.getTargetIndex +import app.revanced.util.getTargetIndexWithMethodReferenceName +import app.revanced.util.getWalkerMethod +import app.revanced.util.getWideLiteralInstructionIndex +import app.revanced.util.indexOfFirstInstruction +import app.revanced.util.literalInstructionBooleanHook +import app.revanced.util.patch.BaseBytecodePatch +import app.revanced.util.resultOrThrow +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.ReferenceInstruction +import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction +import com.android.tools.smali.dexlib2.iface.reference.MethodReference + +@Suppress("unused") +object FlyoutMenuComponentsPatch : BaseBytecodePatch( + name = "Flyout menu components", + description = "Adds options to hide or change flyout menu components.", + dependencies = setOf( + FlyoutMenuComponentsResourcePatch::class, + FlyoutMenuHookPatch::class, + LithoFilterPatch::class, + SettingsPatch::class, + SharedResourceIdPatch::class, + VideoInformationPatch::class, + VideoTypeHookPatch::class + ), + compatiblePackages = COMPATIBLE_PACKAGE, + fingerprints = setOf( + DialogSolidFingerprint, + EndButtonsContainerFingerprint, + MenuItemFingerprint, + SleepTimerFingerprint, + TouchOutsideFingerprint, + TrimSilenceConfigFingerprint, + TrimSilenceSwitchFingerprint + ) +) { + private const val FILTER_CLASS_DESCRIPTOR = + "$COMPONENTS_PATH/PlayerFlyoutMenuFilter;" + + override fun execute(context: BytecodeContext) { + var trimSilenceIncluded = false + + // region patch for enable compact dialog + + DialogSolidFingerprint.resultOrThrow().let { + val walkerMethod = it.getWalkerMethod(context, it.scanResult.patternScanResult!!.endIndex) + walkerMethod.addInstructions( + 2, """ + invoke-static {p0}, $FLYOUT_CLASS_DESCRIPTOR->enableCompactDialog(I)I + move-result p0 + """ + ) + } + + // endregion + + // region patch for enable trim silence + + TrimSilenceConfigFingerprint.result?.let { + TrimSilenceConfigFingerprint.literalInstructionBooleanHook( + 45619123, + "$FLYOUT_CLASS_DESCRIPTOR->enableTrimSilence(Z)Z" + ) + + TrimSilenceSwitchFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val constIndex = getWideLiteralInstructionIndex(SharedResourceIdPatch.TrimSilenceSwitch) + val onCheckedChangedListenerIndex = getTargetIndex(constIndex, Opcode.INVOKE_DIRECT) + val onCheckedChangedListenerReference = getInstruction(onCheckedChangedListenerIndex).reference + val onCheckedChangedListenerDefiningClass = (onCheckedChangedListenerReference as MethodReference).definingClass + val onCheckedChangedListenerClass = + context.findClass(onCheckedChangedListenerDefiningClass)!!.mutableClass + + onCheckedChangedListenerClass.methods.find { method -> method.name == "onCheckedChanged" } + ?.apply { + val walkerIndex = indexOfFirstInstruction { + val reference = ((this as? ReferenceInstruction)?.reference as? MethodReference) + + opcode == Opcode.INVOKE_VIRTUAL + && reference?.returnType == "V" + && reference.parameterTypes.size == 1 + && reference.parameterTypes[0] == "Z" + } + getWalkerMethod(context, walkerIndex).apply { + val insertIndex = getTargetIndex(Opcode.MOVE_RESULT) + val insertRegister = getInstruction(insertIndex).registerA + + addInstructions( + insertIndex + 1, """ + invoke-static {v$insertRegister}, $FLYOUT_CLASS_DESCRIPTOR->enableTrimSilenceSwitch(Z)Z + move-result v$insertRegister + """ + ) + } + } ?: throw PatchException("onClickClass not found!") + } + } + + trimSilenceIncluded = true + } + + // endregion + + // region patch for hide flyout menu components and replace menu + + MenuItemFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val freeIndex = getTargetIndex(Opcode.OR_INT_LIT16) + val textViewIndex = it.scanResult.patternScanResult!!.startIndex + val imageViewIndex = it.scanResult.patternScanResult!!.endIndex + + val freeRegister = + getInstruction(freeIndex).registerA + val textViewRegister = + getInstruction(textViewIndex).registerA + val imageViewRegister = + getInstruction(imageViewIndex).registerA + + val enumIndex = indexOfFirstInstruction { + opcode == Opcode.INVOKE_STATIC + && (this as? ReferenceInstruction)?.reference.toString().contains("(I)L") + } + 1 + val enumRegister = getInstruction(enumIndex).registerA + + addInstructionsWithLabels( + enumIndex + 1, """ + invoke-static {v$enumRegister, v$textViewRegister, v$imageViewRegister}, $FLYOUT_CLASS_DESCRIPTOR->replaceComponents(Ljava/lang/Enum;Landroid/widget/TextView;Landroid/widget/ImageView;)V + invoke-static {v$enumRegister}, $FLYOUT_CLASS_DESCRIPTOR->hideComponents(Ljava/lang/Enum;)Z + move-result v$freeRegister + if-nez v$freeRegister, :hide + """, ExternalLabel("hide", getInstruction(implementation!!.instructions.size - 1)) + ) + } + } + + TouchOutsideFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val setOnClickListenerIndex = getTargetIndexWithMethodReferenceName("setOnClickListener") + val setOnClickListenerRegister = getInstruction(setOnClickListenerIndex).registerC + + addInstruction( + setOnClickListenerIndex + 1, + "invoke-static {v$setOnClickListenerRegister}, $FLYOUT_CLASS_DESCRIPTOR->setTouchOutSideView(Landroid/view/View;)V" + ) + } + } + + EndButtonsContainerFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val startIndex = getWideLiteralInstructionIndex(EndButtonsContainer) + val targetIndex = getTargetIndex(startIndex, Opcode.MOVE_RESULT_OBJECT) + val targetRegister = getInstruction(targetIndex).registerA + + addInstruction( + targetIndex + 1, + "invoke-static {v$targetRegister}, $FLYOUT_CLASS_DESCRIPTOR->hideLikeDislikeContainer(Landroid/view/View;)V" + ) + } + } + + // endregion + + // region patch for enable sleep timer + + /** + * Forces sleep timer menu to be enabled. + * This method may be desperate in the future. + */ + SleepTimerFingerprint.result?.let { + it.mutableMethod.apply { + val insertIndex = implementation!!.instructions.size - 1 + val targetRegister = getInstruction(insertIndex).registerA + + addInstruction( + insertIndex, + "const/4 v$targetRegister, 0x1" + ) + } + } + + // endregion + + SettingsPatch.addSwitchPreference( + CategoryType.FLYOUT, + "revanced_enable_compact_dialog", + "true" + ) + if (trimSilenceIncluded) { + SettingsPatch.addSwitchPreference( + CategoryType.FLYOUT, + "revanced_enable_trim_silence", + "true" + ) + } + SettingsPatch.addSwitchPreference( + CategoryType.FLYOUT, + "revanced_hide_flyout_menu_like_dislike", + "false", + false + ) + if (SettingsPatch.upward0636) { + LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR) + + SettingsPatch.addSwitchPreference( + CategoryType.FLYOUT, + "revanced_hide_flyout_menu_3_column_component", + "false", + false + ) + } + SettingsPatch.addSwitchPreference( + CategoryType.FLYOUT, + "revanced_hide_flyout_menu_add_to_queue", + "false", + false + ) + SettingsPatch.addSwitchPreference( + CategoryType.FLYOUT, + "revanced_hide_flyout_menu_captions", + "false", + false + ) + SettingsPatch.addSwitchPreference( + CategoryType.FLYOUT, + "revanced_hide_flyout_menu_delete_playlist", + "false", + false + ) + SettingsPatch.addSwitchPreference( + CategoryType.FLYOUT, + "revanced_hide_flyout_menu_dismiss_queue", + "false", + false + ) + SettingsPatch.addSwitchPreference( + CategoryType.FLYOUT, + "revanced_hide_flyout_menu_download", + "false", + false + ) + SettingsPatch.addSwitchPreference( + CategoryType.FLYOUT, + "revanced_hide_flyout_menu_edit_playlist", + "false", + false + ) + SettingsPatch.addSwitchPreference( + CategoryType.FLYOUT, + "revanced_hide_flyout_menu_go_to_album", + "false", + false + ) + SettingsPatch.addSwitchPreference( + CategoryType.FLYOUT, + "revanced_hide_flyout_menu_go_to_artist", + "false", + false + ) + SettingsPatch.addSwitchPreference( + CategoryType.FLYOUT, + "revanced_hide_flyout_menu_go_to_episode", + "false", + false + ) + SettingsPatch.addSwitchPreference( + CategoryType.FLYOUT, + "revanced_hide_flyout_menu_go_to_podcast", + "false", + false + ) + SettingsPatch.addSwitchPreference( + CategoryType.FLYOUT, + "revanced_hide_flyout_menu_help", + "false", + false + ) + SettingsPatch.addSwitchPreference( + CategoryType.FLYOUT, + "revanced_hide_flyout_menu_play_next", + "false", + false + ) + SettingsPatch.addSwitchPreference( + CategoryType.FLYOUT, + "revanced_hide_flyout_menu_quality", + "false", + false + ) + SettingsPatch.addSwitchPreference( + CategoryType.FLYOUT, + "revanced_hide_flyout_menu_remove_from_library", + "false", + false + ) + SettingsPatch.addSwitchPreference( + CategoryType.FLYOUT, + "revanced_hide_flyout_menu_remove_from_playlist", + "false", + false + ) + SettingsPatch.addSwitchPreference( + CategoryType.FLYOUT, + "revanced_hide_flyout_menu_report", + "false", + false + ) + SettingsPatch.addSwitchPreference( + CategoryType.FLYOUT, + "revanced_hide_flyout_menu_save_episode_for_later", + "false", + false + ) + SettingsPatch.addSwitchPreference( + CategoryType.FLYOUT, + "revanced_hide_flyout_menu_save_to_library", + "false", + false + ) + SettingsPatch.addSwitchPreference( + CategoryType.FLYOUT, + "revanced_hide_flyout_menu_save_to_playlist", + "false", + false + ) + SettingsPatch.addSwitchPreference( + CategoryType.FLYOUT, + "revanced_hide_flyout_menu_share", + "false", + false + ) + SettingsPatch.addSwitchPreference( + CategoryType.FLYOUT, + "revanced_hide_flyout_menu_shuffle_play", + "false", + false + ) + SettingsPatch.addSwitchPreference( + CategoryType.FLYOUT, + "revanced_hide_flyout_menu_sleep_timer", + "false", + false + ) + SettingsPatch.addSwitchPreference( + CategoryType.FLYOUT, + "revanced_hide_flyout_menu_start_radio", + "false", + false + ) + SettingsPatch.addSwitchPreference( + CategoryType.FLYOUT, + "revanced_hide_flyout_menu_stats_for_nerds", + "false", + false + ) + SettingsPatch.addSwitchPreference( + CategoryType.FLYOUT, + "revanced_hide_flyout_menu_subscribe", + "false", + false + ) + SettingsPatch.addSwitchPreference( + CategoryType.FLYOUT, + "revanced_hide_flyout_menu_view_song_credit", + "false", + false + ) + SettingsPatch.addSwitchPreference( + CategoryType.FLYOUT, + "revanced_replace_flyout_menu_dismiss_queue", + "false" + ) + SettingsPatch.addSwitchPreference( + CategoryType.FLYOUT, + "revanced_replace_flyout_menu_dismiss_queue_continue_watch", + "true", + "revanced_replace_flyout_menu_dismiss_queue" + ) + SettingsPatch.addSwitchPreference( + CategoryType.FLYOUT, + "revanced_replace_flyout_menu_report", + "true" + ) + SettingsPatch.addSwitchPreference( + CategoryType.FLYOUT, + "revanced_replace_flyout_menu_report_only_player", + "true", + "revanced_replace_flyout_menu_report" + ) + } +} diff --git a/src/main/kotlin/app/revanced/patches/music/flyoutpanel/replace/ReplaceReportResourcePatch.kt b/src/main/kotlin/app/revanced/patches/music/flyoutmenu/components/FlyoutMenuComponentsResourcePatch.kt similarity index 87% rename from src/main/kotlin/app/revanced/patches/music/flyoutpanel/replace/ReplaceReportResourcePatch.kt rename to src/main/kotlin/app/revanced/patches/music/flyoutmenu/components/FlyoutMenuComponentsResourcePatch.kt index 8c4a9de90..96daa0e75 100644 --- a/src/main/kotlin/app/revanced/patches/music/flyoutpanel/replace/ReplaceReportResourcePatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/flyoutmenu/components/FlyoutMenuComponentsResourcePatch.kt @@ -1,11 +1,11 @@ -package app.revanced.patches.music.flyoutpanel.replace +package app.revanced.patches.music.flyoutmenu.components import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.patch.ResourcePatch import app.revanced.util.ResourceGroup import app.revanced.util.copyResources -object ReplaceReportResourcePatch : ResourcePatch() { +object FlyoutMenuComponentsResourcePatch : ResourcePatch() { override fun execute(context: ResourceContext) { fun copyResources(resourceGroups: List) { diff --git a/src/main/kotlin/app/revanced/patches/music/flyoutpanel/compactdialog/fingerprints/DialogSolidFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/flyoutmenu/components/fingerprints/DialogSolidFingerprint.kt similarity index 89% rename from src/main/kotlin/app/revanced/patches/music/flyoutpanel/compactdialog/fingerprints/DialogSolidFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/flyoutmenu/components/fingerprints/DialogSolidFingerprint.kt index 5d47af14a..9d8ad020d 100644 --- a/src/main/kotlin/app/revanced/patches/music/flyoutpanel/compactdialog/fingerprints/DialogSolidFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/flyoutmenu/components/fingerprints/DialogSolidFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.flyoutpanel.compactdialog.fingerprints +package app.revanced.patches.music.flyoutmenu.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.DialogSolid diff --git a/src/main/kotlin/app/revanced/patches/music/flyoutpanel/component/fingerprints/EndButtonsContainerFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/flyoutmenu/components/fingerprints/EndButtonsContainerFingerprint.kt similarity index 82% rename from src/main/kotlin/app/revanced/patches/music/flyoutpanel/component/fingerprints/EndButtonsContainerFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/flyoutmenu/components/fingerprints/EndButtonsContainerFingerprint.kt index 76162f1c2..c06ff0ea8 100644 --- a/src/main/kotlin/app/revanced/patches/music/flyoutpanel/component/fingerprints/EndButtonsContainerFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/flyoutmenu/components/fingerprints/EndButtonsContainerFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.flyoutpanel.component.fingerprints +package app.revanced.patches.music.flyoutmenu.components.fingerprints import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.EndButtonsContainer import app.revanced.util.fingerprint.LiteralValueFingerprint diff --git a/src/main/kotlin/app/revanced/patches/music/flyoutpanel/shared/fingerprints/MenuItemFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/flyoutmenu/components/fingerprints/MenuItemFingerprint.kt similarity index 88% rename from src/main/kotlin/app/revanced/patches/music/flyoutpanel/shared/fingerprints/MenuItemFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/flyoutmenu/components/fingerprints/MenuItemFingerprint.kt index 53998416c..33fcbd3a1 100644 --- a/src/main/kotlin/app/revanced/patches/music/flyoutpanel/shared/fingerprints/MenuItemFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/flyoutmenu/components/fingerprints/MenuItemFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.flyoutpanel.shared.fingerprints +package app.revanced.patches.music.flyoutmenu.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/music/flyoutpanel/component/fingerprints/SleepTimerFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/flyoutmenu/components/fingerprints/SleepTimerFingerprint.kt similarity index 77% rename from src/main/kotlin/app/revanced/patches/music/flyoutpanel/component/fingerprints/SleepTimerFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/flyoutmenu/components/fingerprints/SleepTimerFingerprint.kt index ac91d20a8..79e58c36f 100644 --- a/src/main/kotlin/app/revanced/patches/music/flyoutpanel/component/fingerprints/SleepTimerFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/flyoutmenu/components/fingerprints/SleepTimerFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.flyoutpanel.component.fingerprints +package app.revanced.patches.music.flyoutmenu.components.fingerprints import app.revanced.util.fingerprint.LiteralValueFingerprint diff --git a/src/main/kotlin/app/revanced/patches/music/flyoutpanel/replace/fingerprints/TouchOutsideFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/flyoutmenu/components/fingerprints/TouchOutsideFingerprint.kt similarity index 80% rename from src/main/kotlin/app/revanced/patches/music/flyoutpanel/replace/fingerprints/TouchOutsideFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/flyoutmenu/components/fingerprints/TouchOutsideFingerprint.kt index d3107516b..a53a0fbc5 100644 --- a/src/main/kotlin/app/revanced/patches/music/flyoutpanel/replace/fingerprints/TouchOutsideFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/flyoutmenu/components/fingerprints/TouchOutsideFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.flyoutpanel.replace.fingerprints +package app.revanced.patches.music.flyoutmenu.components.fingerprints import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.TouchOutside import app.revanced.util.fingerprint.LiteralValueFingerprint diff --git a/src/main/kotlin/app/revanced/patches/music/flyoutmenu/components/fingerprints/TrimSilenceConfigFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/flyoutmenu/components/fingerprints/TrimSilenceConfigFingerprint.kt new file mode 100644 index 000000000..b33df48b6 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/flyoutmenu/components/fingerprints/TrimSilenceConfigFingerprint.kt @@ -0,0 +1,8 @@ +package app.revanced.patches.music.flyoutmenu.components.fingerprints + +import app.revanced.util.fingerprint.LiteralValueFingerprint + +object TrimSilenceConfigFingerprint : LiteralValueFingerprint( + returnType = "Z", + literalSupplier = { 45619123 } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/flyoutmenu/components/fingerprints/TrimSilenceSwitchFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/flyoutmenu/components/fingerprints/TrimSilenceSwitchFingerprint.kt new file mode 100644 index 000000000..1330ccdc5 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/flyoutmenu/components/fingerprints/TrimSilenceSwitchFingerprint.kt @@ -0,0 +1,13 @@ +package app.revanced.patches.music.flyoutmenu.components.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.TrimSilenceSwitch +import app.revanced.util.fingerprint.LiteralValueFingerprint +import com.android.tools.smali.dexlib2.AccessFlags + +object TrimSilenceSwitchFingerprint : LiteralValueFingerprint( + returnType = "Landroid/view/View;", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + literalSupplier = { TrimSilenceSwitch } +) + diff --git a/src/main/kotlin/app/revanced/patches/music/flyoutpanel/compactdialog/CompactDialogPatch.kt b/src/main/kotlin/app/revanced/patches/music/flyoutpanel/compactdialog/CompactDialogPatch.kt deleted file mode 100644 index 3348a0166..000000000 --- a/src/main/kotlin/app/revanced/patches/music/flyoutpanel/compactdialog/CompactDialogPatch.kt +++ /dev/null @@ -1,44 +0,0 @@ -package app.revanced.patches.music.flyoutpanel.compactdialog - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patches.music.flyoutpanel.compactdialog.fingerprints.DialogSolidFingerprint -import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.music.utils.integrations.Constants.FLYOUT_CLASS_DESCRIPTOR -import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch -import app.revanced.patches.music.utils.settings.CategoryType -import app.revanced.patches.music.utils.settings.SettingsPatch -import app.revanced.util.getWalkerMethod -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow - -@Suppress("unused") -object CompactDialogPatch : BaseBytecodePatch( - name = "Enable compact dialog", - description = "Adds an option to enable the compact flyout menu on phones.", - dependencies = setOf( - SettingsPatch::class, - SharedResourceIdPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(DialogSolidFingerprint) -) { - override fun execute(context: BytecodeContext) { - DialogSolidFingerprint.resultOrThrow().let { - val walkerMethod = it.getWalkerMethod(context, it.scanResult.patternScanResult!!.endIndex) - walkerMethod.addInstructions( - 2, """ - invoke-static {p0}, $FLYOUT_CLASS_DESCRIPTOR->enableCompactDialog(I)I - move-result p0 - """ - ) - } - - SettingsPatch.addSwitchPreference( - CategoryType.FLYOUT, - "revanced_enable_compact_dialog", - "true" - ) - - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/flyoutpanel/component/FlyoutPanelPatch.kt b/src/main/kotlin/app/revanced/patches/music/flyoutpanel/component/FlyoutPanelPatch.kt deleted file mode 100644 index 63c5ec136..000000000 --- a/src/main/kotlin/app/revanced/patches/music/flyoutpanel/component/FlyoutPanelPatch.kt +++ /dev/null @@ -1,248 +0,0 @@ -package app.revanced.patches.music.flyoutpanel.component - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patches.music.flyoutpanel.component.fingerprints.EndButtonsContainerFingerprint -import app.revanced.patches.music.flyoutpanel.component.fingerprints.SleepTimerFingerprint -import app.revanced.patches.music.flyoutpanel.shared.FlyoutPanelMenuItemPatch -import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH -import app.revanced.patches.music.utils.integrations.Constants.FLYOUT_CLASS_DESCRIPTOR -import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch -import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.EndButtonsContainer -import app.revanced.patches.music.utils.settings.CategoryType -import app.revanced.patches.music.utils.settings.SettingsPatch -import app.revanced.patches.shared.litho.LithoFilterPatch -import app.revanced.util.getTargetIndex -import app.revanced.util.getWideLiteralInstructionIndex -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction - -@Suppress("unused") -object FlyoutPanelPatch : BaseBytecodePatch( - name = "Hide flyout panel", - description = "Adds options to hide flyout panel components.", - dependencies = setOf( - FlyoutPanelMenuItemPatch::class, - LithoFilterPatch::class, - SettingsPatch::class, - SharedResourceIdPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf( - EndButtonsContainerFingerprint, - SleepTimerFingerprint - ) -) { - private const val FILTER_CLASS_DESCRIPTOR = - "$COMPONENTS_PATH/PlayerFlyoutPanelsFilter;" - - override fun execute(context: BytecodeContext) { - FlyoutPanelMenuItemPatch.hideComponents() - - EndButtonsContainerFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val startIndex = getWideLiteralInstructionIndex(EndButtonsContainer) - val targetIndex = getTargetIndex(startIndex, Opcode.MOVE_RESULT_OBJECT) - val targetRegister = getInstruction(targetIndex).registerA - - addInstruction( - targetIndex + 1, - "invoke-static {v$targetRegister}, $FLYOUT_CLASS_DESCRIPTOR->hideLikeDislikeContainer(Landroid/view/View;)V" - ) - } - } - - /** - * Forces sleep timer menu to be enabled. - * This method may be desperate in the future. - */ - SleepTimerFingerprint.result?.let { - it.mutableMethod.apply { - val insertIndex = implementation!!.instructions.size - 1 - val targetRegister = getInstruction(insertIndex).registerA - - addInstruction( - insertIndex, - "const/4 v$targetRegister, 0x1" - ) - } - } - - if (SettingsPatch.upward0636) { - LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR) - - SettingsPatch.addSwitchPreference( - CategoryType.FLYOUT, - "revanced_hide_flyout_panel_3_column_component", - "false" - ) - } - - SettingsPatch.addSwitchPreference( - CategoryType.FLYOUT, - "revanced_hide_flyout_panel_add_to_queue", - "false", - false - ) - SettingsPatch.addSwitchPreference( - CategoryType.FLYOUT, - "revanced_hide_flyout_panel_captions", - "false", - false - ) - SettingsPatch.addSwitchPreference( - CategoryType.FLYOUT, - "revanced_hide_flyout_panel_delete_playlist", - "false", - false - ) - SettingsPatch.addSwitchPreference( - CategoryType.FLYOUT, - "revanced_hide_flyout_panel_dismiss_queue", - "false", - false - ) - SettingsPatch.addSwitchPreference( - CategoryType.FLYOUT, - "revanced_hide_flyout_panel_download", - "false", - false - ) - SettingsPatch.addSwitchPreference( - CategoryType.FLYOUT, - "revanced_hide_flyout_panel_edit_playlist", - "false", - false - ) - SettingsPatch.addSwitchPreference( - CategoryType.FLYOUT, - "revanced_hide_flyout_panel_go_to_album", - "false", - false - ) - SettingsPatch.addSwitchPreference( - CategoryType.FLYOUT, - "revanced_hide_flyout_panel_go_to_artist", - "false", - false - ) - SettingsPatch.addSwitchPreference( - CategoryType.FLYOUT, - "revanced_hide_flyout_panel_go_to_episode", - "false", - false - ) - SettingsPatch.addSwitchPreference( - CategoryType.FLYOUT, - "revanced_hide_flyout_panel_go_to_podcast", - "false", - false - ) - SettingsPatch.addSwitchPreference( - CategoryType.FLYOUT, - "revanced_hide_flyout_panel_help", - "false", - false - ) - SettingsPatch.addSwitchPreference( - CategoryType.FLYOUT, - "revanced_hide_flyout_panel_like_dislike", - "false", - false - ) - SettingsPatch.addSwitchPreference( - CategoryType.FLYOUT, - "revanced_hide_flyout_panel_play_next", - "false", - false - ) - SettingsPatch.addSwitchPreference( - CategoryType.FLYOUT, - "revanced_hide_flyout_panel_quality", - "false", - false - ) - SettingsPatch.addSwitchPreference( - CategoryType.FLYOUT, - "revanced_hide_flyout_panel_remove_from_library", - "false", - false - ) - SettingsPatch.addSwitchPreference( - CategoryType.FLYOUT, - "revanced_hide_flyout_panel_remove_from_playlist", - "false", - false - ) - SettingsPatch.addSwitchPreference( - CategoryType.FLYOUT, - "revanced_hide_flyout_panel_report", - "false", - false - ) - SettingsPatch.addSwitchPreference( - CategoryType.FLYOUT, - "revanced_hide_flyout_panel_save_episode_for_later", - "false", - false - ) - SettingsPatch.addSwitchPreference( - CategoryType.FLYOUT, - "revanced_hide_flyout_panel_save_to_library", - "false", - false - ) - SettingsPatch.addSwitchPreference( - CategoryType.FLYOUT, - "revanced_hide_flyout_panel_save_to_playlist", - "false", - false - ) - SettingsPatch.addSwitchPreference( - CategoryType.FLYOUT, - "revanced_hide_flyout_panel_share", - "false", - false - ) - SettingsPatch.addSwitchPreference( - CategoryType.FLYOUT, - "revanced_hide_flyout_panel_shuffle_play", - "false", - false - ) - SettingsPatch.addSwitchPreference( - CategoryType.FLYOUT, - "revanced_hide_flyout_panel_sleep_timer", - "false", - false - ) - SettingsPatch.addSwitchPreference( - CategoryType.FLYOUT, - "revanced_hide_flyout_panel_start_radio", - "false", - false - ) - SettingsPatch.addSwitchPreference( - CategoryType.FLYOUT, - "revanced_hide_flyout_panel_stats_for_nerds", - "false", - false - ) - SettingsPatch.addSwitchPreference( - CategoryType.FLYOUT, - "revanced_hide_flyout_panel_subscribe", - "false", - false - ) - SettingsPatch.addSwitchPreference( - CategoryType.FLYOUT, - "revanced_hide_flyout_panel_view_song_credit", - "false", - false - ) - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/flyoutpanel/replace/ReplaceDismissQueuePatch.kt b/src/main/kotlin/app/revanced/patches/music/flyoutpanel/replace/ReplaceDismissQueuePatch.kt deleted file mode 100644 index 960c213e8..000000000 --- a/src/main/kotlin/app/revanced/patches/music/flyoutpanel/replace/ReplaceDismissQueuePatch.kt +++ /dev/null @@ -1,38 +0,0 @@ -package app.revanced.patches.music.flyoutpanel.replace - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patches.music.flyoutpanel.shared.FlyoutPanelMenuItemPatch -import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.music.utils.settings.CategoryType -import app.revanced.patches.music.utils.settings.SettingsPatch -import app.revanced.patches.music.video.information.VideoInformationPatch -import app.revanced.util.patch.BaseBytecodePatch - -@Suppress("unused") -object ReplaceDismissQueuePatch : BaseBytecodePatch( - name = "Replace dismiss queue", - description = "Adds an option to replace \"Dismiss queue\" with \"Watch on YouTube\" in the flyout menu.", - dependencies = setOf( - FlyoutPanelMenuItemPatch::class, - SettingsPatch::class, - VideoInformationPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE -) { - override fun execute(context: BytecodeContext) { - FlyoutPanelMenuItemPatch.replaceComponents() - - SettingsPatch.addSwitchPreference( - CategoryType.FLYOUT, - "revanced_replace_flyout_panel_dismiss_queue", - "false" - ) - SettingsPatch.addSwitchPreference( - CategoryType.FLYOUT, - "revanced_replace_flyout_panel_dismiss_queue_continue_watch", - "true", - "revanced_replace_flyout_panel_dismiss_queue" - ) - - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/flyoutpanel/replace/ReplaceReportPatch.kt b/src/main/kotlin/app/revanced/patches/music/flyoutpanel/replace/ReplaceReportPatch.kt deleted file mode 100644 index b3f3c29f4..000000000 --- a/src/main/kotlin/app/revanced/patches/music/flyoutpanel/replace/ReplaceReportPatch.kt +++ /dev/null @@ -1,63 +0,0 @@ -package app.revanced.patches.music.flyoutpanel.replace - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patches.music.flyoutpanel.replace.fingerprints.TouchOutsideFingerprint -import app.revanced.patches.music.flyoutpanel.shared.FlyoutPanelMenuItemPatch -import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.music.utils.flyoutpanel.PlaybackSpeedFlyoutPanelHookPatch -import app.revanced.patches.music.utils.integrations.Constants.FLYOUT_CLASS_DESCRIPTOR -import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch -import app.revanced.patches.music.utils.settings.CategoryType -import app.revanced.patches.music.utils.settings.SettingsPatch -import app.revanced.patches.music.video.information.VideoInformationPatch -import app.revanced.util.getTargetIndexWithMethodReferenceName -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction - -@Suppress("unused") -object ReplaceReportPatch : BaseBytecodePatch( - name = "Replace report", - description = "Adds an option to replace \"Report\" with \"Playback speed\" in the flyout menu.", - dependencies = setOf( - FlyoutPanelMenuItemPatch::class, - PlaybackSpeedFlyoutPanelHookPatch::class, - ReplaceReportResourcePatch::class, - SettingsPatch::class, - SharedResourceIdPatch::class, - VideoInformationPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(TouchOutsideFingerprint) -) { - override fun execute(context: BytecodeContext) { - FlyoutPanelMenuItemPatch.replaceComponents() - - TouchOutsideFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val setOnClickListenerIndex = getTargetIndexWithMethodReferenceName("setOnClickListener") - val setOnClickListenerRegister = getInstruction(setOnClickListenerIndex).registerC - - addInstruction( - setOnClickListenerIndex + 1, - "sput-object v$setOnClickListenerRegister, $FLYOUT_CLASS_DESCRIPTOR->touchOutSideView:Landroid/view/View;" - ) - } - } - - SettingsPatch.addSwitchPreference( - CategoryType.FLYOUT, - "revanced_replace_flyout_panel_report", - "true" - ) - SettingsPatch.addSwitchPreference( - CategoryType.FLYOUT, - "revanced_replace_flyout_panel_report_only_player", - "true", - "revanced_replace_flyout_panel_report" - ) - - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/flyoutpanel/shared/FlyoutPanelMenuItemPatch.kt b/src/main/kotlin/app/revanced/patches/music/flyoutpanel/shared/FlyoutPanelMenuItemPatch.kt deleted file mode 100644 index c78c72b14..000000000 --- a/src/main/kotlin/app/revanced/patches/music/flyoutpanel/shared/FlyoutPanelMenuItemPatch.kt +++ /dev/null @@ -1,83 +0,0 @@ -package app.revanced.patches.music.flyoutpanel.shared - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.music.flyoutpanel.shared.fingerprints.MenuItemFingerprint -import app.revanced.patches.music.utils.integrations.Constants.FLYOUT_CLASS_DESCRIPTOR -import app.revanced.util.getTargetIndex -import app.revanced.util.indexOfFirstInstruction -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction -import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction -import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction -import kotlin.properties.Delegates - -object FlyoutPanelMenuItemPatch : BytecodePatch( - setOf(MenuItemFingerprint) -) { - private lateinit var menuItemMethod: MutableMethod - private var freeRegister by Delegates.notNull() - private var textViewRegister by Delegates.notNull() - private var imageViewRegister by Delegates.notNull() - private var instructionAdded = false - - override fun execute(context: BytecodeContext) { - MenuItemFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val freeIndex = getTargetIndex(Opcode.OR_INT_LIT16) - val textViewIndex = it.scanResult.patternScanResult!!.startIndex - val imageViewIndex = it.scanResult.patternScanResult!!.endIndex - - freeRegister = - getInstruction(freeIndex).registerA - textViewRegister = - getInstruction(textViewIndex).registerA - imageViewRegister = - getInstruction(imageViewIndex).registerA - - menuItemMethod = this - } - } - } - - private fun MutableMethod.getEnumIndex() = indexOfFirstInstruction { - opcode == Opcode.INVOKE_STATIC - && (this as? ReferenceInstruction)?.reference.toString().contains("(I)L") - } + 1 - - internal fun hideComponents() { - menuItemMethod.apply { - val enumIndex = getEnumIndex() - val enumRegister = getInstruction(enumIndex).registerA - - addInstructionsWithLabels( - enumIndex + 1, """ - invoke-static {v$enumRegister}, $FLYOUT_CLASS_DESCRIPTOR->hideComponents(Ljava/lang/Enum;)Z - move-result v$freeRegister - if-nez v$freeRegister, :hide - """, ExternalLabel("hide", getInstruction(implementation!!.instructions.size - 1)) - ) - } - } - - internal fun replaceComponents() { - if (!instructionAdded) { - menuItemMethod.apply { - val enumIndex = getEnumIndex() - val enumRegister = getInstruction(enumIndex).registerA - - addInstruction( - enumIndex + 1, - "invoke-static {v$enumRegister, v$textViewRegister, v$imageViewRegister}, $FLYOUT_CLASS_DESCRIPTOR->replaceComponents(Ljava/lang/Enum;Landroid/widget/TextView;Landroid/widget/ImageView;)V" - ) - } - instructionAdded = true - } - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/general/autocaptions/AutoCaptionsPatch.kt b/src/main/kotlin/app/revanced/patches/music/general/autocaptions/AutoCaptionsPatch.kt index 406bf59a6..f3efcaddc 100644 --- a/src/main/kotlin/app/revanced/patches/music/general/autocaptions/AutoCaptionsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/general/autocaptions/AutoCaptionsPatch.kt @@ -21,7 +21,7 @@ object AutoCaptionsPatch : BaseResourcePatch( ) { override fun execute(context: ResourceContext) { - VideoIdPatch.hookBackgroundPlayVideoId("$GENERAL_CLASS_DESCRIPTOR->newVideoStarted(Ljava/lang/String;)V") + VideoIdPatch.hookVideoId("$GENERAL_CLASS_DESCRIPTOR->newVideoStarted(Ljava/lang/String;)V") SettingsPatch.addSwitchPreference( CategoryType.GENERAL, diff --git a/src/main/kotlin/app/revanced/patches/music/general/buttonshelf/ButtonShelfPatch.kt b/src/main/kotlin/app/revanced/patches/music/general/buttonshelf/ButtonShelfPatch.kt deleted file mode 100644 index 5fc03c136..000000000 --- a/src/main/kotlin/app/revanced/patches/music/general/buttonshelf/ButtonShelfPatch.kt +++ /dev/null @@ -1,34 +0,0 @@ -package app.revanced.patches.music.general.buttonshelf - -import app.revanced.patcher.data.ResourceContext -import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH -import app.revanced.patches.music.utils.settings.CategoryType -import app.revanced.patches.music.utils.settings.SettingsPatch -import app.revanced.patches.shared.litho.LithoFilterPatch -import app.revanced.util.patch.BaseResourcePatch - -@Suppress("unused") -object ButtonShelfPatch : BaseResourcePatch( - name = "Hide button shelf", - description = "Adds an option to hide the button shelf from the homepage and explore tab.", - dependencies = setOf( - LithoFilterPatch::class, - SettingsPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE -) { - private const val FILTER_CLASS_DESCRIPTOR = - "$COMPONENTS_PATH/ButtonShelfFilter;" - - override fun execute(context: ResourceContext) { - LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR) - - SettingsPatch.addSwitchPreference( - CategoryType.GENERAL, - "revanced_hide_button_shelf", - "false" - ) - - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/general/carouselshelf/CarouselShelfPatch.kt b/src/main/kotlin/app/revanced/patches/music/general/carouselshelf/CarouselShelfPatch.kt deleted file mode 100644 index 2ae2178fe..000000000 --- a/src/main/kotlin/app/revanced/patches/music/general/carouselshelf/CarouselShelfPatch.kt +++ /dev/null @@ -1,34 +0,0 @@ -package app.revanced.patches.music.general.carouselshelf - -import app.revanced.patcher.data.ResourceContext -import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH -import app.revanced.patches.music.utils.settings.CategoryType -import app.revanced.patches.music.utils.settings.SettingsPatch -import app.revanced.patches.shared.litho.LithoFilterPatch -import app.revanced.util.patch.BaseResourcePatch - -@Suppress("unused") -object CarouselShelfPatch : BaseResourcePatch( - name = "Hide carousel shelf", - description = "Adds an option to hide the carousel shelf from the homepage and explore tab.", - dependencies = setOf( - LithoFilterPatch::class, - SettingsPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE -) { - private const val FILTER_CLASS_DESCRIPTOR = - "$COMPONENTS_PATH/CarouselShelfFilter;" - - override fun execute(context: ResourceContext) { - LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR) - - SettingsPatch.addSwitchPreference( - CategoryType.GENERAL, - "revanced_hide_carousel_shelf", - "false" - ) - - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/general/castbutton/CastButtonPatch.kt b/src/main/kotlin/app/revanced/patches/music/general/castbutton/CastButtonPatch.kt deleted file mode 100644 index 95356e9ec..000000000 --- a/src/main/kotlin/app/revanced/patches/music/general/castbutton/CastButtonPatch.kt +++ /dev/null @@ -1,76 +0,0 @@ -package app.revanced.patches.music.general.castbutton - -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.patch.PatchException -import app.revanced.patches.music.general.castbutton.fingerprints.MediaRouteButtonFingerprint -import app.revanced.patches.music.general.castbutton.fingerprints.PlayerOverlayChipFingerprint -import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.music.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR -import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch -import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.PlayerOverlayChip -import app.revanced.patches.music.utils.settings.CategoryType -import app.revanced.patches.music.utils.settings.SettingsPatch -import app.revanced.util.getWideLiteralInstructionIndex -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction - -@Suppress("unused") -object CastButtonPatch : BaseBytecodePatch( - name = "Hide cast button", - description = "Adds an option to hide the cast button.", - dependencies = setOf( - SettingsPatch::class, - SharedResourceIdPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf( - MediaRouteButtonFingerprint, - PlayerOverlayChipFingerprint - ) -) { - override fun execute(context: BytecodeContext) { - - /** - * Hide cast button - */ - MediaRouteButtonFingerprint.resultOrThrow().let { - val setVisibilityMethod = - it.mutableClass.methods.find { method -> method.name == "setVisibility" } - - setVisibilityMethod?.apply { - addInstructions( - 0, """ - invoke-static {p1}, $GENERAL_CLASS_DESCRIPTOR->hideCastButton(I)I - move-result p1 - """ - ) - } ?: throw PatchException("Failed to find setVisibility method") - } - - /** - * Hide floating cast banner - */ - PlayerOverlayChipFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val targetIndex = getWideLiteralInstructionIndex(PlayerOverlayChip) + 2 - val targetRegister = getInstruction(targetIndex).registerA - - addInstruction( - targetIndex + 1, - "invoke-static {v$targetRegister}, $GENERAL_CLASS_DESCRIPTOR->hideCastButton(Landroid/view/View;)V" - ) - } - } - - SettingsPatch.addSwitchPreference( - CategoryType.GENERAL, - "revanced_hide_cast_button", - "true" - ) - - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/general/categorybar/CategoryBarPatch.kt b/src/main/kotlin/app/revanced/patches/music/general/categorybar/CategoryBarPatch.kt deleted file mode 100644 index a41a32f73..000000000 --- a/src/main/kotlin/app/revanced/patches/music/general/categorybar/CategoryBarPatch.kt +++ /dev/null @@ -1,47 +0,0 @@ -package app.revanced.patches.music.general.categorybar - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patches.music.general.categorybar.fingerprints.ChipCloudFingerprint -import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.music.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR -import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch -import app.revanced.patches.music.utils.settings.CategoryType -import app.revanced.patches.music.utils.settings.SettingsPatch -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction - -@Suppress("unused") -object CategoryBarPatch : BaseBytecodePatch( - name = "Hide category bar", - description = "Adds an option to hide the category bar.", - dependencies = setOf( - SettingsPatch::class, - SharedResourceIdPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(ChipCloudFingerprint) -) { - override fun execute(context: BytecodeContext) { - ChipCloudFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val targetIndex = it.scanResult.patternScanResult!!.endIndex - val targetRegister = getInstruction(targetIndex).registerA - - addInstruction( - targetIndex + 1, - "invoke-static { v$targetRegister }, $GENERAL_CLASS_DESCRIPTOR->hideCategoryBar(Landroid/view/View;)V" - ) - } - } - - SettingsPatch.addSwitchPreference( - CategoryType.GENERAL, - "revanced_hide_category_bar", - "false" - ) - - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/general/channelguidelines/ChannelGuidelinesPatch.kt b/src/main/kotlin/app/revanced/patches/music/general/channelguidelines/ChannelGuidelinesPatch.kt deleted file mode 100644 index ae6a64eb0..000000000 --- a/src/main/kotlin/app/revanced/patches/music/general/channelguidelines/ChannelGuidelinesPatch.kt +++ /dev/null @@ -1,34 +0,0 @@ -package app.revanced.patches.music.general.channelguidelines - -import app.revanced.patcher.data.ResourceContext -import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH -import app.revanced.patches.music.utils.settings.CategoryType -import app.revanced.patches.music.utils.settings.SettingsPatch -import app.revanced.patches.shared.litho.LithoFilterPatch -import app.revanced.util.patch.BaseResourcePatch - -@Suppress("unused") -object ChannelGuidelinesPatch : BaseResourcePatch( - name = "Hide channel guidelines", - description = "Adds an option to hide the channel guidelines at the top of the comments section.", - dependencies = setOf( - LithoFilterPatch::class, - SettingsPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE -) { - private const val FILTER_CLASS_DESCRIPTOR = - "$COMPONENTS_PATH/ChannelGuidelinesFilter;" - - override fun execute(context: ResourceContext) { - LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR) - - SettingsPatch.addSwitchPreference( - CategoryType.GENERAL, - "revanced_hide_channel_guidelines", - "true" - ) - - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/general/components/LayoutComponentsPatch.kt b/src/main/kotlin/app/revanced/patches/music/general/components/LayoutComponentsPatch.kt new file mode 100644 index 000000000..4bc048cf3 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/general/components/LayoutComponentsPatch.kt @@ -0,0 +1,378 @@ +package app.revanced.patches.music.general.components + +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.addInstructionsWithLabels +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction +import app.revanced.patcher.patch.PatchException +import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.booleanPatchOption +import app.revanced.patcher.util.smali.ExternalLabel +import app.revanced.patches.music.general.components.fingerprints.ChipCloudFingerprint +import app.revanced.patches.music.general.components.fingerprints.ContentPillInFingerprint +import app.revanced.patches.music.general.components.fingerprints.FloatingButtonFingerprint +import app.revanced.patches.music.general.components.fingerprints.FloatingButtonParentFingerprint +import app.revanced.patches.music.general.components.fingerprints.HistoryMenuItemFingerprint +import app.revanced.patches.music.general.components.fingerprints.HistoryMenuItemOfflineTabFingerprint +import app.revanced.patches.music.general.components.fingerprints.MediaRouteButtonFingerprint +import app.revanced.patches.music.general.components.fingerprints.PlayerOverlayChipFingerprint +import app.revanced.patches.music.general.components.fingerprints.SearchBarFingerprint +import app.revanced.patches.music.general.components.fingerprints.SearchBarParentFingerprint +import app.revanced.patches.music.general.components.fingerprints.SoundSearchFingerprint +import app.revanced.patches.music.general.components.fingerprints.TasteBuilderConstructorFingerprint +import app.revanced.patches.music.general.components.fingerprints.TasteBuilderSyntheticFingerprint +import app.revanced.patches.music.general.components.fingerprints.TooltipContentViewFingerprint +import app.revanced.patches.music.general.components.fingerprints.TopBarMenuItemImageViewFingerprint +import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE +import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH +import app.revanced.patches.music.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR +import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch +import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.TopBarMenuItemImageView +import app.revanced.patches.music.utils.settings.CategoryType +import app.revanced.patches.music.utils.settings.SettingsPatch +import app.revanced.patches.shared.litho.LithoFilterPatch +import app.revanced.patches.shared.voicesearch.VoiceSearchUtils.patchXml +import app.revanced.util.getTargetIndex +import app.revanced.util.getTargetIndexWithMethodReferenceName +import app.revanced.util.getWideLiteralInstructionIndex +import app.revanced.util.literalInstructionBooleanHook +import app.revanced.util.patch.BaseBytecodePatch +import app.revanced.util.resultOrThrow +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 + +@Suppress("unused") +object LayoutComponentsPatch : BaseBytecodePatch( + name = "Hide layout components", + description = "Adds options to hide general layout components.", + dependencies = setOf( + LithoFilterPatch::class, + SharedResourceIdPatch::class, + SettingsPatch::class + ), + compatiblePackages = COMPATIBLE_PACKAGE, + fingerprints = setOf( + ChipCloudFingerprint, + ContentPillInFingerprint, + FloatingButtonParentFingerprint, + HistoryMenuItemFingerprint, + HistoryMenuItemOfflineTabFingerprint, + MediaRouteButtonFingerprint, + PlayerOverlayChipFingerprint, + SearchBarParentFingerprint, + SoundSearchFingerprint, + TasteBuilderConstructorFingerprint, + TooltipContentViewFingerprint, + TopBarMenuItemImageViewFingerprint + ) +) { + private const val CUSTOM_FILTER_CLASS_DESCRIPTOR = + "$COMPONENTS_PATH/CustomFilter;" + + private const val LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR = + "$COMPONENTS_PATH/LayoutComponentsFilter;" + + private val ForceHideVoiceSearchButton by booleanPatchOption( + key = "ForceHideVoiceSearchButton", + default = false, + title = "Force hide voice search button", + description = "Hide voice search button with legacy method, button will always be hidden." + ) + + override fun execute(context: BytecodeContext) { + var notificationButtonIncluded = false + var soundSearchButtonIncluded = false + var voiceSearchButtonIncluded = false + + // region patch for hide cast button + + // hide cast button + MediaRouteButtonFingerprint.resultOrThrow().let { + val setVisibilityMethod = + it.mutableClass.methods.find { method -> method.name == "setVisibility" } + + setVisibilityMethod?.apply { + addInstructions( + 0, """ + invoke-static {p1}, $GENERAL_CLASS_DESCRIPTOR->hideCastButton(I)I + move-result p1 + """ + ) + } ?: throw PatchException("Failed to find setVisibility method") + } + + // hide floating cast banner + PlayerOverlayChipFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val targetIndex = getWideLiteralInstructionIndex(SharedResourceIdPatch.PlayerOverlayChip) + 2 + val targetRegister = getInstruction(targetIndex).registerA + + addInstruction( + targetIndex + 1, + "invoke-static {v$targetRegister}, $GENERAL_CLASS_DESCRIPTOR->hideCastButton(Landroid/view/View;)V" + ) + } + } + + // endregion + + // region patch for hide category bar + + ChipCloudFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val targetIndex = it.scanResult.patternScanResult!!.endIndex + val targetRegister = getInstruction(targetIndex).registerA + + addInstruction( + targetIndex + 1, + "invoke-static { v$targetRegister }, $GENERAL_CLASS_DESCRIPTOR->hideCategoryBar(Landroid/view/View;)V" + ) + } + } + + // endregion + + // region patch for hide floating button + + FloatingButtonFingerprint.resolve( + context, + FloatingButtonParentFingerprint.resultOrThrow().classDef + ) + FloatingButtonFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + addInstructionsWithLabels( + 1, """ + invoke-static {}, $GENERAL_CLASS_DESCRIPTOR->hideFloatingButton()Z + move-result v0 + if-eqz v0, :show + return-void + """, ExternalLabel("show", getInstruction(1)) + ) + } + } + + // endregion + + // region patch for hide history button + + arrayOf( + HistoryMenuItemFingerprint, + HistoryMenuItemOfflineTabFingerprint + ).forEach { fingerprint -> + fingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val insertIndex = it.scanResult.patternScanResult!!.startIndex + val insertRegister = getInstruction(insertIndex).registerD + + addInstructions( + insertIndex, """ + invoke-static {v$insertRegister}, $GENERAL_CLASS_DESCRIPTOR->hideHistoryButton(Z)Z + move-result v$insertRegister + """ + ) + } + } + } + + // endregion + + // region patch for hide notification button + + if (SettingsPatch.upward0642) { + TopBarMenuItemImageViewFingerprint.resultOrThrow().mutableMethod.apply { + val constIndex = getWideLiteralInstructionIndex(TopBarMenuItemImageView) + val targetIndex = getTargetIndex(constIndex, Opcode.MOVE_RESULT_OBJECT) + val targetRegister = getInstruction(targetIndex).registerA + + addInstruction( + targetIndex + 1, + "invoke-static {v$targetRegister}, $GENERAL_CLASS_DESCRIPTOR->hideNotificationButton(Landroid/view/View;)V" + ) + } + notificationButtonIncluded = true + } + + // endregion + + // region patch for hide sound search button + + SoundSearchFingerprint.result?.let { + SoundSearchFingerprint.literalInstructionBooleanHook( + 45625491, + "$GENERAL_CLASS_DESCRIPTOR->hideSoundSearchButton(Z)Z" + ) + soundSearchButtonIncluded = true + } + + // endregion + + // region patch for hide tap to update button + + ContentPillInFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + addInstructionsWithLabels( + 0, + """ + invoke-static {}, $GENERAL_CLASS_DESCRIPTOR->hideTapToUpdateButton()Z + move-result v0 + if-eqz v0, :show + return-void + """, ExternalLabel("show", getInstruction(0)) + ) + } + } + + // endregion + + // region patch for hide taste builder + + TasteBuilderConstructorFingerprint.resultOrThrow().let { parentResult -> + TasteBuilderSyntheticFingerprint.resolve(context, parentResult.classDef) + + parentResult.mutableMethod.apply { + val constIndex = getWideLiteralInstructionIndex(SharedResourceIdPatch.MusicTasteBuilderShelf) + val targetIndex = getTargetIndex(constIndex, Opcode.MOVE_RESULT_OBJECT) + val targetRegister = getInstruction(targetIndex).registerA + + addInstruction( + targetIndex + 1, + "invoke-static {v$targetRegister}, $GENERAL_CLASS_DESCRIPTOR->hideTasteBuilder(Landroid/view/View;)V" + ) + } + } + + TasteBuilderSyntheticFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val insertIndex = it.scanResult.patternScanResult!!.startIndex + val insertRegister = getInstruction(insertIndex).registerA + + addInstruction( + insertIndex, + "const/4 v$insertRegister, 0x0" + ) + } + } + + // endregion + + // region patch for hide tooltip content + + TooltipContentViewFingerprint.resultOrThrow().mutableMethod.addInstruction( + 0, + "return-void" + ) + + // endregion + + // region patch for hide voice search button + + if (ForceHideVoiceSearchButton == true) { + SettingsPatch.contexts.patchXml( + arrayOf("search_toolbar_view.xml"), + arrayOf("height", "width") + ) + } else { + SearchBarFingerprint.resolve( + context, + SearchBarParentFingerprint.resultOrThrow().classDef + ) + SearchBarFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val setVisibilityIndex = getTargetIndexWithMethodReferenceName("setVisibility") + val setVisibilityInstruction = getInstruction(setVisibilityIndex) + + replaceInstruction( + setVisibilityIndex, + "invoke-static {v${setVisibilityInstruction.registerC}, v${setVisibilityInstruction.registerD}}, " + + "$GENERAL_CLASS_DESCRIPTOR->hideVoiceSearchButton(Landroid/widget/ImageView;I)V" + ) + } + } + voiceSearchButtonIncluded = true + } + + // endregion + + LithoFilterPatch.addFilter(CUSTOM_FILTER_CLASS_DESCRIPTOR) + LithoFilterPatch.addFilter(LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR) + + SettingsPatch.addSwitchPreference( + CategoryType.GENERAL, + "revanced_custom_filter", + "false" + ) + SettingsPatch.addPreferenceWithIntent( + CategoryType.GENERAL, + "revanced_custom_filter_strings", + "revanced_custom_filter" + ) + SettingsPatch.addSwitchPreference( + CategoryType.GENERAL, + "revanced_hide_button_shelf", + "false" + ) + SettingsPatch.addSwitchPreference( + CategoryType.GENERAL, + "revanced_hide_carousel_shelf", + "false" + ) + SettingsPatch.addSwitchPreference( + CategoryType.GENERAL, + "revanced_hide_playlist_card_shelf", + "false" + ) + SettingsPatch.addSwitchPreference( + CategoryType.GENERAL, + "revanced_hide_samples_shelf", + "false" + ) + SettingsPatch.addSwitchPreference( + CategoryType.GENERAL, + "revanced_hide_cast_button", + "true" + ) + SettingsPatch.addSwitchPreference( + CategoryType.GENERAL, + "revanced_hide_category_bar", + "false" + ) + SettingsPatch.addSwitchPreference( + CategoryType.GENERAL, + "revanced_hide_floating_button", + "false" + ) + SettingsPatch.addSwitchPreference( + CategoryType.GENERAL, + "revanced_hide_tap_to_update_button", + "false" + ) + SettingsPatch.addSwitchPreference( + CategoryType.GENERAL, + "revanced_hide_history_button", + "false" + ) + if (notificationButtonIncluded) { + SettingsPatch.addSwitchPreference( + CategoryType.GENERAL, + "revanced_hide_notification_button", + "false" + ) + } + if (soundSearchButtonIncluded) { + SettingsPatch.addSwitchPreference( + CategoryType.GENERAL, + "revanced_hide_sound_search_button", + "false" + ) + } + if (voiceSearchButtonIncluded) { + SettingsPatch.addSwitchPreference( + CategoryType.GENERAL, + "revanced_hide_voice_search_button", + "false" + ) + } + } +} diff --git a/src/main/kotlin/app/revanced/patches/music/general/categorybar/fingerprints/ChipCloudFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/ChipCloudFingerprint.kt similarity index 87% rename from src/main/kotlin/app/revanced/patches/music/general/categorybar/fingerprints/ChipCloudFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/ChipCloudFingerprint.kt index 2d38e31c9..f96fdb6ff 100644 --- a/src/main/kotlin/app/revanced/patches/music/general/categorybar/fingerprints/ChipCloudFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/ChipCloudFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.general.categorybar.fingerprints +package app.revanced.patches.music.general.components.fingerprints import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.ChipCloud import app.revanced.util.fingerprint.LiteralValueFingerprint diff --git a/src/main/kotlin/app/revanced/patches/music/general/taptoupdate/fingerprints/ContentPillInFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/ContentPillInFingerprint.kt similarity index 73% rename from src/main/kotlin/app/revanced/patches/music/general/taptoupdate/fingerprints/ContentPillInFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/ContentPillInFingerprint.kt index 60ada9ff5..6fed0ad94 100644 --- a/src/main/kotlin/app/revanced/patches/music/general/taptoupdate/fingerprints/ContentPillInFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/ContentPillInFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.general.taptoupdate.fingerprints +package app.revanced.patches.music.general.components.fingerprints import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/music/general/floatingbutton/fingerprints/FloatingButtonFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/FloatingButtonFingerprint.kt similarity index 78% rename from src/main/kotlin/app/revanced/patches/music/general/floatingbutton/fingerprints/FloatingButtonFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/FloatingButtonFingerprint.kt index 9f69c5209..f834317cb 100644 --- a/src/main/kotlin/app/revanced/patches/music/general/floatingbutton/fingerprints/FloatingButtonFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/FloatingButtonFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.general.floatingbutton.fingerprints +package app.revanced.patches.music.general.components.fingerprints import app.revanced.patcher.fingerprint.MethodFingerprint import com.android.tools.smali.dexlib2.Opcode diff --git a/src/main/kotlin/app/revanced/patches/music/general/floatingbutton/fingerprints/FloatingButtonParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/FloatingButtonParentFingerprint.kt similarity index 86% rename from src/main/kotlin/app/revanced/patches/music/general/floatingbutton/fingerprints/FloatingButtonParentFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/FloatingButtonParentFingerprint.kt index c8f5ad107..360c10ad4 100644 --- a/src/main/kotlin/app/revanced/patches/music/general/floatingbutton/fingerprints/FloatingButtonParentFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/FloatingButtonParentFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.general.floatingbutton.fingerprints +package app.revanced.patches.music.general.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.util.fingerprint.LiteralValueFingerprint diff --git a/src/main/kotlin/app/revanced/patches/music/general/historybutton/fingerprints/HistoryMenuItemFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/HistoryMenuItemFingerprint.kt similarity index 92% rename from src/main/kotlin/app/revanced/patches/music/general/historybutton/fingerprints/HistoryMenuItemFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/HistoryMenuItemFingerprint.kt index b4b276085..bbf6b50ce 100644 --- a/src/main/kotlin/app/revanced/patches/music/general/historybutton/fingerprints/HistoryMenuItemFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/HistoryMenuItemFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.general.historybutton.fingerprints +package app.revanced.patches.music.general.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/music/general/historybutton/fingerprints/HistoryMenuItemOfflineTabFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/HistoryMenuItemOfflineTabFingerprint.kt similarity index 93% rename from src/main/kotlin/app/revanced/patches/music/general/historybutton/fingerprints/HistoryMenuItemOfflineTabFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/HistoryMenuItemOfflineTabFingerprint.kt index ac98be844..e875e2be9 100644 --- a/src/main/kotlin/app/revanced/patches/music/general/historybutton/fingerprints/HistoryMenuItemOfflineTabFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/HistoryMenuItemOfflineTabFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.general.historybutton.fingerprints +package app.revanced.patches.music.general.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/music/general/castbutton/fingerprints/MediaRouteButtonFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/MediaRouteButtonFingerprint.kt similarity index 84% rename from src/main/kotlin/app/revanced/patches/music/general/castbutton/fingerprints/MediaRouteButtonFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/MediaRouteButtonFingerprint.kt index de0d3d633..5d5eb7790 100644 --- a/src/main/kotlin/app/revanced/patches/music/general/castbutton/fingerprints/MediaRouteButtonFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/MediaRouteButtonFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.general.castbutton.fingerprints +package app.revanced.patches.music.general.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/music/general/castbutton/fingerprints/PlayerOverlayChipFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/PlayerOverlayChipFingerprint.kt similarity index 87% rename from src/main/kotlin/app/revanced/patches/music/general/castbutton/fingerprints/PlayerOverlayChipFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/PlayerOverlayChipFingerprint.kt index c71ecebc5..30978def7 100644 --- a/src/main/kotlin/app/revanced/patches/music/general/castbutton/fingerprints/PlayerOverlayChipFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/PlayerOverlayChipFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.general.castbutton.fingerprints +package app.revanced.patches.music.general.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.PlayerOverlayChip diff --git a/src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/SearchBarFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/SearchBarFingerprint.kt new file mode 100644 index 000000000..fbcd0ec91 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/SearchBarFingerprint.kt @@ -0,0 +1,8 @@ +package app.revanced.patches.music.general.components.fingerprints + +import app.revanced.util.fingerprint.MethodReferenceNameFingerprint + +object SearchBarFingerprint : MethodReferenceNameFingerprint( + returnType = "V", + reference = { "setVisibility" } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/SearchBarParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/SearchBarParentFingerprint.kt new file mode 100644 index 000000000..4f85d5827 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/SearchBarParentFingerprint.kt @@ -0,0 +1,8 @@ +package app.revanced.patches.music.general.components.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint + +object SearchBarParentFingerprint : MethodFingerprint( + returnType = "Landroid/content/Intent;", + strings = listOf("web_search") +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/SoundSearchFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/SoundSearchFingerprint.kt new file mode 100644 index 000000000..86f4fe708 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/SoundSearchFingerprint.kt @@ -0,0 +1,8 @@ +package app.revanced.patches.music.general.components.fingerprints + +import app.revanced.util.fingerprint.LiteralValueFingerprint + +internal object SoundSearchFingerprint : LiteralValueFingerprint( + parameters = emptyList(), + literalSupplier = { 45625491 } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/misc/tastebuilder/fingerprints/TasteBuilderConstructorFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/TasteBuilderConstructorFingerprint.kt similarity index 87% rename from src/main/kotlin/app/revanced/patches/music/misc/tastebuilder/fingerprints/TasteBuilderConstructorFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/TasteBuilderConstructorFingerprint.kt index 622ffefbe..148e3f36c 100644 --- a/src/main/kotlin/app/revanced/patches/music/misc/tastebuilder/fingerprints/TasteBuilderConstructorFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/TasteBuilderConstructorFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.misc.tastebuilder.fingerprints +package app.revanced.patches.music.general.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MusicTasteBuilderShelf diff --git a/src/main/kotlin/app/revanced/patches/music/misc/tastebuilder/fingerprints/TasteBuilderSyntheticFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/TasteBuilderSyntheticFingerprint.kt similarity index 88% rename from src/main/kotlin/app/revanced/patches/music/misc/tastebuilder/fingerprints/TasteBuilderSyntheticFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/TasteBuilderSyntheticFingerprint.kt index 6d0825a9e..7226d660c 100644 --- a/src/main/kotlin/app/revanced/patches/music/misc/tastebuilder/fingerprints/TasteBuilderSyntheticFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/TasteBuilderSyntheticFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.misc.tastebuilder.fingerprints +package app.revanced.patches.music.general.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/music/general/tooltip/fingerprints/TooltipContentViewFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/TooltipContentViewFingerprint.kt similarity index 87% rename from src/main/kotlin/app/revanced/patches/music/general/tooltip/fingerprints/TooltipContentViewFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/TooltipContentViewFingerprint.kt index fe7ad9630..e5934cefa 100644 --- a/src/main/kotlin/app/revanced/patches/music/general/tooltip/fingerprints/TooltipContentViewFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/TooltipContentViewFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.general.tooltip.fingerprints +package app.revanced.patches.music.general.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.ToolTipContentView diff --git a/src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/TopBarMenuItemImageViewFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/TopBarMenuItemImageViewFingerprint.kt new file mode 100644 index 000000000..5f7b40f4e --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/general/components/fingerprints/TopBarMenuItemImageViewFingerprint.kt @@ -0,0 +1,14 @@ +package app.revanced.patches.music.general.components.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.TopBarMenuItemImageView +import app.revanced.util.fingerprint.LiteralValueFingerprint +import com.android.tools.smali.dexlib2.AccessFlags + +internal object TopBarMenuItemImageViewFingerprint : LiteralValueFingerprint( + returnType = "Landroid/view/View;", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = emptyList(), + literalSupplier = { TopBarMenuItemImageView } +) + diff --git a/src/main/kotlin/app/revanced/patches/music/general/customfilter/CustomFilterPatch.kt b/src/main/kotlin/app/revanced/patches/music/general/customfilter/CustomFilterPatch.kt deleted file mode 100644 index 19d527d5a..000000000 --- a/src/main/kotlin/app/revanced/patches/music/general/customfilter/CustomFilterPatch.kt +++ /dev/null @@ -1,39 +0,0 @@ -package app.revanced.patches.music.general.customfilter - -import app.revanced.patcher.data.ResourceContext -import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH -import app.revanced.patches.music.utils.settings.CategoryType -import app.revanced.patches.music.utils.settings.SettingsPatch -import app.revanced.patches.shared.litho.LithoFilterPatch -import app.revanced.util.patch.BaseResourcePatch - -@Suppress("unused") -object CustomFilterPatch : BaseResourcePatch( - name = "Enable custom filter", - description = "Adds a custom filter which can be used to hide layout components.", - dependencies = setOf( - LithoFilterPatch::class, - SettingsPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE -) { - private const val FILTER_CLASS_DESCRIPTOR = - "$COMPONENTS_PATH/CustomFilter;" - - override fun execute(context: ResourceContext) { - LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR) - - SettingsPatch.addSwitchPreference( - CategoryType.GENERAL, - "revanced_custom_filter", - "false" - ) - SettingsPatch.addPreferenceWithIntent( - CategoryType.GENERAL, - "revanced_custom_filter_strings", - "revanced_custom_filter" - ) - - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/general/emojipicker/EmojiPickerPatch.kt b/src/main/kotlin/app/revanced/patches/music/general/emojipicker/EmojiPickerPatch.kt deleted file mode 100644 index d32facfc0..000000000 --- a/src/main/kotlin/app/revanced/patches/music/general/emojipicker/EmojiPickerPatch.kt +++ /dev/null @@ -1,34 +0,0 @@ -package app.revanced.patches.music.general.emojipicker - -import app.revanced.patcher.data.ResourceContext -import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH -import app.revanced.patches.music.utils.settings.CategoryType -import app.revanced.patches.music.utils.settings.SettingsPatch -import app.revanced.patches.shared.litho.LithoFilterPatch -import app.revanced.util.patch.BaseResourcePatch - -@Suppress("unused") -object EmojiPickerPatch : BaseResourcePatch( - name = "Hide emoji picker and time stamp", - description = "Adds an option to hide the emoji picker and time stamp when typing comments.", - dependencies = setOf( - LithoFilterPatch::class, - SettingsPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE -) { - private const val FILTER_CLASS_DESCRIPTOR = - "$COMPONENTS_PATH/EmojiPickerFilter;" - - override fun execute(context: ResourceContext) { - LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR) - - SettingsPatch.addSwitchPreference( - CategoryType.GENERAL, - "revanced_hide_emoji_picker", - "false" - ) - - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/general/floatingbutton/FloatingButtonPatch.kt b/src/main/kotlin/app/revanced/patches/music/general/floatingbutton/FloatingButtonPatch.kt deleted file mode 100644 index 0d4a16efe..000000000 --- a/src/main/kotlin/app/revanced/patches/music/general/floatingbutton/FloatingButtonPatch.kt +++ /dev/null @@ -1,57 +0,0 @@ -package app.revanced.patches.music.general.floatingbutton - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.music.general.floatingbutton.fingerprints.FloatingButtonFingerprint -import app.revanced.patches.music.general.floatingbutton.fingerprints.FloatingButtonParentFingerprint -import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.music.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR -import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch -import app.revanced.patches.music.utils.settings.CategoryType -import app.revanced.patches.music.utils.settings.SettingsPatch -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow - -@Suppress("unused") -object FloatingButtonPatch : BaseBytecodePatch( - name = "Hide new playlist button", - description = "Adds an option to hide the \"New playlist\" button in the library.", - dependencies = setOf( - SettingsPatch::class, - SharedResourceIdPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(FloatingButtonParentFingerprint) -) { - override fun execute(context: BytecodeContext) { - - FloatingButtonParentFingerprint.resultOrThrow().let { parentResult -> - FloatingButtonFingerprint.also { - it.resolve( - context, - parentResult.classDef - ) - }.resultOrThrow().let { - it.mutableMethod.apply { - addInstructionsWithLabels( - 1, """ - invoke-static {}, $GENERAL_CLASS_DESCRIPTOR->hideNewPlaylistButton()Z - move-result v0 - if-eqz v0, :show - return-void - """, ExternalLabel("show", getInstruction(1)) - ) - } - } - } - - SettingsPatch.addSwitchPreference( - CategoryType.GENERAL, - "revanced_hide_new_playlist_button", - "false" - ) - - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/general/historybutton/HistoryButtonPatch.kt b/src/main/kotlin/app/revanced/patches/music/general/historybutton/HistoryButtonPatch.kt deleted file mode 100644 index a92278104..000000000 --- a/src/main/kotlin/app/revanced/patches/music/general/historybutton/HistoryButtonPatch.kt +++ /dev/null @@ -1,59 +0,0 @@ -package app.revanced.patches.music.general.historybutton - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patches.music.general.historybutton.fingerprints.HistoryMenuItemFingerprint -import app.revanced.patches.music.general.historybutton.fingerprints.HistoryMenuItemOfflineTabFingerprint -import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.music.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR -import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch -import app.revanced.patches.music.utils.settings.CategoryType -import app.revanced.patches.music.utils.settings.SettingsPatch -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction - -@Suppress("unused") -object HistoryButtonPatch : BaseBytecodePatch( - name = "Hide history button", - description = "Adds an option to hide the history button in the toolbar.", - dependencies = setOf( - SettingsPatch::class, - SharedResourceIdPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf( - HistoryMenuItemFingerprint, - HistoryMenuItemOfflineTabFingerprint - ) -) { - override fun execute(context: BytecodeContext) { - - arrayOf( - HistoryMenuItemFingerprint, - HistoryMenuItemOfflineTabFingerprint - ).forEach { fingerprint -> - fingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val insertIndex = it.scanResult.patternScanResult!!.startIndex - val insertRegister = getInstruction(insertIndex).registerD - - addInstructions( - insertIndex, """ - invoke-static {v$insertRegister}, $GENERAL_CLASS_DESCRIPTOR->hideHistoryButton(Z)Z - move-result v$insertRegister - """ - ) - } - } - } - - SettingsPatch.addSwitchPreference( - CategoryType.GENERAL, - "revanced_hide_history_button", - "false" - ) - - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/general/oldstylelibraryshelf/OldStyleLibraryShelfPatch.kt b/src/main/kotlin/app/revanced/patches/music/general/oldstylelibraryshelf/OldStyleLibraryShelfPatch.kt index 2137cf085..c49ac9501 100644 --- a/src/main/kotlin/app/revanced/patches/music/general/oldstylelibraryshelf/OldStyleLibraryShelfPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/general/oldstylelibraryshelf/OldStyleLibraryShelfPatch.kt @@ -17,7 +17,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction @Suppress("unused") object OldStyleLibraryShelfPatch : BaseBytecodePatch( - name = "Enable old style library shelf", + name = "Restore old style library shelf", description = "Adds an option to return the library tab to the old style.", dependencies = setOf(SettingsPatch::class), compatiblePackages = COMPATIBLE_PACKAGE, @@ -33,7 +33,7 @@ object OldStyleLibraryShelfPatch : BaseBytecodePatch( addInstructions( targetIndex + 1, """ - invoke-static {v$targetRegister}, $GENERAL_CLASS_DESCRIPTOR->enableOldStyleLibraryShelf(Ljava/lang/String;)Ljava/lang/String; + invoke-static {v$targetRegister}, $GENERAL_CLASS_DESCRIPTOR->restoreOldStyleLibraryShelf(Ljava/lang/String;)Ljava/lang/String; move-result-object v$targetRegister """ ) @@ -42,7 +42,7 @@ object OldStyleLibraryShelfPatch : BaseBytecodePatch( SettingsPatch.addSwitchPreference( CategoryType.GENERAL, - "revanced_enable_old_style_library_shelf", + "revanced_restore_old_style_library_shelf", "false" ) diff --git a/src/main/kotlin/app/revanced/patches/music/general/playlistcard/PlaylistCardPatch.kt b/src/main/kotlin/app/revanced/patches/music/general/playlistcard/PlaylistCardPatch.kt deleted file mode 100644 index 479605a06..000000000 --- a/src/main/kotlin/app/revanced/patches/music/general/playlistcard/PlaylistCardPatch.kt +++ /dev/null @@ -1,34 +0,0 @@ -package app.revanced.patches.music.general.playlistcard - -import app.revanced.patcher.data.ResourceContext -import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH -import app.revanced.patches.music.utils.settings.CategoryType -import app.revanced.patches.music.utils.settings.SettingsPatch -import app.revanced.patches.shared.litho.LithoFilterPatch -import app.revanced.util.patch.BaseResourcePatch - -@Suppress("unused") -object PlaylistCardPatch : BaseResourcePatch( - name = "Hide playlist card", - description = "Adds an option to hide the playlist card from the homepage.", - dependencies = setOf( - LithoFilterPatch::class, - SettingsPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE -) { - private const val FILTER_CLASS_DESCRIPTOR = - "$COMPONENTS_PATH/PlaylistCardFilter;" - - override fun execute(context: ResourceContext) { - LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR) - - SettingsPatch.addSwitchPreference( - CategoryType.GENERAL, - "revanced_hide_playlist_card", - "false" - ) - - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/general/sampleshelf/SampleShelfPatch.kt b/src/main/kotlin/app/revanced/patches/music/general/sampleshelf/SampleShelfPatch.kt deleted file mode 100644 index c249fe802..000000000 --- a/src/main/kotlin/app/revanced/patches/music/general/sampleshelf/SampleShelfPatch.kt +++ /dev/null @@ -1,34 +0,0 @@ -package app.revanced.patches.music.general.sampleshelf - -import app.revanced.patcher.data.ResourceContext -import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH -import app.revanced.patches.music.utils.settings.CategoryType -import app.revanced.patches.music.utils.settings.SettingsPatch -import app.revanced.patches.shared.litho.LithoFilterPatch -import app.revanced.util.patch.BaseResourcePatch - -@Suppress("unused") -object SampleShelfPatch : BaseResourcePatch( - name = "Hide sample shelf", - description = "Adds an option to hide the sample shelf from the homepage.", - dependencies = setOf( - LithoFilterPatch::class, - SettingsPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE -) { - private const val FILTER_CLASS_DESCRIPTOR = - "$COMPONENTS_PATH/SampleShelfFilter;" - - override fun execute(context: ResourceContext) { - LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR) - - SettingsPatch.addSwitchPreference( - CategoryType.GENERAL, - "revanced_hide_samples_shelf", - "false" - ) - - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/general/spoofappversion/SpoofAppVersionBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/music/general/spoofappversion/SpoofAppVersionBytecodePatch.kt new file mode 100644 index 000000000..183505c57 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/general/spoofappversion/SpoofAppVersionBytecodePatch.kt @@ -0,0 +1,8 @@ +package app.revanced.patches.music.general.spoofappversion + +import app.revanced.patches.music.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR +import app.revanced.patches.shared.spoofappversion.BaseSpoofAppVersionPatch + +object SpoofAppVersionBytecodePatch : BaseSpoofAppVersionPatch( + "$GENERAL_CLASS_DESCRIPTOR->getVersionOverride(Ljava/lang/String;)Ljava/lang/String;" +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/misc/spoofappversion/SpoofAppVersionPatch.kt b/src/main/kotlin/app/revanced/patches/music/general/spoofappversion/SpoofAppVersionPatch.kt similarity index 78% rename from src/main/kotlin/app/revanced/patches/music/misc/spoofappversion/SpoofAppVersionPatch.kt rename to src/main/kotlin/app/revanced/patches/music/general/spoofappversion/SpoofAppVersionPatch.kt index 51e2950e2..f179b4c43 100644 --- a/src/main/kotlin/app/revanced/patches/music/misc/spoofappversion/SpoofAppVersionPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/general/spoofappversion/SpoofAppVersionPatch.kt @@ -1,10 +1,10 @@ -package app.revanced.patches.music.misc.spoofappversion +package app.revanced.patches.music.general.spoofappversion import app.revanced.patcher.data.ResourceContext +import app.revanced.patches.music.general.oldstylelibraryshelf.OldStyleLibraryShelfPatch import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.music.utils.settings.CategoryType import app.revanced.patches.music.utils.settings.SettingsPatch -import app.revanced.util.copyXmlNode import app.revanced.util.patch.BaseResourcePatch @Suppress("unused") @@ -13,6 +13,7 @@ object SpoofAppVersionPatch : BaseResourcePatch( description = "Adds options to spoof the YouTube Music client version. " + "This can remove the radio mode restriction in Canadian regions or disable real-time lyrics.", dependencies = setOf( + OldStyleLibraryShelfPatch::class, SettingsPatch::class, SpoofAppVersionBytecodePatch::class ), @@ -20,18 +21,13 @@ object SpoofAppVersionPatch : BaseResourcePatch( ) { override fun execute(context: ResourceContext) { - /** - * Copy arrays - */ - context.copyXmlNode("music/spoofappversion/host", "values/arrays.xml", "resources") - SettingsPatch.addSwitchPreference( - CategoryType.MISC, + CategoryType.GENERAL, "revanced_spoof_app_version", "false" ) SettingsPatch.addPreferenceWithIntent( - CategoryType.MISC, + CategoryType.GENERAL, "revanced_spoof_app_version_target", "revanced_spoof_app_version" ) diff --git a/src/main/kotlin/app/revanced/patches/music/general/startpage/ChangeStartPagePatch.kt b/src/main/kotlin/app/revanced/patches/music/general/startpage/ChangeStartPagePatch.kt index 95dc79aea..06a05633f 100644 --- a/src/main/kotlin/app/revanced/patches/music/general/startpage/ChangeStartPagePatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/general/startpage/ChangeStartPagePatch.kt @@ -9,8 +9,6 @@ import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKA import app.revanced.patches.music.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR import app.revanced.patches.music.utils.settings.CategoryType import app.revanced.patches.music.utils.settings.SettingsPatch -import app.revanced.patches.music.utils.settings.SettingsPatch.contexts -import app.revanced.util.copyXmlNode import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.resultOrThrow import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction @@ -41,11 +39,6 @@ object ChangeStartPagePatch : BaseBytecodePatch( } } - /** - * Copy arrays - */ - contexts.copyXmlNode("music/startpage/host", "values/arrays.xml", "resources") - SettingsPatch.addPreferenceWithIntent( CategoryType.GENERAL, "revanced_change_start_page" diff --git a/src/main/kotlin/app/revanced/patches/music/general/taptoupdate/TapToUpdateButtonPatch.kt b/src/main/kotlin/app/revanced/patches/music/general/taptoupdate/TapToUpdateButtonPatch.kt deleted file mode 100644 index 401d70a96..000000000 --- a/src/main/kotlin/app/revanced/patches/music/general/taptoupdate/TapToUpdateButtonPatch.kt +++ /dev/null @@ -1,46 +0,0 @@ -package app.revanced.patches.music.general.taptoupdate - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.music.general.taptoupdate.fingerprints.ContentPillInFingerprint -import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.music.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR -import app.revanced.patches.music.utils.settings.CategoryType -import app.revanced.patches.music.utils.settings.SettingsPatch -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow - -@Suppress("unused") -object TapToUpdateButtonPatch : BaseBytecodePatch( - name = "Hide tap to update button", - description = "Adds an option to hide the tap to update button.", - dependencies = setOf(SettingsPatch::class), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(ContentPillInFingerprint) -) { - override fun execute(context: BytecodeContext) { - - ContentPillInFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - addInstructionsWithLabels( - 0, - """ - invoke-static {}, $GENERAL_CLASS_DESCRIPTOR->hideTapToUpdateButton()Z - move-result v0 - if-eqz v0, :show - return-void - """, ExternalLabel("show", getInstruction(0)) - ) - } - } - - SettingsPatch.addSwitchPreference( - CategoryType.GENERAL, - "revanced_hide_tap_to_update_button", - "false" - ) - - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/general/tooltip/TooltipContentViewPatch.kt b/src/main/kotlin/app/revanced/patches/music/general/tooltip/TooltipContentViewPatch.kt deleted file mode 100644 index 1f1aba0a6..000000000 --- a/src/main/kotlin/app/revanced/patches/music/general/tooltip/TooltipContentViewPatch.kt +++ /dev/null @@ -1,27 +0,0 @@ -package app.revanced.patches.music.general.tooltip - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -import app.revanced.patches.music.general.tooltip.fingerprints.TooltipContentViewFingerprint -import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow - -@Suppress("unused") -object TooltipContentViewPatch : BaseBytecodePatch( - name = "Hide tooltip content", - description = "Hides the tooltip box that appears when opening the app for the first time.", - dependencies = setOf(SharedResourceIdPatch::class), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(TooltipContentViewFingerprint) -) { - override fun execute(context: BytecodeContext) { - - TooltipContentViewFingerprint.resultOrThrow().mutableMethod.addInstruction( - 0, - "return-void" - ) - - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/general/voicesearch/VoiceSearchButtonPatch.kt b/src/main/kotlin/app/revanced/patches/music/general/voicesearch/VoiceSearchButtonPatch.kt deleted file mode 100644 index 10c951dab..000000000 --- a/src/main/kotlin/app/revanced/patches/music/general/voicesearch/VoiceSearchButtonPatch.kt +++ /dev/null @@ -1,23 +0,0 @@ -package app.revanced.patches.music.general.voicesearch - -import app.revanced.patcher.data.ResourceContext -import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.shared.voicesearch.VoiceSearchUtils.patchXml -import app.revanced.util.patch.BaseResourcePatch - -@Suppress("unused") -object VoiceSearchButtonPatch : BaseResourcePatch( - name = "Hide voice search button", - description = "Hides the voice search button in the search bar.", - compatiblePackages = COMPATIBLE_PACKAGE, - use = false -) { - override fun execute(context: ResourceContext) { - - context.patchXml( - arrayOf("search_toolbar_view.xml"), - arrayOf("height", "width") - ) - - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/layout/branding/name/CustomBrandingNamePatch.kt b/src/main/kotlin/app/revanced/patches/music/layout/branding/name/CustomBrandingNamePatch.kt index 887d1c03c..b4491ad3c 100644 --- a/src/main/kotlin/app/revanced/patches/music/layout/branding/name/CustomBrandingNamePatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/layout/branding/name/CustomBrandingNamePatch.kt @@ -4,7 +4,6 @@ import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringPatchOption import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.music.utils.integrations.Constants.LANGUAGE_LIST import app.revanced.patches.shared.elements.StringsElementsUtils.removeStringsElements import app.revanced.util.patch.BaseResourcePatch @@ -19,7 +18,7 @@ object CustomBrandingNamePatch : BaseResourcePatch( private val AppNameNotification by stringPatchOption( key = "AppNameNotification", - default = APP_NAME_NOTIFICATION, + default = APP_NAME_LAUNCHER, values = mapOf( "Full name" to APP_NAME_NOTIFICATION, "Short name" to APP_NAME_LAUNCHER @@ -44,7 +43,6 @@ object CustomBrandingNamePatch : BaseResourcePatch( override fun execute(context: ResourceContext) { context.removeStringsElements( - LANGUAGE_LIST, arrayOf("app_launcher_name", "app_name") ) diff --git a/src/main/kotlin/app/revanced/patches/music/misc/backgroundplay/BackgroundPlayPatch.kt b/src/main/kotlin/app/revanced/patches/music/misc/backgroundplay/BackgroundPlayPatch.kt deleted file mode 100644 index 29b3bc7fa..000000000 --- a/src/main/kotlin/app/revanced/patches/music/misc/backgroundplay/BackgroundPlayPatch.kt +++ /dev/null @@ -1,31 +0,0 @@ -package app.revanced.patches.music.misc.backgroundplay - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patches.music.misc.backgroundplay.fingerprints.BackgroundPlaybackFingerprint -import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow - -@Suppress("unused") -object BackgroundPlayPatch : BaseBytecodePatch( - name = "Background play", - description = "Enables playing music in the background.", - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(BackgroundPlaybackFingerprint) -) { - override fun execute(context: BytecodeContext) { - - BackgroundPlaybackFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - addInstructions( - 0, """ - const/4 v0, 0x1 - return v0 - """ - ) - } - } - - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/misc/bitrate/BitrateDefaultValuePatch.kt b/src/main/kotlin/app/revanced/patches/music/misc/bitrate/BitrateDefaultValuePatch.kt index 9fa3f6c99..a8b4d4616 100644 --- a/src/main/kotlin/app/revanced/patches/music/misc/bitrate/BitrateDefaultValuePatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/misc/bitrate/BitrateDefaultValuePatch.kt @@ -7,7 +7,7 @@ import app.revanced.util.patch.BaseResourcePatch @Suppress("DEPRECATION", "unused") object BitrateDefaultValuePatch : BaseResourcePatch( name = "Bitrate default value", - description = "Sets the audio quality to \"Always High\" when you first install the app.", + description = "Sets the audio quality to 'Always High' when you first install the app.", compatiblePackages = COMPATIBLE_PACKAGE ) { private const val RESOURCE_FILE_PATH = "res/xml/data_saving_settings.xml" diff --git a/src/main/kotlin/app/revanced/patches/music/misc/exclusiveaudio/ExclusiveAudioPatch.kt b/src/main/kotlin/app/revanced/patches/music/misc/exclusiveaudio/ExclusiveAudioPatch.kt deleted file mode 100644 index 9ffbc2684..000000000 --- a/src/main/kotlin/app/revanced/patches/music/misc/exclusiveaudio/ExclusiveAudioPatch.kt +++ /dev/null @@ -1,88 +0,0 @@ -package app.revanced.patches.music.misc.exclusiveaudio - -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.patches.music.misc.exclusiveaudio.fingerprints.DataSavingSettingsFragmentFingerprint -import app.revanced.patches.music.misc.exclusiveaudio.fingerprints.MusicBrowserServiceFingerprint -import app.revanced.patches.music.misc.exclusiveaudio.fingerprints.PodCastConfigFingerprint -import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.util.getStringInstructionIndex -import app.revanced.util.getWalkerMethod -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -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.ReferenceInstruction - -@Suppress("unused") -object ExclusiveAudioPatch : BaseBytecodePatch( - name = "Exclusive audio playback", - description = "Unlocks the option to play music without video.", - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf( - DataSavingSettingsFragmentFingerprint, - MusicBrowserServiceFingerprint, - PodCastConfigFingerprint - ) -) { - override fun execute(context: BytecodeContext) { - - /** - * Don't play music videos - */ - MusicBrowserServiceFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val targetIndex = - getStringInstructionIndex("MBS: Return empty root for client: %s, isFullMediaBrowserEnabled: %b, is client browsable: %b, isRedAccount: %b") - - for (index in targetIndex downTo 0) { - if (getInstruction(index).opcode != Opcode.INVOKE_VIRTUAL) continue - - val targetReference = getInstruction(index).reference - - if (!targetReference.toString().endsWith("()Z")) continue - - val walkerMethod = getWalkerMethod(context, index) - - walkerMethod.addInstructions( - 0, """ - const/4 v0, 0x1 - return v0 - """ - ) - break - } - } - } - - /** - * Don't play podcast videos - */ - PodCastConfigFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val insertIndex = implementation!!.instructions.size - 1 - val targetRegister = getInstruction(insertIndex).registerA - - addInstruction( - insertIndex, - "const/4 v$targetRegister, 0x1" - ) - } - } - - DataSavingSettingsFragmentFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val insertIndex = getStringInstructionIndex("pref_key_dont_play_nma_video") + 4 - val targetRegister = getInstruction(insertIndex).registerD - - addInstruction( - insertIndex, - "const/4 v$targetRegister, 0x1" - ) - } - } - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/misc/minimizedplayback/MinimizedPlaybackPatch.kt b/src/main/kotlin/app/revanced/patches/music/misc/minimizedplayback/MinimizedPlaybackPatch.kt index 345726289..09b00fe40 100644 --- a/src/main/kotlin/app/revanced/patches/music/misc/minimizedplayback/MinimizedPlaybackPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/misc/minimizedplayback/MinimizedPlaybackPatch.kt @@ -2,23 +2,112 @@ package app.revanced.patches.music.misc.minimizedplayback 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.patches.music.misc.minimizedplayback.fingerprints.BackgroundPlaybackFingerprint +import app.revanced.patches.music.misc.minimizedplayback.fingerprints.DataSavingSettingsFragmentFingerprint import app.revanced.patches.music.misc.minimizedplayback.fingerprints.MinimizedPlaybackManagerFingerprint +import app.revanced.patches.music.misc.minimizedplayback.fingerprints.MusicBrowserServiceFingerprint +import app.revanced.patches.music.misc.minimizedplayback.fingerprints.PodCastConfigFingerprint import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE +import app.revanced.util.getStringInstructionIndex +import app.revanced.util.getWalkerMethod import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.resultOrThrow +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.ReferenceInstruction @Suppress("unused") object MinimizedPlaybackPatch : BaseBytecodePatch( name = "Enable minimized playback", - description = "Enables playback in miniplayer for Kids music.", + description = "Enables minimized and background playback.", compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(MinimizedPlaybackManagerFingerprint) + fingerprints = setOf( + BackgroundPlaybackFingerprint, + DataSavingSettingsFragmentFingerprint, + MinimizedPlaybackManagerFingerprint, + MusicBrowserServiceFingerprint, + PodCastConfigFingerprint, + ) ) { override fun execute(context: BytecodeContext) { + // region patch for background play + + BackgroundPlaybackFingerprint.resultOrThrow().mutableMethod.addInstructions( + 0, """ + const/4 v0, 0x1 + return v0 + """ + ) + + // endregion + + // region patch for exclusive audio playback + + // don't play music video + MusicBrowserServiceFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val targetIndex = + getStringInstructionIndex("MBS: Return empty root for client: %s, isFullMediaBrowserEnabled: %b, is client browsable: %b, isRedAccount: %b") + + for (index in targetIndex downTo 0) { + if (getInstruction(index).opcode != Opcode.INVOKE_VIRTUAL) continue + + val targetReference = getInstruction(index).reference + + if (!targetReference.toString().endsWith("()Z")) continue + + val walkerMethod = getWalkerMethod(context, index) + + walkerMethod.addInstructions( + 0, """ + const/4 v0, 0x1 + return v0 + """ + ) + break + } + } + } + + // don't play podcast videos + PodCastConfigFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val insertIndex = implementation!!.instructions.size - 1 + val targetRegister = getInstruction(insertIndex).registerA + + addInstruction( + insertIndex, + "const/4 v$targetRegister, 0x1" + ) + } + } + + // don't play podcast videos + DataSavingSettingsFragmentFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val insertIndex = getStringInstructionIndex("pref_key_dont_play_nma_video") + 4 + val targetRegister = getInstruction(insertIndex).registerD + + addInstruction( + insertIndex, + "const/4 v$targetRegister, 0x1" + ) + } + } + + // endregion + + // region patch for minimized playback + MinimizedPlaybackManagerFingerprint.resultOrThrow().mutableMethod.addInstruction( 0, "return-void" ) + // endregion + } } diff --git a/src/main/kotlin/app/revanced/patches/music/misc/backgroundplay/fingerprints/BackgroundPlaybackFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/misc/minimizedplayback/fingerprints/BackgroundPlaybackFingerprint.kt similarity index 84% rename from src/main/kotlin/app/revanced/patches/music/misc/backgroundplay/fingerprints/BackgroundPlaybackFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/misc/minimizedplayback/fingerprints/BackgroundPlaybackFingerprint.kt index a5ce37823..01a307808 100644 --- a/src/main/kotlin/app/revanced/patches/music/misc/backgroundplay/fingerprints/BackgroundPlaybackFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/misc/minimizedplayback/fingerprints/BackgroundPlaybackFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.misc.backgroundplay.fingerprints +package app.revanced.patches.music.misc.minimizedplayback.fingerprints import app.revanced.patcher.extensions.or import app.revanced.util.fingerprint.LiteralValueFingerprint diff --git a/src/main/kotlin/app/revanced/patches/music/misc/exclusiveaudio/fingerprints/DataSavingSettingsFragmentFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/misc/minimizedplayback/fingerprints/DataSavingSettingsFragmentFingerprint.kt similarity index 86% rename from src/main/kotlin/app/revanced/patches/music/misc/exclusiveaudio/fingerprints/DataSavingSettingsFragmentFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/misc/minimizedplayback/fingerprints/DataSavingSettingsFragmentFingerprint.kt index ebfda5a57..b96255cdb 100644 --- a/src/main/kotlin/app/revanced/patches/music/misc/exclusiveaudio/fingerprints/DataSavingSettingsFragmentFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/misc/minimizedplayback/fingerprints/DataSavingSettingsFragmentFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.misc.exclusiveaudio.fingerprints +package app.revanced.patches.music.misc.minimizedplayback.fingerprints import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/music/misc/exclusiveaudio/fingerprints/MusicBrowserServiceFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/misc/minimizedplayback/fingerprints/MusicBrowserServiceFingerprint.kt similarity index 89% rename from src/main/kotlin/app/revanced/patches/music/misc/exclusiveaudio/fingerprints/MusicBrowserServiceFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/misc/minimizedplayback/fingerprints/MusicBrowserServiceFingerprint.kt index fe39a360c..8e890d912 100644 --- a/src/main/kotlin/app/revanced/patches/music/misc/exclusiveaudio/fingerprints/MusicBrowserServiceFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/misc/minimizedplayback/fingerprints/MusicBrowserServiceFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.misc.exclusiveaudio.fingerprints +package app.revanced.patches.music.misc.minimizedplayback.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/music/misc/exclusiveaudio/fingerprints/PodCastConfigFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/misc/minimizedplayback/fingerprints/PodCastConfigFingerprint.kt similarity index 83% rename from src/main/kotlin/app/revanced/patches/music/misc/exclusiveaudio/fingerprints/PodCastConfigFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/misc/minimizedplayback/fingerprints/PodCastConfigFingerprint.kt index c4c75fa8f..57676034d 100644 --- a/src/main/kotlin/app/revanced/patches/music/misc/exclusiveaudio/fingerprints/PodCastConfigFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/misc/minimizedplayback/fingerprints/PodCastConfigFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.misc.exclusiveaudio.fingerprints +package app.revanced.patches.music.misc.minimizedplayback.fingerprints import app.revanced.patcher.extensions.or import app.revanced.util.fingerprint.LiteralValueFingerprint diff --git a/src/main/kotlin/app/revanced/patches/music/misc/premium/GetPremiumPatch.kt b/src/main/kotlin/app/revanced/patches/music/misc/premium/GetPremiumPatch.kt deleted file mode 100644 index 0137984a5..000000000 --- a/src/main/kotlin/app/revanced/patches/music/misc/premium/GetPremiumPatch.kt +++ /dev/null @@ -1,90 +0,0 @@ -package app.revanced.patches.music.misc.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.patches.music.misc.premium.fingerprints.AccountMenuFooterFingerprint -import app.revanced.patches.music.misc.premium.fingerprints.HideGetPremiumFingerprint -import app.revanced.patches.music.misc.premium.fingerprints.MembershipSettingsFingerprint -import app.revanced.patches.music.misc.premium.fingerprints.MembershipSettingsParentFingerprint -import app.revanced.patches.music.navigation.component.NavigationBarComponentPatch -import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch -import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.PrivacyTosFooter -import app.revanced.util.getTargetIndex -import app.revanced.util.getTargetIndexWithReference -import app.revanced.util.getWalkerMethod -import app.revanced.util.getWideLiteralInstructionIndex -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction -import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction -import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction - -@Suppress("unused") -object GetPremiumPatch : BaseBytecodePatch( - name = "Hide get premium", - description = "Hides the \"Get Music Premium\" label from the account menu and settings.", - dependencies = setOf( - NavigationBarComponentPatch::class, - SharedResourceIdPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf( - AccountMenuFooterFingerprint, - HideGetPremiumFingerprint, - MembershipSettingsParentFingerprint - ) -) { - override fun execute(context: BytecodeContext) { - - // Hides get premium button at the bottom of the account switching menu - HideGetPremiumFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val insertIndex = it.scanResult.patternScanResult!!.startIndex - val register = getInstruction(insertIndex).registerA - - addInstruction( - insertIndex + 1, - "const/4 v$register, 0x0" - ) - } - } - - // Hides get premium button at the top of the account switching menu - AccountMenuFooterFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val constIndex = getWideLiteralInstructionIndex(PrivacyTosFooter) - val walkerIndex = getTargetIndex(constIndex + 2, Opcode.INVOKE_VIRTUAL) - val viewIndex = getTargetIndex(constIndex, Opcode.IGET_OBJECT) - val viewReference = getInstruction(viewIndex).reference.toString() - - val walkerMethod = getWalkerMethod(context, walkerIndex) - walkerMethod.apply { - val insertIndex = getTargetIndexWithReference(viewReference) - val nullCheckIndex = getTargetIndex(insertIndex - 1, Opcode.IF_NEZ) - val nullCheckRegister = getInstruction(nullCheckIndex).registerA - - addInstruction( - nullCheckIndex, - "const/4 v$nullCheckRegister, 0x0" - ) - } - } - } - - // Hides premium membership menu in settings - MembershipSettingsParentFingerprint.resultOrThrow().classDef.let { classDef -> - MembershipSettingsFingerprint.resolve(context, classDef) - MembershipSettingsFingerprint.resultOrThrow().mutableMethod.addInstructions( - 0, """ - const/4 v0, 0x0 - return-object v0 - """ - ) - } - - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/misc/spoofappversion/SpoofAppVersionBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/music/misc/spoofappversion/SpoofAppVersionBytecodePatch.kt deleted file mode 100644 index c1f5f4726..000000000 --- a/src/main/kotlin/app/revanced/patches/music/misc/spoofappversion/SpoofAppVersionBytecodePatch.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.music.misc.spoofappversion - -import app.revanced.patches.music.utils.integrations.Constants.MISC_PATH -import app.revanced.patches.shared.spoofappversion.BaseSpoofAppVersionPatch - -object SpoofAppVersionBytecodePatch : BaseSpoofAppVersionPatch( - "$MISC_PATH/SpoofAppVersionPatch;->getVersionOverride(Ljava/lang/String;)Ljava/lang/String;" -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/misc/tastebuilder/TasteBuilderPatch.kt b/src/main/kotlin/app/revanced/patches/music/misc/tastebuilder/TasteBuilderPatch.kt deleted file mode 100644 index eb9989280..000000000 --- a/src/main/kotlin/app/revanced/patches/music/misc/tastebuilder/TasteBuilderPatch.kt +++ /dev/null @@ -1,58 +0,0 @@ -package app.revanced.patches.music.misc.tastebuilder - -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.patches.music.misc.tastebuilder.fingerprints.TasteBuilderConstructorFingerprint -import app.revanced.patches.music.misc.tastebuilder.fingerprints.TasteBuilderSyntheticFingerprint -import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch -import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MusicTasteBuilderShelf -import app.revanced.util.getTargetIndex -import app.revanced.util.getWideLiteralInstructionIndex -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction - -@Suppress("unused") -object TasteBuilderPatch : BaseBytecodePatch( - name = "Hide taste builder", - description = "Hides the \"Tell us which artists you like\" card from the homepage.", - dependencies = setOf(SharedResourceIdPatch::class), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(TasteBuilderConstructorFingerprint) -) { - override fun execute(context: BytecodeContext) { - TasteBuilderConstructorFingerprint.resultOrThrow().let { parentResult -> - TasteBuilderSyntheticFingerprint.resolve(context, parentResult.classDef) - - parentResult.mutableMethod.apply { - val freeRegister = implementation!!.registerCount - parameters.size - 2 - val constIndex = getWideLiteralInstructionIndex(MusicTasteBuilderShelf) - val targetIndex = getTargetIndex(constIndex, Opcode.MOVE_RESULT_OBJECT) - val targetRegister = getInstruction(targetIndex).registerA - - addInstructions( - targetIndex + 1, """ - const/16 v$freeRegister, 0x8 - invoke-virtual {v$targetRegister, v$freeRegister}, Landroid/view/View;->setVisibility(I)V - """ - ) - } - } - - TasteBuilderSyntheticFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val insertIndex = it.scanResult.patternScanResult!!.startIndex - val insertRegister = getInstruction(insertIndex).registerA - - addInstruction( - insertIndex, - "const/4 v$insertRegister, 0x0" - ) - } - } - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/navigation/black/BlackNavigationBarPatch.kt b/src/main/kotlin/app/revanced/patches/music/navigation/black/BlackNavigationBarPatch.kt deleted file mode 100644 index 7ad494479..000000000 --- a/src/main/kotlin/app/revanced/patches/music/navigation/black/BlackNavigationBarPatch.kt +++ /dev/null @@ -1,50 +0,0 @@ -package app.revanced.patches.music.navigation.black - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patches.music.navigation.black.fingerprints.TabLayoutFingerprint -import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.music.utils.integrations.Constants.NAVIGATION_CLASS_DESCRIPTOR -import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch -import app.revanced.patches.music.utils.settings.CategoryType -import app.revanced.patches.music.utils.settings.SettingsPatch -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction - -@Suppress("unused") -object BlackNavigationBarPatch : BaseBytecodePatch( - name = "Enable black navigation bar", - description = "Adds an option to set the navigation bar color to black.", - dependencies = setOf( - SettingsPatch::class, - SharedResourceIdPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(TabLayoutFingerprint) -) { - override fun execute(context: BytecodeContext) { - - TabLayoutFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val targetIndex = it.scanResult.patternScanResult!!.endIndex - val targetRegister = getInstruction(targetIndex).registerA - - addInstructions( - targetIndex + 1, """ - invoke-static {}, $NAVIGATION_CLASS_DESCRIPTOR->enableBlackNavigationBar()I - move-result v$targetRegister - """ - ) - } - } - - SettingsPatch.addSwitchPreference( - CategoryType.NAVIGATION, - "revanced_enable_black_navigation_bar", - "true" - ) - - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/navigation/component/NavigationBarComponentPatch.kt b/src/main/kotlin/app/revanced/patches/music/navigation/components/NavigationBarComponentsPatch.kt similarity index 74% rename from src/main/kotlin/app/revanced/patches/music/navigation/component/NavigationBarComponentPatch.kt rename to src/main/kotlin/app/revanced/patches/music/navigation/components/NavigationBarComponentsPatch.kt index ec2e70c1e..a8eff2973 100644 --- a/src/main/kotlin/app/revanced/patches/music/navigation/component/NavigationBarComponentPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/navigation/components/NavigationBarComponentsPatch.kt @@ -1,10 +1,12 @@ -package app.revanced.patches.music.navigation.component +package app.revanced.patches.music.navigation.components 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.patch.PatchException -import app.revanced.patches.music.navigation.component.fingerprints.TabLayoutTextFingerprint +import app.revanced.patches.music.navigation.components.fingerprints.TabLayoutFingerprint +import app.revanced.patches.music.navigation.components.fingerprints.TabLayoutTextFingerprint import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.music.utils.integrations.Constants.NAVIGATION_CLASS_DESCRIPTOR import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch @@ -21,20 +23,41 @@ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c @Suppress("DEPRECATION", "SpellCheckingInspection", "unused") -object NavigationBarComponentPatch : BaseBytecodePatch( - name = "Hide navigation bar component", - description = "Adds options to hide navigation bar components.", +object NavigationBarComponentsPatch : BaseBytecodePatch( + name = "Navigation bar components", + description = "Adds options to hide or change components related to navigation bar.", dependencies = setOf( SettingsPatch::class, SharedResourceIdPatch::class ), compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(TabLayoutTextFingerprint) + fingerprints = setOf( + TabLayoutFingerprint, + TabLayoutTextFingerprint + ) ) { private const val FLAG = "android:layout_weight" private const val RESOURCE_FILE_PATH = "res/layout/image_with_text_tab.xml" override fun execute(context: BytecodeContext) { + + /** + * Enable black navigation bar + */ + TabLayoutFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val targetIndex = it.scanResult.patternScanResult!!.endIndex + val targetRegister = getInstruction(targetIndex).registerA + + addInstructions( + targetIndex + 1, """ + invoke-static {}, $NAVIGATION_CLASS_DESCRIPTOR->enableBlackNavigationBar()I + move-result v$targetRegister + """ + ) + } + } + /** * Hide navigation labels */ @@ -94,19 +117,34 @@ object NavigationBarComponentPatch : BaseBytecodePatch( SettingsPatch.addSwitchPreference( CategoryType.NAVIGATION, - "revanced_hide_explore_button", + "revanced_enable_black_navigation_bar", + "true" + ) + SettingsPatch.addSwitchPreference( + CategoryType.NAVIGATION, + "revanced_hide_navigation_home_button", "false" ) SettingsPatch.addSwitchPreference( CategoryType.NAVIGATION, - "revanced_hide_home_button", + "revanced_hide_navigation_samples_button", "false" ) SettingsPatch.addSwitchPreference( CategoryType.NAVIGATION, - "revanced_hide_library_button", + "revanced_hide_navigation_explore_button", "false" ) + SettingsPatch.addSwitchPreference( + CategoryType.NAVIGATION, + "revanced_hide_navigation_library_button", + "false" + ) + SettingsPatch.addSwitchPreference( + CategoryType.NAVIGATION, + "revanced_hide_navigation_upgrade_button", + "true" + ) SettingsPatch.addSwitchPreference( CategoryType.NAVIGATION, "revanced_hide_navigation_bar", @@ -117,15 +155,5 @@ object NavigationBarComponentPatch : BaseBytecodePatch( "revanced_hide_navigation_label", "false" ) - SettingsPatch.addSwitchPreference( - CategoryType.NAVIGATION, - "revanced_hide_samples_button", - "false" - ) - SettingsPatch.addSwitchPreference( - CategoryType.NAVIGATION, - "revanced_hide_upgrade_button", - "true" - ) } } diff --git a/src/main/kotlin/app/revanced/patches/music/navigation/black/fingerprints/TabLayoutFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/navigation/components/fingerprints/TabLayoutFingerprint.kt similarity index 89% rename from src/main/kotlin/app/revanced/patches/music/navigation/black/fingerprints/TabLayoutFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/navigation/components/fingerprints/TabLayoutFingerprint.kt index a526fbb8a..30ff0ee68 100644 --- a/src/main/kotlin/app/revanced/patches/music/navigation/black/fingerprints/TabLayoutFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/navigation/components/fingerprints/TabLayoutFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.navigation.black.fingerprints +package app.revanced.patches.music.navigation.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.ColorGrey diff --git a/src/main/kotlin/app/revanced/patches/music/navigation/component/fingerprints/TabLayoutTextFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/navigation/components/fingerprints/TabLayoutTextFingerprint.kt similarity index 91% rename from src/main/kotlin/app/revanced/patches/music/navigation/component/fingerprints/TabLayoutTextFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/navigation/components/fingerprints/TabLayoutTextFingerprint.kt index 4bd367b02..7d6613b23 100644 --- a/src/main/kotlin/app/revanced/patches/music/navigation/component/fingerprints/TabLayoutTextFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/navigation/components/fingerprints/TabLayoutTextFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.navigation.component.fingerprints +package app.revanced.patches.music.navigation.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.Text1 diff --git a/src/main/kotlin/app/revanced/patches/music/player/colormatchplayer/ColorMatchPlayerPatch.kt b/src/main/kotlin/app/revanced/patches/music/player/colormatchplayer/ColorMatchPlayerPatch.kt deleted file mode 100644 index 9f70453d8..000000000 --- a/src/main/kotlin/app/revanced/patches/music/player/colormatchplayer/ColorMatchPlayerPatch.kt +++ /dev/null @@ -1,107 +0,0 @@ -package app.revanced.patches.music.player.colormatchplayer - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction -import app.revanced.patcher.extensions.or -import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.music.utils.fingerprints.MiniPlayerConstructorFingerprint -import app.revanced.patches.music.utils.fingerprints.SwitchToggleColorFingerprint -import app.revanced.patches.music.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR -import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch -import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.ColorGrey -import app.revanced.patches.music.utils.settings.CategoryType -import app.revanced.patches.music.utils.settings.SettingsPatch -import app.revanced.util.getTargetIndex -import app.revanced.util.getTargetIndexReversed -import app.revanced.util.getWideLiteralInstructionIndex -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.AccessFlags -import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.MethodParameter -import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction -import com.android.tools.smali.dexlib2.iface.reference.FieldReference -import com.android.tools.smali.dexlib2.iface.reference.Reference - -@Suppress("unused") -object ColorMatchPlayerPatch : BaseBytecodePatch( - name = "Enable color match player", - description = "Adds an option to match the color of the miniplayer to the fullscreen player.", - dependencies = setOf( - SettingsPatch::class, - SharedResourceIdPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(MiniPlayerConstructorFingerprint) -) { - private lateinit var invokeVirtualReference: Reference - private lateinit var iGetReference: Reference - private lateinit var iPutReference: Reference - private lateinit var methodParameter: List - - override fun execute(context: BytecodeContext) { - - MiniPlayerConstructorFingerprint.resultOrThrow().let { parentResult -> - // Resolves fingerprints - SwitchToggleColorFingerprint.resolve(context, parentResult.classDef) - - SwitchToggleColorFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - methodParameter = parameters - - val relativeIndex = it.scanResult.patternScanResult!!.endIndex + 1 - val invokeVirtualIndex = getTargetIndex(relativeIndex, Opcode.INVOKE_VIRTUAL) - val iGetIndex = getTargetIndex(relativeIndex, Opcode.IGET) - - invokeVirtualReference = getInstruction(invokeVirtualIndex).reference - iGetReference = getInstruction(iGetIndex).reference - } - - parentResult.mutableMethod.apply { - val colorGreyIndex = getWideLiteralInstructionIndex(ColorGrey) - val iPutIndex = getTargetIndex(colorGreyIndex, Opcode.IPUT) - - iPutReference = getInstruction(iPutIndex).reference - } - - parentResult.mutableClass.methods.filter { method -> - method.accessFlags == AccessFlags.PUBLIC or AccessFlags.FINAL - && method.parameters == methodParameter - && method.returnType == "V" - }.forEach { mutableMethod -> - mutableMethod.apply { - val freeRegister = implementation!!.registerCount - parameters.size - 3 - - val invokeDirectIndex = getTargetIndexReversed(implementation!!.instructions.size - 1, Opcode.INVOKE_DIRECT) - val invokeDirectReference = getInstruction(invokeDirectIndex).reference - - addInstructionsWithLabels( - invokeDirectIndex + 1, """ - invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->enableColorMatchPlayer()Z - move-result v$freeRegister - if-eqz v$freeRegister, :off - invoke-virtual {p1}, $invokeVirtualReference - move-result-object v$freeRegister - check-cast v$freeRegister, ${(iGetReference as FieldReference).definingClass} - iget v$freeRegister, v$freeRegister, $iGetReference - iput v$freeRegister, p0, $iPutReference - :off - invoke-direct {p0}, $invokeDirectReference - """ - ) - removeInstruction(invokeDirectIndex) - } - } - } - } - - SettingsPatch.addSwitchPreference( - CategoryType.PLAYER, - "revanced_enable_color_match_player", - "true" - ) - - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/player/components/PlayerComponentsPatch.kt b/src/main/kotlin/app/revanced/patches/music/player/components/PlayerComponentsPatch.kt new file mode 100644 index 000000000..451ef83c6 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/player/components/PlayerComponentsPatch.kt @@ -0,0 +1,836 @@ +package app.revanced.patches.music.player.components + +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.addInstructionsWithLabels +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction +import app.revanced.patcher.extensions.or +import app.revanced.patcher.patch.PatchException +import app.revanced.patcher.util.proxy.mutableTypes.MutableField.Companion.toMutable +import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod +import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable +import app.revanced.patcher.util.smali.ExternalLabel +import app.revanced.patches.music.player.components.fingerprints.HandleSearchRenderedFingerprint +import app.revanced.patches.music.player.components.fingerprints.HandleSignInEventFingerprint +import app.revanced.patches.music.player.components.fingerprints.InteractionLoggingEnumFingerprint +import app.revanced.patches.music.player.components.fingerprints.MiniPlayerConstructorFingerprint +import app.revanced.patches.music.player.components.fingerprints.MiniPlayerDefaultTextFingerprint +import app.revanced.patches.music.player.components.fingerprints.MiniPlayerDefaultViewVisibilityFingerprint +import app.revanced.patches.music.player.components.fingerprints.MiniPlayerParentFingerprint +import app.revanced.patches.music.player.components.fingerprints.MinimizedPlayerFingerprint +import app.revanced.patches.music.player.components.fingerprints.MppWatchWhileLayoutFingerprint +import app.revanced.patches.music.player.components.fingerprints.MusicActivityWidgetFingerprint +import app.revanced.patches.music.player.components.fingerprints.MusicPlaybackControlsFingerprint +import app.revanced.patches.music.player.components.fingerprints.NextButtonVisibilityFingerprint +import app.revanced.patches.music.player.components.fingerprints.OldEngagementPanelFingerprint +import app.revanced.patches.music.player.components.fingerprints.OldPlayerBackgroundFingerprint +import app.revanced.patches.music.player.components.fingerprints.OldPlayerLayoutFingerprint +import app.revanced.patches.music.player.components.fingerprints.PlayerPatchConstructorFingerprint +import app.revanced.patches.music.player.components.fingerprints.RemixGenericButtonFingerprint +import app.revanced.patches.music.player.components.fingerprints.RepeatTrackFingerprint +import app.revanced.patches.music.player.components.fingerprints.ShuffleClassReferenceFingerprint +import app.revanced.patches.music.player.components.fingerprints.SwipeToCloseFingerprint +import app.revanced.patches.music.player.components.fingerprints.SwitchToggleColorFingerprint +import app.revanced.patches.music.player.components.fingerprints.ZenModeFingerprint +import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE +import app.revanced.patches.music.utils.fingerprints.PendingIntentReceiverFingerprint +import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH +import app.revanced.patches.music.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR +import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch +import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.ColorGrey +import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MiniPlayerPlayPauseReplayButton +import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.TopEnd +import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.TopStart +import app.revanced.patches.music.utils.settings.CategoryType +import app.revanced.patches.music.utils.settings.SettingsPatch +import app.revanced.patches.music.utils.videotype.VideoTypeHookPatch +import app.revanced.patches.shared.litho.LithoFilterPatch +import app.revanced.util.getReference +import app.revanced.util.getStringInstructionIndex +import app.revanced.util.getTargetIndex +import app.revanced.util.getTargetIndexReversed +import app.revanced.util.getTargetIndexWithFieldReferenceType +import app.revanced.util.getWalkerMethod +import app.revanced.util.getWideLiteralInstructionIndex +import app.revanced.util.literalInstructionBooleanHook +import app.revanced.util.patch.BaseBytecodePatch +import app.revanced.util.resultOrThrow +import app.revanced.util.transformFields +import app.revanced.util.traverseClassHierarchy +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation +import com.android.tools.smali.dexlib2.iface.MethodParameter +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.ReferenceInstruction +import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction +import com.android.tools.smali.dexlib2.iface.reference.FieldReference +import com.android.tools.smali.dexlib2.iface.reference.MethodReference +import com.android.tools.smali.dexlib2.iface.reference.Reference +import com.android.tools.smali.dexlib2.immutable.ImmutableField +import com.android.tools.smali.dexlib2.immutable.ImmutableMethod +import com.android.tools.smali.dexlib2.util.MethodUtil +import kotlin.properties.Delegates + +@Suppress("unused", "LocalVariableName") +object PlayerComponentsPatch : BaseBytecodePatch( + name = "Player components", + description = "Adds options to hide or change components related to player.", + dependencies = setOf( + LithoFilterPatch::class, + PlayerComponentsResourcePatch::class, + SettingsPatch::class, + SharedResourceIdPatch::class, + VideoTypeHookPatch::class + ), + compatiblePackages = COMPATIBLE_PACKAGE, + fingerprints = setOf( + HandleSearchRenderedFingerprint, + InteractionLoggingEnumFingerprint, + MinimizedPlayerFingerprint, + MiniPlayerConstructorFingerprint, + MiniPlayerDefaultTextFingerprint, + MiniPlayerDefaultViewVisibilityFingerprint, + MiniPlayerParentFingerprint, + MppWatchWhileLayoutFingerprint, + MusicActivityWidgetFingerprint, + MusicPlaybackControlsFingerprint, + OldEngagementPanelFingerprint, + OldPlayerBackgroundFingerprint, + OldPlayerLayoutFingerprint, + PendingIntentReceiverFingerprint, + PlayerPatchConstructorFingerprint, + RemixGenericButtonFingerprint, + RepeatTrackFingerprint, + ShuffleClassReferenceFingerprint, + SwipeToCloseFingerprint, + ) +) { + private const val FILTER_CLASS_DESCRIPTOR = + "$COMPONENTS_PATH/PlayerComponentsFilter;" + + override fun execute(context: BytecodeContext) { + + // region patch for enable color match player + + lateinit var colorMathPlayerInvokeVirtualReference: Reference + lateinit var colorMathPlayerIGetReference: Reference + lateinit var colorMathPlayerIPutReference: Reference + lateinit var colorMathPlayerMethodParameter: List + + MiniPlayerConstructorFingerprint.resultOrThrow().let { parentResult -> + // Resolves fingerprints + SwitchToggleColorFingerprint.resolve(context, parentResult.classDef) + + SwitchToggleColorFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + colorMathPlayerMethodParameter = parameters + + val relativeIndex = it.scanResult.patternScanResult!!.endIndex + 1 + val invokeVirtualIndex = getTargetIndex(relativeIndex, Opcode.INVOKE_VIRTUAL) + val iGetIndex = getTargetIndex(relativeIndex, Opcode.IGET) + + colorMathPlayerInvokeVirtualReference = getInstruction(invokeVirtualIndex).reference + colorMathPlayerIGetReference = getInstruction(iGetIndex).reference + } + + parentResult.mutableMethod.apply { + val colorGreyIndex = getWideLiteralInstructionIndex(ColorGrey) + val iPutIndex = getTargetIndex(colorGreyIndex, Opcode.IPUT) + + colorMathPlayerIPutReference = getInstruction(iPutIndex).reference + } + + parentResult.mutableClass.methods.filter { method -> + method.accessFlags == AccessFlags.PUBLIC or AccessFlags.FINAL + && method.parameters == colorMathPlayerMethodParameter + && method.returnType == "V" + }.forEach { mutableMethod -> + mutableMethod.apply { + val freeRegister = implementation!!.registerCount - parameters.size - 3 + + val invokeDirectIndex = getTargetIndexReversed(implementation!!.instructions.size - 1, Opcode.INVOKE_DIRECT) + val invokeDirectReference = getInstruction(invokeDirectIndex).reference + + addInstructionsWithLabels( + invokeDirectIndex + 1, """ + invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->enableColorMatchPlayer()Z + move-result v$freeRegister + if-eqz v$freeRegister, :off + invoke-virtual {p1}, $colorMathPlayerInvokeVirtualReference + move-result-object v$freeRegister + check-cast v$freeRegister, ${(colorMathPlayerIGetReference as FieldReference).definingClass} + iget v$freeRegister, v$freeRegister, $colorMathPlayerIGetReference + iput v$freeRegister, p0, $colorMathPlayerIPutReference + :off + invoke-direct {p0}, $invokeDirectReference + """ + ) + removeInstruction(invokeDirectIndex) + } + } + } + } + + SettingsPatch.addSwitchPreference( + CategoryType.PLAYER, + "revanced_enable_color_match_player", + "true" + ) + + // endregion + + // region patch for enable force minimized player + + MinimizedPlayerFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val insertIndex = it.scanResult.patternScanResult!!.endIndex + val insertRegister = getInstruction(insertIndex).registerA + + addInstructions( + insertIndex, """ + invoke-static {v$insertRegister}, $PLAYER_CLASS_DESCRIPTOR->enableForceMinimizedPlayer(Z)Z + move-result v$insertRegister + """ + ) + } + } + + SettingsPatch.addSwitchPreference( + CategoryType.PLAYER, + "revanced_enable_force_minimized_player", + "true" + ) + + // endregion + + // region patch for enable next previous button + + val NEXT_BUTTON_FIELD_NAME = "nextButton" + val PREVIOUS_BUTTON_FIELD_NAME = "previousButton" + val NEXT_BUTTON_CLASS_FIELD_NAME = "nextButtonClass" + val PREVIOUS_BUTTON_CLASS_FIELD_NAME = "previousButtonClass" + val NEXT_BUTTON_METHOD_NAME = "setNextButton" + val PREVIOUS_BUTTON_METHOD_NAME = "setPreviousButton" + val NEXT_BUTTON_ONCLICK_METHOD_NAME = "setNextButtonOnClickListener" + val PREVIOUS_BUTTON_ONCLICK_METHOD_NAME = "setPreviousButtonOnClickListener" + val NEXT_BUTTON_INTENT_STRING = "YTM Next" + val PREVIOUS_BUTTON_INTENT_STRING = "YTM Previous" + + val miniPlayerConstructorMutableMethod = + MiniPlayerConstructorFingerprint.resultOrThrow().mutableMethod + + val mppWatchWhileLayoutMutableMethod = + MppWatchWhileLayoutFingerprint.resultOrThrow().mutableMethod + + val pendingIntentReceiverMutableMethod = + PendingIntentReceiverFingerprint.resultOrThrow().mutableMethod + + if (!SettingsPatch.upward0642) { + MiniPlayerParentFingerprint.resultOrThrow().let { parentResult -> + // Resolves fingerprints + NextButtonVisibilityFingerprint.resolve(context, parentResult.classDef) + + NextButtonVisibilityFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val targetIndex = it.scanResult.patternScanResult!!.startIndex + 1 + val targetRegister = + getInstruction(targetIndex).registerA + + addInstructions( + targetIndex + 1, """ + invoke-static {v$targetRegister}, $PLAYER_CLASS_DESCRIPTOR->enableMiniPlayerNextButton(Z)Z + move-result v$targetRegister + """ + ) + } + } + } + } else { + miniPlayerConstructorMutableMethod.setInstanceFieldValue(NEXT_BUTTON_METHOD_NAME, TopStart) + mppWatchWhileLayoutMutableMethod.setStaticFieldValue(NEXT_BUTTON_FIELD_NAME, TopStart) + pendingIntentReceiverMutableMethod.setOnClickListener(context, NEXT_BUTTON_INTENT_STRING, NEXT_BUTTON_ONCLICK_METHOD_NAME, NEXT_BUTTON_CLASS_FIELD_NAME) + } + + miniPlayerConstructorMutableMethod.setInstanceFieldValue(PREVIOUS_BUTTON_METHOD_NAME, TopEnd) + mppWatchWhileLayoutMutableMethod.setStaticFieldValue(PREVIOUS_BUTTON_FIELD_NAME, TopEnd) + pendingIntentReceiverMutableMethod.setOnClickListener(context, PREVIOUS_BUTTON_INTENT_STRING, PREVIOUS_BUTTON_ONCLICK_METHOD_NAME, PREVIOUS_BUTTON_CLASS_FIELD_NAME) + + mppWatchWhileLayoutMutableMethod.setViewArray() + + SettingsPatch.addSwitchPreference( + CategoryType.PLAYER, + "revanced_enable_mini_player_next_button", + "true" + ) + SettingsPatch.addSwitchPreference( + CategoryType.PLAYER, + "revanced_enable_mini_player_previous_button", + "true" + ) + + // endregion + + // region patch for enable swipe to dismiss mini player + + var swipeToDismissWidgetIndex by Delegates.notNull() + lateinit var swipeToDismissIGetObjectReference: Reference + lateinit var swipeToDismissInvokeInterfacePrimaryReference: Reference + lateinit var swipeToDismissCheckCastReference: Reference + lateinit var swipeToDismissSGetObjectReference: Reference + lateinit var swipeToDismissNewInstanceReference: Reference + lateinit var swipeToDismissInvokeStaticReference: Reference + lateinit var swipeToDismissInvokeDirectReference: Reference + lateinit var swipeToDismissInvokeInterfaceSecondaryReference: Reference + + fun MutableMethod.getSwipeToDismissReference( + opcode: Opcode, + reversed: Boolean + ): Reference { + val targetIndex = if (reversed) + getTargetIndexReversed(swipeToDismissWidgetIndex, opcode) + else + getTargetIndex(swipeToDismissWidgetIndex, opcode) + + return getInstruction(targetIndex).reference + } + + if (!SettingsPatch.upward0642) { + SwipeToCloseFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val insertIndex = implementation!!.instructions.size - 1 + val targetRegister = getInstruction(insertIndex).registerA + + addInstructions( + insertIndex, """ + invoke-static {v$targetRegister}, $PLAYER_CLASS_DESCRIPTOR->enableSwipeToDismissMiniPlayer(Z)Z + move-result v$targetRegister + """ + ) + } + } + } else { + + // region dismiss mini player by swiping down + + InteractionLoggingEnumFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val stringIndex = getStringInstructionIndex("INTERACTION_LOGGING_GESTURE_TYPE_SWIPE") + val sPutObjectIndex = getTargetIndex(stringIndex, Opcode.SPUT_OBJECT) + + swipeToDismissSGetObjectReference = getInstruction(sPutObjectIndex).reference + } + } + + MusicActivityWidgetFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + swipeToDismissWidgetIndex = getWideLiteralInstructionIndex(79500) + + swipeToDismissIGetObjectReference = getSwipeToDismissReference(Opcode.IGET_OBJECT, true) + swipeToDismissInvokeInterfacePrimaryReference = getSwipeToDismissReference(Opcode.INVOKE_INTERFACE, true) + swipeToDismissCheckCastReference = getSwipeToDismissReference(Opcode.CHECK_CAST, true) + swipeToDismissNewInstanceReference = getSwipeToDismissReference(Opcode.NEW_INSTANCE, true) + swipeToDismissInvokeStaticReference = getSwipeToDismissReference(Opcode.INVOKE_STATIC, false) + swipeToDismissInvokeDirectReference = getSwipeToDismissReference(Opcode.INVOKE_DIRECT, false) + swipeToDismissInvokeInterfaceSecondaryReference = getSwipeToDismissReference(Opcode.INVOKE_INTERFACE, false) + } + } + + HandleSearchRenderedFingerprint.resultOrThrow().let { parentResult -> + // resolves fingerprints + HandleSignInEventFingerprint.resolve(context, parentResult.classDef) + + HandleSignInEventFingerprint.resultOrThrow().let { + val dismissBehaviorMethod = it.getWalkerMethod(context, it.scanResult.patternScanResult!!.startIndex) + + dismissBehaviorMethod.apply { + val insertIndex = getTargetIndexWithFieldReferenceType("Ljava/util/concurrent/atomic/AtomicBoolean;") + val primaryRegister = getInstruction(insertIndex).registerB + val secondaryRegister = primaryRegister + 1 + val tertiaryRegister = secondaryRegister + 1 + + val freeRegister = implementation!!.registerCount - parameters.size - 2 + + addInstructionsWithLabels( + insertIndex, """ + invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->enableSwipeToDismissMiniPlayer()Z + move-result v$freeRegister + if-nez v$freeRegister, :dismiss + iget-object v$primaryRegister, v$primaryRegister, $swipeToDismissIGetObjectReference + invoke-interface {v$primaryRegister}, $swipeToDismissInvokeInterfacePrimaryReference + move-result-object v$primaryRegister + check-cast v$primaryRegister, $swipeToDismissCheckCastReference + sget-object v$secondaryRegister, $swipeToDismissSGetObjectReference + new-instance v$tertiaryRegister, $swipeToDismissNewInstanceReference + const p0, 0x878b + invoke-static {p0}, $swipeToDismissInvokeStaticReference + move-result-object p0 + invoke-direct {v$tertiaryRegister, p0}, $swipeToDismissInvokeDirectReference + const/4 p0, 0x0 + invoke-interface {v$primaryRegister, v$secondaryRegister, v$tertiaryRegister, p0}, $swipeToDismissInvokeInterfaceSecondaryReference + return-void + """, ExternalLabel("dismiss", getInstruction(insertIndex)) + ) + } + } + } + + // endregion + + // region hides default text display when the app is cold started + + MiniPlayerDefaultTextFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val insertIndex = it.scanResult.patternScanResult!!.endIndex + val insertRegister = getInstruction(insertIndex).registerB + + addInstructions( + insertIndex, """ + invoke-static {v$insertRegister}, $PLAYER_CLASS_DESCRIPTOR->enableSwipeToDismissMiniPlayer(Ljava/lang/Object;)Ljava/lang/Object; + move-result-object v$insertRegister + """ + ) + } + } + + // endregion + + // region hides default text display after dismissing the mini player + + MiniPlayerDefaultViewVisibilityFingerprint.resultOrThrow().let { + it.mutableClass.methods.find { method -> + method.parameters == listOf("Landroid/view/View;", "I") + }?.apply { + val bottomSheetBehaviorIndex = implementation!!.instructions.indexOfFirst { instruction -> + instruction.opcode == Opcode.INVOKE_VIRTUAL + && instruction.getReference()?.definingClass == "Lcom/google/android/material/bottomsheet/BottomSheetBehavior;" + && instruction.getReference()?.parameterTypes?.first() == "Z" + } + if (bottomSheetBehaviorIndex < 0) + throw PatchException("Could not find bottomSheetBehaviorIndex") + + val freeRegister = getInstruction(bottomSheetBehaviorIndex).registerD + + addInstructionsWithLabels( + bottomSheetBehaviorIndex - 2, """ + invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->enableSwipeToDismissMiniPlayer()Z + move-result v$freeRegister + if-nez v$freeRegister, :dismiss + """, ExternalLabel("dismiss", getInstruction(bottomSheetBehaviorIndex + 1)) + ) + } ?: throw PatchException("Could not find targetMethod") + + } + + // endregion + + } + + SettingsPatch.addSwitchPreference( + CategoryType.PLAYER, + "revanced_enable_swipe_to_dismiss_mini_player", + "true" + ) + + // endregion + + // region patch for enable zen mode + + MiniPlayerConstructorFingerprint.resultOrThrow().let { parentResult -> + // resolves fingerprints + SwitchToggleColorFingerprint.resolve(context, parentResult.classDef) + ZenModeFingerprint.resolve(context, parentResult.classDef) + + // this method is used for old player background (deprecated since YT Music v6.34.51) + ZenModeFingerprint.result?.let { + it.mutableMethod.apply { + val startIndex = it.scanResult.patternScanResult!!.startIndex + val targetRegister = getInstruction(startIndex).registerA + + val insertIndex = it.scanResult.patternScanResult!!.endIndex + 1 + + addInstructions( + insertIndex, """ + invoke-static {v$targetRegister}, $PLAYER_CLASS_DESCRIPTOR->enableZenMode(I)I + move-result v$targetRegister + """ + ) + } + } // no exception + + SwitchToggleColorFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val invokeDirectIndex = getTargetIndex(Opcode.INVOKE_DIRECT) + val walkerMethod = getWalkerMethod(context, invokeDirectIndex) + + walkerMethod.addInstructions( + 0, """ + invoke-static {p1}, $PLAYER_CLASS_DESCRIPTOR->enableZenMode(I)I + move-result p1 + invoke-static {p2}, $PLAYER_CLASS_DESCRIPTOR->enableZenMode(I)I + move-result p2 + """ + ) + } + } + } + + SettingsPatch.addSwitchPreference( + CategoryType.PLAYER, + "revanced_enable_zen_mode", + "false" + ) + SettingsPatch.addSwitchPreference( + CategoryType.PLAYER, + "revanced_enable_zen_mode_podcast", + "false", + "revanced_enable_zen_mode" + ) + + // endregion + + // region patch for hide channel guideline, timestamps & emoji picker buttons + + LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR) + + SettingsPatch.addSwitchPreference( + CategoryType.PLAYER, + "revanced_hide_comment_channel_guidelines", + "true" + ) + SettingsPatch.addSwitchPreference( + CategoryType.PLAYER, + "revanced_hide_comment_timestamp_and_emoji_buttons", + "false" + ) + + // region patch for hide fullscreen share button + + RemixGenericButtonFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val targetIndex = it.scanResult.patternScanResult!!.endIndex + val targetRegister = getInstruction(targetIndex).registerA + + addInstructions( + targetIndex + 1, """ + invoke-static {v$targetRegister}, $PLAYER_CLASS_DESCRIPTOR->hideFullscreenShareButton(I)I + move-result v$targetRegister + """ + ) + } + } + + SettingsPatch.addSwitchPreference( + CategoryType.PLAYER, + "revanced_hide_fullscreen_share_button", + "false" + ) + + // endregion + + // region patch for remember repeat state + + RepeatTrackFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val targetIndex = it.scanResult.patternScanResult!!.endIndex + val targetRegister = getInstruction(targetIndex).registerA + + addInstructions( + targetIndex, """ + invoke-static {v$targetRegister}, $PLAYER_CLASS_DESCRIPTOR->rememberRepeatState(Z)Z + move-result v$targetRegister + """ + ) + } + } + + SettingsPatch.addSwitchPreference( + CategoryType.PLAYER, + "revanced_remember_repeat_state", + "true" + ) + + // endregion + + // region patch for remember shuffle state + + val MUSIC_PLAYBACK_CONTROLS_CLASS_DESCRIPTOR = + "Lcom/google/android/apps/youtube/music/watchpage/MusicPlaybackControls;" + + lateinit var rememberShuffleStateObjectClass: String + lateinit var rememberShuffleStateImageViewReference: Reference + lateinit var rememberShuffleStateShuffleStateLabel: String + + ShuffleClassReferenceFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + rememberShuffleStateObjectClass = definingClass + + val startIndex = it.scanResult.patternScanResult!!.startIndex + val endIndex = it.scanResult.patternScanResult!!.endIndex + val imageViewIndex = getTargetIndexWithFieldReferenceType("Landroid/widget/ImageView;") + + val shuffleReference1 = getInstruction(startIndex).reference + val shuffleReference2 = getInstruction(startIndex + 1).reference + val shuffleReference3 = getInstruction(endIndex).reference + val shuffleFieldReference = shuffleReference3 as FieldReference + rememberShuffleStateImageViewReference = getInstruction(imageViewIndex).reference + + rememberShuffleStateShuffleStateLabel = """ + iget-object v1, v0, $shuffleReference1 + invoke-interface {v1}, $shuffleReference2 + move-result-object v1 + check-cast v1, ${shuffleFieldReference.definingClass} + iget-object v1, v1, $shuffleReference3 + invoke-virtual {v1}, ${shuffleFieldReference.type}->ordinal()I + move-result v1 + """ + } + + val constructorMethod = + it.mutableClass.methods.first { method -> MethodUtil.isConstructor(method) } + val onClickMethod = it.mutableClass.methods.first { method -> method.name == "onClick" } + + constructorMethod.apply { + addInstruction( + implementation!!.instructions.size - 1, + "sput-object p0, $MUSIC_PLAYBACK_CONTROLS_CLASS_DESCRIPTOR->shuffleClass:$rememberShuffleStateObjectClass" + ) + } + + onClickMethod.apply { + addInstructions( + 0, """ + move-object v0, p0 + """ + rememberShuffleStateShuffleStateLabel + """ + invoke-static {v1}, $PLAYER_CLASS_DESCRIPTOR->setShuffleState(I)V + """ + ) + } + + context.traverseClassHierarchy(it.mutableClass) { + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL + transformFields { + ImmutableField( + definingClass, + name, + type, + AccessFlags.PUBLIC or AccessFlags.PUBLIC, + null, + annotations, + null + ).toMutable() + } + } + } + + MusicPlaybackControlsFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + addInstruction( + 0, + "invoke-virtual {v0}, $MUSIC_PLAYBACK_CONTROLS_CLASS_DESCRIPTOR->rememberShuffleState()V" + ) + + val shuffleField = ImmutableField( + definingClass, + "shuffleClass", + rememberShuffleStateObjectClass, + AccessFlags.PUBLIC or AccessFlags.STATIC, + null, + annotations, + null + ).toMutable() + + val shuffleMethod = ImmutableMethod( + definingClass, + "rememberShuffleState", + emptyList(), + "V", + AccessFlags.PUBLIC or AccessFlags.FINAL, + annotations, null, + MutableMethodImplementation(5) + ).toMutable() + + shuffleMethod.addInstructionsWithLabels( + 0, """ + invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->getShuffleState()I + move-result v2 + if-nez v2, :dont_shuffle + sget-object v0, $MUSIC_PLAYBACK_CONTROLS_CLASS_DESCRIPTOR->shuffleClass:$rememberShuffleStateObjectClass + """ + rememberShuffleStateShuffleStateLabel + """ + iget-object v3, v0, $rememberShuffleStateImageViewReference + invoke-virtual {v3}, Landroid/widget/ImageView;->performClick()Z + if-eqz v1, :dont_shuffle + invoke-virtual {v3}, Landroid/widget/ImageView;->performClick()Z + :dont_shuffle + return-void + """ + ) + + it.mutableClass.methods.add(shuffleMethod) + it.mutableClass.staticFields.add(shuffleField) + } + } + + SettingsPatch.addSwitchPreference( + CategoryType.PLAYER, + "revanced_remember_shuffle_state", + "true" + ) + + // endregion + + // region patch for restore old comments popup panels + + OldEngagementPanelFingerprint.literalInstructionBooleanHook( + 45427672, + "$PLAYER_CLASS_DESCRIPTOR->restoreOldCommentsPopUpPanels(Z)Z" + ) + + SettingsPatch.addSwitchPreference( + CategoryType.PLAYER, + "revanced_restore_old_comments_popup_panels", + "false" + ) + + // endregion + + // region patch for restore old player background + + OldPlayerBackgroundFingerprint.result?.let { + OldPlayerBackgroundFingerprint.literalInstructionBooleanHook( + 45415319, + "$PLAYER_CLASS_DESCRIPTOR->restoreOldPlayerBackground(Z)Z" + ) + + SettingsPatch.addSwitchPreference( + CategoryType.PLAYER, + "revanced_restore_old_player_background", + "false" + ) + } + + // endregion + + // region patch for restore old player layout + + OldPlayerLayoutFingerprint.result?.let { + OldPlayerLayoutFingerprint.literalInstructionBooleanHook( + 45399578, + "$PLAYER_CLASS_DESCRIPTOR->restoreOldPlayerLayout(Z)Z" + ) + + SettingsPatch.addSwitchPreference( + CategoryType.PLAYER, + "revanced_restore_old_player_layout", + "false" + ) + } + + // endregion + + } + + private fun MutableMethod.setInstanceFieldValue( + methodName: String, + viewId: Long + ) { + val miniPlayerPlayPauseReplayButtonIndex = getWideLiteralInstructionIndex(MiniPlayerPlayPauseReplayButton) + val miniPlayerPlayPauseReplayButtonRegister = getInstruction(miniPlayerPlayPauseReplayButtonIndex).registerA + val findViewByIdIndex = getTargetIndex(miniPlayerPlayPauseReplayButtonIndex, Opcode.INVOKE_VIRTUAL) + val parentViewRegister = getInstruction(findViewByIdIndex).registerC + + addInstructions( + miniPlayerPlayPauseReplayButtonIndex, """ + const v$miniPlayerPlayPauseReplayButtonRegister, $viewId + invoke-virtual {v$parentViewRegister, v$miniPlayerPlayPauseReplayButtonRegister}, Landroid/view/View;->findViewById(I)Landroid/view/View; + move-result-object v$miniPlayerPlayPauseReplayButtonRegister + invoke-static {v$miniPlayerPlayPauseReplayButtonRegister}, $PLAYER_CLASS_DESCRIPTOR->$methodName(Landroid/view/View;)V + """ + ) + } + + private fun MutableMethod.setStaticFieldValue( + fieldName: String, + viewId: Long + ) { + val miniPlayerPlayPauseReplayButtonIndex = getWideLiteralInstructionIndex(MiniPlayerPlayPauseReplayButton) + val constRegister = getInstruction(miniPlayerPlayPauseReplayButtonIndex).registerA + val findViewByIdIndex = getTargetIndex(miniPlayerPlayPauseReplayButtonIndex, Opcode.INVOKE_VIRTUAL) + val findViewByIdRegister = getInstruction(findViewByIdIndex).registerC + + addInstructions( + miniPlayerPlayPauseReplayButtonIndex, """ + const v$constRegister, $viewId + invoke-virtual {v$findViewByIdRegister, v$constRegister}, $definingClass->findViewById(I)Landroid/view/View; + move-result-object v$constRegister + sput-object v$constRegister, $PLAYER_CLASS_DESCRIPTOR->$fieldName:Landroid/view/View; + """ + ) + } + + private fun MutableMethod.setViewArray() { + val miniPlayerPlayPauseReplayButtonIndex = getWideLiteralInstructionIndex(MiniPlayerPlayPauseReplayButton) + val invokeStaticIndex = getTargetIndex(miniPlayerPlayPauseReplayButtonIndex, Opcode.INVOKE_STATIC) + val viewArrayRegister = getInstruction(invokeStaticIndex).registerC + + addInstructions( + invokeStaticIndex, """ + invoke-static {v$viewArrayRegister}, $PLAYER_CLASS_DESCRIPTOR->getViewArray([Landroid/view/View;)[Landroid/view/View; + move-result-object v$viewArrayRegister + """ + ) + } + + private fun MutableMethod.setOnClickListener( + context: BytecodeContext, + intentString: String, + methodName: String, + fieldName: String + ) { + val startIndex = getStringInstructionIndex(intentString) + val onClickIndex = getTargetIndexReversed(startIndex, Opcode.INVOKE_VIRTUAL) + val onClickReference = getInstruction(onClickIndex).reference + val onClickReferenceDefiningClass = (onClickReference as MethodReference).definingClass + + val onClickClass = + context.findClass(onClickReferenceDefiningClass)!!.mutableClass + + onClickClass.methods.find { method -> method.name == "" } + ?.apply { + addInstruction( + implementation!!.instructions.size - 1, + "sput-object p0, $PLAYER_CLASS_DESCRIPTOR->$fieldName:$onClickReferenceDefiningClass" + ) + } ?: throw PatchException("onClickClass not found!") + + PlayerPatchConstructorFingerprint.resultOrThrow().let { + val mutableClass = it.mutableClass + mutableClass.methods.find { method -> method.name == methodName } + ?.apply { + mutableClass.staticFields.add( + ImmutableField( + definingClass, + fieldName, + onClickReferenceDefiningClass, + AccessFlags.PUBLIC or AccessFlags.STATIC, + null, + annotations, + null + ).toMutable() + ) + addInstructionsWithLabels( + 0, """ + sget-object v0, $PLAYER_CLASS_DESCRIPTOR->$fieldName:$onClickReferenceDefiningClass + if-eqz v0, :ignore + invoke-virtual {v0}, $onClickReference + :ignore + return-void + """ + ) + } + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/player/nextprevious/MiniPlayerButtonResourcePatch.kt b/src/main/kotlin/app/revanced/patches/music/player/components/PlayerComponentsResourcePatch.kt similarity index 97% rename from src/main/kotlin/app/revanced/patches/music/player/nextprevious/MiniPlayerButtonResourcePatch.kt rename to src/main/kotlin/app/revanced/patches/music/player/components/PlayerComponentsResourcePatch.kt index 2683fc44d..5f6b9ba28 100644 --- a/src/main/kotlin/app/revanced/patches/music/player/nextprevious/MiniPlayerButtonResourcePatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/player/components/PlayerComponentsResourcePatch.kt @@ -1,6 +1,6 @@ @file:Suppress("DEPRECATION") -package app.revanced.patches.music.player.nextprevious +package app.revanced.patches.music.player.components import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.patch.ResourcePatch @@ -14,7 +14,7 @@ import org.w3c.dom.Element import java.io.Closeable @Patch(dependencies = [SettingsPatch::class]) -object MiniPlayerButtonResourcePatch : ResourcePatch(), Closeable { +object PlayerComponentsResourcePatch : ResourcePatch(), Closeable { private const val IMAGE_VIEW_TAG_NAME = "com.google.android.libraries.youtube.common.ui.TouchImageView" private const val NEXT_BUTTON_VIEW_ID = diff --git a/src/main/kotlin/app/revanced/patches/music/player/swipetodismiss/fingerprints/HandleSearchRenderedFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/HandleSearchRenderedFingerprint.kt similarity index 79% rename from src/main/kotlin/app/revanced/patches/music/player/swipetodismiss/fingerprints/HandleSearchRenderedFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/HandleSearchRenderedFingerprint.kt index 012f02ebc..335313787 100644 --- a/src/main/kotlin/app/revanced/patches/music/player/swipetodismiss/fingerprints/HandleSearchRenderedFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/HandleSearchRenderedFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.player.swipetodismiss.fingerprints +package app.revanced.patches.music.player.components.fingerprints import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/music/player/swipetodismiss/fingerprints/HandleSignInEventFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/HandleSignInEventFingerprint.kt similarity index 84% rename from src/main/kotlin/app/revanced/patches/music/player/swipetodismiss/fingerprints/HandleSignInEventFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/HandleSignInEventFingerprint.kt index 58cf2c27c..460f064d7 100644 --- a/src/main/kotlin/app/revanced/patches/music/player/swipetodismiss/fingerprints/HandleSignInEventFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/HandleSignInEventFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.player.swipetodismiss.fingerprints +package app.revanced.patches.music.player.components.fingerprints import app.revanced.patcher.fingerprint.MethodFingerprint import com.android.tools.smali.dexlib2.Opcode diff --git a/src/main/kotlin/app/revanced/patches/music/player/swipetodismiss/fingerprints/InteractionLoggingEnumFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/InteractionLoggingEnumFingerprint.kt similarity index 75% rename from src/main/kotlin/app/revanced/patches/music/player/swipetodismiss/fingerprints/InteractionLoggingEnumFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/InteractionLoggingEnumFingerprint.kt index 39afea39c..25dc8c8e9 100644 --- a/src/main/kotlin/app/revanced/patches/music/player/swipetodismiss/fingerprints/InteractionLoggingEnumFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/InteractionLoggingEnumFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.player.swipetodismiss.fingerprints +package app.revanced.patches.music.player.components.fingerprints import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/music/utils/fingerprints/MiniPlayerConstructorFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/MiniPlayerConstructorFingerprint.kt similarity index 91% rename from src/main/kotlin/app/revanced/patches/music/utils/fingerprints/MiniPlayerConstructorFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/MiniPlayerConstructorFingerprint.kt index 4a38e2e07..3ac11537f 100644 --- a/src/main/kotlin/app/revanced/patches/music/utils/fingerprints/MiniPlayerConstructorFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/MiniPlayerConstructorFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.utils.fingerprints +package app.revanced.patches.music.player.components.fingerprints import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.ColorGrey diff --git a/src/main/kotlin/app/revanced/patches/music/player/swipetodismiss/fingerprints/MiniPlayerDefaultTextFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/MiniPlayerDefaultTextFingerprint.kt similarity index 87% rename from src/main/kotlin/app/revanced/patches/music/player/swipetodismiss/fingerprints/MiniPlayerDefaultTextFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/MiniPlayerDefaultTextFingerprint.kt index fe2db5faa..84ae01df7 100644 --- a/src/main/kotlin/app/revanced/patches/music/player/swipetodismiss/fingerprints/MiniPlayerDefaultTextFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/MiniPlayerDefaultTextFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.player.swipetodismiss.fingerprints +package app.revanced.patches.music.player.components.fingerprints import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MiniPlayerDefaultText import app.revanced.util.fingerprint.LiteralValueFingerprint diff --git a/src/main/kotlin/app/revanced/patches/music/player/swipetodismiss/fingerprints/MiniPlayerDefaultViewVisibilityFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/MiniPlayerDefaultViewVisibilityFingerprint.kt similarity index 90% rename from src/main/kotlin/app/revanced/patches/music/player/swipetodismiss/fingerprints/MiniPlayerDefaultViewVisibilityFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/MiniPlayerDefaultViewVisibilityFingerprint.kt index 200a20219..a0f926e9f 100644 --- a/src/main/kotlin/app/revanced/patches/music/player/swipetodismiss/fingerprints/MiniPlayerDefaultViewVisibilityFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/MiniPlayerDefaultViewVisibilityFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.player.swipetodismiss.fingerprints +package app.revanced.patches.music.player.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/music/player/nextprevious/fingerprints/MiniPlayerParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/MiniPlayerParentFingerprint.kt similarity index 87% rename from src/main/kotlin/app/revanced/patches/music/player/nextprevious/fingerprints/MiniPlayerParentFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/MiniPlayerParentFingerprint.kt index b9c153727..dd066fde4 100644 --- a/src/main/kotlin/app/revanced/patches/music/player/nextprevious/fingerprints/MiniPlayerParentFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/MiniPlayerParentFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.player.nextprevious.fingerprints +package app.revanced.patches.music.player.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MiniPlayerMdxPlaying diff --git a/src/main/kotlin/app/revanced/patches/music/player/minimizedplayer/fingerprints/MinimizedPlayerFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/MinimizedPlayerFingerprint.kt similarity index 88% rename from src/main/kotlin/app/revanced/patches/music/player/minimizedplayer/fingerprints/MinimizedPlayerFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/MinimizedPlayerFingerprint.kt index d342cc3ad..37f5af3d9 100644 --- a/src/main/kotlin/app/revanced/patches/music/player/minimizedplayer/fingerprints/MinimizedPlayerFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/MinimizedPlayerFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.player.minimizedplayer.fingerprints +package app.revanced.patches.music.player.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/music/player/nextprevious/fingerprints/MppWatchWhileLayoutFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/MppWatchWhileLayoutFingerprint.kt similarity index 90% rename from src/main/kotlin/app/revanced/patches/music/player/nextprevious/fingerprints/MppWatchWhileLayoutFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/MppWatchWhileLayoutFingerprint.kt index cc28303f1..a7e57557d 100644 --- a/src/main/kotlin/app/revanced/patches/music/player/nextprevious/fingerprints/MppWatchWhileLayoutFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/MppWatchWhileLayoutFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.player.nextprevious.fingerprints +package app.revanced.patches.music.player.components.fingerprints import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MiniPlayerPlayPauseReplayButton diff --git a/src/main/kotlin/app/revanced/patches/music/player/swipetodismiss/fingerprints/MusicActivityWidgetFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/MusicActivityWidgetFingerprint.kt similarity index 85% rename from src/main/kotlin/app/revanced/patches/music/player/swipetodismiss/fingerprints/MusicActivityWidgetFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/MusicActivityWidgetFingerprint.kt index 47daebcfc..0eb77a374 100644 --- a/src/main/kotlin/app/revanced/patches/music/player/swipetodismiss/fingerprints/MusicActivityWidgetFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/MusicActivityWidgetFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.player.swipetodismiss.fingerprints +package app.revanced.patches.music.player.components.fingerprints import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.util.containsWideLiteralInstructionIndex diff --git a/src/main/kotlin/app/revanced/patches/music/player/shuffle/fingerprints/MusicPlaybackControlsFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/MusicPlaybackControlsFingerprint.kt similarity index 90% rename from src/main/kotlin/app/revanced/patches/music/player/shuffle/fingerprints/MusicPlaybackControlsFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/MusicPlaybackControlsFingerprint.kt index 2b6e559c5..3d428c5e1 100644 --- a/src/main/kotlin/app/revanced/patches/music/player/shuffle/fingerprints/MusicPlaybackControlsFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/MusicPlaybackControlsFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.player.shuffle.fingerprints +package app.revanced.patches.music.player.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/music/player/nextprevious/fingerprints/NextButtonVisibilityFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/NextButtonVisibilityFingerprint.kt similarity index 88% rename from src/main/kotlin/app/revanced/patches/music/player/nextprevious/fingerprints/NextButtonVisibilityFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/NextButtonVisibilityFingerprint.kt index adeb0719e..853184f70 100644 --- a/src/main/kotlin/app/revanced/patches/music/player/nextprevious/fingerprints/NextButtonVisibilityFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/NextButtonVisibilityFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.player.nextprevious.fingerprints +package app.revanced.patches.music.player.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/OldEngagementPanelFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/OldEngagementPanelFingerprint.kt new file mode 100644 index 000000000..cfac0fb62 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/OldEngagementPanelFingerprint.kt @@ -0,0 +1,9 @@ +package app.revanced.patches.music.player.components.fingerprints + +import app.revanced.util.fingerprint.LiteralValueFingerprint + +internal object OldEngagementPanelFingerprint : LiteralValueFingerprint( + returnType = "Z", + parameters = emptyList(), + literalSupplier = { 45427672 } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/player/oldplayerbackground/fingerprints/OldPlayerBackgroundFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/OldPlayerBackgroundFingerprint.kt similarity index 78% rename from src/main/kotlin/app/revanced/patches/music/player/oldplayerbackground/fingerprints/OldPlayerBackgroundFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/OldPlayerBackgroundFingerprint.kt index 1ef690dc9..f6185e1e9 100644 --- a/src/main/kotlin/app/revanced/patches/music/player/oldplayerbackground/fingerprints/OldPlayerBackgroundFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/OldPlayerBackgroundFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.player.oldplayerbackground.fingerprints +package app.revanced.patches.music.player.components.fingerprints import app.revanced.util.fingerprint.LiteralValueFingerprint diff --git a/src/main/kotlin/app/revanced/patches/music/player/oldplayerlayout/fingerprints/OldPlayerLayoutFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/OldPlayerLayoutFingerprint.kt similarity index 79% rename from src/main/kotlin/app/revanced/patches/music/player/oldplayerlayout/fingerprints/OldPlayerLayoutFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/OldPlayerLayoutFingerprint.kt index 5b632fa31..e4034b50c 100644 --- a/src/main/kotlin/app/revanced/patches/music/player/oldplayerlayout/fingerprints/OldPlayerLayoutFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/OldPlayerLayoutFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.player.oldplayerlayout.fingerprints +package app.revanced.patches.music.player.components.fingerprints import app.revanced.util.fingerprint.LiteralValueFingerprint diff --git a/src/main/kotlin/app/revanced/patches/music/player/nextprevious/fingerprints/PlayerPatchConstructorFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/PlayerPatchConstructorFingerprint.kt similarity index 85% rename from src/main/kotlin/app/revanced/patches/music/player/nextprevious/fingerprints/PlayerPatchConstructorFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/PlayerPatchConstructorFingerprint.kt index 8a69e02cc..5badb1f9c 100644 --- a/src/main/kotlin/app/revanced/patches/music/player/nextprevious/fingerprints/PlayerPatchConstructorFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/PlayerPatchConstructorFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.player.nextprevious.fingerprints +package app.revanced.patches.music.player.components.fingerprints import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patches.music.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR diff --git a/src/main/kotlin/app/revanced/patches/music/player/share/fingerprints/RemixGenericButtonFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/RemixGenericButtonFingerprint.kt similarity index 90% rename from src/main/kotlin/app/revanced/patches/music/player/share/fingerprints/RemixGenericButtonFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/RemixGenericButtonFingerprint.kt index ef0af7e5d..6e9c75bd8 100644 --- a/src/main/kotlin/app/revanced/patches/music/player/share/fingerprints/RemixGenericButtonFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/RemixGenericButtonFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.player.share.fingerprints +package app.revanced.patches.music.player.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.RemixGenericButtonSize diff --git a/src/main/kotlin/app/revanced/patches/music/player/repeat/fingerprints/RepeatTrackFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/RepeatTrackFingerprint.kt similarity index 90% rename from src/main/kotlin/app/revanced/patches/music/player/repeat/fingerprints/RepeatTrackFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/RepeatTrackFingerprint.kt index 355ebbe05..2c61f75b2 100644 --- a/src/main/kotlin/app/revanced/patches/music/player/repeat/fingerprints/RepeatTrackFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/RepeatTrackFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.player.repeat.fingerprints +package app.revanced.patches.music.player.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/music/player/shuffle/fingerprints/ShuffleClassReferenceFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/ShuffleClassReferenceFingerprint.kt similarity index 90% rename from src/main/kotlin/app/revanced/patches/music/player/shuffle/fingerprints/ShuffleClassReferenceFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/ShuffleClassReferenceFingerprint.kt index 4f91c86a2..058bb631d 100644 --- a/src/main/kotlin/app/revanced/patches/music/player/shuffle/fingerprints/ShuffleClassReferenceFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/ShuffleClassReferenceFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.player.shuffle.fingerprints +package app.revanced.patches.music.player.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/music/player/swipetodismiss/fingerprints/SwipeToCloseFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/SwipeToCloseFingerprint.kt similarity index 75% rename from src/main/kotlin/app/revanced/patches/music/player/swipetodismiss/fingerprints/SwipeToCloseFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/SwipeToCloseFingerprint.kt index c0deb3d63..66dc077d9 100644 --- a/src/main/kotlin/app/revanced/patches/music/player/swipetodismiss/fingerprints/SwipeToCloseFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/SwipeToCloseFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.player.swipetodismiss.fingerprints +package app.revanced.patches.music.player.components.fingerprints import app.revanced.util.fingerprint.LiteralValueFingerprint diff --git a/src/main/kotlin/app/revanced/patches/music/utils/fingerprints/SwitchToggleColorFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/SwitchToggleColorFingerprint.kt similarity index 88% rename from src/main/kotlin/app/revanced/patches/music/utils/fingerprints/SwitchToggleColorFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/SwitchToggleColorFingerprint.kt index e367e1c88..6a548d9c9 100644 --- a/src/main/kotlin/app/revanced/patches/music/utils/fingerprints/SwitchToggleColorFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/SwitchToggleColorFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.utils.fingerprints +package app.revanced.patches.music.player.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/music/player/zenmode/fingerprints/ZenModeFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/ZenModeFingerprint.kt similarity index 89% rename from src/main/kotlin/app/revanced/patches/music/player/zenmode/fingerprints/ZenModeFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/ZenModeFingerprint.kt index 337a8df45..463433bb2 100644 --- a/src/main/kotlin/app/revanced/patches/music/player/zenmode/fingerprints/ZenModeFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/player/components/fingerprints/ZenModeFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.player.zenmode.fingerprints +package app.revanced.patches.music.player.components.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/music/player/minimizedplayer/MinimizedPlayerPatch.kt b/src/main/kotlin/app/revanced/patches/music/player/minimizedplayer/MinimizedPlayerPatch.kt deleted file mode 100644 index 9b3d5636e..000000000 --- a/src/main/kotlin/app/revanced/patches/music/player/minimizedplayer/MinimizedPlayerPatch.kt +++ /dev/null @@ -1,46 +0,0 @@ -package app.revanced.patches.music.player.minimizedplayer - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patches.music.player.minimizedplayer.fingerprints.MinimizedPlayerFingerprint -import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.music.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR -import app.revanced.patches.music.utils.settings.CategoryType -import app.revanced.patches.music.utils.settings.SettingsPatch -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction - -@Suppress("unused") -object MinimizedPlayerPatch : BaseBytecodePatch( - name = "Enable force minimized player", - description = "Adds an option to keep the miniplayer minimized even when another track is played.", - dependencies = setOf(SettingsPatch::class), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(MinimizedPlayerFingerprint) -) { - override fun execute(context: BytecodeContext) { - - MinimizedPlayerFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val insertIndex = it.scanResult.patternScanResult!!.endIndex - val insertRegister = getInstruction(insertIndex).registerA - - addInstructions( - insertIndex, """ - invoke-static {v$insertRegister}, $PLAYER_CLASS_DESCRIPTOR->enableForceMinimizedPlayer(Z)Z - move-result v$insertRegister - """ - ) - } - } - - SettingsPatch.addSwitchPreference( - CategoryType.PLAYER, - "revanced_enable_force_minimized_player", - "true" - ) - - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/player/nextprevious/MiniPlayerButtonPatch.kt b/src/main/kotlin/app/revanced/patches/music/player/nextprevious/MiniPlayerButtonPatch.kt deleted file mode 100644 index d14fefc70..000000000 --- a/src/main/kotlin/app/revanced/patches/music/player/nextprevious/MiniPlayerButtonPatch.kt +++ /dev/null @@ -1,237 +0,0 @@ -package app.revanced.patches.music.player.nextprevious - -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.addInstructionsWithLabels -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.extensions.or -import app.revanced.patcher.patch.PatchException -import app.revanced.patcher.util.proxy.mutableTypes.MutableField.Companion.toMutable -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import app.revanced.patches.music.player.nextprevious.fingerprints.MiniPlayerParentFingerprint -import app.revanced.patches.music.player.nextprevious.fingerprints.MppWatchWhileLayoutFingerprint -import app.revanced.patches.music.player.nextprevious.fingerprints.NextButtonVisibilityFingerprint -import app.revanced.patches.music.player.nextprevious.fingerprints.PlayerPatchConstructorFingerprint -import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.music.utils.fingerprints.MiniPlayerConstructorFingerprint -import app.revanced.patches.music.utils.fingerprints.PendingIntentReceiverFingerprint -import app.revanced.patches.music.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR -import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch -import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MiniPlayerPlayPauseReplayButton -import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.TopEnd -import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.TopStart -import app.revanced.patches.music.utils.settings.CategoryType -import app.revanced.patches.music.utils.settings.SettingsPatch -import app.revanced.util.getStringInstructionIndex -import app.revanced.util.getTargetIndex -import app.revanced.util.getTargetIndexReversed -import app.revanced.util.getWideLiteralInstructionIndex -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.AccessFlags -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.ReferenceInstruction -import com.android.tools.smali.dexlib2.iface.reference.MethodReference -import com.android.tools.smali.dexlib2.immutable.ImmutableField - -@Suppress("unused") -object MiniPlayerButtonPatch : BaseBytecodePatch( - name = "Enable next previous button", - description = "Adds an options to show the next and previous buttons to the miniplayer.", - dependencies = setOf( - MiniPlayerButtonResourcePatch::class, - SettingsPatch::class, - SharedResourceIdPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf( - MiniPlayerConstructorFingerprint, - MiniPlayerParentFingerprint, - MppWatchWhileLayoutFingerprint, - PendingIntentReceiverFingerprint, - PlayerPatchConstructorFingerprint - ) -) { - private const val NEXT_BUTTON_FIELD_NAME = - "nextButton" - private const val PREVIOUS_BUTTON_FIELD_NAME = - "previousButton" - private const val NEXT_BUTTON_CLASS_FIELD_NAME = - "nextButtonClass" - private const val PREVIOUS_BUTTON_CLASS_FIELD_NAME = - "previousButtonClass" - private const val NEXT_BUTTON_METHOD_NAME = - "setNextButton" - private const val PREVIOUS_BUTTON_METHOD_NAME = - "setPreviousButton" - private const val NEXT_BUTTON_ONCLICK_METHOD_NAME = - "setNextButtonOnClickListener" - private const val PREVIOUS_BUTTON_ONCLICK_METHOD_NAME = - "setPreviousButtonOnClickListener" - private const val NEXT_BUTTON_INTENT_STRING = - "YTM Next" - private const val PREVIOUS_BUTTON_INTENT_STRING = - "YTM Previous" - - private var arrayCount = 1 - - override fun execute(context: BytecodeContext) { - - val miniPlayerConstructorMutableMethod = - MiniPlayerConstructorFingerprint.resultOrThrow().mutableMethod - - val mppWatchWhileLayoutMutableMethod = - MppWatchWhileLayoutFingerprint.resultOrThrow().mutableMethod - - val pendingIntentReceiverMutableMethod = - PendingIntentReceiverFingerprint.resultOrThrow().mutableMethod - - if (!SettingsPatch.upward0642) { - MiniPlayerParentFingerprint.resultOrThrow().let { parentResult -> - // Resolves fingerprints - NextButtonVisibilityFingerprint.resolve(context, parentResult.classDef) - - NextButtonVisibilityFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val targetIndex = it.scanResult.patternScanResult!!.startIndex + 1 - val targetRegister = - getInstruction(targetIndex).registerA - - addInstructions( - targetIndex + 1, """ - invoke-static {v$targetRegister}, $PLAYER_CLASS_DESCRIPTOR->enableMiniPlayerNextButton(Z)Z - move-result v$targetRegister - """ - ) - } - } - } - } else { - miniPlayerConstructorMutableMethod.setInstanceFieldValue(NEXT_BUTTON_METHOD_NAME, TopStart) - mppWatchWhileLayoutMutableMethod.setStaticFieldValue(NEXT_BUTTON_FIELD_NAME, TopStart) - pendingIntentReceiverMutableMethod.setOnClickListener(context, NEXT_BUTTON_INTENT_STRING, NEXT_BUTTON_ONCLICK_METHOD_NAME, NEXT_BUTTON_CLASS_FIELD_NAME) - } - - miniPlayerConstructorMutableMethod.setInstanceFieldValue(PREVIOUS_BUTTON_METHOD_NAME, TopEnd) - mppWatchWhileLayoutMutableMethod.setStaticFieldValue(PREVIOUS_BUTTON_FIELD_NAME, TopEnd) - pendingIntentReceiverMutableMethod.setOnClickListener(context, PREVIOUS_BUTTON_INTENT_STRING, PREVIOUS_BUTTON_ONCLICK_METHOD_NAME, PREVIOUS_BUTTON_CLASS_FIELD_NAME) - - mppWatchWhileLayoutMutableMethod.setViewArray() - - SettingsPatch.addSwitchPreference( - CategoryType.PLAYER, - "revanced_enable_mini_player_next_button", - "true" - ) - SettingsPatch.addSwitchPreference( - CategoryType.PLAYER, - "revanced_enable_mini_player_previous_button", - "false" - ) - - } - - private fun MutableMethod.setInstanceFieldValue( - methodName: String, - viewId: Long - ) { - val miniPlayerPlayPauseReplayButtonIndex = getWideLiteralInstructionIndex(MiniPlayerPlayPauseReplayButton) - val miniPlayerPlayPauseReplayButtonRegister = getInstruction(miniPlayerPlayPauseReplayButtonIndex).registerA - val findViewByIdIndex = getTargetIndex(miniPlayerPlayPauseReplayButtonIndex, Opcode.INVOKE_VIRTUAL) - val parentViewRegister = getInstruction(findViewByIdIndex).registerC - - addInstructions( - miniPlayerPlayPauseReplayButtonIndex, """ - const v$miniPlayerPlayPauseReplayButtonRegister, $viewId - invoke-virtual {v$parentViewRegister, v$miniPlayerPlayPauseReplayButtonRegister}, Landroid/view/View;->findViewById(I)Landroid/view/View; - move-result-object v$miniPlayerPlayPauseReplayButtonRegister - invoke-static {v$miniPlayerPlayPauseReplayButtonRegister}, $PLAYER_CLASS_DESCRIPTOR->$methodName(Landroid/view/View;)V - """ - ) - } - - private fun MutableMethod.setStaticFieldValue( - fieldName: String, - viewId: Long - ) { - val miniPlayerPlayPauseReplayButtonIndex = getWideLiteralInstructionIndex(MiniPlayerPlayPauseReplayButton) - val constRegister = getInstruction(miniPlayerPlayPauseReplayButtonIndex).registerA - val findViewByIdIndex = getTargetIndex(miniPlayerPlayPauseReplayButtonIndex, Opcode.INVOKE_VIRTUAL) - val findViewByIdRegister = getInstruction(findViewByIdIndex).registerC - - addInstructions( - miniPlayerPlayPauseReplayButtonIndex, """ - const v$constRegister, $viewId - invoke-virtual {v$findViewByIdRegister, v$constRegister}, $definingClass->findViewById(I)Landroid/view/View; - move-result-object v$constRegister - sput-object v$constRegister, $PLAYER_CLASS_DESCRIPTOR->$fieldName:Landroid/view/View; - """ - ) - } - - private fun MutableMethod.setViewArray() { - val miniPlayerPlayPauseReplayButtonIndex = getWideLiteralInstructionIndex(MiniPlayerPlayPauseReplayButton) - val invokeStaticIndex = getTargetIndex(miniPlayerPlayPauseReplayButtonIndex, Opcode.INVOKE_STATIC) - val viewArrayRegister = getInstruction(invokeStaticIndex).registerC - - addInstructions( - invokeStaticIndex, """ - invoke-static {v$viewArrayRegister}, $PLAYER_CLASS_DESCRIPTOR->getViewArray([Landroid/view/View;)[Landroid/view/View; - move-result-object v$viewArrayRegister - """ - ) - } - - private fun MutableMethod.setOnClickListener( - context: BytecodeContext, - intentString: String, - methodName: String, - fieldName: String - ) { - val startIndex = getStringInstructionIndex(intentString) - val onClickIndex = getTargetIndexReversed(startIndex, Opcode.INVOKE_VIRTUAL) - val onClickReference = getInstruction(onClickIndex).reference - val onClickReferenceDefiningClass = (onClickReference as MethodReference).definingClass - - val onClickClass = - context.findClass(onClickReferenceDefiningClass)!!.mutableClass - - onClickClass.methods.find { method -> method.name == "" } - ?.apply { - addInstruction( - implementation!!.instructions.size - 1, - "sput-object p0, $PLAYER_CLASS_DESCRIPTOR->$fieldName:$onClickReferenceDefiningClass" - ) - } ?: throw PatchException("onClickClass not found!") - - PlayerPatchConstructorFingerprint.resultOrThrow().let { - val mutableClass = it.mutableClass - mutableClass.methods.find { method -> method.name == methodName } - ?.apply { - mutableClass.staticFields.add( - ImmutableField( - definingClass, - fieldName, - onClickReferenceDefiningClass, - AccessFlags.PUBLIC or AccessFlags.STATIC, - null, - annotations, - null - ).toMutable() - ) - addInstructionsWithLabels( - 0, """ - sget-object v0, $PLAYER_CLASS_DESCRIPTOR->$fieldName:$onClickReferenceDefiningClass - if-eqz v0, :ignore - invoke-virtual {v0}, $onClickReference - :ignore - return-void - """ - ) - } - } - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/player/oldplayerbackground/OldPlayerBackgroundPatch.kt b/src/main/kotlin/app/revanced/patches/music/player/oldplayerbackground/OldPlayerBackgroundPatch.kt deleted file mode 100644 index 0e6c24cd2..000000000 --- a/src/main/kotlin/app/revanced/patches/music/player/oldplayerbackground/OldPlayerBackgroundPatch.kt +++ /dev/null @@ -1,36 +0,0 @@ -package app.revanced.patches.music.player.oldplayerbackground - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patches.music.player.oldplayerbackground.fingerprints.OldPlayerBackgroundFingerprint -import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.music.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR -import app.revanced.patches.music.utils.settings.CategoryType -import app.revanced.patches.music.utils.settings.SettingsPatch -import app.revanced.util.literalInstructionBooleanHook -import app.revanced.util.patch.BaseBytecodePatch - -@Suppress("unused") -object OldPlayerBackgroundPatch : BaseBytecodePatch( - name = "Enable old player background", - description = "Adds an option to return the player background to the old style. Deprecated on YT Music 6.34.51+.", - dependencies = setOf(SettingsPatch::class), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(OldPlayerBackgroundFingerprint), - use = false -) { - override fun execute(context: BytecodeContext) { - - OldPlayerBackgroundFingerprint.literalInstructionBooleanHook( - 45415319, - "$PLAYER_CLASS_DESCRIPTOR->enableOldPlayerBackground(Z)Z", - "Please use YT Music 6.33.52 or earlier." - ) - - SettingsPatch.addSwitchPreference( - CategoryType.PLAYER, - "revanced_enable_old_player_background", - "false" - ) - - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/player/oldplayerlayout/OldPlayerLayoutPatch.kt b/src/main/kotlin/app/revanced/patches/music/player/oldplayerlayout/OldPlayerLayoutPatch.kt deleted file mode 100644 index 6f64bd1d7..000000000 --- a/src/main/kotlin/app/revanced/patches/music/player/oldplayerlayout/OldPlayerLayoutPatch.kt +++ /dev/null @@ -1,36 +0,0 @@ -package app.revanced.patches.music.player.oldplayerlayout - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patches.music.player.oldplayerlayout.fingerprints.OldPlayerLayoutFingerprint -import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.music.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR -import app.revanced.patches.music.utils.settings.CategoryType -import app.revanced.patches.music.utils.settings.SettingsPatch -import app.revanced.util.literalInstructionBooleanHook -import app.revanced.util.patch.BaseBytecodePatch - -@Suppress("unused") -object OldPlayerLayoutPatch : BaseBytecodePatch( - name = "Enable old player layout", - description = "Adds an option to return the player layout to the old style. Deprecated on YT Music 6.31.55+.", - dependencies = setOf(SettingsPatch::class), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(OldPlayerLayoutFingerprint), - use = false -) { - override fun execute(context: BytecodeContext) { - - OldPlayerLayoutFingerprint.literalInstructionBooleanHook( - 45399578, - "$PLAYER_CLASS_DESCRIPTOR->enableOldPlayerLayout(Z)Z", - "Please use YT Music 6.29.58 or earlier." - ) - - SettingsPatch.addSwitchPreference( - CategoryType.PLAYER, - "revanced_enable_old_player_layout", - "false" - ) - - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/player/repeat/RememberRepeatPatch.kt b/src/main/kotlin/app/revanced/patches/music/player/repeat/RememberRepeatPatch.kt deleted file mode 100644 index 4a58b66f3..000000000 --- a/src/main/kotlin/app/revanced/patches/music/player/repeat/RememberRepeatPatch.kt +++ /dev/null @@ -1,44 +0,0 @@ -package app.revanced.patches.music.player.repeat - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patches.music.player.repeat.fingerprints.RepeatTrackFingerprint -import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.music.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR -import app.revanced.patches.music.utils.settings.CategoryType -import app.revanced.patches.music.utils.settings.SettingsPatch -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction - -@Suppress("unused") -object RememberRepeatPatch : BaseBytecodePatch( - name = "Remember repeat state", - description = "Adds an option to remember the state of the repeat toggle.", - dependencies = setOf(SettingsPatch::class), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(RepeatTrackFingerprint) -) { - override fun execute(context: BytecodeContext) { - RepeatTrackFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val targetIndex = it.scanResult.patternScanResult!!.endIndex - val targetRegister = getInstruction(targetIndex).registerA - - addInstructions( - targetIndex, """ - invoke-static {v$targetRegister}, $PLAYER_CLASS_DESCRIPTOR->rememberRepeatState(Z)Z - move-result v$targetRegister - """ - ) - } - } - - SettingsPatch.addSwitchPreference( - CategoryType.PLAYER, - "revanced_remember_repeat_state", - "true" - ) - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/player/share/ShareButtonPatch.kt b/src/main/kotlin/app/revanced/patches/music/player/share/ShareButtonPatch.kt deleted file mode 100644 index bcdf7b9ff..000000000 --- a/src/main/kotlin/app/revanced/patches/music/player/share/ShareButtonPatch.kt +++ /dev/null @@ -1,48 +0,0 @@ -package app.revanced.patches.music.player.share - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patches.music.player.share.fingerprints.RemixGenericButtonFingerprint -import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.music.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR -import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch -import app.revanced.patches.music.utils.settings.CategoryType -import app.revanced.patches.music.utils.settings.SettingsPatch -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction - -@Suppress("unused") -object ShareButtonPatch : BaseBytecodePatch( - name = "Hide fullscreen share button", - description = "Adds an option to hide the share button in the fullscreen player.", - dependencies = setOf( - SettingsPatch::class, - SharedResourceIdPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(RemixGenericButtonFingerprint) -) { - override fun execute(context: BytecodeContext) { - RemixGenericButtonFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val targetIndex = it.scanResult.patternScanResult!!.endIndex - val targetRegister = getInstruction(targetIndex).registerA - - addInstructions( - targetIndex + 1, """ - invoke-static {v$targetRegister}, $PLAYER_CLASS_DESCRIPTOR->hideFullscreenShareButton(I)I - move-result v$targetRegister - """ - ) - } - } - - SettingsPatch.addSwitchPreference( - CategoryType.PLAYER, - "revanced_hide_fullscreen_share_button", - "false" - ) - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/player/shuffle/RememberShufflePatch.kt b/src/main/kotlin/app/revanced/patches/music/player/shuffle/RememberShufflePatch.kt deleted file mode 100644 index 6ac5b099d..000000000 --- a/src/main/kotlin/app/revanced/patches/music/player/shuffle/RememberShufflePatch.kt +++ /dev/null @@ -1,174 +0,0 @@ -package app.revanced.patches.music.player.shuffle - -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.addInstructionsWithLabels -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.extensions.or -import app.revanced.patcher.util.proxy.mutableTypes.MutableField.Companion.toMutable -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable -import app.revanced.patches.music.player.shuffle.fingerprints.MusicPlaybackControlsFingerprint -import app.revanced.patches.music.player.shuffle.fingerprints.ShuffleClassReferenceFingerprint -import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.music.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR -import app.revanced.patches.music.utils.settings.CategoryType -import app.revanced.patches.music.utils.settings.SettingsPatch -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import app.revanced.util.transformFields -import app.revanced.util.traverseClassHierarchy -import com.android.tools.smali.dexlib2.AccessFlags -import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation -import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction -import com.android.tools.smali.dexlib2.iface.reference.FieldReference -import com.android.tools.smali.dexlib2.iface.reference.Reference -import com.android.tools.smali.dexlib2.immutable.ImmutableField -import com.android.tools.smali.dexlib2.immutable.ImmutableMethod -import com.android.tools.smali.dexlib2.util.MethodUtil - -@Suppress("unused") -object RememberShufflePatch : BaseBytecodePatch( - name = "Remember shuffle state", - description = "Adds an option to remember the state of the shuffle toggle.", - dependencies = setOf(SettingsPatch::class), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf( - MusicPlaybackControlsFingerprint, - ShuffleClassReferenceFingerprint - ) -) { - private const val PLAYBACK_CONTROLS_CLASS_DESCRIPTOR = - "Lcom/google/android/apps/youtube/music/watchpage/MusicPlaybackControls;" - - private lateinit var objectClass: String - private lateinit var imageViewReference: Reference - private lateinit var shuffleStateLabel: String - - override fun execute(context: BytecodeContext) { - - ShuffleClassReferenceFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val startIndex = it.scanResult.patternScanResult!!.startIndex - val endIndex = it.scanResult.patternScanResult!!.endIndex - val imageViewIndex = implementation!!.instructions.indexOfFirst { instruction -> - ((instruction as? ReferenceInstruction)?.reference as? FieldReference)?.type == "Landroid/widget/ImageView;" - } - - objectClass = it.classDef.type - - val shuffleReference1 = descriptor(startIndex) - val shuffleReference2 = descriptor(startIndex + 1) - val shuffleReference3 = descriptor(endIndex) - val shuffleFieldReference = shuffleReference3 as FieldReference - imageViewReference = descriptor(imageViewIndex) - - shuffleStateLabel = """ - iget-object v1, v0, $shuffleReference1 - invoke-interface {v1}, $shuffleReference2 - move-result-object v1 - check-cast v1, ${shuffleFieldReference.definingClass} - iget-object v1, v1, $shuffleReference3 - invoke-virtual {v1}, ${shuffleFieldReference.type}->ordinal()I - move-result v1 - """ - } - - val constructorMethod = - it.mutableClass.methods.first { method -> MethodUtil.isConstructor(method) } - val onClickMethod = it.mutableClass.methods.first { method -> method.name == "onClick" } - - constructorMethod.apply { - addInstruction( - implementation!!.instructions.size - 1, - "sput-object p0, $PLAYBACK_CONTROLS_CLASS_DESCRIPTOR->shuffleClass:$objectClass" - ) - } - - onClickMethod.apply { - addInstructions( - 0, """ - move-object v0, p0 - """ + shuffleStateLabel + """ - invoke-static {v1}, $PLAYER_CLASS_DESCRIPTOR->setShuffleState(I)V - """ - ) - } - - context.traverseClassHierarchy(it.mutableClass) { - accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL - transformFields { - ImmutableField( - definingClass, - name, - type, - AccessFlags.PUBLIC or AccessFlags.PUBLIC, - null, - annotations, - null - ).toMutable() - } - } - } - - MusicPlaybackControlsFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - addInstruction( - 0, - "invoke-virtual {v0}, $PLAYBACK_CONTROLS_CLASS_DESCRIPTOR->rememberShuffleState()V" - ) - - val shuffleField = ImmutableField( - definingClass, - "shuffleClass", - objectClass, - AccessFlags.PUBLIC or AccessFlags.STATIC, - null, - annotations, - null - ).toMutable() - - val shuffleMethod = ImmutableMethod( - definingClass, - "rememberShuffleState", - emptyList(), - "V", - AccessFlags.PUBLIC or AccessFlags.FINAL, - annotations, null, - MutableMethodImplementation(5) - ).toMutable() - - shuffleMethod.addInstructionsWithLabels( - 0, """ - invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->getShuffleState()I - move-result v2 - if-nez v2, :dont_shuffle - sget-object v0, $PLAYBACK_CONTROLS_CLASS_DESCRIPTOR->shuffleClass:$objectClass - """ + shuffleStateLabel + """ - iget-object v3, v0, $imageViewReference - invoke-virtual {v3}, Landroid/widget/ImageView;->performClick()Z - if-eqz v1, :dont_shuffle - invoke-virtual {v3}, Landroid/widget/ImageView;->performClick()Z - :dont_shuffle - return-void - """ - ) - - it.mutableClass.methods.add(shuffleMethod) - it.mutableClass.staticFields.add(shuffleField) - } - } - - SettingsPatch.addSwitchPreference( - CategoryType.PLAYER, - "revanced_remember_shuffle_state", - "true" - ) - - } - - private fun MutableMethod.descriptor(index: Int): Reference { - return getInstruction(index).reference - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/player/swipetodismiss/SwipeToDismissMiniPlayerPatch.kt b/src/main/kotlin/app/revanced/patches/music/player/swipetodismiss/SwipeToDismissMiniPlayerPatch.kt deleted file mode 100644 index bedd107e8..000000000 --- a/src/main/kotlin/app/revanced/patches/music/player/swipetodismiss/SwipeToDismissMiniPlayerPatch.kt +++ /dev/null @@ -1,221 +0,0 @@ -package app.revanced.patches.music.player.swipetodismiss - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.patch.PatchException -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.music.player.swipetodismiss.fingerprints.HandleSearchRenderedFingerprint -import app.revanced.patches.music.player.swipetodismiss.fingerprints.HandleSignInEventFingerprint -import app.revanced.patches.music.player.swipetodismiss.fingerprints.InteractionLoggingEnumFingerprint -import app.revanced.patches.music.player.swipetodismiss.fingerprints.MiniPlayerDefaultTextFingerprint -import app.revanced.patches.music.player.swipetodismiss.fingerprints.MiniPlayerDefaultViewVisibilityFingerprint -import app.revanced.patches.music.player.swipetodismiss.fingerprints.MusicActivityWidgetFingerprint -import app.revanced.patches.music.player.swipetodismiss.fingerprints.SwipeToCloseFingerprint -import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.music.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR -import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch -import app.revanced.patches.music.utils.settings.CategoryType -import app.revanced.patches.music.utils.settings.SettingsPatch -import app.revanced.util.getReference -import app.revanced.util.getStringInstructionIndex -import app.revanced.util.getTargetIndex -import app.revanced.util.getTargetIndexReversed -import app.revanced.util.getTargetIndexWithFieldReferenceType -import app.revanced.util.getWideLiteralInstructionIndex -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -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.ReferenceInstruction -import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction -import com.android.tools.smali.dexlib2.iface.reference.MethodReference -import com.android.tools.smali.dexlib2.iface.reference.Reference -import kotlin.properties.Delegates - -@Suppress("unused") -object SwipeToDismissMiniPlayerPatch : BaseBytecodePatch( - name = "Enable swipe to dismiss miniplayer", - description = "Adds an option to swipe down to dismiss the miniplayer.", - dependencies = setOf( - SettingsPatch::class, - SharedResourceIdPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf( - HandleSearchRenderedFingerprint, - InteractionLoggingEnumFingerprint, - MiniPlayerDefaultTextFingerprint, - MiniPlayerDefaultViewVisibilityFingerprint, - MusicActivityWidgetFingerprint, - SwipeToCloseFingerprint - ) -) { - private var widgetIndex by Delegates.notNull() - private lateinit var iGetObjectReference: Reference - private lateinit var invokeInterfacePrimaryReference: Reference - private lateinit var checkCastReference: Reference - private lateinit var sGetObjectReference: Reference - private lateinit var newInstanceReference: Reference - private lateinit var invokeStaticReference: Reference - private lateinit var invokeDirectReference: Reference - private lateinit var invokeInterfaceSecondaryReference: Reference - - override fun execute(context: BytecodeContext) { - - if (!SettingsPatch.upward0642) { - SwipeToCloseFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val insertIndex = implementation!!.instructions.size - 1 - val targetRegister = getInstruction(insertIndex).registerA - - addInstructions( - insertIndex, """ - invoke-static {v$targetRegister}, $PLAYER_CLASS_DESCRIPTOR->enableSwipeToDismissMiniPlayer(Z)Z - move-result v$targetRegister - """ - ) - } - } - } else { - - // Dismiss mini player by swiping down - - InteractionLoggingEnumFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val stringIndex = getStringInstructionIndex("INTERACTION_LOGGING_GESTURE_TYPE_SWIPE") - val sPutObjectIndex = getTargetIndex(stringIndex, Opcode.SPUT_OBJECT) - - sGetObjectReference = getInstruction(sPutObjectIndex).reference - } - } - - MusicActivityWidgetFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - widgetIndex = getWideLiteralInstructionIndex(79500) - - iGetObjectReference = getReference(Opcode.IGET_OBJECT, true) - invokeInterfacePrimaryReference = getReference(Opcode.INVOKE_INTERFACE, true) - checkCastReference = getReference(Opcode.CHECK_CAST, true) - newInstanceReference = getReference(Opcode.NEW_INSTANCE, true) - invokeStaticReference = getReference(Opcode.INVOKE_STATIC, false) - invokeDirectReference = getReference(Opcode.INVOKE_DIRECT, false) - invokeInterfaceSecondaryReference = getReference(Opcode.INVOKE_INTERFACE, false) - } - } - - HandleSearchRenderedFingerprint.resultOrThrow().let { parentResult -> - // Resolves fingerprints - HandleSignInEventFingerprint.resolve(context, parentResult.classDef) - - HandleSignInEventFingerprint.resultOrThrow().let { - val dismissBehaviorMethod = context.toMethodWalker(it.method) - .nextMethod(it.scanResult.patternScanResult!!.startIndex, true) - .getMethod() as MutableMethod - - dismissBehaviorMethod.apply { - val insertIndex = getTargetIndexWithFieldReferenceType("Ljava/util/concurrent/atomic/AtomicBoolean;") - val primaryRegister = getInstruction(insertIndex).registerB - val secondaryRegister = primaryRegister + 1 - val tertiaryRegister = secondaryRegister + 1 - - val freeRegister = implementation!!.registerCount - parameters.size - 2 - - addInstructionsWithLabels( - insertIndex, """ - invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->enableSwipeToDismissMiniPlayer()Z - move-result v$freeRegister - if-nez v$freeRegister, :dismiss - iget-object v$primaryRegister, v$primaryRegister, $iGetObjectReference - invoke-interface {v$primaryRegister}, $invokeInterfacePrimaryReference - move-result-object v$primaryRegister - check-cast v$primaryRegister, $checkCastReference - sget-object v$secondaryRegister, $sGetObjectReference - new-instance v$tertiaryRegister, $newInstanceReference - const p0, 0x878b - invoke-static {p0}, $invokeStaticReference - move-result-object p0 - invoke-direct {v$tertiaryRegister, p0}, $invokeDirectReference - const/4 p0, 0x0 - invoke-interface {v$primaryRegister, v$secondaryRegister, v$tertiaryRegister, p0}, $invokeInterfaceSecondaryReference - return-void - """, ExternalLabel("dismiss", getInstruction(insertIndex)) - ) - } - } - } - - // Endregion - - // Hides default text display when the app is cold started - - MiniPlayerDefaultTextFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val insertIndex = it.scanResult.patternScanResult!!.endIndex - val insertRegister = getInstruction(insertIndex).registerB - - addInstructions( - insertIndex, """ - invoke-static {v$insertRegister}, $PLAYER_CLASS_DESCRIPTOR->enableSwipeToDismissMiniPlayer(Ljava/lang/Object;)Ljava/lang/Object; - move-result-object v$insertRegister - """ - ) - } - } - - // Endregion - - // Hides default text display after dismissing the mini player - - MiniPlayerDefaultViewVisibilityFingerprint.resultOrThrow().let { - it.mutableClass.methods.find { method -> - method.parameters == listOf("Landroid/view/View;", "I") - }?.apply { - val bottomSheetBehaviorIndex = implementation!!.instructions.indexOfFirst { instruction -> - instruction.opcode == Opcode.INVOKE_VIRTUAL - && instruction.getReference()?.definingClass == "Lcom/google/android/material/bottomsheet/BottomSheetBehavior;" - && instruction.getReference()?.parameterTypes?.first() == "Z" - } - if (bottomSheetBehaviorIndex < 0) - throw PatchException("Could not find bottomSheetBehaviorIndex") - - val freeRegister = getInstruction(bottomSheetBehaviorIndex).registerD - - addInstructionsWithLabels( - bottomSheetBehaviorIndex - 2, """ - invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->enableSwipeToDismissMiniPlayer()Z - move-result v$freeRegister - if-nez v$freeRegister, :dismiss - """, ExternalLabel("dismiss", getInstruction(bottomSheetBehaviorIndex + 1)) - ) - } ?: throw PatchException("Could not find targetMethod") - - } - - // Endregion - - } - - SettingsPatch.addSwitchPreference( - CategoryType.PLAYER, - "revanced_enable_swipe_to_dismiss_mini_player", - "true" - ) - - } - - private fun MutableMethod.getReference( - opcode: Opcode, - reversed: Boolean - ): Reference { - val targetIndex = if (reversed) - getTargetIndexReversed(widgetIndex, opcode) - else - getTargetIndex(widgetIndex, opcode) - - return getInstruction(targetIndex).reference - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/player/zenmode/ZenModePatch.kt b/src/main/kotlin/app/revanced/patches/music/player/zenmode/ZenModePatch.kt deleted file mode 100644 index 5953f8cb4..000000000 --- a/src/main/kotlin/app/revanced/patches/music/player/zenmode/ZenModePatch.kt +++ /dev/null @@ -1,89 +0,0 @@ -package app.revanced.patches.music.player.zenmode - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patches.music.player.zenmode.fingerprints.ZenModeFingerprint -import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.music.utils.fingerprints.MiniPlayerConstructorFingerprint -import app.revanced.patches.music.utils.fingerprints.SwitchToggleColorFingerprint -import app.revanced.patches.music.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR -import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch -import app.revanced.patches.music.utils.settings.CategoryType -import app.revanced.patches.music.utils.settings.SettingsPatch -import app.revanced.patches.music.utils.videotype.VideoTypeHookPatch -import app.revanced.util.getTargetIndex -import app.revanced.util.getWalkerMethod -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction - -@Suppress("unused") -object ZenModePatch : BaseBytecodePatch( - name = "Enable zen mode", - description = "Adds an option to change the player background to light grey to reduce eye strain.", - dependencies = setOf( - SettingsPatch::class, - SharedResourceIdPatch::class, - VideoTypeHookPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(MiniPlayerConstructorFingerprint) -) { - override fun execute(context: BytecodeContext) { - - MiniPlayerConstructorFingerprint.resultOrThrow().let { parentResult -> - // Resolves fingerprints - SwitchToggleColorFingerprint.resolve(context, parentResult.classDef) - ZenModeFingerprint.resolve(context, parentResult.classDef) - - // This method is used for old player background - // Deprecated since YT Music v6.34.51 - ZenModeFingerprint.result?.let { - it.mutableMethod.apply { - val startIndex = it.scanResult.patternScanResult!!.startIndex - val targetRegister = getInstruction(startIndex).registerA - - val insertIndex = it.scanResult.patternScanResult!!.endIndex + 1 - - addInstructions( - insertIndex, """ - invoke-static {v$targetRegister}, $PLAYER_CLASS_DESCRIPTOR->enableZenMode(I)I - move-result v$targetRegister - """ - ) - } - } - - SwitchToggleColorFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val invokeDirectIndex = getTargetIndex(Opcode.INVOKE_DIRECT) - val walkerMethod = getWalkerMethod(context, invokeDirectIndex) - - walkerMethod.addInstructions( - 0, """ - invoke-static {p1}, $PLAYER_CLASS_DESCRIPTOR->enableZenMode(I)I - move-result p1 - invoke-static {p2}, $PLAYER_CLASS_DESCRIPTOR->enableZenMode(I)I - move-result p2 - """ - ) - } - } - } - - SettingsPatch.addSwitchPreference( - CategoryType.PLAYER, - "revanced_enable_zen_mode", - "false" - ) - SettingsPatch.addSwitchPreference( - CategoryType.PLAYER, - "revanced_enable_zen_mode_podcast", - "false", - "revanced_enable_zen_mode" - ) - - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/utils/compatibility/Constants.kt b/src/main/kotlin/app/revanced/patches/music/utils/compatibility/Constants.kt index 1179892ed..cb762b13f 100644 --- a/src/main/kotlin/app/revanced/patches/music/utils/compatibility/Constants.kt +++ b/src/main/kotlin/app/revanced/patches/music/utils/compatibility/Constants.kt @@ -9,7 +9,8 @@ object Constants { setOf( "6.29.58", "6.31.55", - "6.33.52" + "6.33.52", + "6.50.51" ) ) ) diff --git a/src/main/kotlin/app/revanced/patches/music/utils/flyoutmenu/FlyoutMenuHookPatch.kt b/src/main/kotlin/app/revanced/patches/music/utils/flyoutmenu/FlyoutMenuHookPatch.kt new file mode 100644 index 000000000..37c876d38 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/utils/flyoutmenu/FlyoutMenuHookPatch.kt @@ -0,0 +1,47 @@ +package app.revanced.patches.music.utils.flyoutmenu + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patches.music.utils.flyoutmenu.fingerprints.PlaybackRateBottomSheetClassFingerprint +import app.revanced.patches.music.utils.integrations.Constants.INTEGRATIONS_PATH +import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch +import app.revanced.util.addFieldAndInstructions +import app.revanced.util.resultOrThrow + +@Patch( + description = "Hooks YouTube Music to open the playback speed flyout menu in the integration.", + dependencies = [SharedResourceIdPatch::class] +) +object FlyoutMenuHookPatch : BytecodePatch( + setOf(PlaybackRateBottomSheetClassFingerprint) +) { + private const val INTEGRATIONS_VIDEO_UTILS_CLASS_DESCRIPTOR = + "$INTEGRATIONS_PATH/utils/VideoUtils;" + + override fun execute(context: BytecodeContext) { + + PlaybackRateBottomSheetClassFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val smaliInstructions = + """ + if-eqz v0, :ignore + invoke-virtual {v0}, $definingClass->$name()V + :ignore + return-void + """ + + context.findClass( + INTEGRATIONS_VIDEO_UTILS_CLASS_DESCRIPTOR + )!!.mutableClass.addFieldAndInstructions( + context, + "showPlaybackSpeedFlyoutMenu", + "playbackRateBottomSheetClass", + definingClass, + smaliInstructions, + true + ) + } + } + } +} diff --git a/src/main/kotlin/app/revanced/patches/music/utils/flyoutmenu/fingerprints/PlaybackRateBottomSheetClassFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/utils/flyoutmenu/fingerprints/PlaybackRateBottomSheetClassFingerprint.kt new file mode 100644 index 000000000..e5a241eac --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/utils/flyoutmenu/fingerprints/PlaybackRateBottomSheetClassFingerprint.kt @@ -0,0 +1,13 @@ +package app.revanced.patches.music.utils.flyoutmenu.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.VarispeedUnavailableTitle +import app.revanced.util.fingerprint.LiteralValueFingerprint +import com.android.tools.smali.dexlib2.AccessFlags + +internal object PlaybackRateBottomSheetClassFingerprint : LiteralValueFingerprint( + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + returnType = "V", + parameters = emptyList(), + literalSupplier = { VarispeedUnavailableTitle } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/utils/flyoutpanel/PlaybackSpeedFlyoutPanelHookPatch.kt b/src/main/kotlin/app/revanced/patches/music/utils/flyoutpanel/PlaybackSpeedFlyoutPanelHookPatch.kt deleted file mode 100644 index 93206482c..000000000 --- a/src/main/kotlin/app/revanced/patches/music/utils/flyoutpanel/PlaybackSpeedFlyoutPanelHookPatch.kt +++ /dev/null @@ -1,99 +0,0 @@ -package app.revanced.patches.music.utils.flyoutpanel - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.extensions.or -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.annotation.Patch -import app.revanced.patcher.util.proxy.mutableTypes.MutableField.Companion.toMutable -import app.revanced.patches.music.utils.flyoutpanel.fingerprints.PlaybackSpeedOnClickListenerFingerprint -import app.revanced.patches.music.utils.integrations.Constants.INTEGRATIONS_PATH -import app.revanced.util.getTargetIndex -import app.revanced.util.getWideLiteralInstructionIndex -import app.revanced.util.indexOfFirstInstruction -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.AccessFlags -import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction -import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction -import com.android.tools.smali.dexlib2.iface.reference.FieldReference -import com.android.tools.smali.dexlib2.iface.reference.MethodReference -import com.android.tools.smali.dexlib2.immutable.ImmutableField -import com.android.tools.smali.dexlib2.util.MethodUtil - -@Patch(description = "Hooks YouTube Music to open the playback speed flyout panel in the integration.") -object PlaybackSpeedFlyoutPanelHookPatch : BytecodePatch( - setOf(PlaybackSpeedOnClickListenerFingerprint) -) { - private const val INTEGRATIONS_VIDEO_UTILS_CLASS_DESCRIPTOR = - "$INTEGRATIONS_PATH/utils/VideoUtils;" - - override fun execute(context: BytecodeContext) { - - PlaybackSpeedOnClickListenerFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val startIndex = getWideLiteralInstructionIndex(147448) - val iGetObjectIndex = getTargetIndex(startIndex, Opcode.IGET_OBJECT) - val invokeInterfaceIndex = getTargetIndex(startIndex, Opcode.INVOKE_INTERFACE) - val invokeVirtualIndex = getTargetIndex(startIndex, Opcode.INVOKE_VIRTUAL) - - val iGetObjectReference = getInstruction(iGetObjectIndex).reference - val playbackRateBottomSheetClass = (iGetObjectReference as FieldReference).type - val invokeInterfaceReference = getInstruction(invokeInterfaceIndex).reference - val invokeVirtualReference = getInstruction(invokeVirtualIndex).reference - - it.mutableClass.methods.first { method -> - MethodUtil.isConstructor(method) - }.apply { - val iPutIndex = - indexOfFirstInstruction { - opcode == Opcode.IPUT_OBJECT && - (this as? ReferenceInstruction)?.reference == iGetObjectReference - } - val iPutRegister = getInstruction(iPutIndex).registerA - - addInstruction( - iPutIndex, - "sput-object v$iPutRegister, $INTEGRATIONS_VIDEO_UTILS_CLASS_DESCRIPTOR->playbackRateBottomSheetClass:$playbackRateBottomSheetClass" - ) - } - - val videoUtilsMutableClass = context.findClass( - INTEGRATIONS_VIDEO_UTILS_CLASS_DESCRIPTOR - )!!.mutableClass - videoUtilsMutableClass.methods.single { method -> - method.name == "showPlaybackSpeedFlyoutMenu" - }.apply { - // add playback rate bottom sheet class - videoUtilsMutableClass.staticFields.add( - ImmutableField( - definingClass, - "playbackRateBottomSheetClass", - playbackRateBottomSheetClass, - AccessFlags.PUBLIC or AccessFlags.STATIC, - null, - annotations, - null - ).toMutable() - ) - - // call playback rate bottom sheet method - addInstructionsWithLabels( - 0, """ - sget-object v0, $INTEGRATIONS_VIDEO_UTILS_CLASS_DESCRIPTOR->playbackRateBottomSheetClass:$playbackRateBottomSheetClass - if-eqz v0, :ignore - invoke-interface {v0}, $invokeInterfaceReference - move-result-object v0 - check-cast v0, ${(invokeVirtualReference as MethodReference).definingClass} - invoke-virtual {v0}, $invokeVirtualReference - :ignore - return-void - """ - ) - } - } - } - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/utils/flyoutpanel/fingerprints/PlaybackSpeedOnClickListenerFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/utils/flyoutpanel/fingerprints/PlaybackSpeedOnClickListenerFingerprint.kt deleted file mode 100644 index 950d02d96..000000000 --- a/src/main/kotlin/app/revanced/patches/music/utils/flyoutpanel/fingerprints/PlaybackSpeedOnClickListenerFingerprint.kt +++ /dev/null @@ -1,19 +0,0 @@ -package app.revanced.patches.music.utils.flyoutpanel.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.MethodFingerprint -import app.revanced.util.containsWideLiteralInstructionIndex -import com.android.tools.smali.dexlib2.AccessFlags - -internal object PlaybackSpeedOnClickListenerFingerprint : MethodFingerprint( - returnType = "V", - accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - parameters = listOf("Landroid/view/View;"), - customFingerprint = handler@{ methodDef, _ -> - if (methodDef.definingClass.startsWith("Lcom/")) - return@handler false - - methodDef.name == "onClick" - && methodDef.containsWideLiteralInstructionIndex(147448) - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/utils/integrations/Constants.kt b/src/main/kotlin/app/revanced/patches/music/utils/integrations/Constants.kt index fdb738f76..762b76e16 100644 --- a/src/main/kotlin/app/revanced/patches/music/utils/integrations/Constants.kt +++ b/src/main/kotlin/app/revanced/patches/music/utils/integrations/Constants.kt @@ -3,6 +3,7 @@ package app.revanced.patches.music.utils.integrations @Suppress("MemberVisibilityCanBePrivate") object Constants { const val INTEGRATIONS_PATH = "Lapp/revanced/integrations/music" + const val SHARED_PATH = "$INTEGRATIONS_PATH/shared" const val PATCHES_PATH = "$INTEGRATIONS_PATH/patches" const val ACCOUNT_PATH = "$PATCHES_PATH/account" @@ -23,99 +24,4 @@ object Constants { const val GENERAL_CLASS_DESCRIPTOR = "$GENERAL_PATH/GeneralPatch;" const val NAVIGATION_CLASS_DESCRIPTOR = "$NAVIGATION_PATH/NavigationPatch;" const val PLAYER_CLASS_DESCRIPTOR = "$PLAYER_PATH/PlayerPatch;" - - val LANGUAGE_LIST = arrayOf( - "values", - "values-af", - "values-am", - "values-ar", - "values-ar-rXB", - "values-as", - "values-az", - "values-b+es+419", - "values-b+sr+Latn", - "values-be", - "values-bg", - "values-bn", - "values-bs", - "values-ca", - "values-cs", - "values-da", - "values-de", - "values-el", - "values-en-rAU", - "values-en-rCA", - "values-en-rGB", - "values-en-rIN", - "values-en-rXA", - "values-en-rXC", - "values-es", - "values-es-rUS", - "values-et", - "values-eu", - "values-fa", - "values-fi", - "values-fr", - "values-fr-rCA", - "values-gl", - "values-gu", - "values-hi", - "values-hr", - "values-hu", - "values-hy", - "values-id", - "values-in", - "values-is", - "values-it", - "values-iw", - "values-ja", - "values-ka", - "values-kk", - "values-km", - "values-kn", - "values-ko", - "values-ky", - "values-lo", - "values-lt", - "values-lv", - "values-mk", - "values-ml", - "values-mn", - "values-mr", - "values-ms", - "values-my", - "values-nb", - "values-ne", - "values-nl", - "values-no", - "values-or", - "values-pa", - "values-pl", - "values-pt", - "values-pt-rBR", - "values-pt-rPT", - "values-ro", - "values-ru", - "values-si", - "values-sk", - "values-sl", - "values-sq", - "values-sr", - "values-sv", - "values-sw", - "values-ta", - "values-te", - "values-th", - "values-tl", - "values-tr", - "values-uk", - "values-ur", - "values-uz", - "values-vi", - "values-zh", - "values-zh-rCN", - "values-zh-rHK", - "values-zh-rTW", - "values-zu" - ) } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/utils/resourceid/SharedResourceIdPatch.kt b/src/main/kotlin/app/revanced/patches/music/utils/resourceid/SharedResourceIdPatch.kt index 2b790ad35..a192d32c8 100644 --- a/src/main/kotlin/app/revanced/patches/music/utils/resourceid/SharedResourceIdPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/utils/resourceid/SharedResourceIdPatch.kt @@ -47,8 +47,11 @@ object SharedResourceIdPatch : ResourcePatch() { var ToolTipContentView = -1L var TopEnd = -1L var TopStart = -1L + var TopBarMenuItemImageView = -1L var TosFooter = -1L var TouchOutside = -1L + var TrimSilenceSwitch: Long = -1 + var VarispeedUnavailableTitle = -1L override fun execute(context: ResourceContext) { @@ -84,8 +87,11 @@ object SharedResourceIdPatch : ResourcePatch() { ToolTipContentView = getId(LAYOUT, "tooltip_content_view") TopEnd = getId(ID, "TOP_END") TopStart = getId(ID, "TOP_START") + TopBarMenuItemImageView = getId(ID, "top_bar_menu_item_image_view") TosFooter = getId(ID, "tos_footer") TouchOutside = getId(ID, "touch_outside") + TrimSilenceSwitch = getId(ID, "trim_silence_switch") + VarispeedUnavailableTitle = getId(STRING, "varispeed_unavailable_title") } } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/utils/settings/CategoryType.kt b/src/main/kotlin/app/revanced/patches/music/utils/settings/CategoryType.kt index 2629e9cf2..963afa60b 100644 --- a/src/main/kotlin/app/revanced/patches/music/utils/settings/CategoryType.kt +++ b/src/main/kotlin/app/revanced/patches/music/utils/settings/CategoryType.kt @@ -6,10 +6,10 @@ enum class CategoryType(val value: String, var added: Boolean) { ADS("ads", false), FLYOUT("flyout", false), GENERAL("general", false), - MISC("misc", false), NAVIGATION("navigation", false), PLAYER("player", false), + VIDEO("video", false), RETURN_YOUTUBE_DISLIKE("ryd", false), SPONSOR_BLOCK("sb", false), - VIDEO("video", false) + MISC("misc", false) } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/utils/settings/ResourceUtils.kt b/src/main/kotlin/app/revanced/patches/music/utils/settings/ResourceUtils.kt index 0cad92813..a4ba63b23 100644 --- a/src/main/kotlin/app/revanced/patches/music/utils/settings/ResourceUtils.kt +++ b/src/main/kotlin/app/revanced/patches/music/utils/settings/ResourceUtils.kt @@ -65,8 +65,8 @@ object ResourceUtils { .forEach { if (!isIncludedCategory(category)) { it.adoptChild(PREFERENCE_SCREEN_TAG_NAME) { - setAttribute("android:title", "@string/revanced_category_$category") - setAttribute("android:key", "revanced_settings_$category") + setAttribute("android:title", "@string/revanced_preference_screen_$category" + "_title") + setAttribute("android:key", "revanced_preference_screen_$category") } setPreferenceCategory(category) } @@ -99,7 +99,7 @@ object ResourceUtils { if (it !is Element) return@loop it.getAttributeNode("android:key")?.let { attribute -> - if (attribute.textContent == "revanced_settings_$category") { + if (attribute.textContent == "revanced_preference_screen_$category") { it.cloneNodes(it.parentNode) } } @@ -117,7 +117,7 @@ object ResourceUtils { this.xmlEditor[SETTINGS_HEADER_PATH].use { editor -> val tags = editor.file.getElementsByTagName(PREFERENCE_SCREEN_TAG_NAME) List(tags.length) { tags.item(it) as Element } - .filter { it.getAttribute("android:key").contains("revanced_settings_$category") } + .filter { it.getAttribute("android:key").contains("revanced_preference_screen_$category") } .forEach { it.adoptChild("Preference") { setAttribute("android:title", "@string/$key" + "_title") @@ -145,7 +145,7 @@ object ResourceUtils { this.xmlEditor[SETTINGS_HEADER_PATH].use { editor -> val tags = editor.file.getElementsByTagName(PREFERENCE_SCREEN_TAG_NAME) List(tags.length) { tags.item(it) as Element } - .filter { it.getAttribute("android:key").contains("revanced_settings_$category") } + .filter { it.getAttribute("android:key").contains("revanced_preference_screen_$category") } .forEach { it.adoptChild(SWITCH_PREFERENCE_TAG_NAME) { setAttribute("android:title", "@string/$key" + "_title") @@ -170,7 +170,7 @@ object ResourceUtils { this.xmlEditor[SETTINGS_HEADER_PATH].use { editor -> val tags = editor.file.getElementsByTagName(PREFERENCE_SCREEN_TAG_NAME) List(tags.length) { tags.item(it) as Element } - .filter { it.getAttribute("android:key").contains("revanced_settings_$category") } + .filter { it.getAttribute("android:key").contains("revanced_preference_screen_$category") } .forEach { it.adoptChild("Preference") { setAttribute("android:title", "@string/$key" + "_title") diff --git a/src/main/kotlin/app/revanced/patches/music/utils/settings/SettingsPatch.kt b/src/main/kotlin/app/revanced/patches/music/utils/settings/SettingsPatch.kt index 8a9243e3d..ba129d438 100644 --- a/src/main/kotlin/app/revanced/patches/music/utils/settings/SettingsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/utils/settings/SettingsPatch.kt @@ -8,8 +8,6 @@ import app.revanced.patches.music.utils.settings.ResourceUtils.addPreferenceWith import app.revanced.patches.music.utils.settings.ResourceUtils.addRVXSettingsPreference import app.revanced.patches.music.utils.settings.ResourceUtils.addSwitchPreference import app.revanced.patches.music.utils.settings.ResourceUtils.sortPreferenceCategory -import app.revanced.util.ResourceGroup -import app.revanced.util.copyResources import app.revanced.util.copyXmlNode import app.revanced.util.patch.BaseResourcePatch import org.w3c.dom.Element @@ -79,20 +77,6 @@ object SettingsPatch : BaseResourcePatch( */ context.copyXmlNode("music/settings/host", "values/strings.xml", "resources") - /** - * create directory for the untranslated language resources - */ - context["res/values-v21"].mkdirs() - - arrayOf( - ResourceGroup( - "values-v21", - "strings.xml" - ) - ).forEach { resourceGroup -> - context.copyResources("music/settings", resourceGroup) - } - /** * hide divider */ diff --git a/src/main/kotlin/app/revanced/patches/music/utils/sponsorblock/SponsorBlockBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/music/utils/sponsorblock/SponsorBlockBytecodePatch.kt index d92ad5445..e1e1160d5 100644 --- a/src/main/kotlin/app/revanced/patches/music/utils/sponsorblock/SponsorBlockBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/utils/sponsorblock/SponsorBlockBytecodePatch.kt @@ -127,7 +127,6 @@ object SponsorBlockBytecodePatch : BytecodePatch( /** * Set current video id */ - VideoIdPatch.hookBackgroundPlayVideoId("$INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setVideoId(Ljava/lang/String;)V") VideoIdPatch.hookVideoId("$INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setVideoId(Ljava/lang/String;)V") } } diff --git a/src/main/kotlin/app/revanced/patches/music/utils/sponsorblock/SponsorBlockPatch.kt b/src/main/kotlin/app/revanced/patches/music/utils/sponsorblock/SponsorBlockPatch.kt index 4e9c4ce07..08f5ebce9 100644 --- a/src/main/kotlin/app/revanced/patches/music/utils/sponsorblock/SponsorBlockPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/utils/sponsorblock/SponsorBlockPatch.kt @@ -60,7 +60,7 @@ object SponsorBlockPatch : BaseResourcePatch( ) addPreferenceCategoryUnderPreferenceScreen( - CategoryType.SPONSOR_BLOCK.value, + SPONSOR_BLOCK_CATEGORY, SEGMENTS_CATEGORY_KEY ) @@ -143,7 +143,7 @@ object SponsorBlockPatch : BaseResourcePatch( context.xmlEditor[SETTINGS_HEADER_PATH].use { editor -> val tags = editor.file.getElementsByTagName(PREFERENCE_SCREEN_TAG_NAME) List(tags.length) { tags.item(it) as Element } - .filter { it.getAttribute("android:key").contains("revanced_settings_$category") } + .filter { it.getAttribute("android:key").contains("revanced_preference_screen_$category") } .forEach { it.adoptChild(SWITCH_PREFERENCE_TAG_NAME) { setAttribute("android:title", "@string/revanced_$key") @@ -166,7 +166,7 @@ object SponsorBlockPatch : BaseResourcePatch( context.xmlEditor[SETTINGS_HEADER_PATH].use { editor -> val tags = editor.file.getElementsByTagName(PREFERENCE_SCREEN_TAG_NAME) List(tags.length) { tags.item(it) as Element } - .filter { it.getAttribute("android:key").contains("revanced_settings_$category") } + .filter { it.getAttribute("android:key").contains("revanced_preference_screen_$category") } .forEach { it.adoptChild("Preference") { setAttribute("android:title", "@string/revanced_$key") diff --git a/src/main/kotlin/app/revanced/patches/music/video/customspeed/CustomPlaybackSpeedPatch.kt b/src/main/kotlin/app/revanced/patches/music/video/customspeed/CustomPlaybackSpeedPatch.kt deleted file mode 100644 index 5d09e0193..000000000 --- a/src/main/kotlin/app/revanced/patches/music/video/customspeed/CustomPlaybackSpeedPatch.kt +++ /dev/null @@ -1,27 +0,0 @@ -package app.revanced.patches.music.video.customspeed - -import app.revanced.patcher.data.ResourceContext -import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.music.utils.settings.CategoryType -import app.revanced.patches.music.utils.settings.SettingsPatch -import app.revanced.util.patch.BaseResourcePatch - -@Suppress("unused") -object CustomPlaybackSpeedPatch : BaseResourcePatch( - name = "Custom playback speed", - description = "Adds an option to customize available playback speeds.", - dependencies = setOf( - CustomPlaybackSpeedBytecodePatch::class, - SettingsPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE -) { - override fun execute(context: ResourceContext) { - - SettingsPatch.addPreferenceWithIntent( - CategoryType.VIDEO, - "revanced_custom_playback_speeds" - ) - - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/video/information/VideoInformationPatch.kt b/src/main/kotlin/app/revanced/patches/music/video/information/VideoInformationPatch.kt index 32c2ae059..2aa21d9b5 100644 --- a/src/main/kotlin/app/revanced/patches/music/video/information/VideoInformationPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/video/information/VideoInformationPatch.kt @@ -2,19 +2,17 @@ package app.revanced.patches.music.video.information import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprintResult import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.annotation.Patch -import app.revanced.patcher.util.proxy.mutableTypes.MutableField.Companion.toMutable import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable import app.revanced.patcher.util.smali.toInstructions import app.revanced.patches.music.utils.fingerprints.SeekBarConstructorFingerprint -import app.revanced.patches.music.utils.integrations.Constants.VIDEO_PATH +import app.revanced.patches.music.utils.integrations.Constants.SHARED_PATH import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch import app.revanced.patches.music.video.information.fingerprints.PlaybackSpeedFingerprint import app.revanced.patches.music.video.information.fingerprints.PlaybackSpeedParentFingerprint @@ -24,6 +22,7 @@ import app.revanced.patches.music.video.information.fingerprints.VideoLengthFing import app.revanced.patches.music.video.information.fingerprints.VideoQualityListFingerprint import app.revanced.patches.music.video.information.fingerprints.VideoQualityTextFingerprint import app.revanced.patches.music.video.videoid.VideoIdPatch +import app.revanced.util.addFieldAndInstructions import app.revanced.util.getTargetIndexWithFieldReferenceTypeReversed import app.revanced.util.getTargetIndexWithMethodReferenceNameReversed import app.revanced.util.getWalkerMethod @@ -34,11 +33,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction import com.android.tools.smali.dexlib2.iface.reference.FieldReference -import com.android.tools.smali.dexlib2.immutable.ImmutableField import com.android.tools.smali.dexlib2.immutable.ImmutableMethod import com.android.tools.smali.dexlib2.immutable.ImmutableMethodImplementation import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter -import com.android.tools.smali.dexlib2.util.MethodUtil @Patch( dependencies = [ @@ -58,10 +55,7 @@ object VideoInformationPatch : BytecodePatch( ) ) { private const val INTEGRATIONS_CLASS_DESCRIPTOR = - "$VIDEO_PATH/VideoInformation;" - - private lateinit var playerConstructorMethod: MutableMethod - private var playerConstructorInsertIndex = 4 + "$SHARED_PATH/VideoInformation;" private lateinit var videoTimeConstructorMethod: MutableMethod private var videoTimeConstructorInsertIndex = 2 @@ -71,13 +65,9 @@ object VideoInformationPatch : BytecodePatch( internal lateinit var playbackSpeedResult: MethodFingerprintResult override fun execute(context: BytecodeContext) { + val videoInformationMutableClass = context.findClass(INTEGRATIONS_CLASS_DESCRIPTOR)!!.mutableClass + VideoEndFingerprint.resultOrThrow().let { - playerConstructorMethod = - it.mutableClass.methods.first { method -> MethodUtil.isConstructor(method) } - - // hook the player controller for use through integrations - onCreateHook(INTEGRATIONS_CLASS_DESCRIPTOR, "initialize") - it.mutableMethod.apply { val seekSourceEnumType = parameterTypes[1].toString() @@ -102,6 +92,26 @@ object VideoInformationPatch : BytecodePatch( ) ).toMutable() ) + + val smaliInstructions = + """ + if-eqz v0, :ignore + invoke-virtual {v0, p0, p1}, $definingClass->seekTo(J)Z + move-result v0 + return v0 + :ignore + const/4 v0, 0x0 + return v0 + """ + + videoInformationMutableClass.addFieldAndInstructions( + context, + "overrideVideoTime", + "videoInformationClass", + definingClass, + smaliInstructions, + true + ) } } @@ -146,11 +156,7 @@ object VideoInformationPatch : BytecodePatch( /** * Set current video id */ - val videoIdMethodDescriptor = "$INTEGRATIONS_CLASS_DESCRIPTOR->setVideoId(Ljava/lang/String;)V" - VideoIdPatch.hookVideoId(videoIdMethodDescriptor) - VideoIdPatch.hookBackgroundPlayVideoId(videoIdMethodDescriptor) - - val videoInformationMutableClass = context.findClass(INTEGRATIONS_CLASS_DESCRIPTOR)!!.mutableClass + VideoIdPatch.hookVideoId("$INTEGRATIONS_CLASS_DESCRIPTOR->setVideoId(Ljava/lang/String;)V") /** * Hook current playback speed @@ -177,8 +183,6 @@ object VideoInformationPatch : BytecodePatch( * Hook current video quality */ VideoQualityListFingerprint.resultOrThrow().let { - val constructorMethod = - it.mutableClass.methods.first { method -> MethodUtil.isConstructor(method) } val overrideMethod = it.mutableClass.methods.find { method -> method.parameterTypes.first() == "I" } @@ -186,14 +190,6 @@ object VideoInformationPatch : BytecodePatch( val videoQualityMethodName = overrideMethod?.name ?: throw PatchException("Failed to find hook method") - // set video quality class - constructorMethod.apply { - addInstruction( - 2, - "sput-object p0, $INTEGRATIONS_CLASS_DESCRIPTOR->videoQualityClass:$videoQualityClass" - ) - } - // set video quality array it.mutableMethod.apply { val listIndex = it.scanResult.patternScanResult!!.startIndex @@ -205,32 +201,22 @@ object VideoInformationPatch : BytecodePatch( ) } - videoInformationMutableClass.methods.single { method -> - method.name == "overrideVideoQuality" - }.apply { - videoInformationMutableClass.staticFields.add( - ImmutableField( - definingClass, - "videoQualityClass", - videoQualityClass, - AccessFlags.PUBLIC or AccessFlags.STATIC, - null, - annotations, - null - ).toMutable() - ) + val smaliInstructions = + """ + if-eqz v0, :ignore + invoke-virtual {v0, p0}, $videoQualityClass->$videoQualityMethodName(I)V + :ignore + return-void + """ - // call override video quality method - addInstructionsWithLabels( - 0, """ - sget-object v0, $INTEGRATIONS_CLASS_DESCRIPTOR->videoQualityClass:$videoQualityClass - if-eqz v0, :ignore - invoke-virtual {v0, p0}, $videoQualityClass->$videoQualityMethodName(I)V - :ignore - return-void - """ - ) - } + videoInformationMutableClass.addFieldAndInstructions( + context, + "overrideVideoQuality", + "videoQualityClass", + videoQualityClass, + smaliInstructions, + true + ) } // set current video quality @@ -253,22 +239,6 @@ object VideoInformationPatch : BytecodePatch( private fun MutableMethod.insertTimeHook(insertIndex: Int, descriptor: String) = insert(insertIndex, "p1, p2", descriptor) - /** - * Hook the player controller. Called when a video is opened or the current video is changed. - * - * Note: This hook is called very early and is called before the video id, video time, video length, - * and many other data fields are set. - * - * @param targetMethodClass The descriptor for the class to invoke when the player controller is created. - * @param targetMethodName The name of the static method to invoke when the player controller is created. - */ - internal fun onCreateHook(targetMethodClass: String, targetMethodName: String) = - playerConstructorMethod.insert( - playerConstructorInsertIndex++, - "v0", - "$targetMethodClass->$targetMethodName(Ljava/lang/Object;)V" - ) - /** * Hook the video time. * The hook is usually called once per second. diff --git a/src/main/kotlin/app/revanced/patches/music/video/customspeed/CustomPlaybackSpeedBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/music/video/playback/CustomPlaybackSpeedPatch.kt similarity index 59% rename from src/main/kotlin/app/revanced/patches/music/video/customspeed/CustomPlaybackSpeedBytecodePatch.kt rename to src/main/kotlin/app/revanced/patches/music/video/playback/CustomPlaybackSpeedPatch.kt index 3e4ae4f71..157718212 100644 --- a/src/main/kotlin/app/revanced/patches/music/video/customspeed/CustomPlaybackSpeedBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/video/playback/CustomPlaybackSpeedPatch.kt @@ -1,9 +1,9 @@ -package app.revanced.patches.music.video.customspeed +package app.revanced.patches.music.video.playback import app.revanced.patches.music.utils.integrations.Constants.VIDEO_PATH import app.revanced.patches.shared.customspeed.BaseCustomPlaybackSpeedPatch -object CustomPlaybackSpeedBytecodePatch : BaseCustomPlaybackSpeedPatch( +object CustomPlaybackSpeedPatch : BaseCustomPlaybackSpeedPatch( "$VIDEO_PATH/CustomPlaybackSpeedPatch;", - 3.0f + 5.0f ) diff --git a/src/main/kotlin/app/revanced/patches/music/video/playback/VideoPlaybackPatch.kt b/src/main/kotlin/app/revanced/patches/music/video/playback/VideoPlaybackPatch.kt new file mode 100644 index 000000000..cfb6cdcb5 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/video/playback/VideoPlaybackPatch.kt @@ -0,0 +1,124 @@ +package app.revanced.patches.music.video.playback + +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.patch.PatchException +import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE +import app.revanced.patches.music.utils.integrations.Constants.VIDEO_PATH +import app.revanced.patches.music.utils.settings.CategoryType +import app.revanced.patches.music.utils.settings.SettingsPatch +import app.revanced.patches.music.video.information.VideoInformationPatch +import app.revanced.patches.music.video.playback.fingerprints.PlaybackSpeedBottomSheetFingerprint +import app.revanced.patches.music.video.playback.fingerprints.UserQualityChangeFingerprint +import app.revanced.patches.music.video.videoid.VideoIdPatch +import app.revanced.util.getTargetIndex +import app.revanced.util.patch.BaseBytecodePatch +import app.revanced.util.resultOrThrow +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction21c +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction +import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction + +@Suppress("unused") +object VideoPlaybackPatch : BaseBytecodePatch( + name = "Video playback", + description = "Adds options to customize settings related to video playback," + + "such as default video quality and playback speed.", + dependencies = setOf( + CustomPlaybackSpeedPatch::class, + SettingsPatch::class, + VideoIdPatch::class, + VideoInformationPatch::class + ), + compatiblePackages = COMPATIBLE_PACKAGE, + fingerprints = setOf( + PlaybackSpeedBottomSheetFingerprint, + UserQualityChangeFingerprint + ) +) { + private const val INTEGRATIONS_PLAYBACK_SPEED_CLASS_DESCRIPTOR = + "$VIDEO_PATH/PlaybackSpeedPatch;" + private const val INTEGRATIONS_VIDEO_QUALITY_CLASS_DESCRIPTOR = + "$VIDEO_PATH/VideoQualityPatch;" + + override fun execute(context: BytecodeContext) { + + // region patch for default playback speed + + PlaybackSpeedBottomSheetFingerprint.resultOrThrow().let { + val onItemClickMethod = + it.mutableClass.methods.find { method -> method.name == "onItemClick" } + + onItemClickMethod?.apply { + val targetIndex = getTargetIndex(Opcode.IGET) + val targetRegister = + getInstruction(targetIndex).registerA + + addInstruction( + targetIndex + 1, + "invoke-static {v$targetRegister}, $INTEGRATIONS_PLAYBACK_SPEED_CLASS_DESCRIPTOR->userSelectedPlaybackSpeed(F)V" + ) + } ?: throw PatchException("Failed to find onItemClick method") + } + + VideoInformationPatch.playbackSpeedResult.let { + it.mutableMethod.apply { + val startIndex = it.scanResult.patternScanResult!!.startIndex + val speedRegister = + getInstruction(startIndex + 1).registerA + + addInstructions( + startIndex + 2, """ + invoke-static {v$speedRegister}, $INTEGRATIONS_PLAYBACK_SPEED_CLASS_DESCRIPTOR->getPlaybackSpeed(F)F + move-result v$speedRegister + """ + ) + } + } + + // endregion + + // region patch for default video quality + + UserQualityChangeFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + val endIndex = it.scanResult.patternScanResult!!.endIndex + val qualityChangedClass = + context.findClass( + (getInstruction(endIndex)) + .reference.toString() + )!! + .mutableClass + + val onItemClickMethod = + qualityChangedClass.methods.find { method -> method.name == "onItemClick" } + + onItemClickMethod?.addInstruction( + 0, + "invoke-static {}, $INTEGRATIONS_VIDEO_QUALITY_CLASS_DESCRIPTOR->userSelectedVideoQuality()V" + ) ?: throw PatchException("Failed to find onItemClick method") + } + } + + VideoIdPatch.hookVideoId("$INTEGRATIONS_VIDEO_QUALITY_CLASS_DESCRIPTOR->newVideoStarted(Ljava/lang/String;)V") + + // endregion + + SettingsPatch.addPreferenceWithIntent( + CategoryType.VIDEO, + "revanced_custom_playback_speeds" + ) + SettingsPatch.addSwitchPreference( + CategoryType.VIDEO, + "revanced_remember_playback_speed_last_selected", + "true" + ) + SettingsPatch.addSwitchPreference( + CategoryType.VIDEO, + "revanced_remember_video_quality_last_selected", + "true" + ) + } +} diff --git a/src/main/kotlin/app/revanced/patches/music/video/speed/fingerprints/PlaybackSpeedBottomSheetParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/video/playback/fingerprints/PlaybackSpeedBottomSheetFingerprint.kt similarity index 70% rename from src/main/kotlin/app/revanced/patches/music/video/speed/fingerprints/PlaybackSpeedBottomSheetParentFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/video/playback/fingerprints/PlaybackSpeedBottomSheetFingerprint.kt index 6751715b6..a698351c8 100644 --- a/src/main/kotlin/app/revanced/patches/music/video/speed/fingerprints/PlaybackSpeedBottomSheetParentFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/video/playback/fingerprints/PlaybackSpeedBottomSheetFingerprint.kt @@ -1,10 +1,10 @@ -package app.revanced.patches.music.video.speed.fingerprints +package app.revanced.patches.music.video.playback.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint import com.android.tools.smali.dexlib2.AccessFlags -internal object PlaybackSpeedBottomSheetParentFingerprint : MethodFingerprint( +internal object PlaybackSpeedBottomSheetFingerprint : MethodFingerprint( returnType = "V", accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, parameters = listOf("L"), diff --git a/src/main/kotlin/app/revanced/patches/music/video/quality/fingerprints/UserQualityChangeFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/video/playback/fingerprints/UserQualityChangeFingerprint.kt similarity index 87% rename from src/main/kotlin/app/revanced/patches/music/video/quality/fingerprints/UserQualityChangeFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/video/playback/fingerprints/UserQualityChangeFingerprint.kt index 180ae66c9..4335cc5df 100644 --- a/src/main/kotlin/app/revanced/patches/music/video/quality/fingerprints/UserQualityChangeFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/video/playback/fingerprints/UserQualityChangeFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.music.video.quality.fingerprints +package app.revanced.patches.music.video.playback.fingerprints import app.revanced.patcher.fingerprint.MethodFingerprint import com.android.tools.smali.dexlib2.Opcode diff --git a/src/main/kotlin/app/revanced/patches/music/video/quality/VideoQualityPatch.kt b/src/main/kotlin/app/revanced/patches/music/video/quality/VideoQualityPatch.kt deleted file mode 100644 index 269b63aee..000000000 --- a/src/main/kotlin/app/revanced/patches/music/video/quality/VideoQualityPatch.kt +++ /dev/null @@ -1,64 +0,0 @@ -package app.revanced.patches.music.video.quality - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.patch.PatchException -import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.music.utils.integrations.Constants.VIDEO_PATH -import app.revanced.patches.music.utils.settings.CategoryType -import app.revanced.patches.music.utils.settings.SettingsPatch -import app.revanced.patches.music.video.information.VideoInformationPatch -import app.revanced.patches.music.video.quality.fingerprints.UserQualityChangeFingerprint -import app.revanced.patches.music.video.videoid.VideoIdPatch -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction21c - -@Suppress("unused") -object VideoQualityPatch : BaseBytecodePatch( - name = "Remember video quality", - description = "Adds an option to remember the last video quality selected.", - dependencies = setOf( - SettingsPatch::class, - VideoIdPatch::class, - VideoInformationPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(UserQualityChangeFingerprint) -) { - private const val INTEGRATIONS_VIDEO_QUALITY_CLASS_DESCRIPTOR = - "$VIDEO_PATH/VideoQualityPatch;" - - override fun execute(context: BytecodeContext) { - - UserQualityChangeFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val endIndex = it.scanResult.patternScanResult!!.endIndex - val qualityChangedClass = - context.findClass( - (getInstruction(endIndex)) - .reference.toString() - )!! - .mutableClass - - val onItemClickMethod = - qualityChangedClass.methods.find { method -> method.name == "onItemClick" } - - onItemClickMethod?.addInstruction( - 0, - "invoke-static {}, $INTEGRATIONS_VIDEO_QUALITY_CLASS_DESCRIPTOR->userSelectedVideoQuality()V" - ) ?: throw PatchException("Failed to find onItemClick method") - } - } - - VideoIdPatch.hookVideoId("$INTEGRATIONS_VIDEO_QUALITY_CLASS_DESCRIPTOR->newVideoStarted(Ljava/lang/String;)V") - - SettingsPatch.addSwitchPreference( - CategoryType.VIDEO, - "revanced_enable_save_video_quality", - "true" - ) - - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/video/speed/PlaybackSpeedPatch.kt b/src/main/kotlin/app/revanced/patches/music/video/speed/PlaybackSpeedPatch.kt deleted file mode 100644 index df6822cc7..000000000 --- a/src/main/kotlin/app/revanced/patches/music/video/speed/PlaybackSpeedPatch.kt +++ /dev/null @@ -1,73 +0,0 @@ -package app.revanced.patches.music.video.speed - -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.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.music.utils.integrations.Constants.VIDEO_PATH -import app.revanced.patches.music.utils.settings.CategoryType -import app.revanced.patches.music.utils.settings.SettingsPatch -import app.revanced.patches.music.video.information.VideoInformationPatch -import app.revanced.patches.music.video.speed.fingerprints.PlaybackSpeedBottomSheetFingerprint -import app.revanced.patches.music.video.speed.fingerprints.PlaybackSpeedBottomSheetParentFingerprint -import app.revanced.util.patch.BaseBytecodePatch -import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction - -@Suppress("unused") -object PlaybackSpeedPatch : BaseBytecodePatch( - name = "Remember playback speed", - description = "Adds an option to remember the last playback speed selected.", - dependencies = setOf( - SettingsPatch::class, - VideoInformationPatch::class - ), - compatiblePackages = COMPATIBLE_PACKAGE, - fingerprints = setOf(PlaybackSpeedBottomSheetParentFingerprint) -) { - private const val INTEGRATIONS_CLASS_DESCRIPTOR = - "$VIDEO_PATH/PlaybackSpeedPatch;" - - override fun execute(context: BytecodeContext) { - - PlaybackSpeedBottomSheetFingerprint.resolve( - context, - PlaybackSpeedBottomSheetParentFingerprint.resultOrThrow().classDef - ) - PlaybackSpeedBottomSheetFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val targetIndex = it.scanResult.patternScanResult!!.startIndex - val targetRegister = - getInstruction(targetIndex).registerD - - addInstruction( - targetIndex, - "invoke-static {v$targetRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->userSelectedPlaybackSpeed(F)V" - ) - } - } - - VideoInformationPatch.playbackSpeedResult.let { - it.mutableMethod.apply { - val startIndex = it.scanResult.patternScanResult!!.startIndex - val speedRegister = - getInstruction(startIndex + 1).registerA - - addInstructions( - startIndex + 2, """ - invoke-static {v$speedRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->getPlaybackSpeed(F)F - move-result v$speedRegister - """ - ) - } - } - - SettingsPatch.addSwitchPreference( - CategoryType.VIDEO, - "revanced_enable_save_playback_speed", - "true" - ) - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/video/speed/fingerprints/PlaybackSpeedBottomSheetFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/video/speed/fingerprints/PlaybackSpeedBottomSheetFingerprint.kt deleted file mode 100644 index 15ef29037..000000000 --- a/src/main/kotlin/app/revanced/patches/music/video/speed/fingerprints/PlaybackSpeedBottomSheetFingerprint.kt +++ /dev/null @@ -1,16 +0,0 @@ -package app.revanced.patches.music.video.speed.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 PlaybackSpeedBottomSheetFingerprint : MethodFingerprint( - returnType = "V", - accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - opcodes = listOf( - Opcode.INVOKE_VIRTUAL, - Opcode.IGET_OBJECT - ), - customFingerprint = { methodDef, _ -> methodDef.name == "onItemClick" } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/video/videoid/VideoIdPatch.kt b/src/main/kotlin/app/revanced/patches/music/video/videoid/VideoIdPatch.kt index 9683ac09c..f115f61e0 100644 --- a/src/main/kotlin/app/revanced/patches/music/video/videoid/VideoIdPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/video/videoid/VideoIdPatch.kt @@ -2,101 +2,27 @@ package app.revanced.patches.music.video.videoid import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.music.video.videoid.fingerprints.PlayerResponseModelStoryboardRendererFingerprint -import app.revanced.patches.music.video.videoid.fingerprints.VideoIdParentFingerprint -import app.revanced.util.getTargetIndexReversed +import app.revanced.patches.music.video.videoid.fingerprints.VideoIdFingerprint import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction -import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction -import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction -import com.android.tools.smali.dexlib2.iface.reference.FieldReference -import com.android.tools.smali.dexlib2.iface.reference.MethodReference -import java.io.Closeable object VideoIdPatch : BytecodePatch( - setOf( - PlayerResponseModelStoryboardRendererFingerprint, - VideoIdParentFingerprint - ) -), Closeable { + setOf(VideoIdFingerprint) +) { private var videoIdRegister = 0 private var videoIdInsertIndex = 0 private lateinit var videoIdMethod: MutableMethod - private var backgroundPlaybackInsertIndex = 0 - private var backgroundPlaybackMethodName = "" - private lateinit var backgroundPlaybackMethod: MutableMethod - override fun execute(context: BytecodeContext) { - VideoIdParentFingerprint.resultOrThrow().let { result -> - val targetIndex = result.scanResult.patternScanResult!!.endIndex - val targetReference = result.mutableMethod.getInstruction(targetIndex).reference - val targetClass = (targetReference as FieldReference).type - - context.findClass(targetClass)!! - .mutableClass.methods.first { method -> method.name == "handleVideoStageEvent" } - .apply { - videoIdMethod = this - videoIdInsertIndex = implementation!!.instructions.indexOfLast { instruction -> - val invokeReference = ((instruction as? ReferenceInstruction)?.reference) as? MethodReference - backgroundPlaybackMethodName = invokeReference?.name.toString() - - instruction.opcode == Opcode.INVOKE_INTERFACE - && invokeReference?.returnType == "Ljava/lang/String;" - } + 2 - - videoIdRegister = getInstruction(videoIdInsertIndex - 1).registerA - } - } - - PlayerResponseModelStoryboardRendererFingerprint - .resultOrThrow() - .mutableClass - .methods - .find { method -> method.name == backgroundPlaybackMethodName } - ?.apply { - backgroundPlaybackMethod = this - backgroundPlaybackInsertIndex = implementation!!.instructions.size - 1 - } - } - - override fun close () { - backgroundPlaybackMethod.apply { - val videoIdIndex = getTargetIndexReversed(Opcode.IGET_OBJECT) - val videoIdRegister = getInstruction(videoIdIndex).registerB - val videoIdReference = getInstruction(videoIdIndex).reference - val videoIdInstructionCall = "iget-object p0, v$videoIdRegister, $videoIdReference" - - if (backgroundPlaybackInsertIndex != videoIdIndex + 1) { - replaceInstruction( - backgroundPlaybackInsertIndex, - "return-object p0" - ) - replaceInstruction( - videoIdIndex, - videoIdInstructionCall - ) - addInstruction( - backgroundPlaybackInsertIndex, - videoIdInstructionCall - ) - addInstructionsWithLabels( - videoIdIndex + 1, """ - if-eqz p0, :ignore - invoke-virtual {p0}, Ljava/lang/String;->isEmpty()Z - move-result p0 - if-nez p0, :ignore - $videoIdInstructionCall - """, ExternalLabel("ignore", getInstruction(backgroundPlaybackInsertIndex)) - ) + VideoIdFingerprint.resultOrThrow().let { + it.mutableMethod.apply { + videoIdMethod = this + videoIdInsertIndex = it.scanResult.patternScanResult!!.startIndex + 2 + videoIdRegister = getInstruction(videoIdInsertIndex - 1).registerA } } } @@ -107,12 +33,5 @@ object VideoIdPatch : BytecodePatch( videoIdInsertIndex++, "invoke-static {v$videoIdRegister}, $methodDescriptor" ) - - fun hookBackgroundPlayVideoId( - methodDescriptor: String - ) = backgroundPlaybackMethod.addInstruction( - backgroundPlaybackInsertIndex++, // move-result-object offset - "invoke-static {p0}, $methodDescriptor" - ) } diff --git a/src/main/kotlin/app/revanced/patches/music/video/videoid/fingerprints/PlayerResponseModelStoryboardRendererFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/video/videoid/fingerprints/PlayerResponseModelStoryboardRendererFingerprint.kt deleted file mode 100644 index f76ae77a3..000000000 --- a/src/main/kotlin/app/revanced/patches/music/video/videoid/fingerprints/PlayerResponseModelStoryboardRendererFingerprint.kt +++ /dev/null @@ -1,18 +0,0 @@ -package app.revanced.patches.music.video.videoid.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.util.fingerprint.LiteralValueFingerprint -import com.android.tools.smali.dexlib2.AccessFlags -import com.android.tools.smali.dexlib2.Opcode - -internal object PlayerResponseModelStoryboardRendererFingerprint : LiteralValueFingerprint( - returnType = "Ljava/lang/String;", - accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - parameters = emptyList(), - opcodes = listOf( - Opcode.RETURN_OBJECT, - Opcode.CONST_4, - Opcode.RETURN_OBJECT - ), - literalSupplier = {55735497} -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/video/videoid/fingerprints/VideoIdParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/video/videoid/fingerprints/VideoIdFingerprint.kt similarity index 50% rename from src/main/kotlin/app/revanced/patches/music/video/videoid/fingerprints/VideoIdParentFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/video/videoid/fingerprints/VideoIdFingerprint.kt index c4272c94d..bc75a0302 100644 --- a/src/main/kotlin/app/revanced/patches/music/video/videoid/fingerprints/VideoIdParentFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/video/videoid/fingerprints/VideoIdFingerprint.kt @@ -5,16 +5,15 @@ import app.revanced.patcher.fingerprint.MethodFingerprint import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal object VideoIdParentFingerprint : MethodFingerprint( +internal object VideoIdFingerprint : MethodFingerprint( returnType = "V", - parameters = emptyList(), + parameters = listOf("L", "Ljava/lang/String;"), accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, opcodes = listOf( - Opcode.INVOKE_SUPER, - Opcode.IGET_OBJECT, - Opcode.CONST_4, - Opcode.IPUT_OBJECT, - Opcode.IGET_OBJECT + Opcode.INVOKE_INTERFACE_RANGE, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_INTERFACE_RANGE, + Opcode.MOVE_RESULT_OBJECT, ), - customFingerprint = { methodDef, _ -> methodDef.definingClass.endsWith("/WatchFragment;") && methodDef.name == "onDestroyView" } + strings = listOf("Null initialPlayabilityStatus") ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/ads/general/GeneralAdsBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/ads/general/AdsBytecodePatch.kt similarity index 99% rename from src/main/kotlin/app/revanced/patches/youtube/ads/general/GeneralAdsBytecodePatch.kt rename to src/main/kotlin/app/revanced/patches/youtube/ads/general/AdsBytecodePatch.kt index 88d889f1e..f3296484e 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/ads/general/GeneralAdsBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/ads/general/AdsBytecodePatch.kt @@ -25,7 +25,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction31i import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c @Patch(dependencies = [SharedResourceIdPatch::class]) -object GeneralAdsBytecodePatch : BytecodePatch( +object AdsBytecodePatch : BytecodePatch( setOf( CompactYpcOfferModuleViewFingerprint, InterstitialsContainerFingerprint, @@ -33,6 +33,7 @@ object GeneralAdsBytecodePatch : BytecodePatch( ) ) { override fun execute(context: BytecodeContext) { + // region patch for hide fullscreen ads // non-litho view, used in some old clients. diff --git a/src/main/kotlin/app/revanced/patches/youtube/ads/general/GeneralAdsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/ads/general/AdsPatch.kt similarity index 95% rename from src/main/kotlin/app/revanced/patches/youtube/ads/general/GeneralAdsPatch.kt rename to src/main/kotlin/app/revanced/patches/youtube/ads/general/AdsPatch.kt index 4e6a506e7..059c81c5f 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/ads/general/GeneralAdsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/ads/general/AdsPatch.kt @@ -2,7 +2,6 @@ package app.revanced.patches.youtube.ads.general import app.revanced.patcher.data.ResourceContext import app.revanced.patches.shared.litho.LithoFilterPatch -import app.revanced.patches.youtube.ads.video.VideoAdsPatch import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.youtube.utils.fix.doublebacktoclose.DoubleBackToClosePatch import app.revanced.patches.youtube.utils.fix.swiperefresh.SwipeRefreshPatch @@ -14,12 +13,12 @@ import app.revanced.util.startsWithAny import org.w3c.dom.Element @Suppress("DEPRECATION", "unused") -object GeneralAdsPatch : BaseResourcePatch( +object AdsPatch : BaseResourcePatch( name = "Hide ads", description = "Adds options to hide ads.", dependencies = setOf( + AdsBytecodePatch::class, DoubleBackToClosePatch::class, - GeneralAdsBytecodePatch::class, LithoFilterPatch::class, SettingsPatch::class, SwipeRefreshPatch::class, diff --git a/src/main/kotlin/app/revanced/patches/youtube/ads/video/VideoAdsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/ads/general/VideoAdsPatch.kt similarity index 82% rename from src/main/kotlin/app/revanced/patches/youtube/ads/video/VideoAdsPatch.kt rename to src/main/kotlin/app/revanced/patches/youtube/ads/general/VideoAdsPatch.kt index cc563cd9c..2f0f6e16c 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/ads/video/VideoAdsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/ads/general/VideoAdsPatch.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.ads.video +package app.revanced.patches.youtube.ads.general import app.revanced.patches.shared.ads.BaseAdsPatch import app.revanced.patches.youtube.utils.integrations.Constants.ADS_CLASS_DESCRIPTOR diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/navigation/NavigationBarComponentsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/general/navigation/NavigationBarComponentsPatch.kt index e4caeddf5..ca24d8040 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/general/navigation/NavigationBarComponentsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/general/navigation/NavigationBarComponentsPatch.kt @@ -21,8 +21,8 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction @Suppress("unused") object NavigationBarComponentsPatch : BaseBytecodePatch( - name = "Hide navigation bar components", - description = "Adds options to hide components related to navigation bar.", + name = "Navigation bar components", + description = "Adds options to hide or change components related to navigation bar.", dependencies = setOf( SettingsPatch::class, NavigationBarHookPatch::class diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/splashanimation/SplashAnimationPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/general/splashanimation/SplashAnimationPatch.kt index 5806b9467..377724735 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/general/splashanimation/SplashAnimationPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/general/splashanimation/SplashAnimationPatch.kt @@ -9,11 +9,10 @@ import app.revanced.patches.youtube.utils.integrations.Constants.GENERAL_CLASS_D import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.DarkSplashAnimation import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.getTargetIndexReversed +import app.revanced.util.getTargetIndexWithReferenceReversed import app.revanced.util.getWideLiteralInstructionIndex import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.resultOrThrow -import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction @Suppress("unused") @@ -32,7 +31,7 @@ object SplashAnimationPatch : BaseBytecodePatch( SplashAnimationFingerprint.resultOrThrow().let { it.mutableMethod.apply { val constIndex = getWideLiteralInstructionIndex(DarkSplashAnimation) - val targetIndex = getTargetIndexReversed(constIndex, Opcode.INVOKE_STATIC) + 2 + val targetIndex = getTargetIndexWithReferenceReversed(constIndex, "(I)Z") + 2 val targetRegister = getInstruction(targetIndex - 1).registerA addInstructions( diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/toolbar/ToolBarComponentsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/general/toolbar/ToolBarComponentsPatch.kt index 43d2c0228..b178ad154 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/general/toolbar/ToolBarComponentsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/general/toolbar/ToolBarComponentsPatch.kt @@ -89,7 +89,7 @@ object ToolBarComponentsPatch : BaseBytecodePatch( key = "ForceHideVoiceSearchButton", default = false, title = "Force hide voice search button", - description = "Hide voice search button with legacy method, button will always be hidden" + description = "Hide voice search button with legacy method, button will always be hidden." ) override fun execute(context: BytecodeContext) { diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/branding/name/CustomBrandingNamePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/branding/name/CustomBrandingNamePatch.kt index f443b8450..1ba90af2f 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/branding/name/CustomBrandingNamePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/branding/name/CustomBrandingNamePatch.kt @@ -16,14 +16,14 @@ object CustomBrandingNamePatch : BaseResourcePatch( dependencies = setOf(SettingsPatch::class), compatiblePackages = COMPATIBLE_PACKAGE ) { - private const val APP_NAME = "ReVanced Extended" + private const val APP_NAME = "RVX" private val AppName by stringPatchOption( key = "AppName", default = APP_NAME, values = mapOf( - "Full name" to APP_NAME, - "Short name" to "RVX" + "Full name" to "ReVanced Extended", + "Short name" to APP_NAME ), title = "App name", description = "The name of the app.", diff --git a/src/main/kotlin/app/revanced/patches/youtube/player/overlaybuttons/OverlayButtonsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/player/overlaybuttons/OverlayButtonsPatch.kt index 414d73b08..48429ef80 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/player/overlaybuttons/OverlayButtonsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/player/overlaybuttons/OverlayButtonsPatch.kt @@ -60,11 +60,6 @@ object OverlayButtonsPatch : BaseResourcePatch( PlayerControlsPatch.hookOverlayButtons("$OVERLAY_BUTTONS_PATH/$className") } - /** - * Copy arrays - */ - context.copyXmlNode("youtube/overlaybuttons/shared/host", "values/arrays.xml", "resources") - /** * Copy resources */ diff --git a/src/main/kotlin/app/revanced/util/BytecodeUtils.kt b/src/main/kotlin/app/revanced/util/BytecodeUtils.kt index 7a15e066d..0bb78155a 100644 --- a/src/main/kotlin/app/revanced/util/BytecodeUtils.kt +++ b/src/main/kotlin/app/revanced/util/BytecodeUtils.kt @@ -98,29 +98,11 @@ fun MethodFingerprint.literalInstructionBooleanHook( descriptor: String ) = literalInstructionBooleanHook(literal.toLong(), descriptor) -fun MethodFingerprint.literalInstructionBooleanHook( - literal: Int, - descriptor: String, - message: String -) = literalInstructionBooleanHook(literal.toLong(), descriptor, message) - fun MethodFingerprint.literalInstructionBooleanHook( literal: Long, descriptor: String -) = literalInstructionBooleanHook(literal, descriptor, "") - -fun MethodFingerprint.literalInstructionBooleanHook( - literal: Long, - descriptor: String, - message: String ) { - val method = result?.mutableMethod - ?: if (message.isEmpty()) - throw exception - else - throw PatchException("This version is not supported. $message") - - method.apply { + resultOrThrow().mutableMethod.apply { val literalIndex = getWideLiteralInstructionIndex(literal) val targetIndex = getTargetIndex(literalIndex, Opcode.MOVE_RESULT) val targetRegister = getInstruction(targetIndex).registerA @@ -224,13 +206,15 @@ fun Method.getWideLiteralInstructionIndex(literal: Long) = implementation?.let { } } ?: -1 -fun MutableMethod.getEmptyStringInstructionIndex() +fun Method.getEmptyStringInstructionIndex() = getStringInstructionIndex("") -fun MutableMethod.getStringInstructionIndex(value: String) = indexOfFirstInstruction { - opcode == Opcode.CONST_STRING - && (this as? BuilderInstruction21c)?.reference.toString() == value -} +fun Method.getStringInstructionIndex(value: String) = implementation?.let { + it.instructions.indexOfFirst { instruction -> + instruction.opcode == Opcode.CONST_STRING + && (instruction as? BuilderInstruction21c)?.reference.toString() == value + } +} ?: -1 /** * Check if the method contains a literal with the given value. @@ -246,7 +230,6 @@ fun Method.containsMethodReferenceNameInstructionIndex(methodName: String) = fun Method.containsReferenceInstructionIndex(reference: String) = getTargetIndexWithReference(reference) >= 0 - /** * Traverse the class hierarchy starting from the given root class. * diff --git a/src/main/resources/music/settings/host/values/arrays.xml b/src/main/resources/music/settings/host/values/arrays.xml index 512adb976..6c3e25d26 100644 --- a/src/main/resources/music/settings/host/values/arrays.xml +++ b/src/main/resources/music/settings/host/values/arrays.xml @@ -1,8 +1,48 @@ - + + @string/revanced_change_start_page_entry_chart + @string/revanced_change_start_page_entry_explore + @string/revanced_change_start_page_entry_home + @string/revanced_change_start_page_entry_library + @string/revanced_change_start_page_entry_subscription + + + FEmusic_charts + FEmusic_explore + FEmusic_home + FEmusic_library_landing + FEmusic_library_corpus_artists + + @string/revanced_extended_settings_export_as_file @string/revanced_extended_settings_import_as_file @string/revanced_extended_settings_import_export_as_text + + NewPipe + Seal + Tubular + YTDLnis + + + org.schabi.newpipe + com.junkfood.seal + org.polymorphicshade.tubular + com.deniscerri.ytdl + + + https://github.com/TeamNewPipe/NewPipe/releases/latest + https://github.com/JunkFood02/Seal/releases/latest + https://github.com/polymorphicshade/Tubular/releases/latest + https://github.com/deniscerri/ytdlnis/releases/latest + + + @string/revanced_spoof_app_version_target_entry_6_11_52 + @string/revanced_spoof_app_version_target_entry_4_27_53 + + + 6.11.52 + 4.27.53 + diff --git a/src/main/resources/music/settings/host/values/strings.xml b/src/main/resources/music/settings/host/values/strings.xml index 62b3e4743..9bfe3daf5 100644 --- a/src/main/resources/music/settings/host/values/strings.xml +++ b/src/main/resources/music/settings/host/values/strings.xml @@ -1,274 +1,301 @@ - Open GmsCore - Enable cloud messaging to receive notifications. - GmsCore is not installed. Install it. - Action needed - "GmsCore does not have permission to run in the background. + + ReVanced Extended -Follow the 'Don't kill my app' guide for your phone, and apply the instructions to your MicroG installation. + + Restart to load the layout normally + Refresh and restart -This is required for the app to work." - Open website - "GmsCore battery optimizations must be disabled to prevent issues. + + Account -Tap on the continue button and disable battery optimizations." - Continue + Hide account menu + Hides account menu elements in the custom filter. + Account menu filter + List of account menu names to filter separated by a new line. + Hide empty component + Hides empty components in the account menu. + Hide handle + Hides the handle in the account menu. + Hide terms container + Hides terms of service container. - Account - Action Bar - Ads - Flyout - General - Miscellaneous - Navigation - Player - Video + + + Action Bar + + Hide like and dislike buttons + Hides the like and dislike buttons. It does not work in the old player layout. + Hide comment button + Hides comment button. + Hide add to playlist button + Hides add to playlist button. + Hide download button + Hides download button. + Hide share button + Hides share button. + Hide radio button + Hides start radio button. + Hides labels in action buttons. + Hide action button labels + Override download action button + "Download button opens your external downloader. + +• Only overrides download action button in player. +• Does not override download button in flyout menu or library." + External downloader package name + Package name of your installed external downloader app, such as NewPipe or YTDLnis. + External downloader + Warning + "%1$s is not installed. +Please download %2$s from the website." + %s is not installed. Please install it. + + + + Ads + + Hide fullscreen ads + Hides fullscreen ads. + Hide general ads + Hides general ads. + Hide music ads + Hides ads before playing a music. + Hide paid promotion label + Hides paid promotion label. + Hide premium promotion popup + Hides premium promotion popups. + Hide premium renewal banner + Hides the premium renewal banner. + + + + Flyout Menu + + Enable compact dialog + "Enables the compact flyout menu on phones. + +Limitations: +• Album art in the library tab becomes smaller when organized in a grid. +• Sleep timer layout may appear unusual." + Enable trim silence + "Enables 'Trim silence' switch to the playback speed flyout menu. + +Info: +• This feature is for podcasts. +• This feature is still in development, so it may be unstable." + Hide like and dislike button + Hide 3-column component + Hide add to queue menu + Hide captions menu + Hide delete playlist menu + Hide dismiss queue menu + Hide download menu + Hide edit playlist menu + Hide go to album menu + Hide go to artist menu + Hide go to episode menu + Hide go to podcast menu + Hide help & feedback menu + Hide play next menu + Hide quality menu + Hide remove from library menu + Hide remove from playlist menu + Hide report menu + Hide save episode for later menu + Hide save to library menu + Hide save to playlist menu + Hide share menu + Hide shuffle play menu + Hide sleep timer menu + Hide start radio menu + Hide stats for nerds menu + Hide subscribe / unsubscribe menu + Hide view song credit menu + Continue watching + Continues the video from the current time when switching to YouTube. + Watch on YouTube + Invalid video url. + Replace dismiss queue + Replaces \'Dismiss queue\' with \'Watch on YouTube\'. + Applies only to player flyout menu + Report menu in comments will not be replaced. + Replace report + Replaces \'Report\' with \'Playback speed\'. + + + + General + + Change start page + Select which page the app opens in. Charts Explore Home Library Subscriptions - Select which page the app opens in. - Change start page - Configure which components to filter, separated by new lines. - Edit custom filter - Invalid custom filter: %s. - Enables the custom filter to hide layout components. - Enable custom filter - Invalid custom playback speeds. Speeds reset to default. - Configure the available playback speeds. - Edit custom playback speeds - Custom speeds can\'t be more than %sx. - Disables captions from being automatically enabled. Disable forced auto captions - Disables redirection to the next track when clicking dislike button. + Disables captions from being automatically enabled. Disable dislike redirection - %s is not installed. Please install it. - Sets the navigation bar color to black. - Enable black navigation bar - Matches the color of the miniplayer to the fullscreen player. - Enable color match player - "Enables the compact flyout menu on phones. - -Known issues: -• Album art in the library tab becomes smaller when organized in a grid. -• Sleep timer layout may appear unusual." - Enable compact dialog - Prints the debug logs include buffer. - Enable debug buffer logging - Prints the debug log. - Enable debug logging - Keeps the player minimized even when another track is played. - Enable force minimized player - Enables landscape mode when rotating the screen on phones. + Disables redirection to the next track when clicking dislike button. Enable landscape mode - Enables next button in the miniplayer. - Enable miniplayer next button - Enables previous button in the miniplayer. - Enable miniplayer previous button - Returns the player background to the old style. - Enable old player background - "Returns the player layout to the old style. -Some features may not work properly in the old player layout." - Enable old player layout - Returns the library tab to the old style. (Experimental) - Enable old style library shelf - Enables the opus audio codec instead of the mp4a audio codec. - Enable opus codec - Remembers the last playback speed selected. - Enable save playback speed - Remembers the last video quality selected. - Enable save video quality - Enables swipe down to dismiss miniplayer. - Enable swipe to dismiss miniplayer - Zen mode is also applied to podcasts. - Enable zen mode in podcasts - Changes the player background to light grey to reduce eye strain. - Enable zen mode - Export settings to file - Failed to export settings. - Settings were successfully exported. - Import - Import settings from file - Copy - Import / Export settings as text - Import or export settings. - Import / Export settings - Import failed: %s. - Settings reset to default. - Imported %d settings. - Reset - %s is not installed. Please install it. - Package name of your installed external downloader app, such as NewPipe or YTDLnis. - External downloader package name - Watch on YouTube - Hides empty components in the account menu. - Hide empty component - Hides account menu elements in the custom filter. - Hide account menu - Hides add to playlist button. - Hide add to playlist button - Hides comment button. - Hide comment button - Hides download button. - Hide download button - Hides labels in action buttons. - Hide action button labels - Hides the like and dislike buttons. It does not work in the old player layout. - Hide like and dislike buttons - Hides start radio button. - Hide radio button - Hides share button. - Hide share button - Hides the button shelf from the homepage and explore tab. + Enables landscape mode when rotating the screen on phones. + Enable custom filter + Enables the custom filter to hide layout components. + Custom filter + + List of component path builder strings to filter separated by new line. + Invalid custom filter: %s. Hide button shelf - Hides the carousel shelf from the homepage and explore tab. + Hides button shelf in feed. Hide carousel shelf - Hides the cast button. - Hide cast button - Hides the category bar. - Hide category bar - Hides the channel guidelines at the top of the comments section. - Hide channel guidelines - Hides the emoji picker and time stamp when typing comments. - Hide emoji picker and time stamp - Hides the explore button. - Hide explore button - Hide play next, save to playlist, share menus. - Hide 3-column component - Hide add to queue menu - Hide captions menu - Hide delete playlist menu - Hide dismiss queue menu - Hide download menu - Hide edit playlist menu - Hide go to album menu - Hide go to artist menu - Hide go to episode menu - Hide go to podcast menu - Hide help & feedback menu - Hide like and dislike button - Hide play next menu - Hide quality menu - Hide remove from library menu - Hide remove from playlist menu - Hide report menu - Hide save episode for later menu - Hide save to library menu - Hide save to playlist menu - Hide share menu - Hide shuffle play menu - Hide sleep timer menu - Hide start radio menu - Hide stats for nerds menu - Hide subscribe / unsubscribe menu - Hide view song credit menu - Hides fullscreen ads. - Hide fullscreen ads - Hides the share button in the fullscreen player. - Hide fullscreen share button - Hides general ads. - Hide general ads - Hides the handle in the account menu. - Hide handle - Hides the history button in the toolbar. - Hide history button - Hides the home button. - Hide home button - Hides the library button. - Hide library button - Hides ads before playing a music. - Hide music ads - Hides the navigation bar. - Hide navigation bar - Hides labels below the navigation buttons. - Hide navigation label - Hides the \"New playlist\" button in the library. - Hide new playlist button - Hides paid promotion banner. - Hide paid promotion banner - Hides the playlist card from the homepage. - Hide playlist card - Hides premium promotion popups. - Hide premium promotion popup - Hides the premium renewal banner. - Hide premium renewal banner - Hides the samples button. - Hide samples button - Hides the samples shelf from the homepage. + Hides carousel shelf in feed. + Hide playlist card shelf + Hides playlist card shelf in feed. Hide samples shelf - Hides the \"Tap to update\" button. - Hide \"Tap to update\" button - Hides terms of service container. - Hide terms container - Hides the upgrade button. - Hide upgrade button - Replaces the offline download button with an external download button. - Hook download button - Already playing from the official music source. - Official music source is unavailable. + Hides samples shelf in feed. + Hide cast button + Hides cast button. + Hide category bar + Hides category bar. + Hide floating button + Hides floating button in library. + Hide \'Tap to update\' button + Hides \'Tap to update\' button. + Hide history button + Hides history button in toolbar. + Hide notification button + Hides notification button in toolbar. + Hide sound search button + Hides sound search button in search bar. + Hide voice search button + Hides voice search button in search bar. + Restore old style library shelf + Returns the library tab to the old style. (Experimental) + Remove viewer discretion dialog "Removes the viewer discretion dialog. This does not bypass the age restriction. It just accepts it automatically." - Remove viewer discretion dialog - Restart to load the layout normally - Refresh and restart - Continues the video from the current time when switching to YouTube. - Continue watching - Replaces \"Dismiss queue\" with \"Watch on YouTube\". - Replace dismiss queue - Report menu in comments will not be replaced. - Applies only to player flyout menu - Replaces \"Report\" with \"Playback speed\". - Replace report - "Replace the cast button in the player with the "Open music" button. (Experimental) -Known issue: If one or more music that cannot be played in the playlist, it does not work normally." - Replace cast button - Remembers the state of the repeat toggle. - Remember repeat state - Remembers the state of the shuffle toggle. - Remember shuffle state - About - Data is provided by the Return YouTube Dislike API. Tap here to learn more. - Hides the separator of the like button. - Compact like button - Displays the percentage of dislikes instead of the dislike count. - Dislikes as percentage - Shows the dislike count of videos. - Dislikes are temporarily unavailable (API timed out). - Dislikes are unavailable (status %d). - Dislikes are unavailable (client API limit reached). - Dislikes are unavailable (%s). - Shows a toast if the Return YouTube Dislike API is unavailable. - Show a toast if API is unavailable - Hidden - Removes tracking query parameters from URLs when sharing links. - Sanitize sharing links - Changing default speed to %s. - Changing default mobile data quality to %s. - Failed to set quality. - Changing default Wi-Fi quality to %s. - Settings copied to clipboard. + Spoof app version "Spoofs the client version to an older version. • This will change the appearance of the app, but unknown side effects may occur. • If later turned off, the old UI may remain until the app data is cleared." - 4.27.53 - Disable radio mode in Canadian regions - 6.10.53 - Disable real-time lyrics - Select the spoof app version target. Spoof app version target - Spoof app version - Invalid video url. + Select the spoof app version target. + 4.27.53 - Disable radio mode in Canadian regions + 6.11.52 - Disable real-time lyrics + + + + Navigation Bar + + Enable black navigation bar + Sets the navigation bar color to black. + Hide home button + Hides the home button. + Hide samples button + Hides the samples button. + Hide explore button + Hides the explore button. + Hide library button + Hides the library button. + Hide upgrade button + Hides the upgrade button. + Hide navigation bar + Hides the navigation bar. + Hide navigation label + Hides labels below the navigation buttons. + + + + Player + + Enable color match player + Matches the color of the miniplayer to the fullscreen player. + Enable force minimized player + Keeps the player minimized even when another track is played. + Enable miniplayer next button + Enables next button in the miniplayer. + Enable miniplayer previous button + Enables previous button in the miniplayer. + Enable swipe to dismiss miniplayer + Enables swipe down to dismiss miniplayer. + Enable zen mode + Changes the player background to light grey to reduce eye strain. + Enable zen mode in podcasts + Zen mode is also applied to podcasts. + Hide channel guidelines + Hides channel guidelines at the top of the comments section. + Hide timestamp and emoji buttons + Hides timestamp and emoji buttons when typing comments. + Hide fullscreen share button + Hides the share button in the fullscreen player. + Remember repeat state + Remembers the state of the repeat toggle. + Remember shuffle state + Remembers the state of the shuffle toggle. + Restore old comments popup panels + Returns the comments popup panels to the old style. + Restore old player background + Returns the player background to the old style. + Restore old player layout + "Returns the player layout to the old style. +Some features may not work properly in the old player layout." + Replace cast button + "Replace the cast button in the player with the 'Open music' button. (Experimental) +Limitation: If one or more music that cannot be played in the playlist, it does not work normally." + Already playing from the official music source. + Official music source is unavailable. + + + + Video + + Edit custom playback speeds + Add or change available playback speeds. + Remember playback speed changes + Remembers the last playback speed selected. + Remember video quality changes + Remembers the last video quality selected. + Custom speeds must be less than %sx. Using default values. + Invalid custom playback speeds. Using default values. + Changing default speed to %s. + Changing default mobile data quality to %s. + Failed to set quality. + Changing default Wi-Fi quality to %s. + + + Return YouTube Dislike + + Enable Return YouTube Dislike + Shows the dislike count of videos. + Dislikes as percentage + Displays the percentage of dislikes instead of the dislike count. + Compact like button + Hides the separator of the like button. + Show a toast if API is unavailable + Shows a toast if the Return YouTube Dislike API is unavailable. + About + ReturnYouTubeDislike.com + Data is provided by the Return YouTube Dislike API. Tap here to learn more. + + Dislikes are temporarily unavailable (API timed out). + Dislikes are unavailable (status %d). + Dislikes are unavailable (client API limit reached). + Dislikes are unavailable (%s). + Hidden + + + + SponsorBlock Enable SponsorBlock SponsorBlock is a crowd-sourced system for skipping annoying parts of YouTube videos. - Show a toast if API is not available Shows a toast if the SponsorBlock API is unavailable. - Show a toast when skipping automatically Shows a toast when a segment is automatically skipped. - Change API URL The address SponsorBlock uses to make calls to the server. Do not change this unless you know what you\'re doing. API URL reset. @@ -321,4 +348,52 @@ Known issue: If one or more music that cannot be played in the playlist, it does Data is provided by the SponsorBlock API. Tap here to learn more and see downloads for other platforms. About + sponsor.ajay.app + + + + Miscellaneous + + Enable debug logging + Prints the debug log. + Enable debug buffer logging + Prints the debug logs include buffer. + Enable opus codec + Enables the opus audio codec instead of the mp4a audio codec. + + Open GmsCore + Enable cloud messaging to receive notifications. + GmsCore is not installed. Install it. + Action needed + "GmsCore does not have permission to run in the background. + +Follow the 'Don't kill my app' guide for your phone, and apply the instructions to your MicroG installation. + +This is required for the app to work." + Open website + "GmsCore battery optimizations must be disabled to prevent issues. + +Tap on the continue button and disable battery optimizations." + Continue + + Sanitize sharing links + Removes tracking query parameters from URLs when sharing links. + + Import / Export settings + Import or export settings. + + Export settings to file + Import settings from file + Import / Export settings as text + + Failed to export settings. + Settings were successfully exported. + Import + Copy + Import failed: %s. + Settings reset to default. + Imported %d settings. + Reset + Settings copied to clipboard. + diff --git a/src/main/resources/music/settings/values-v21/strings.xml b/src/main/resources/music/settings/values-v21/strings.xml deleted file mode 100644 index 997922164..000000000 --- a/src/main/resources/music/settings/values-v21/strings.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - Return YouTube Dislike - SponsorBlock - - ReVanced Extended - - @string/revanced_custom_filter_strings_summary - @string/revanced_custom_filter_strings_title - - ReturnYouTubeDislike.com - @string/revanced_category_ryd - - sponsor.ajay.app - diff --git a/src/main/resources/music/spoofappversion/host/values/arrays.xml b/src/main/resources/music/spoofappversion/host/values/arrays.xml deleted file mode 100644 index f2b6fd09a..000000000 --- a/src/main/resources/music/spoofappversion/host/values/arrays.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - @string/revanced_spoof_app_version_target_entry_6_10_53 - @string/revanced_spoof_app_version_target_entry_4_27_53 - - - 6.10.53 - 4.27.53 - - diff --git a/src/main/resources/music/startpage/host/values/arrays.xml b/src/main/resources/music/startpage/host/values/arrays.xml deleted file mode 100644 index 3f3e14323..000000000 --- a/src/main/resources/music/startpage/host/values/arrays.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - @string/revanced_change_start_page_entry_chart - @string/revanced_change_start_page_entry_explore - @string/revanced_change_start_page_entry_home - @string/revanced_change_start_page_entry_library - @string/revanced_change_start_page_entry_subscription - - - FEmusic_charts - FEmusic_explore - FEmusic_home - FEmusic_library_landing - FEmusic_library_corpus_artists - - diff --git a/src/main/resources/youtube/overlaybuttons/shared/host/values/arrays.xml b/src/main/resources/youtube/overlaybuttons/shared/host/values/arrays.xml deleted file mode 100644 index fd7f228c3..000000000 --- a/src/main/resources/youtube/overlaybuttons/shared/host/values/arrays.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - NewPipe - Seal - Tubular - YTDLnis - - - org.schabi.newpipe - com.junkfood.seal - org.polymorphicshade.tubular - com.deniscerri.ytdl - - - https://github.com/TeamNewPipe/NewPipe/releases/latest - https://github.com/JunkFood02/Seal/releases/latest - https://github.com/polymorphicshade/Tubular/releases/latest - https://github.com/deniscerri/ytdlnis/releases/latest - - diff --git a/src/main/resources/youtube/settings/host/values/arrays.xml b/src/main/resources/youtube/settings/host/values/arrays.xml index 41962ebaf..4c80d1b52 100644 --- a/src/main/resources/youtube/settings/host/values/arrays.xml +++ b/src/main/resources/youtube/settings/host/values/arrays.xml @@ -80,6 +80,24 @@ 1440 2160 + + NewPipe + Seal + Tubular + YTDLnis + + + org.schabi.newpipe + com.junkfood.seal + org.polymorphicshade.tubular + com.deniscerri.ytdl + + + https://github.com/TeamNewPipe/NewPipe/releases/latest + https://github.com/JunkFood02/Seal/releases/latest + https://github.com/polymorphicshade/Tubular/releases/latest + https://github.com/deniscerri/ytdlnis/releases/latest + @string/revanced_spoof_app_version_target_entry_18_17_43 @string/revanced_spoof_app_version_target_entry_18_05_40 diff --git a/src/main/resources/youtube/settings/xml/revanced_prefs.xml b/src/main/resources/youtube/settings/xml/revanced_prefs.xml index 70ba8d03a..ed48af445 100644 --- a/src/main/resources/youtube/settings/xml/revanced_prefs.xml +++ b/src/main/resources/youtube/settings/xml/revanced_prefs.xml @@ -579,8 +579,8 @@ - +