From 611f4d31598a10613ff4472f899eec32189474ce Mon Sep 17 00:00:00 2001 From: gdlbo <41114720+gdlbo@users.noreply.github.com> Date: Tue, 6 Feb 2024 18:37:30 +0300 Subject: [PATCH 1/2] updated run configs --- .run/RClass Regeneration.run.xml | 28 +++++++++++++++++++ .run/Update APKs Jars (MacOS).run.xml | 17 +++++++++++ .run/Update APKs Jars.run.xml | 17 +++++++++++ .../lite [app_buildAndInstallVTLBeta].run.xml | 24 ++++++++++++++++ .run/lite [app_buildAndInstallVTLDev].run.xml | 24 ++++++++++++++++ ...te [app_buildAndInstallVTLRelease].run.xml | 24 ++++++++++++++++ .run/lite [app_buildAndLaunchVTLBeta].run.xml | 24 ++++++++++++++++ .run/lite [app_buildAndLaunchVTLDev].run.xml | 24 ++++++++++++++++ ...ite [app_buildAndLaunchVTLRelease].run.xml | 24 ++++++++++++++++ .run/lite [app_buildVTLBeta].run.xml | 24 ++++++++++++++++ .run/lite [app_buildVTLDev].run.xml | 24 ++++++++++++++++ .run/lite [app_buildVTLRelease].run.xml | 24 ++++++++++++++++ .run/lite [app_exportDexBeta].run.xml | 24 ++++++++++++++++ .run/lite [app_exportDexDev].run.xml | 24 ++++++++++++++++ .run/lite [app_exportDexRelease].run.xml | 24 ++++++++++++++++ .run/lite [app_prepareDexForMergeDev].run.xml | 24 ++++++++++++++++ ...te [app_prepareDexForMergeRelease].run.xml | 24 ++++++++++++++++ 17 files changed, 398 insertions(+) create mode 100644 .run/RClass Regeneration.run.xml create mode 100644 .run/Update APKs Jars (MacOS).run.xml create mode 100644 .run/Update APKs Jars.run.xml create mode 100644 .run/lite [app_buildAndInstallVTLBeta].run.xml create mode 100644 .run/lite [app_buildAndInstallVTLDev].run.xml create mode 100644 .run/lite [app_buildAndInstallVTLRelease].run.xml create mode 100644 .run/lite [app_buildAndLaunchVTLBeta].run.xml create mode 100644 .run/lite [app_buildAndLaunchVTLDev].run.xml create mode 100644 .run/lite [app_buildAndLaunchVTLRelease].run.xml create mode 100644 .run/lite [app_buildVTLBeta].run.xml create mode 100644 .run/lite [app_buildVTLDev].run.xml create mode 100644 .run/lite [app_buildVTLRelease].run.xml create mode 100644 .run/lite [app_exportDexBeta].run.xml create mode 100644 .run/lite [app_exportDexDev].run.xml create mode 100644 .run/lite [app_exportDexRelease].run.xml create mode 100644 .run/lite [app_prepareDexForMergeDev].run.xml create mode 100644 .run/lite [app_prepareDexForMergeRelease].run.xml diff --git a/.run/RClass Regeneration.run.xml b/.run/RClass Regeneration.run.xml new file mode 100644 index 000000000..618f14347 --- /dev/null +++ b/.run/RClass Regeneration.run.xml @@ -0,0 +1,28 @@ + + + + + + \ No newline at end of file diff --git a/.run/Update APKs Jars (MacOS).run.xml b/.run/Update APKs Jars (MacOS).run.xml new file mode 100644 index 000000000..116562072 --- /dev/null +++ b/.run/Update APKs Jars (MacOS).run.xml @@ -0,0 +1,17 @@ + + + + \ No newline at end of file diff --git a/.run/Update APKs Jars.run.xml b/.run/Update APKs Jars.run.xml new file mode 100644 index 000000000..14f97f265 --- /dev/null +++ b/.run/Update APKs Jars.run.xml @@ -0,0 +1,17 @@ + + + + \ No newline at end of file diff --git a/.run/lite [app_buildAndInstallVTLBeta].run.xml b/.run/lite [app_buildAndInstallVTLBeta].run.xml new file mode 100644 index 000000000..7d4388d64 --- /dev/null +++ b/.run/lite [app_buildAndInstallVTLBeta].run.xml @@ -0,0 +1,24 @@ + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.run/lite [app_buildAndInstallVTLDev].run.xml b/.run/lite [app_buildAndInstallVTLDev].run.xml new file mode 100644 index 000000000..541d05184 --- /dev/null +++ b/.run/lite [app_buildAndInstallVTLDev].run.xml @@ -0,0 +1,24 @@ + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.run/lite [app_buildAndInstallVTLRelease].run.xml b/.run/lite [app_buildAndInstallVTLRelease].run.xml new file mode 100644 index 000000000..2997f9377 --- /dev/null +++ b/.run/lite [app_buildAndInstallVTLRelease].run.xml @@ -0,0 +1,24 @@ + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.run/lite [app_buildAndLaunchVTLBeta].run.xml b/.run/lite [app_buildAndLaunchVTLBeta].run.xml new file mode 100644 index 000000000..6a1ff3c0d --- /dev/null +++ b/.run/lite [app_buildAndLaunchVTLBeta].run.xml @@ -0,0 +1,24 @@ + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.run/lite [app_buildAndLaunchVTLDev].run.xml b/.run/lite [app_buildAndLaunchVTLDev].run.xml new file mode 100644 index 000000000..b44c03b5c --- /dev/null +++ b/.run/lite [app_buildAndLaunchVTLDev].run.xml @@ -0,0 +1,24 @@ + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.run/lite [app_buildAndLaunchVTLRelease].run.xml b/.run/lite [app_buildAndLaunchVTLRelease].run.xml new file mode 100644 index 000000000..6cf36adad --- /dev/null +++ b/.run/lite [app_buildAndLaunchVTLRelease].run.xml @@ -0,0 +1,24 @@ + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.run/lite [app_buildVTLBeta].run.xml b/.run/lite [app_buildVTLBeta].run.xml new file mode 100644 index 000000000..3b5c8cea6 --- /dev/null +++ b/.run/lite [app_buildVTLBeta].run.xml @@ -0,0 +1,24 @@ + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.run/lite [app_buildVTLDev].run.xml b/.run/lite [app_buildVTLDev].run.xml new file mode 100644 index 000000000..fa33a5575 --- /dev/null +++ b/.run/lite [app_buildVTLDev].run.xml @@ -0,0 +1,24 @@ + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.run/lite [app_buildVTLRelease].run.xml b/.run/lite [app_buildVTLRelease].run.xml new file mode 100644 index 000000000..b1eccb89a --- /dev/null +++ b/.run/lite [app_buildVTLRelease].run.xml @@ -0,0 +1,24 @@ + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.run/lite [app_exportDexBeta].run.xml b/.run/lite [app_exportDexBeta].run.xml new file mode 100644 index 000000000..e3539cccc --- /dev/null +++ b/.run/lite [app_exportDexBeta].run.xml @@ -0,0 +1,24 @@ + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.run/lite [app_exportDexDev].run.xml b/.run/lite [app_exportDexDev].run.xml new file mode 100644 index 000000000..afbcdd214 --- /dev/null +++ b/.run/lite [app_exportDexDev].run.xml @@ -0,0 +1,24 @@ + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.run/lite [app_exportDexRelease].run.xml b/.run/lite [app_exportDexRelease].run.xml new file mode 100644 index 000000000..b5f8da435 --- /dev/null +++ b/.run/lite [app_exportDexRelease].run.xml @@ -0,0 +1,24 @@ + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.run/lite [app_prepareDexForMergeDev].run.xml b/.run/lite [app_prepareDexForMergeDev].run.xml new file mode 100644 index 000000000..e68ec37c0 --- /dev/null +++ b/.run/lite [app_prepareDexForMergeDev].run.xml @@ -0,0 +1,24 @@ + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.run/lite [app_prepareDexForMergeRelease].run.xml b/.run/lite [app_prepareDexForMergeRelease].run.xml new file mode 100644 index 000000000..21aaf9b4a --- /dev/null +++ b/.run/lite [app_prepareDexForMergeRelease].run.xml @@ -0,0 +1,24 @@ + + + + + + + true + true + false + false + + + \ No newline at end of file From ad3f70f4ac4ae2e8753ed44115b906efda1bd7f7 Mon Sep 17 00:00:00 2001 From: gdlbo <41114720+gdlbo@users.noreply.github.com> Date: Wed, 7 Feb 2024 13:55:53 +0300 Subject: [PATCH 2/2] Sponsorpost integration (#1553) --- .../libvkx/client/LibVKXClient.java | 5 +- .../gmscore/tools/apk/arsc/ArscBlamer.java | 56 +- .../apk/arsc/BinaryResourceConfiguration.java | 461 ++++++++------- .../apk/arsc/BinaryResourceIdentifier.java | 12 +- .../tools/apk/arsc/BinaryResourceString.java | 36 +- .../tools/apk/arsc/BinaryResourceValue.java | 156 +++--- .../devrel/gmscore/tools/apk/arsc/Chunk.java | 242 ++++---- .../gmscore/tools/apk/arsc/LibraryChunk.java | 12 +- .../gmscore/tools/apk/arsc/PackageChunk.java | 28 +- .../tools/apk/arsc/ResourceTableChunk.java | 11 +- .../tools/apk/arsc/StringPoolChunk.java | 24 +- .../gmscore/tools/apk/arsc/TypeChunk.java | 114 ++-- .../gmscore/tools/apk/arsc/TypeSpecChunk.java | 2 +- .../gmscore/tools/apk/arsc/UnknownChunk.java | 2 +- .../gmscore/tools/apk/arsc/XmlAttribute.java | 24 +- .../gmscore/tools/apk/arsc/XmlCdataChunk.java | 2 +- .../gmscore/tools/apk/arsc/XmlChunk.java | 2 +- .../tools/apk/arsc/XmlEndElementChunk.java | 2 +- .../tools/apk/arsc/XmlNamespaceEndChunk.java | 2 +- .../apk/arsc/XmlNamespaceStartChunk.java | 2 +- .../tools/apk/arsc/XmlStartElementChunk.java | 2 +- .../com/vk/api/gifts/GiftGetByStickerId.java | 20 +- .../vk/core/drawable/RecoloredDrawable.java | 18 +- .../com/vk/core/utils/VerifyInfoHelper.java | 104 ++-- .../DialogGetMentionSuggestionCmd.java | 50 +- .../common/DialogActionsHelper.java | 6 +- .../ui/components/common/MsgActionHelper.java | 4 +- .../msg_list/adapter/VhBindArgs.java | 166 +----- .../adapter/msgparts/MsgPartCallHolder.java | 6 +- .../msg_list/adapter/vh/VhMsg.java | 194 +++---- .../vk/im/ui/q/h/e/MentionsController.java | 53 +- .../im/ui/views/avatars/StoryBorderView.java | 88 +-- .../community/CommunityBorderedImageView.java | 18 +- .../com/vk/sharing/view/TargetImageView.java | 82 +-- .../details/StickerDetailsAdapter.java | 38 +- .../vk/stories/view/StoryCircleImageView.java | 2 +- .../BottomNavigationItemView.java | 16 +- .../java/ru/vtosters/hooks/AdBlockHook.java | 12 +- .../java/ru/vtosters/hooks/JsonInjectors.java | 7 +- .../vtosters/hooks/MainActivityInjector.java | 7 +- .../java/ru/vtosters/hooks/NewsfeedHook.java | 88 ++- .../vtosters/hooks/OnlineFormatterHook.java | 3 - .../ru/vtosters/hooks/other/Preferences.java | 1 - .../lite/music/cache/db/MusicCacheDb.java | 11 +- .../lite/music/converter/ts/FFMpeg.java | 1 - .../lite/music/downloader/M3UDownloader.java | 2 +- .../java/ru/vtosters/lite/net/NetCall.java | 1 - .../ru/vtosters/lite/proxy/ProxyUtils.java | 1 - .../ru/vtosters/lite/ssfs/ProfileButtons.java | 1 - .../java/ru/vtosters/lite/ssfs/UsersList.java | 2 - .../lite/ui/components/IconManager.java | 1 - .../lite/ui/fragments/ActivityFragment.java | 1 - .../ui/fragments/DataSettingsFragment.java | 11 - .../lite/ui/fragments/FeedFragment.java | 55 +- .../lite/ui/fragments/IconsFragment.java | 2 - .../lite/ui/fragments/OtherFragment.java | 2 - .../ui/fragments/ProxySettingsFragment.java | 5 - .../ui/fragments/SponsorPostFragment.java | 97 ++++ .../lite/ui/fragments/SystemInfo.java | 2 +- .../lite/ui/fragments/VTSettings.java | 7 - .../ui/wallpapers/WallpaperMenuFragment.java | 1 - .../ru/vtosters/lite/utils/AndroidUtils.java | 14 +- .../lite/utils/NewsFeedFiltersUtils.java | 526 ------------------ .../utils/newsfeed/NewsFeedFiltersUtils.java | 444 +++++++++++++++ .../ru/vtosters/sponsorpost/data/Filter.java | 70 +++ .../ru/vtosters/sponsorpost/data/Post.java | 59 ++ .../sponsorpost/services/FilterService.java | 108 ++++ .../sponsorpost/services/PostService.java | 241 ++++++++ .../vtosters/sponsorpost/utils/ApiUtils.java | 7 + .../sponsorpost/utils/FiltersPreferences.java | 114 ++++ .../sponsorpost/utils/GzipDecompressor.java | 29 + .../sponsorpost/utils/PostsPreferences.java | 94 ++++ .../vtosters/sponsorpost/utils/Updates.java | 71 +++ smali/assets/CopyrightAds.txt | 14 - smali/assets/IDontWantToReadIt.txt | 189 ------- smali/assets/LinkShorter.txt | 29 - smali/assets/Referals.txt | 12 - smali/assets/StandartFilter.txt | 100 ---- smali/res/xml/preferences_debug.xml | 2 +- smali/res/xml/preferences_feed.xml | 60 +- .../com/vtosters/lite/api/wall/WallGet.smali | 4 + .../vtosters/lite/api/wall/WallGetById.smali | 4 +- 82 files changed, 2405 insertions(+), 2169 deletions(-) create mode 100644 app/src/main/java/ru/vtosters/lite/ui/fragments/SponsorPostFragment.java delete mode 100644 app/src/main/java/ru/vtosters/lite/utils/NewsFeedFiltersUtils.java create mode 100644 app/src/main/java/ru/vtosters/lite/utils/newsfeed/NewsFeedFiltersUtils.java create mode 100644 app/src/main/java/ru/vtosters/sponsorpost/data/Filter.java create mode 100644 app/src/main/java/ru/vtosters/sponsorpost/data/Post.java create mode 100644 app/src/main/java/ru/vtosters/sponsorpost/services/FilterService.java create mode 100644 app/src/main/java/ru/vtosters/sponsorpost/services/PostService.java create mode 100644 app/src/main/java/ru/vtosters/sponsorpost/utils/ApiUtils.java create mode 100644 app/src/main/java/ru/vtosters/sponsorpost/utils/FiltersPreferences.java create mode 100644 app/src/main/java/ru/vtosters/sponsorpost/utils/GzipDecompressor.java create mode 100644 app/src/main/java/ru/vtosters/sponsorpost/utils/PostsPreferences.java create mode 100644 app/src/main/java/ru/vtosters/sponsorpost/utils/Updates.java delete mode 100644 smali/assets/CopyrightAds.txt delete mode 100644 smali/assets/IDontWantToReadIt.txt delete mode 100644 smali/assets/LinkShorter.txt delete mode 100644 smali/assets/Referals.txt delete mode 100644 smali/assets/StandartFilter.txt diff --git a/app/src/main/java/bruhcollective/itaysonlab/libvkx/client/LibVKXClient.java b/app/src/main/java/bruhcollective/itaysonlab/libvkx/client/LibVKXClient.java index 270aa6c70..4d669c24a 100644 --- a/app/src/main/java/bruhcollective/itaysonlab/libvkx/client/LibVKXClient.java +++ b/app/src/main/java/bruhcollective/itaysonlab/libvkx/client/LibVKXClient.java @@ -81,6 +81,7 @@ public class LibVKXClient { lambdaplay(list, musicTrack, iLibVkxService, null); } - public static String asId(MusicTrack musicTrack) - { return musicTrack.y1(); } + public static String asId(MusicTrack musicTrack) { + return musicTrack.y1(); + } } \ No newline at end of file diff --git a/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/ArscBlamer.java b/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/ArscBlamer.java index df22f8e98..2956a77a4 100644 --- a/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/ArscBlamer.java +++ b/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/ArscBlamer.java @@ -59,26 +59,22 @@ public class ArscBlamer { * Maps type chunk entries to blamed resources. */ private final Multimap typeEntryToBlame = HashMultimap.create(); - - /** - * Maps resources to the type chunk entries they reference. - */ - private Multimap resourceEntries; - - /** - * Maps resources which have no base config to the type chunk entries they reference. - */ - private Multimap baselessKeys; - - /** - * Contains all of the type chunks in {@link #resourceTable}. - */ - private List typeChunks; - /** * This is the {@link ResourceTableChunk} inside of the resources.arsc file in the APK. */ private final ResourceTableChunk resourceTable; + /** + * Maps resources to the type chunk entries they reference. + */ + private Multimap resourceEntries; + /** + * Maps resources which have no base config to the type chunk entries they reference. + */ + private Multimap baselessKeys; + /** + * Contains all of the type chunks in {@link #resourceTable}. + */ + private List typeChunks; /** * Creates a new {@link ArscBlamer}. @@ -90,6 +86,14 @@ public class ArscBlamer { this.stringToBlame = createEntryListArray(resourceTable.getStringPool().getStringCount()); } + private static List[] createEntryListArray(int size) { + ArrayListResourceEntry[] result = new ArrayListResourceEntry[size]; + for (int i = 0; i < size; ++i) { + result[i] = new ArrayListResourceEntry(); + } + return result; + } + /** * Generates blame mappings. */ @@ -257,14 +261,6 @@ public class ArscBlamer { return false; } - private static List[] createEntryListArray(int size) { - ArrayListResourceEntry[] result = new ArrayListResourceEntry[size]; - for (int i = 0; i < size; ++i) { - result[i] = new ArrayListResourceEntry(); - } - return result; - } - /** * Allows creation of concrete parameterized type arr {@link ArscBlamer#createEntryListArray}. */ @@ -283,6 +279,12 @@ public class ArscBlamer { private final String typeName; private final String entryName; + private ResourceEntry(String packageName, String typeName, String entryName) { + this.packageName = packageName; + this.typeName = typeName; + this.entryName = entryName; + } + static ResourceEntry create(TypeChunk.Entry entry) { PackageChunk packageChunk = Preconditions.checkNotNull(entry.parent().getPackageChunk()); String packageName = packageChunk.getPackageName(); @@ -291,12 +293,6 @@ public class ArscBlamer { return new ResourceEntry(packageName, typeName, entryName); } - private ResourceEntry(String packageName, String typeName, String entryName) { - this.packageName = packageName; - this.typeName = typeName; - this.entryName = entryName; - } - public String packageName() { return packageName; } diff --git a/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/BinaryResourceConfiguration.java b/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/BinaryResourceConfiguration.java index 922871833..06a50e176 100644 --- a/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/BinaryResourceConfiguration.java +++ b/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/BinaryResourceConfiguration.java @@ -31,6 +31,148 @@ import static java.nio.charset.StandardCharsets.US_ASCII; * Describes a particular resource configuration. */ public class BinaryResourceConfiguration implements SerializableResource { + /** + * The below constants are from android.content.res.Configuration. + */ + private static final int DENSITY_DPI_UNDEFINED = 0; + private static final int DENSITY_DPI_LDPI = 120; + private static final int DENSITY_DPI_MDPI = 160; + private static final int DENSITY_DPI_TVDPI = 213; + private static final int DENSITY_DPI_HDPI = 240; + private static final int DENSITY_DPI_XHDPI = 320; + private static final int DENSITY_DPI_XXHDPI = 480; + private static final int DENSITY_DPI_XXXHDPI = 640; + private static final int DENSITY_DPI_ANY = 0xFFFE; + private static final int DENSITY_DPI_NONE = 0xFFFF; + private static final Map DENSITY_DPI_VALUES = + ImmutableMap.builder() + .put(DENSITY_DPI_UNDEFINED, "") + .put(DENSITY_DPI_LDPI, "ldpi") + .put(DENSITY_DPI_MDPI, "mdpi") + .put(DENSITY_DPI_TVDPI, "tvdpi") + .put(DENSITY_DPI_HDPI, "hdpi") + .put(DENSITY_DPI_XHDPI, "xhdpi") + .put(DENSITY_DPI_XXHDPI, "xxhdpi") + .put(DENSITY_DPI_XXXHDPI, "xxxhdpi") + .put(DENSITY_DPI_ANY, "anydpi") + .put(DENSITY_DPI_NONE, "nodpi") + .build(); + private static final int KEYBOARD_NOKEYS = 1; + private static final int KEYBOARD_QWERTY = 2; + private static final int KEYBOARD_12KEY = 3; + private static final Map KEYBOARD_VALUES = ImmutableMap.of( + KEYBOARD_NOKEYS, "nokeys", + KEYBOARD_QWERTY, "qwerty", + KEYBOARD_12KEY, "12key"); + private static final int KEYBOARDHIDDEN_MASK = 0x03; + private static final int KEYBOARDHIDDEN_NO = 1; + private static final int KEYBOARDHIDDEN_YES = 2; + private static final int KEYBOARDHIDDEN_SOFT = 3; + private static final Map KEYBOARDHIDDEN_VALUES = ImmutableMap.of( + KEYBOARDHIDDEN_NO, "keysexposed", + KEYBOARDHIDDEN_YES, "keyshidden", + KEYBOARDHIDDEN_SOFT, "keyssoft"); + private static final int NAVIGATION_NONAV = 1; + private static final int NAVIGATION_DPAD = 2; + private static final int NAVIGATION_TRACKBALL = 3; + private static final int NAVIGATION_WHEEL = 4; + private static final Map NAVIGATION_VALUES = ImmutableMap.of( + NAVIGATION_NONAV, "nonav", + NAVIGATION_DPAD, "dpad", + NAVIGATION_TRACKBALL, "trackball", + NAVIGATION_WHEEL, "wheel"); + private static final int NAVIGATIONHIDDEN_MASK = 0x0C; + private static final int NAVIGATIONHIDDEN_NO = 0x04; + private static final int NAVIGATIONHIDDEN_YES = 0x08; + private static final Map NAVIGATIONHIDDEN_VALUES = ImmutableMap.of( + NAVIGATIONHIDDEN_NO, "navexposed", + NAVIGATIONHIDDEN_YES, "navhidden"); + private static final int ORIENTATION_PORTRAIT = 0x01; + private static final int ORIENTATION_LANDSCAPE = 0x02; + private static final Map ORIENTATION_VALUES = ImmutableMap.of( + ORIENTATION_PORTRAIT, "port", + ORIENTATION_LANDSCAPE, "land"); + private static final int SCREENLAYOUT_LAYOUTDIR_MASK = 0xC0; + private static final int SCREENLAYOUT_LAYOUTDIR_LTR = 0x40; + private static final int SCREENLAYOUT_LAYOUTDIR_RTL = 0x80; + private static final Map SCREENLAYOUT_LAYOUTDIR_VALUES = ImmutableMap.of( + SCREENLAYOUT_LAYOUTDIR_LTR, "ldltr", + SCREENLAYOUT_LAYOUTDIR_RTL, "ldrtl"); + private static final int SCREENLAYOUT_LONG_MASK = 0x30; + private static final int SCREENLAYOUT_LONG_NO = 0x10; + private static final int SCREENLAYOUT_LONG_YES = 0x20; + private static final Map SCREENLAYOUT_LONG_VALUES = ImmutableMap.of( + SCREENLAYOUT_LONG_NO, "notlong", + SCREENLAYOUT_LONG_YES, "long"); + private static final int SCREENLAYOUT_ROUND_MASK = 0x03; + private static final int SCREENLAYOUT_ROUND_NO = 0x01; + private static final int SCREENLAYOUT_ROUND_YES = 0x02; + private static final Map SCREENLAYOUT_ROUND_VALUES = ImmutableMap.of( + SCREENLAYOUT_ROUND_NO, "notround", + SCREENLAYOUT_ROUND_YES, "round"); + private static final int SCREENLAYOUT_SIZE_MASK = 0x0F; + private static final int SCREENLAYOUT_SIZE_SMALL = 0x01; + private static final int SCREENLAYOUT_SIZE_NORMAL = 0x02; + private static final int SCREENLAYOUT_SIZE_LARGE = 0x03; + private static final int SCREENLAYOUT_SIZE_XLARGE = 0x04; + private static final Map SCREENLAYOUT_SIZE_VALUES = ImmutableMap.of( + SCREENLAYOUT_SIZE_SMALL, "small", + SCREENLAYOUT_SIZE_NORMAL, "normal", + SCREENLAYOUT_SIZE_LARGE, "large", + SCREENLAYOUT_SIZE_XLARGE, "xlarge"); + private static final int TOUCHSCREEN_NOTOUCH = 1; + private static final int TOUCHSCREEN_FINGER = 3; + private static final Map TOUCHSCREEN_VALUES = ImmutableMap.of( + TOUCHSCREEN_NOTOUCH, "notouch", + TOUCHSCREEN_FINGER, "finger"); + private static final int UI_MODE_NIGHT_MASK = 0x30; + private static final int UI_MODE_NIGHT_NO = 0x10; + private static final int UI_MODE_NIGHT_YES = 0x20; + private static final Map UI_MODE_NIGHT_VALUES = ImmutableMap.of( + UI_MODE_NIGHT_NO, "notnight", + UI_MODE_NIGHT_YES, "night"); + private static final int UI_MODE_TYPE_MASK = 0x0F; + private static final int UI_MODE_TYPE_DESK = 0x02; + private static final int UI_MODE_TYPE_CAR = 0x03; + private static final int UI_MODE_TYPE_TELEVISION = 0x04; + private static final int UI_MODE_TYPE_APPLIANCE = 0x05; + private static final int UI_MODE_TYPE_WATCH = 0x06; + private static final int UI_MODE_TYPE_VR_HEADSET = 0x07; + // start - miui + private static final int UI_MODE_TYPE_GODZILLAUI = 0x0b; + private static final int UI_MODE_TYPE_SMALLUI = 0x0c; + private static final int UI_MODE_TYPE_MEDIUMUI = 0x0d; + private static final int UI_MODE_TYPE_LARGEUI = 0x0e; + private static final int UI_MODE_TYPE_HUGEUI = 0x0f; + private static final Map UI_MODE_TYPE_VALUES = + ImmutableMap.builder() + .put(UI_MODE_TYPE_DESK, "desk") + .put(UI_MODE_TYPE_CAR, "car") + .put(UI_MODE_TYPE_TELEVISION, "television") + .put(UI_MODE_TYPE_APPLIANCE, "appliance") + .put(UI_MODE_TYPE_WATCH, "watch") + .put(UI_MODE_TYPE_VR_HEADSET, "vrheadset") + .put(UI_MODE_TYPE_GODZILLAUI, "godzillaui") + .put(UI_MODE_TYPE_SMALLUI, "smallui") + .put(UI_MODE_TYPE_MEDIUMUI, "mediumui") + .put(UI_MODE_TYPE_LARGEUI, "largeui") + .put(UI_MODE_TYPE_HUGEUI, "hugeui").build(); + /** + * The minimum size in bytes that this configuration must be to contain screen config info. + */ + private static final int SCREEN_CONFIG_MIN_SIZE = 32; + /** + * The minimum size in bytes that this configuration must be to contain screen dp info. + */ + private static final int SCREEN_DP_MIN_SIZE = 36; + /** + * The minimum size in bytes that this configuration must be to contain locale info. + */ + private static final int LOCALE_MIN_SIZE = 48; + /** + * The minimum size in bytes that this config must be to contain the screenConfig extension. + */ + private static final int SCREEN_CONFIG_EXTENSION_MIN_SIZE = 52; private final int size; private final int mcc; private final int mnc; @@ -53,9 +195,60 @@ public class BinaryResourceConfiguration implements SerializableResource { private final int screenHeightDp; private final byte[] localeScript; private final byte[] localeVariant; + // end - miui private final int screenLayout2; private final byte[] unknown; + private BinaryResourceConfiguration(int size, + int mcc, + int mnc, + byte[] language, + byte[] region, + int orientation, + int touchscreen, + int density, + int keyboard, + int navigation, + int inputFlags, + int screenWidth, + int screenHeight, + int sdkVersion, + int minorVersion, + int screenLayout, + int uiMode, + int smallestScreenWidthDp, + int screenWidthDp, + int screenHeightDp, + byte[] localeScript, + byte[] localeVariant, + int screenLayout2, + byte[] unknown) { + this.size = size; + this.mcc = mcc; + this.mnc = mnc; + this.language = language; + this.region = region; + this.orientation = orientation; + this.touchscreen = touchscreen; + this.density = density; + this.keyboard = keyboard; + this.navigation = navigation; + this.inputFlags = inputFlags; + this.screenWidth = screenWidth; + this.screenHeight = screenHeight; + this.sdkVersion = sdkVersion; + this.minorVersion = minorVersion; + this.screenLayout = screenLayout; + this.uiMode = uiMode; + this.smallestScreenWidthDp = smallestScreenWidthDp; + this.screenWidthDp = screenWidthDp; + this.screenHeightDp = screenHeightDp; + this.localeScript = localeScript; + this.localeVariant = localeVariant; + this.screenLayout2 = screenLayout2; + this.unknown = unknown; + } + static BinaryResourceConfiguration create(ByteBuffer buffer) { int startPosition = buffer.position(); // The starting buffer position to calculate bytes read. int size = buffer.getInt(); @@ -121,245 +314,6 @@ public class BinaryResourceConfiguration implements SerializableResource { screenHeightDp, localeScript, localeVariant, screenLayout2, unknown); } - private BinaryResourceConfiguration(int size, - int mcc, - int mnc, - byte[] language, - byte[] region, - int orientation, - int touchscreen, - int density, - int keyboard, - int navigation, - int inputFlags, - int screenWidth, - int screenHeight, - int sdkVersion, - int minorVersion, - int screenLayout, - int uiMode, - int smallestScreenWidthDp, - int screenWidthDp, - int screenHeightDp, - byte[] localeScript, - byte[] localeVariant, - int screenLayout2, - byte[] unknown) { - this.size = size; - this.mcc = mcc; - this.mnc = mnc; - this.language = language; - this.region = region; - this.orientation = orientation; - this.touchscreen = touchscreen; - this.density = density; - this.keyboard = keyboard; - this.navigation = navigation; - this.inputFlags = inputFlags; - this.screenWidth = screenWidth; - this.screenHeight = screenHeight; - this.sdkVersion = sdkVersion; - this.minorVersion = minorVersion; - this.screenLayout = screenLayout; - this.uiMode = uiMode; - this.smallestScreenWidthDp = smallestScreenWidthDp; - this.screenWidthDp = screenWidthDp; - this.screenHeightDp = screenHeightDp; - this.localeScript = localeScript; - this.localeVariant = localeVariant; - this.screenLayout2 = screenLayout2; - this.unknown = unknown; - } - - /** - * The different types of configs that can be present in a {@link BinaryResourceConfiguration}. - */ - public enum Type { - MCC, - MNC, - LANGUAGE_STRING, - REGION_STRING, - SCREEN_LAYOUT_DIRECTION, - SMALLEST_SCREEN_WIDTH_DP, - SCREEN_WIDTH_DP, - SCREEN_HEIGHT_DP, - SCREEN_LAYOUT_SIZE, - SCREEN_LAYOUT_LONG, - SCREEN_LAYOUT_ROUND, - ORIENTATION, - UI_MODE_TYPE, - UI_MODE_NIGHT, - DENSITY_DPI, - TOUCHSCREEN, - KEYBOARD_HIDDEN, - KEYBOARD, - NAVIGATION_HIDDEN, - NAVIGATION, - SDK_VERSION - } - - /** - * The below constants are from android.content.res.Configuration. - */ - private static final int DENSITY_DPI_UNDEFINED = 0; - private static final int DENSITY_DPI_LDPI = 120; - private static final int DENSITY_DPI_MDPI = 160; - private static final int DENSITY_DPI_TVDPI = 213; - private static final int DENSITY_DPI_HDPI = 240; - private static final int DENSITY_DPI_XHDPI = 320; - private static final int DENSITY_DPI_XXHDPI = 480; - private static final int DENSITY_DPI_XXXHDPI = 640; - private static final int DENSITY_DPI_ANY = 0xFFFE; - private static final int DENSITY_DPI_NONE = 0xFFFF; - private static final Map DENSITY_DPI_VALUES = - ImmutableMap.builder() - .put(DENSITY_DPI_UNDEFINED, "") - .put(DENSITY_DPI_LDPI, "ldpi") - .put(DENSITY_DPI_MDPI, "mdpi") - .put(DENSITY_DPI_TVDPI, "tvdpi") - .put(DENSITY_DPI_HDPI, "hdpi") - .put(DENSITY_DPI_XHDPI, "xhdpi") - .put(DENSITY_DPI_XXHDPI, "xxhdpi") - .put(DENSITY_DPI_XXXHDPI, "xxxhdpi") - .put(DENSITY_DPI_ANY, "anydpi") - .put(DENSITY_DPI_NONE, "nodpi") - .build(); - - private static final int KEYBOARD_NOKEYS = 1; - private static final int KEYBOARD_QWERTY = 2; - private static final int KEYBOARD_12KEY = 3; - private static final Map KEYBOARD_VALUES = ImmutableMap.of( - KEYBOARD_NOKEYS, "nokeys", - KEYBOARD_QWERTY, "qwerty", - KEYBOARD_12KEY, "12key"); - - private static final int KEYBOARDHIDDEN_MASK = 0x03; - private static final int KEYBOARDHIDDEN_NO = 1; - private static final int KEYBOARDHIDDEN_YES = 2; - private static final int KEYBOARDHIDDEN_SOFT = 3; - private static final Map KEYBOARDHIDDEN_VALUES = ImmutableMap.of( - KEYBOARDHIDDEN_NO, "keysexposed", - KEYBOARDHIDDEN_YES, "keyshidden", - KEYBOARDHIDDEN_SOFT, "keyssoft"); - - private static final int NAVIGATION_NONAV = 1; - private static final int NAVIGATION_DPAD = 2; - private static final int NAVIGATION_TRACKBALL = 3; - private static final int NAVIGATION_WHEEL = 4; - private static final Map NAVIGATION_VALUES = ImmutableMap.of( - NAVIGATION_NONAV, "nonav", - NAVIGATION_DPAD, "dpad", - NAVIGATION_TRACKBALL, "trackball", - NAVIGATION_WHEEL, "wheel"); - - private static final int NAVIGATIONHIDDEN_MASK = 0x0C; - private static final int NAVIGATIONHIDDEN_NO = 0x04; - private static final int NAVIGATIONHIDDEN_YES = 0x08; - private static final Map NAVIGATIONHIDDEN_VALUES = ImmutableMap.of( - NAVIGATIONHIDDEN_NO, "navexposed", - NAVIGATIONHIDDEN_YES, "navhidden"); - - private static final int ORIENTATION_PORTRAIT = 0x01; - private static final int ORIENTATION_LANDSCAPE = 0x02; - private static final Map ORIENTATION_VALUES = ImmutableMap.of( - ORIENTATION_PORTRAIT, "port", - ORIENTATION_LANDSCAPE, "land"); - - private static final int SCREENLAYOUT_LAYOUTDIR_MASK = 0xC0; - private static final int SCREENLAYOUT_LAYOUTDIR_LTR = 0x40; - private static final int SCREENLAYOUT_LAYOUTDIR_RTL = 0x80; - private static final Map SCREENLAYOUT_LAYOUTDIR_VALUES = ImmutableMap.of( - SCREENLAYOUT_LAYOUTDIR_LTR, "ldltr", - SCREENLAYOUT_LAYOUTDIR_RTL, "ldrtl"); - - private static final int SCREENLAYOUT_LONG_MASK = 0x30; - private static final int SCREENLAYOUT_LONG_NO = 0x10; - private static final int SCREENLAYOUT_LONG_YES = 0x20; - private static final Map SCREENLAYOUT_LONG_VALUES = ImmutableMap.of( - SCREENLAYOUT_LONG_NO, "notlong", - SCREENLAYOUT_LONG_YES, "long"); - - private static final int SCREENLAYOUT_ROUND_MASK = 0x03; - private static final int SCREENLAYOUT_ROUND_NO = 0x01; - private static final int SCREENLAYOUT_ROUND_YES = 0x02; - private static final Map SCREENLAYOUT_ROUND_VALUES = ImmutableMap.of( - SCREENLAYOUT_ROUND_NO, "notround", - SCREENLAYOUT_ROUND_YES, "round"); - - private static final int SCREENLAYOUT_SIZE_MASK = 0x0F; - private static final int SCREENLAYOUT_SIZE_SMALL = 0x01; - private static final int SCREENLAYOUT_SIZE_NORMAL = 0x02; - private static final int SCREENLAYOUT_SIZE_LARGE = 0x03; - private static final int SCREENLAYOUT_SIZE_XLARGE = 0x04; - private static final Map SCREENLAYOUT_SIZE_VALUES = ImmutableMap.of( - SCREENLAYOUT_SIZE_SMALL, "small", - SCREENLAYOUT_SIZE_NORMAL, "normal", - SCREENLAYOUT_SIZE_LARGE, "large", - SCREENLAYOUT_SIZE_XLARGE, "xlarge"); - - private static final int TOUCHSCREEN_NOTOUCH = 1; - private static final int TOUCHSCREEN_FINGER = 3; - private static final Map TOUCHSCREEN_VALUES = ImmutableMap.of( - TOUCHSCREEN_NOTOUCH, "notouch", - TOUCHSCREEN_FINGER, "finger"); - - private static final int UI_MODE_NIGHT_MASK = 0x30; - private static final int UI_MODE_NIGHT_NO = 0x10; - private static final int UI_MODE_NIGHT_YES = 0x20; - private static final Map UI_MODE_NIGHT_VALUES = ImmutableMap.of( - UI_MODE_NIGHT_NO, "notnight", - UI_MODE_NIGHT_YES, "night"); - - private static final int UI_MODE_TYPE_MASK = 0x0F; - private static final int UI_MODE_TYPE_DESK = 0x02; - private static final int UI_MODE_TYPE_CAR = 0x03; - private static final int UI_MODE_TYPE_TELEVISION = 0x04; - private static final int UI_MODE_TYPE_APPLIANCE = 0x05; - private static final int UI_MODE_TYPE_WATCH = 0x06; - private static final int UI_MODE_TYPE_VR_HEADSET = 0x07; - - // start - miui - private static final int UI_MODE_TYPE_GODZILLAUI = 0x0b; - private static final int UI_MODE_TYPE_SMALLUI = 0x0c; - private static final int UI_MODE_TYPE_MEDIUMUI = 0x0d; - private static final int UI_MODE_TYPE_LARGEUI = 0x0e; - private static final int UI_MODE_TYPE_HUGEUI = 0x0f; - // end - miui - - private static final Map UI_MODE_TYPE_VALUES = - ImmutableMap.builder() - .put(UI_MODE_TYPE_DESK, "desk") - .put(UI_MODE_TYPE_CAR, "car") - .put(UI_MODE_TYPE_TELEVISION, "television") - .put(UI_MODE_TYPE_APPLIANCE, "appliance") - .put(UI_MODE_TYPE_WATCH, "watch") - .put(UI_MODE_TYPE_VR_HEADSET, "vrheadset") - .put(UI_MODE_TYPE_GODZILLAUI, "godzillaui") - .put(UI_MODE_TYPE_SMALLUI, "smallui") - .put(UI_MODE_TYPE_MEDIUMUI, "mediumui") - .put(UI_MODE_TYPE_LARGEUI, "largeui") - .put(UI_MODE_TYPE_HUGEUI, "hugeui").build(); - - /** - * The minimum size in bytes that this configuration must be to contain screen config info. - */ - private static final int SCREEN_CONFIG_MIN_SIZE = 32; - - /** - * The minimum size in bytes that this configuration must be to contain screen dp info. - */ - private static final int SCREEN_DP_MIN_SIZE = 36; - - /** - * The minimum size in bytes that this configuration must be to contain locale info. - */ - private static final int LOCALE_MIN_SIZE = 48; - - /** - * The minimum size in bytes that this config must be to contain the screenConfig extension. - */ - private static final int SCREEN_CONFIG_EXTENSION_MIN_SIZE = 52; - /** * The number of bytes that this resource configuration takes up. */ @@ -708,7 +662,7 @@ public class BinaryResourceConfiguration implements SerializableResource { Map result = new LinkedHashMap<>(); // Preserve order for #toString(). result.put(Type.MCC, mcc() != 0 ? "mcc" + mcc() : ""); result.put(Type.MNC, mnc() != 0 ? "mnc" + mnc() : ""); - result.put(Type.LANGUAGE_STRING, !languageString().isEmpty() ? "" + languageString() : ""); + result.put(Type.LANGUAGE_STRING, !languageString().isEmpty() ? languageString() : ""); result.put(Type.REGION_STRING, !regionString().isEmpty() ? "r" + regionString() : ""); result.put(Type.SCREEN_LAYOUT_DIRECTION, getOrDefault(SCREENLAYOUT_LAYOUTDIR_VALUES, screenLayoutDirection(), "")); @@ -742,4 +696,31 @@ public class BinaryResourceConfiguration implements SerializableResource { V value = map.get(key); return value != null ? value : defaultValue; } + + /** + * The different types of configs that can be present in a {@link BinaryResourceConfiguration}. + */ + public enum Type { + MCC, + MNC, + LANGUAGE_STRING, + REGION_STRING, + SCREEN_LAYOUT_DIRECTION, + SMALLEST_SCREEN_WIDTH_DP, + SCREEN_WIDTH_DP, + SCREEN_HEIGHT_DP, + SCREEN_LAYOUT_SIZE, + SCREEN_LAYOUT_LONG, + SCREEN_LAYOUT_ROUND, + ORIENTATION, + UI_MODE_TYPE, + UI_MODE_NIGHT, + DENSITY_DPI, + TOUCHSCREEN, + KEYBOARD_HIDDEN, + KEYBOARD, + NAVIGATION_HIDDEN, + NAVIGATION, + SDK_VERSION + } } diff --git a/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/BinaryResourceIdentifier.java b/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/BinaryResourceIdentifier.java index 32a61cf60..6f97d7cf5 100644 --- a/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/BinaryResourceIdentifier.java +++ b/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/BinaryResourceIdentifier.java @@ -49,6 +49,12 @@ public class BinaryResourceIdentifier { private final int typeId; private final int entryId; + private BinaryResourceIdentifier(int packageId, int typeId, int entryId) { + this.packageId = packageId; + this.typeId = typeId; + this.entryId = entryId; + } + /** * Returns a {@link BinaryResourceIdentifier} from a {@code resourceId} of the form 0xpptteeee. */ @@ -69,12 +75,6 @@ public class BinaryResourceIdentifier { return new BinaryResourceIdentifier(packageId, typeId, entryId); } - private BinaryResourceIdentifier(int packageId, int typeId, int entryId) { - this.packageId = packageId; - this.typeId = typeId; - this.entryId = entryId; - } - /** * The (1-based) id of the {@link PackageChunk} containing this resource. */ diff --git a/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/BinaryResourceString.java b/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/BinaryResourceString.java index 3fe721a60..23196cca7 100644 --- a/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/BinaryResourceString.java +++ b/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/BinaryResourceString.java @@ -31,24 +31,6 @@ import static java.nio.charset.StandardCharsets.UTF_8; */ public final class BinaryResourceString { - /** - * Type of {@link BinaryResourceString} to encode / decode. - */ - public enum Type { - UTF8(UTF_8), - UTF16(UTF_16LE); - - private final Charset charset; - - Type(Charset charset) { - this.charset = charset; - } - - public Charset charset() { - return charset; - } - } - private BinaryResourceString() { } // Private constructor @@ -166,4 +148,22 @@ public final class BinaryResourceString { } return length; } + + /** + * Type of {@link BinaryResourceString} to encode / decode. + */ + public enum Type { + UTF8(UTF_8), + UTF16(UTF_16LE); + + private final Charset charset; + + Type(Charset charset) { + this.charset = charset; + } + + public Charset charset() { + return charset; + } + } } diff --git a/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/BinaryResourceValue.java b/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/BinaryResourceValue.java index 50e8d9e44..64a992352 100644 --- a/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/BinaryResourceValue.java +++ b/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/BinaryResourceValue.java @@ -31,6 +31,78 @@ import java.util.Objects; */ public class BinaryResourceValue implements SerializableResource { + /** + * The serialized size in bytes of a {@link BinaryResourceValue}. + */ + public static final int SIZE = 8; + public int size; + public Type type; + public int data; + public BinaryResourceValue(int size, Type type, int data) { + this.size = size; + this.type = type; + this.data = data; + } + + public static BinaryResourceValue create(ByteBuffer buffer) { + int size = (buffer.getShort() & 0xFFFF); + buffer.get(); // Unused + Type type = Type.fromCode(buffer.get()); + int data = buffer.getInt(); + return new BinaryResourceValue(size, type, data); + } + + /** + * The length in bytes of this value. + */ + public int size() { + return size; + } + + /** + * The raw data type of this value. + */ + public Type type() { + return type; + } + + /** + * The actual 4-byte value; interpretation of the value depends on {@code dataType}. + */ + public int data() { + return data; + } + + @Override + public byte[] toByteArray() { + return toByteArray(false); + } + + @Override + public byte[] toByteArray(boolean shrink) { + ByteBuffer buffer = ByteBuffer.allocate(SIZE).order(ByteOrder.LITTLE_ENDIAN); + buffer.putShort((short) size()); + buffer.put((byte) 0); // Unused + buffer.put(type().code()); + buffer.putInt(data()); + return buffer.array(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + BinaryResourceValue that = (BinaryResourceValue) o; + return size == that.size && + data == that.data && + type == that.type; + } + + @Override + public int hashCode() { + return Objects.hash(size, type, data); + } + /** * Resource type codes. */ @@ -100,8 +172,6 @@ public class BinaryResourceValue implements SerializableResource { */ INT_COLOR_RGB4(0x1f); - private final byte code; - private static final Map FROM_BYTE; static { @@ -112,90 +182,18 @@ public class BinaryResourceValue implements SerializableResource { FROM_BYTE = builder.build(); } + private final byte code; + Type(int code) { this.code = UnsignedBytes.checkedCast(code); } - public byte code() { - return code; - } - public static Type fromCode(byte code) { return Preconditions.checkNotNull(FROM_BYTE.get(code), "Unknown resource type: %s", code); } - } - /** - * The serialized size in bytes of a {@link BinaryResourceValue}. - */ - public static final int SIZE = 8; - - public int size; - public Type type; - public int data; - - public static BinaryResourceValue create(ByteBuffer buffer) { - int size = (buffer.getShort() & 0xFFFF); - buffer.get(); // Unused - Type type = Type.fromCode(buffer.get()); - int data = buffer.getInt(); - return new BinaryResourceValue(size, type, data); - } - - public BinaryResourceValue(int size, Type type, int data) { - this.size = size; - this.type = type; - this.data = data; - } - - /** - * The length in bytes of this value. - */ - public int size() { - return size; - } - - /** - * The raw data type of this value. - */ - public Type type() { - return type; - } - - /** - * The actual 4-byte value; interpretation of the value depends on {@code dataType}. - */ - public int data() { - return data; - } - - @Override - public byte[] toByteArray() { - return toByteArray(false); - } - - @Override - public byte[] toByteArray(boolean shrink) { - ByteBuffer buffer = ByteBuffer.allocate(SIZE).order(ByteOrder.LITTLE_ENDIAN); - buffer.putShort((short) size()); - buffer.put((byte) 0); // Unused - buffer.put(type().code()); - buffer.putInt(data()); - return buffer.array(); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - BinaryResourceValue that = (BinaryResourceValue) o; - return size == that.size && - data == that.data && - type == that.type; - } - - @Override - public int hashCode() { - return Objects.hash(size, type, data); + public byte code() { + return code; + } } } diff --git a/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/Chunk.java b/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/Chunk.java index 665b8cd06..f31e4692d 100644 --- a/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/Chunk.java +++ b/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/Chunk.java @@ -35,86 +35,36 @@ import java.util.Map; */ public abstract class Chunk implements SerializableResource { - /** - * Types of chunks that can exist. - */ - public enum Type { - NULL(0x0000), - STRING_POOL(0x0001), - TABLE(0x0002), - XML(0x0003), - XML_START_NAMESPACE(0x0100), - XML_END_NAMESPACE(0x0101), - XML_START_ELEMENT(0x0102), - XML_END_ELEMENT(0x0103), - XML_CDATA(0x0104), - XML_RESOURCE_MAP(0x0180), - TABLE_PACKAGE(0x0200), - TABLE_TYPE(0x0201), - TABLE_TYPE_SPEC(0x0202), - TABLE_LIBRARY(0x0203); - - private final short code; - - private static final Map FROM_SHORT; - - static { - Builder builder = ImmutableMap.builder(); - for (Type type : values()) { - builder.put(type.code(), type); - } - FROM_SHORT = builder.build(); - } - - Type(int code) { - this.code = Shorts.checkedCast(code); - } - - public short code() { - return code; - } - - public static Type fromCode(short code) { - return Preconditions.checkNotNull(FROM_SHORT.get(code), "Unknown chunk type: %s", code); - } - } - /** * The byte boundary to pad chunks on. */ public static final int PAD_BOUNDARY = 4; - /** * The number of bytes in every chunk that describes chunk type, header size, and chunk size. */ public static final int METADATA_SIZE = 8; - /** * The offset in bytes, from the start of the chunk, where the chunk size can be found. */ private static final int CHUNK_SIZE_OFFSET = 4; - + /** + * Size of the chunk header in bytes. + */ + protected final int headerSize; + /** + * headerSize + dataSize. The total size of this chunk. + */ + protected final int chunkSize; + /** + * Offset of this chunk from the start of the file. + */ + protected final int offset; /** * The parent to this chunk, if any. */ @Nullable private final Chunk parent; - /** - * Size of the chunk header in bytes. - */ - protected final int headerSize; - - /** - * headerSize + dataSize. The total size of this chunk. - */ - protected final int chunkSize; - - /** - * Offset of this chunk from the start of the file. - */ - protected final int offset; - protected Chunk(ByteBuffer buffer, @Nullable Chunk parent) { this.parent = parent; offset = buffer.position() - 2; @@ -122,6 +72,74 @@ public abstract class Chunk implements SerializableResource { chunkSize = buffer.getInt(); } + /** + * Creates a new chunk whose contents start at {@code buffer}'s current position. + * + * @param buffer A buffer positioned at the start of a chunk. + * @return new chunk + */ + public static Chunk newInstance(ByteBuffer buffer) { + return newInstance(buffer, null); + } + + /** + * Creates a new chunk whose contents start at {@code buffer}'s current position. + * + * @param buffer A buffer positioned at the start of a chunk. + * @param parent The parent to this chunk (or null if there's no parent). + * @return new chunk + */ + public static Chunk newInstance(ByteBuffer buffer, @Nullable Chunk parent) { + Chunk result; + Type type = Type.fromCode(buffer.getShort()); + switch (type) { + case STRING_POOL: + result = new StringPoolChunk(buffer, parent); + break; + case TABLE: + result = new ResourceTableChunk(buffer, parent); + break; + case XML: + result = new XmlChunk(buffer, parent); + break; + case XML_START_NAMESPACE: + result = new XmlNamespaceStartChunk(buffer, parent); + break; + case XML_END_NAMESPACE: + result = new XmlNamespaceEndChunk(buffer, parent); + break; + case XML_START_ELEMENT: + result = new XmlStartElementChunk(buffer, parent); + break; + case XML_END_ELEMENT: + result = new XmlEndElementChunk(buffer, parent); + break; + case XML_CDATA: + result = new XmlCdataChunk(buffer, parent); + break; + case XML_RESOURCE_MAP: + result = new XmlResourceMapChunk(buffer, parent); + break; + case TABLE_PACKAGE: + result = new PackageChunk(buffer, parent); + break; + case TABLE_TYPE: + result = new TypeChunk(buffer, parent); + break; + case TABLE_TYPE_SPEC: + result = new TypeSpecChunk(buffer, parent); + break; + case TABLE_LIBRARY: + result = new LibraryChunk(buffer, parent); + break; + default: + result = new UnknownChunk(buffer, parent); + } + result.init(buffer); + result.seekToEndOfChunk(buffer); + return result; + } + /** * Finishes initialization of a chunk. This should be called immediately after the constructor. * This is separate from the constructor so that the header of a chunk can be fully initialized @@ -256,70 +274,46 @@ public abstract class Chunk implements SerializableResource { } /** - * Creates a new chunk whose contents start at {@code buffer}'s current position. - * - * @param buffer A buffer positioned at the start of a chunk. - * @return new chunk + * Types of chunks that can exist. */ - public static Chunk newInstance(ByteBuffer buffer) { - return newInstance(buffer, null); - } + public enum Type { + NULL(0x0000), + STRING_POOL(0x0001), + TABLE(0x0002), + XML(0x0003), + XML_START_NAMESPACE(0x0100), + XML_END_NAMESPACE(0x0101), + XML_START_ELEMENT(0x0102), + XML_END_ELEMENT(0x0103), + XML_CDATA(0x0104), + XML_RESOURCE_MAP(0x0180), + TABLE_PACKAGE(0x0200), + TABLE_TYPE(0x0201), + TABLE_TYPE_SPEC(0x0202), + TABLE_LIBRARY(0x0203); - /** - * Creates a new chunk whose contents start at {@code buffer}'s current position. - * - * @param buffer A buffer positioned at the start of a chunk. - * @param parent The parent to this chunk (or null if there's no parent). - * @return new chunk - */ - public static Chunk newInstance(ByteBuffer buffer, @Nullable Chunk parent) { - Chunk result; - Type type = Type.fromCode(buffer.getShort()); - switch (type) { - case STRING_POOL: - result = new StringPoolChunk(buffer, parent); - break; - case TABLE: - result = new ResourceTableChunk(buffer, parent); - break; - case XML: - result = new XmlChunk(buffer, parent); - break; - case XML_START_NAMESPACE: - result = new XmlNamespaceStartChunk(buffer, parent); - break; - case XML_END_NAMESPACE: - result = new XmlNamespaceEndChunk(buffer, parent); - break; - case XML_START_ELEMENT: - result = new XmlStartElementChunk(buffer, parent); - break; - case XML_END_ELEMENT: - result = new XmlEndElementChunk(buffer, parent); - break; - case XML_CDATA: - result = new XmlCdataChunk(buffer, parent); - break; - case XML_RESOURCE_MAP: - result = new XmlResourceMapChunk(buffer, parent); - break; - case TABLE_PACKAGE: - result = new PackageChunk(buffer, parent); - break; - case TABLE_TYPE: - result = new TypeChunk(buffer, parent); - break; - case TABLE_TYPE_SPEC: - result = new TypeSpecChunk(buffer, parent); - break; - case TABLE_LIBRARY: - result = new LibraryChunk(buffer, parent); - break; - default: - result = new UnknownChunk(buffer, parent); + private static final Map FROM_SHORT; + + static { + Builder builder = ImmutableMap.builder(); + for (Type type : values()) { + builder.put(type.code(), type); + } + FROM_SHORT = builder.build(); + } + + private final short code; + + Type(int code) { + this.code = Shorts.checkedCast(code); + } + + public static Type fromCode(short code) { + return Preconditions.checkNotNull(FROM_SHORT.get(code), "Unknown chunk type: %s", code); + } + + public short code() { + return code; } - result.init(buffer); - result.seekToEndOfChunk(buffer); - return result; } } diff --git a/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/LibraryChunk.java b/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/LibraryChunk.java index 4a31546f4..946604172 100644 --- a/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/LibraryChunk.java +++ b/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/LibraryChunk.java @@ -43,7 +43,7 @@ public final class LibraryChunk extends Chunk { */ private final List entries = new ArrayList<>(); - protected LibraryChunk(ByteBuffer buffer, @Nullable Chunk parent) { + LibraryChunk(ByteBuffer buffer, @Nullable Chunk parent) { super(buffer, parent); entryCount = buffer.getInt(); } @@ -98,17 +98,17 @@ public final class LibraryChunk extends Chunk { private final int packageId; private final String packageName; + private Entry(int packageId, String packageName) { + this.packageId = packageId; + this.packageName = packageName; + } + static Entry create(ByteBuffer buffer, int offset) { int packageId = buffer.getInt(offset); String packageName = PackageUtils.readPackageName(buffer, offset + 4); return new Entry(packageId, packageName); } - private Entry(int packageId, String packageName) { - this.packageId = packageId; - this.packageName = packageName; - } - /** * The id assigned to the shared library at build time. */ diff --git a/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/PackageChunk.java b/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/PackageChunk.java index 9ede60266..6eb495f1d 100644 --- a/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/PackageChunk.java +++ b/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/PackageChunk.java @@ -43,58 +43,48 @@ public final class PackageChunk extends ChunkWithChunks { * Offset in bytes, from the start of the chunk, where {@code keyStringsOffset} can be found. */ private static final int KEY_OFFSET_OFFSET = 276; - - /** - * The package id if this is a base package, or 0 if not a base package. - */ - private int id; - - /** - * The name of the package. - */ - private String packageName; - /** * The offset (from {@code offset}) in the original buffer where type strings start. */ private final int typeStringsOffset; - /** * The index into the type string pool of the last public type. */ private final int lastPublicType; - /** * An offset to the string pool that contains the key strings for this package. */ private final int keyStringsOffset; - /** * The index into the key string pool of the last public key. */ private final int lastPublicKey; - /** * An offset to the type ID(s). This is undocumented in the original code. */ private final int typeIdOffset; - /** * Contains a mapping of a type index to its {@link TypeSpecChunk}. */ private final Map typeSpecs = new HashMap<>(); - /** * Contains a mapping of a type index to all of the {@link TypeChunk} with that index. */ private final Multimap types = ArrayListMultimap.create(); - + /** + * The package id if this is a base package, or 0 if not a base package. + */ + private int id; + /** + * The name of the package. + */ + private String packageName; /** * May contain a library chunk for mapping dynamic references to resolved references. */ private Optional libraryChunk = Optional.empty(); - protected PackageChunk(ByteBuffer buffer, @Nullable Chunk parent) { + PackageChunk(ByteBuffer buffer, @Nullable Chunk parent) { super(buffer, parent); id = buffer.getInt(); packageName = PackageUtils.readPackageName(buffer, buffer.position()); diff --git a/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/ResourceTableChunk.java b/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/ResourceTableChunk.java index b6dffd660..1644b74bb 100644 --- a/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/ResourceTableChunk.java +++ b/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/ResourceTableChunk.java @@ -36,17 +36,16 @@ import java.util.Map; */ public final class ResourceTableChunk extends ChunkWithChunks { + /** + * The packages contained in this resource table. + */ + private final Map packages = new HashMap<>(); /** * A string pool containing all string resource values in the entire resource table. */ private StringPoolChunk stringPool; - /** - * The packages contained in this resource table. - */ - private final Map packages = new HashMap<>(); - - protected ResourceTableChunk(ByteBuffer buffer, @Nullable Chunk parent) { + ResourceTableChunk(ByteBuffer buffer, @Nullable Chunk parent) { super(buffer, parent); // packageCount. We ignore this, because we already know how many chunks we have. Preconditions.checkState(buffer.getInt() >= 1, "ResourceTableChunk package count was < 1."); diff --git a/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/StringPoolChunk.java b/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/StringPoolChunk.java index 28b7f5907..61ee5aa60 100644 --- a/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/StringPoolChunk.java +++ b/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/StringPoolChunk.java @@ -89,7 +89,7 @@ public final class StringPoolChunk extends Chunk { */ private boolean isOriginalDeduped = false; - protected StringPoolChunk(ByteBuffer buffer, @Nullable Chunk parent) { + StringPoolChunk(ByteBuffer buffer, @Nullable Chunk parent) { super(buffer, parent); stringCount = buffer.getInt(); styleCount = buffer.getInt(); @@ -310,6 +310,10 @@ public final class StringPoolChunk extends Chunk { static final int RES_STRING_POOL_SPAN_END = 0xFFFFFFFF; private final List spans; + private StringPoolStyle(List spans) { + this.spans = spans; + } + static StringPoolStyle create(ByteBuffer buffer, int offset, StringPoolChunk parent) { Builder spans = ImmutableList.builder(); int nameIndex = buffer.getInt(offset); @@ -321,10 +325,6 @@ public final class StringPoolChunk extends Chunk { return new StringPoolStyle(spans.build()); } - private StringPoolStyle(List spans) { - this.spans = spans; - } - @Override public byte[] toByteArray() throws IOException { return toByteArray(false); @@ -384,13 +384,6 @@ public final class StringPoolChunk extends Chunk { private final int stop; private final StringPoolChunk parent; - static StringPoolSpan create(ByteBuffer buffer, int offset, StringPoolChunk parent) { - int nameIndex = buffer.getInt(offset); - int start = buffer.getInt(offset + 4); - int stop = buffer.getInt(offset + 8); - return new StringPoolSpan(nameIndex, start, stop, parent); - } - private StringPoolSpan(int nameIndex, int start, int stop, StringPoolChunk parent) { this.nameIndex = nameIndex; this.start = start; @@ -398,6 +391,13 @@ public final class StringPoolChunk extends Chunk { this.parent = parent; } + static StringPoolSpan create(ByteBuffer buffer, int offset, StringPoolChunk parent) { + int nameIndex = buffer.getInt(offset); + int start = buffer.getInt(offset + 4); + int stop = buffer.getInt(offset + 8); + return new StringPoolSpan(nameIndex, start, stop, parent); + } + @Override public final byte[] toByteArray() { return toByteArray(false); diff --git a/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/TypeChunk.java b/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/TypeChunk.java index 1030df262..66cf7182b 100644 --- a/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/TypeChunk.java +++ b/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/TypeChunk.java @@ -52,18 +52,16 @@ public final class TypeChunk extends Chunk { * The offset (from {@code offset}) in the original buffer where {@code entries} start. */ private final int entriesStart; - + /** + * A sparse list of resource entries defined by this chunk. + */ + private final Map entries = new TreeMap<>(); /** * The resource configuration that these resource entries correspond to. */ private BinaryResourceConfiguration configuration; - /** - * A sparse list of resource entries defined by this chunk. - */ - private final Map entries = new TreeMap<>(); - - protected TypeChunk(ByteBuffer buffer, @Nullable Chunk parent) { + TypeChunk(ByteBuffer buffer, @Nullable Chunk parent) { super(buffer, parent); id = UnsignedBytes.toInt(buffer.get()); buffer.position(buffer.position() + 3); // Skip 3 bytes for packing @@ -176,13 +174,13 @@ public final class TypeChunk extends Chunk { } } - protected String getString(int index) { + private String getString(int index) { ResourceTableChunk resourceTable = getResourceTableChunk(); Preconditions.checkNotNull(resourceTable, "%s has no resource table.", getClass()); return resourceTable.getStringPool().getString(index); } - protected String getKeyName(int index) { + private String getKeyName(int index) { PackageChunk packageChunk = getPackageChunk(); Preconditions.checkNotNull(packageChunk, "%s has no parent package.", getClass()); StringPoolChunk keyPool = packageChunk.getKeyStringPool(); @@ -190,7 +188,7 @@ public final class TypeChunk extends Chunk { return keyPool.getString(index); } - protected void updateKey(int index, String value) { + private void updateKey(int index, String value) { PackageChunk packageChunk = getPackageChunk(); Preconditions.checkNotNull(packageChunk, "%s has no parent package.", getClass()); StringPoolChunk keyPool = packageChunk.getKeyStringPool(); @@ -293,10 +291,10 @@ public final class TypeChunk extends Chunk { private final int headerSize; private final int flags; private final int keyIndex; - private BinaryResourceValue value; - private Map values; private final int parentEntry; private final TypeChunk parent; + private BinaryResourceValue value; + private final Map values; private Entry(int headerSize, int flags, @@ -314,6 +312,52 @@ public final class TypeChunk extends Chunk { this.parent = parent; } + /** + * Creates a new {@link Entry} whose contents start at the 0-based position in + * {@code buffer} given by a 4-byte value read from {@code buffer} and then added to + * {@code baseOffset}. If the value read from {@code buffer} is equal to {@link #NO_ENTRY}, then + * null is returned as there is no resource at that position. + * + *

Otherwise, this position is parsed and returned as an {@link Entry}. + * + * @param buffer A buffer positioned at an offset to an {@link Entry}. + * @param baseOffset Offset that must be added to the value at {@code buffer}'s position. + * @param parent The {@link TypeChunk} that this resource entry belongs to. + * @return New {@link Entry} or null if there is no resource at this location. + */ + @Nullable + public static Entry create(ByteBuffer buffer, int baseOffset, TypeChunk parent) { + int offset = buffer.getInt(); + if (offset == NO_ENTRY) { + return null; + } + int position = buffer.position(); + buffer.position(baseOffset + offset); // Set buffer position to resource entry start + Entry result = newInstance(buffer, parent); + buffer.position(position); // Restore buffer position + return result; + } + + @Nullable + private static Entry newInstance(ByteBuffer buffer, TypeChunk parent) { + int headerSize = buffer.getShort() & 0xFFFF; + int flags = buffer.getShort() & 0xFFFF; + int keyIndex = buffer.getInt(); + BinaryResourceValue value = null; + Map values = new LinkedHashMap<>(); + int parentEntry = 0; + if ((flags & FLAG_COMPLEX) != 0) { + parentEntry = buffer.getInt(); + int valueCount = buffer.getInt(); + for (int i = 0; i < valueCount; ++i) { + values.put(buffer.getInt(), BinaryResourceValue.create(buffer)); + } + } else { + value = BinaryResourceValue.create(buffer); + } + return new Entry(headerSize, flags, keyIndex, value, values, parentEntry, parent); + } + /** * Number of bytes in the header of the {@link Entry}. */ @@ -422,52 +466,6 @@ public final class TypeChunk extends Chunk { return (flags() & FLAG_COMPLEX) != 0; } - /** - * Creates a new {@link Entry} whose contents start at the 0-based position in - * {@code buffer} given by a 4-byte value read from {@code buffer} and then added to - * {@code baseOffset}. If the value read from {@code buffer} is equal to {@link #NO_ENTRY}, then - * null is returned as there is no resource at that position. - * - *

Otherwise, this position is parsed and returned as an {@link Entry}. - * - * @param buffer A buffer positioned at an offset to an {@link Entry}. - * @param baseOffset Offset that must be added to the value at {@code buffer}'s position. - * @param parent The {@link TypeChunk} that this resource entry belongs to. - * @return New {@link Entry} or null if there is no resource at this location. - */ - @Nullable - public static Entry create(ByteBuffer buffer, int baseOffset, TypeChunk parent) { - int offset = buffer.getInt(); - if (offset == NO_ENTRY) { - return null; - } - int position = buffer.position(); - buffer.position(baseOffset + offset); // Set buffer position to resource entry start - Entry result = newInstance(buffer, parent); - buffer.position(position); // Restore buffer position - return result; - } - - @Nullable - private static Entry newInstance(ByteBuffer buffer, TypeChunk parent) { - int headerSize = buffer.getShort() & 0xFFFF; - int flags = buffer.getShort() & 0xFFFF; - int keyIndex = buffer.getInt(); - BinaryResourceValue value = null; - Map values = new LinkedHashMap<>(); - int parentEntry = 0; - if ((flags & FLAG_COMPLEX) != 0) { - parentEntry = buffer.getInt(); - int valueCount = buffer.getInt(); - for (int i = 0; i < valueCount; ++i) { - values.put(buffer.getInt(), BinaryResourceValue.create(buffer)); - } - } else { - value = BinaryResourceValue.create(buffer); - } - return new Entry(headerSize, flags, keyIndex, value, values, parentEntry, parent); - } - @Override public final byte[] toByteArray() { return toByteArray(false); diff --git a/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/TypeSpecChunk.java b/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/TypeSpecChunk.java index c12922b8d..55c6464ed 100644 --- a/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/TypeSpecChunk.java +++ b/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/TypeSpecChunk.java @@ -39,7 +39,7 @@ public final class TypeSpecChunk extends Chunk { */ private final int[] resources; - protected TypeSpecChunk(ByteBuffer buffer, @Nullable Chunk parent) { + TypeSpecChunk(ByteBuffer buffer, @Nullable Chunk parent) { super(buffer, parent); id = UnsignedBytes.toInt(buffer.get()); buffer.position(buffer.position() + 3); // Skip 3 bytes for packing diff --git a/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/UnknownChunk.java b/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/UnknownChunk.java index 0d07c3199..5bdf015a6 100644 --- a/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/UnknownChunk.java +++ b/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/UnknownChunk.java @@ -34,7 +34,7 @@ public final class UnknownChunk extends Chunk { private final byte[] payload; - protected UnknownChunk(ByteBuffer buffer, @Nullable Chunk parent) { + UnknownChunk(ByteBuffer buffer, @Nullable Chunk parent) { super(buffer, parent); type = Type.fromCode(buffer.getShort(offset)); diff --git a/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/XmlAttribute.java b/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/XmlAttribute.java index f3d696834..5b02b89c9 100644 --- a/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/XmlAttribute.java +++ b/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/XmlAttribute.java @@ -36,6 +36,18 @@ public class XmlAttribute implements SerializableResource { private final BinaryResourceValue typedValue; private final XmlNodeChunk parent; + private XmlAttribute(int namespaceIndex, + int nameIndex, + int rawValueIndex, + BinaryResourceValue typedValue, + XmlNodeChunk parent) { + this.namespaceIndex = namespaceIndex; + this.nameIndex = nameIndex; + this.rawValueIndex = rawValueIndex; + this.typedValue = typedValue; + this.parent = parent; + } + /** * Creates a new {@link XmlAttribute} based on the bytes at the current {@code buffer} position. * @@ -50,18 +62,6 @@ public class XmlAttribute implements SerializableResource { return new XmlAttribute(namespace, name, rawValue, typedValue, parent); } - private XmlAttribute(int namespaceIndex, - int nameIndex, - int rawValueIndex, - BinaryResourceValue typedValue, - XmlNodeChunk parent) { - this.namespaceIndex = namespaceIndex; - this.nameIndex = nameIndex; - this.rawValueIndex = rawValueIndex; - this.typedValue = typedValue; - this.parent = parent; - } - /** * A string reference to the namespace URI, or -1 if not present. */ diff --git a/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/XmlCdataChunk.java b/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/XmlCdataChunk.java index 2f961cb35..f6af250d0 100644 --- a/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/XmlCdataChunk.java +++ b/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/XmlCdataChunk.java @@ -37,7 +37,7 @@ public final class XmlCdataChunk extends XmlNodeChunk { */ private final BinaryResourceValue binaryResourceValue; - protected XmlCdataChunk(ByteBuffer buffer, @Nullable Chunk parent) { + XmlCdataChunk(ByteBuffer buffer, @Nullable Chunk parent) { super(buffer, parent); rawValue = buffer.getInt(); binaryResourceValue = BinaryResourceValue.create(buffer); diff --git a/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/XmlChunk.java b/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/XmlChunk.java index 9c55bd42a..1d1867b92 100644 --- a/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/XmlChunk.java +++ b/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/XmlChunk.java @@ -28,7 +28,7 @@ import java.nio.ByteBuffer; */ public final class XmlChunk extends ChunkWithChunks { - protected XmlChunk(ByteBuffer buffer, @Nullable Chunk parent) { + XmlChunk(ByteBuffer buffer, @Nullable Chunk parent) { super(buffer, parent); } diff --git a/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/XmlEndElementChunk.java b/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/XmlEndElementChunk.java index f3020eeb8..e8b9837ed 100644 --- a/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/XmlEndElementChunk.java +++ b/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/XmlEndElementChunk.java @@ -37,7 +37,7 @@ public final class XmlEndElementChunk extends XmlNodeChunk { */ private final int name; - protected XmlEndElementChunk(ByteBuffer buffer, @Nullable Chunk parent) { + XmlEndElementChunk(ByteBuffer buffer, @Nullable Chunk parent) { super(buffer, parent); namespace = buffer.getInt(); name = buffer.getInt(); diff --git a/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/XmlNamespaceEndChunk.java b/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/XmlNamespaceEndChunk.java index 49f70957d..14dab122f 100644 --- a/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/XmlNamespaceEndChunk.java +++ b/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/XmlNamespaceEndChunk.java @@ -25,7 +25,7 @@ import java.nio.ByteBuffer; */ public final class XmlNamespaceEndChunk extends XmlNamespaceChunk { - protected XmlNamespaceEndChunk(ByteBuffer buffer, @Nullable Chunk parent) { + XmlNamespaceEndChunk(ByteBuffer buffer, @Nullable Chunk parent) { super(buffer, parent); } diff --git a/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/XmlNamespaceStartChunk.java b/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/XmlNamespaceStartChunk.java index 1fbd23383..dcf5b8133 100644 --- a/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/XmlNamespaceStartChunk.java +++ b/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/XmlNamespaceStartChunk.java @@ -25,7 +25,7 @@ import java.nio.ByteBuffer; */ public final class XmlNamespaceStartChunk extends XmlNamespaceChunk { - protected XmlNamespaceStartChunk(ByteBuffer buffer, @Nullable Chunk parent) { + XmlNamespaceStartChunk(ByteBuffer buffer, @Nullable Chunk parent) { super(buffer, parent); } diff --git a/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/XmlStartElementChunk.java b/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/XmlStartElementChunk.java index d219dec23..75073d279 100644 --- a/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/XmlStartElementChunk.java +++ b/app/src/main/java/com/google/devrel/gmscore/tools/apk/arsc/XmlStartElementChunk.java @@ -71,7 +71,7 @@ public final class XmlStartElementChunk extends XmlNodeChunk { */ private final List attributes = new ArrayList<>(); - protected XmlStartElementChunk(ByteBuffer buffer, @Nullable Chunk parent) { + XmlStartElementChunk(ByteBuffer buffer, @Nullable Chunk parent) { super(buffer, parent); namespace = buffer.getInt(); name = buffer.getInt(); diff --git a/app/src/main/java/com/vk/api/gifts/GiftGetByStickerId.java b/app/src/main/java/com/vk/api/gifts/GiftGetByStickerId.java index dfa535f88..df60d0535 100644 --- a/app/src/main/java/com/vk/api/gifts/GiftGetByStickerId.java +++ b/app/src/main/java/com/vk/api/gifts/GiftGetByStickerId.java @@ -7,16 +7,6 @@ import org.json.JSONException; import org.json.JSONObject; public class GiftGetByStickerId extends ApiRequest { - public static class a { - public final int a; - public final CatalogedGift b; - - public a(int i, CatalogedGift catalogedGift) { - this.a = i; - this.b = catalogedGift; - } - } - public GiftGetByStickerId(Context context, int i) { super("execute.getGiftByStickerId"); b("sticker_id", i); @@ -30,4 +20,14 @@ public class GiftGetByStickerId extends ApiRequest { return new a(jSONObject2.optInt("balance"), new CatalogedGift(jSONObject2.getJSONObject("gift"))); } + + public static class a { + public final int a; + public final CatalogedGift b; + + public a(int i, CatalogedGift catalogedGift) { + this.a = i; + this.b = catalogedGift; + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/vk/core/drawable/RecoloredDrawable.java b/app/src/main/java/com/vk/core/drawable/RecoloredDrawable.java index bd60ee6b6..dfeb4779b 100644 --- a/app/src/main/java/com/vk/core/drawable/RecoloredDrawable.java +++ b/app/src/main/java/com/vk/core/drawable/RecoloredDrawable.java @@ -27,6 +27,15 @@ public class RecoloredDrawable extends Drawable implements Drawable.Callback { onStateChange(new int[0]); } + public RecoloredDrawable(Drawable drawable, int i) { + this(drawable, new ColorStateList(new int[][]{new int[0]}, new int[]{i})); + } + + public RecoloredDrawable() { + this.c = 255; + this.d = 255; + } + public void a(int i) { a(new ColorStateList(new int[][]{new int[0]}, new int[]{i})); } @@ -120,13 +129,4 @@ public class RecoloredDrawable extends Drawable implements Drawable.Callback { public Drawable a() { return this.drawable; } - - public RecoloredDrawable(Drawable drawable, int i) { - this(drawable, new ColorStateList(new int[][]{new int[0]}, new int[]{i})); - } - - public RecoloredDrawable() { - this.c = 255; - this.d = 255; - } } \ No newline at end of file diff --git a/app/src/main/java/com/vk/core/utils/VerifyInfoHelper.java b/app/src/main/java/com/vk/core/utils/VerifyInfoHelper.java index f32c281df..9a5781a64 100644 --- a/app/src/main/java/com/vk/core/utils/VerifyInfoHelper.java +++ b/app/src/main/java/com/vk/core/utils/VerifyInfoHelper.java @@ -21,6 +21,13 @@ public final class VerifyInfoHelper { public static final VerifyInfoHelper h; public static int devIcon = R.drawable.ic_favorite_16; + static { + h = new VerifyInfoHelper(); + } + + private VerifyInfoHelper() { + } + public static Integer enumSwitchMapping(VerifyInfoHelper.ColorTheme color) { return switch (color) { case normal -> 1; @@ -30,18 +37,47 @@ public final class VerifyInfoHelper { }; } - public enum ColorTheme { - white, - normal, - light, - ultraLight + public static Drawable b(VerifyInfoHelper verifyInfoHelper, boolean z, boolean z2, boolean dev, Context context, ColorTheme colorTheme, int i, Object obj) { + if ((i & 8) != 0) { + colorTheme = ColorTheme.normal; + } + return verifyInfoHelper.b(z, z2, dev, context, colorTheme); } - static { - h = new VerifyInfoHelper(); + public static Drawable b(VerifyInfoHelper verifyInfoHelper, VerifyInfo verifyInfo, Context context, ColorTheme colorTheme, int i, Object obj) { + return b(verifyInfoHelper, verifyInfo.u1(), verifyInfo.t1(), verifyInfo.dev(), context, colorTheme, i, obj); } - private VerifyInfoHelper() { + public static Drawable b(VerifyInfoHelper verifyInfoHelper, boolean z, boolean z2, Context context, ColorTheme colorTheme, int i, Object obj) { + return b(verifyInfoHelper, z, z2, false, context, colorTheme, i, obj); + } + + public static Drawable a(VerifyInfoHelper verifyInfoHelper, VerifyInfo verifyInfo, Context context, ColorTheme colorTheme, int i, Object obj) { + if ((i & 4) != 0) { + colorTheme = ColorTheme.normal; + } + return verifyInfoHelper.b(verifyInfo, context, colorTheme); + } + + public static Drawable a(VerifyInfoHelper verifyInfoHelper, boolean z, boolean z2, boolean dev, Context context, ColorTheme colorTheme, int i, Object obj) { + if ((i & 8) != 0) { + colorTheme = ColorTheme.normal; + } + return verifyInfoHelper.a(z, z2, dev, context, colorTheme); + } + + public static Drawable a(VerifyInfoHelper verifyInfoHelper, boolean z, boolean z2, Context context, ColorTheme colorTheme, int i, Object obj) { + return a(verifyInfoHelper, z, z2, false, context, colorTheme, i, obj); + } + + public static void a(VerifyInfoHelper verifyInfoHelper, TextView textView, VerifyInfo verifyInfo, boolean z, ColorTheme colorTheme, int i, Object obj) { + if ((i & 4) != 0) { + z = false; + } + if ((i & 8) != 0) { + colorTheme = ColorTheme.normal; + } + verifyInfoHelper.a(textView, verifyInfo, z, colorTheme); } private int a() { @@ -89,7 +125,6 @@ public final class VerifyInfoHelper { return b(this, z, z2, false, context, null, 8, null); } - public int b(ColorTheme colorTheme) { return a(colorTheme); } @@ -104,7 +139,6 @@ public final class VerifyInfoHelper { }; } - public Drawable b(Context context, VerifyInfo verifyInfo) { if (verifyInfo.dev()) { return new RecoloredDrawable(ContextCompat.getDrawable(context, devIcon), c(ColorTheme.normal)); @@ -123,21 +157,6 @@ public final class VerifyInfoHelper { return b(verifyInfo.u1(), verifyInfo.t1(), verifyInfo.dev(), context, colorTheme); } - public static Drawable b(VerifyInfoHelper verifyInfoHelper, boolean z, boolean z2, boolean dev, Context context, ColorTheme colorTheme, int i, Object obj) { - if ((i & 8) != 0) { - colorTheme = ColorTheme.normal; - } - return verifyInfoHelper.b(z, z2, dev, context, colorTheme); - } - - public static Drawable b(VerifyInfoHelper verifyInfoHelper, VerifyInfo verifyInfo, Context context, ColorTheme colorTheme, int i, Object obj) { - return b(verifyInfoHelper, verifyInfo.u1(), verifyInfo.t1(), verifyInfo.dev(), context, colorTheme, i, obj); - } - - public static Drawable b(VerifyInfoHelper verifyInfoHelper, boolean z, boolean z2, Context context, ColorTheme colorTheme, int i, Object obj) { - return b(verifyInfoHelper, z, z2, false, context, colorTheme, i, obj); - } - public Drawable a(Context context, VerifyInfo verifyInfo) { if (verifyInfo.dev()) { return new RecoloredDrawable(ContextCompat.getDrawable(context, devIcon), c(ColorTheme.normal)); @@ -181,28 +200,10 @@ public final class VerifyInfoHelper { return new RecoloredDrawable(ContextCompat.getDrawable(context, i), c2); } - public static Drawable a(VerifyInfoHelper verifyInfoHelper, VerifyInfo verifyInfo, Context context, ColorTheme colorTheme, int i, Object obj) { - if ((i & 4) != 0) { - colorTheme = ColorTheme.normal; - } - return verifyInfoHelper.b(verifyInfo, context, colorTheme); - } - public Drawable a(VerifyInfo verifyInfo, Context context, ColorTheme colorTheme) { return a(verifyInfo.u1(), verifyInfo.t1(), verifyInfo.dev(), context, colorTheme); } - public static Drawable a(VerifyInfoHelper verifyInfoHelper, boolean z, boolean z2, boolean dev, Context context, ColorTheme colorTheme, int i, Object obj) { - if ((i & 8) != 0) { - colorTheme = ColorTheme.normal; - } - return verifyInfoHelper.a(z, z2, dev, context, colorTheme); - } - - public static Drawable a(VerifyInfoHelper verifyInfoHelper, boolean z, boolean z2, Context context, ColorTheme colorTheme, int i, Object obj) { - return a(verifyInfoHelper, z, z2, false, context, colorTheme, i, obj); - } - public Drawable a(boolean z, boolean z2, Context context, ColorTheme colorTheme) { return a(z, z2, false, context, colorTheme); } @@ -230,16 +231,6 @@ public final class VerifyInfoHelper { return new RecoloredDrawable(ContextCompat.getDrawable(context, i), c2); } - public static void a(VerifyInfoHelper verifyInfoHelper, TextView textView, VerifyInfo verifyInfo, boolean z, ColorTheme colorTheme, int i, Object obj) { - if ((i & 4) != 0) { - z = false; - } - if ((i & 8) != 0) { - colorTheme = ColorTheme.normal; - } - verifyInfoHelper.a(textView, verifyInfo, z, colorTheme); - } - public void a(TextView textView, VerifyInfo verifyInfo, boolean z, ColorTheme colorTheme) { Drawable drawable; Context context = textView.getContext(); @@ -267,4 +258,11 @@ public final class VerifyInfoHelper { } ViewExtKt.p(imageView); } + + public enum ColorTheme { + white, + normal, + light, + ultraLight + } } \ No newline at end of file diff --git a/app/src/main/java/com/vk/im/engine/commands/dialogs/DialogGetMentionSuggestionCmd.java b/app/src/main/java/com/vk/im/engine/commands/dialogs/DialogGetMentionSuggestionCmd.java index 644415d33..18b59bb6e 100644 --- a/app/src/main/java/com/vk/im/engine/commands/dialogs/DialogGetMentionSuggestionCmd.java +++ b/app/src/main/java/com/vk/im/engine/commands/dialogs/DialogGetMentionSuggestionCmd.java @@ -31,30 +31,6 @@ public final class DialogGetMentionSuggestionCmd extends BaseImEngineCmd implements Comparator { - List a; - - a(List list) { - this.a = list; - } - - @Override // java.util.Comparator - /* renamed from: a */ - public int compare(Member member, Member member2) { - int indexOf = this.a.indexOf(member); - int indexOf2 = this.a.indexOf(member2); - int i = indexOf; - if (indexOf < 0) { - i = Integer.MAX_VALUE; - } - int i2 = indexOf2; - if (indexOf2 < 0) { - i2 = Integer.MAX_VALUE; - } - return Intrinsics.a(i, i2); - } - } - public DialogGetMentionSuggestionCmd(int i, String str, Source source, boolean z, Object obj) { this.f2365b = i; this.c = str; @@ -150,7 +126,7 @@ public final class DialogGetMentionSuggestionCmd extends BaseImEngineCmd a2; Source source; if (ImDialogsUtils.d(this.f2365b) != PeerType.CHAT) { - return new Suggestion((EntityValue) null, (ProfilesInfo) null); + return new Suggestion(null, null); } Member Z = imEnvironment.Z(); int d = imEnvironment.a0().n().d(); @@ -235,4 +211,28 @@ public final class DialogGetMentionSuggestionCmd extends BaseImEngineCmd implements Comparator { + List a; + + a(List list) { + this.a = list; + } + + @Override // java.util.Comparator + /* renamed from: a */ + public int compare(Member member, Member member2) { + int indexOf = this.a.indexOf(member); + int indexOf2 = this.a.indexOf(member2); + int i = indexOf; + if (indexOf < 0) { + i = Integer.MAX_VALUE; + } + int i2 = indexOf2; + if (indexOf2 < 0) { + i2 = Integer.MAX_VALUE; + } + return Intrinsics.a(i, i2); + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/vk/im/ui/components/common/DialogActionsHelper.java b/app/src/main/java/com/vk/im/ui/components/common/DialogActionsHelper.java index ab52f7655..b4e113155 100644 --- a/app/src/main/java/com/vk/im/ui/components/common/DialogActionsHelper.java +++ b/app/src/main/java/com/vk/im/ui/components/common/DialogActionsHelper.java @@ -19,7 +19,7 @@ import java.util.List; public final class DialogActionsHelper { public static final DialogActionsHelper a = new DialogActionsHelper(); - public final List a(ImConfig imConfig, Dialog dialog, ProfilesSimpleInfo profilesSimpleInfo) { + public List a(ImConfig imConfig, Dialog dialog, ProfilesSimpleInfo profilesSimpleInfo) { if (dialog != null && profilesSimpleInfo != null) { long b2 = TimeProvider.f.b(); ChatSettings z1 = dialog.z1(); @@ -84,7 +84,7 @@ public final class DialogActionsHelper { return new ArrayList<>(); } - public final List a(Dialog dialog, ProfilesSimpleInfo profilesSimpleInfo) { + public List a(Dialog dialog, ProfilesSimpleInfo profilesSimpleInfo) { long b2 = TimeProvider.f.b(); Profile profile = profilesSimpleInfo.get(dialog.getId()); @@ -138,7 +138,7 @@ public final class DialogActionsHelper { return arrayList; } - public final boolean a(Dialog dialog) { + public boolean a(Dialog dialog) { if (dialog.V1() || !dialog.y1()) { return false; } diff --git a/app/src/main/java/com/vk/im/ui/components/common/MsgActionHelper.java b/app/src/main/java/com/vk/im/ui/components/common/MsgActionHelper.java index 438d192a4..a32e89e70 100644 --- a/app/src/main/java/com/vk/im/ui/components/common/MsgActionHelper.java +++ b/app/src/main/java/com/vk/im/ui/components/common/MsgActionHelper.java @@ -16,11 +16,11 @@ import java.util.List; public final class MsgActionHelper { public static final MsgActionHelper a = new MsgActionHelper(); - public final List a(ImEngine imEngine, Dialog dialog, Collection collection) { + public List a(ImEngine imEngine, Dialog dialog, Collection collection) { return a(imEngine != null ? imEngine.g() : null, dialog, collection); } - public final List a(ImConfig imConfig, Dialog dialog, Collection collection) { + public List a(ImConfig imConfig, Dialog dialog, Collection collection) { if (imConfig != null && dialog != null && collection != null) { MsgPermissionHelper.a aVar = new MsgPermissionHelper.a(imConfig, dialog, collection); ArrayList arrayList = new ArrayList<>(); diff --git a/app/src/main/java/com/vk/im/ui/components/viewcontrollers/msg_list/adapter/VhBindArgs.java b/app/src/main/java/com/vk/im/ui/components/viewcontrollers/msg_list/adapter/VhBindArgs.java index 8d8bb9e30..4bc07d663 100644 --- a/app/src/main/java/com/vk/im/ui/components/viewcontrollers/msg_list/adapter/VhBindArgs.java +++ b/app/src/main/java/com/vk/im/ui/components/viewcontrollers/msg_list/adapter/VhBindArgs.java @@ -74,11 +74,7 @@ public class VhBindArgs { private boolean L() { boolean var1; - if (this.K() <= this.m && !TimeProvider.f.c()) { - var1 = false; - } else { - var1 = true; - } + var1 = this.K() > this.m || TimeProvider.f.c(); return var1; } @@ -109,11 +105,7 @@ public class VhBindArgs { public boolean B() { AdapterEntry var1 = this.a; boolean var2; - if (var1 != null && var1.c()) { - var2 = true; - } else { - var2 = false; - } + var2 = var1 != null && var1.c(); return var2; } @@ -121,11 +113,7 @@ public class VhBindArgs { public boolean C() { AdapterEntry var1 = this.a; boolean var2; - if (var1 != null && var1.c() && this.a.c.getLocalId() == this.b.c.getLocalId()) { - var2 = true; - } else { - var2 = false; - } + var2 = var1 != null && var1.c() && this.a.c.getLocalId() == this.b.c.getLocalId(); return var2; } @@ -133,11 +121,7 @@ public class VhBindArgs { public boolean D() { AdapterEntry var1 = this.a; boolean var2; - if (var1 != null && var1.a == 83) { - var2 = true; - } else { - var2 = false; - } + var2 = var1 != null && var1.a == 83; return var2; } @@ -145,11 +129,7 @@ public class VhBindArgs { public boolean E() { Msg var1 = this.b.c; boolean var2; - if (var1 instanceof MsgFromUser && ((MsgFromUser) var1).i2()) { - var2 = true; - } else { - var2 = false; - } + var2 = var1 instanceof MsgFromUser && ((MsgFromUser) var1).i2(); return var2; } @@ -157,11 +137,7 @@ public class VhBindArgs { public boolean F() { Msg var1 = this.b.c; boolean var2; - if (var1 instanceof MsgFromUser && ((MsgFromUser) var1).F0()) { - var2 = true; - } else { - var2 = false; - } + var2 = var1 instanceof MsgFromUser && ((MsgFromUser) var1).F0(); return var2; } @@ -169,11 +145,7 @@ public class VhBindArgs { public boolean G() { AdapterEntry var1 = this.b; boolean var2; - if (var1 != null && var1.a == 51) { - var2 = true; - } else { - var2 = false; - } + var2 = var1 != null && var1.a == 51; return var2; } @@ -186,11 +158,7 @@ public class VhBindArgs { long var1 = this.K(); long var3 = this.m; boolean var5; - if (var1 > var3 && var1 < var3 * 2L) { - var5 = true; - } else { - var5 = false; - } + var5 = var1 > var3 && var1 < var3 * 2L; return var5; } @@ -206,18 +174,10 @@ public class VhBindArgs { MsgFromUser var7 = (MsgFromUser) var1; Msg var3 = this.a.c; boolean var4; - if (var3 != null && var3.d() == MsgSyncState.DONE) { - var4 = true; - } else { - var4 = false; - } + var4 = var3 != null && var3.d() == MsgSyncState.DONE; boolean var5; - if (this.o == ImBgSyncState.CONNECTED) { - var5 = true; - } else { - var5 = false; - } + var5 = this.o == ImBgSyncState.CONNECTED; boolean var6 = var2; if (!var7.H0()) { @@ -242,7 +202,7 @@ public class VhBindArgs { byte var2 = 0; int var3 = var2; if (var1) { - AttachAudioMsg var4 = (AttachAudioMsg) ((MsgFromUser) this.b.c).c(AttachAudioMsg.class, false); + AttachAudioMsg var4 = ((MsgFromUser) this.b.c).c(AttachAudioMsg.class, false); var3 = var2; if (var4 != null) { var3 = var4.f(); @@ -267,11 +227,7 @@ public class VhBindArgs { public boolean c() { Msg var1 = this.b.c; boolean var2; - if (var1 instanceof MsgFromUser && ((MsgFromUser) var1).I0()) { - var2 = true; - } else { - var2 = false; - } + var2 = var1 instanceof MsgFromUser && ((MsgFromUser) var1).I0(); return var2; } @@ -279,22 +235,14 @@ public class VhBindArgs { public boolean d() { Msg var1 = this.b.c; boolean var2; - if (var1 instanceof WithUserContent && ((WithUserContent) var1).D0() != null) { - var2 = true; - } else { - var2 = false; - } + var2 = var1 instanceof WithUserContent && ((WithUserContent) var1).D0() != null; return var2; } public boolean e() { boolean var1; - if (this.b.i > 0) { - var1 = true; - } else { - var1 = false; - } + var1 = this.b.i > 0; return var1; } @@ -317,11 +265,7 @@ public class VhBindArgs { public boolean g() { Msg var1 = this.b.c; boolean var2; - if (var1 instanceof MsgFromUser && ((MsgFromUser) var1).G0()) { - var2 = true; - } else { - var2 = false; - } + var2 = var1 instanceof MsgFromUser && ((MsgFromUser) var1).G0(); return var2; } @@ -329,33 +273,21 @@ public class VhBindArgs { public boolean h() { Msg var1 = this.b.c; boolean var2; - if (var1 instanceof MsgFromUser && ((MsgFromUser) var1).Z1()) { - var2 = true; - } else { - var2 = false; - } + var2 = var1 instanceof MsgFromUser && ((MsgFromUser) var1).Z1(); return var2; } public boolean i() { boolean var1; - if (this.j && !this.u() && !this.l()) { - var1 = true; - } else { - var1 = false; - } + var1 = this.j && !this.u() && !this.l(); return var1; } public boolean j() { boolean var1; - if (!this.j || this.u() || this.B() && this.A() && !this.a.c.H1()) { - var1 = false; - } else { - var1 = true; - } + var1 = this.j && !this.u() && (!this.B() || !this.A() || this.a.c.H1()); return var1; } @@ -363,11 +295,7 @@ public class VhBindArgs { public boolean k() { Dialog var1 = this.e; boolean var2; - if (var1 != null && var1.U1()) { - var2 = true; - } else { - var2 = false; - } + var2 = var1 != null && var1.U1(); return var2; } @@ -375,11 +303,7 @@ public class VhBindArgs { public boolean l() { Dialog var1 = this.e; boolean var2; - if (var1 != null && var1.V1()) { - var2 = true; - } else { - var2 = false; - } + var2 = var1 != null && var1.V1(); return var2; } @@ -387,11 +311,7 @@ public class VhBindArgs { public boolean m() { Dialog var1 = this.e; boolean var2; - if (var1 != null && var1.W1()) { - var2 = true; - } else { - var2 = false; - } + var2 = var1 != null && var1.W1(); return var2; } @@ -404,11 +324,7 @@ public class VhBindArgs { public boolean o() { AdapterEntry var1 = this.b; boolean var2; - if (var1 != null && var1.a == 101) { - var2 = true; - } else { - var2 = false; - } + var2 = var1 != null && var1.a == 101; return var2; } @@ -416,11 +332,7 @@ public class VhBindArgs { public boolean p() { Msg var1 = this.b.c; boolean var2; - if (var1 != null && var1.G1()) { - var2 = true; - } else { - var2 = false; - } + var2 = var1 != null && var1.G1(); return var2; } @@ -443,11 +355,7 @@ public class VhBindArgs { public boolean r() { Msg var1 = this.b.c; boolean var2; - if (var1 instanceof MsgFromUser && ((MsgFromUser) var1).e2()) { - var2 = true; - } else { - var2 = false; - } + var2 = var1 instanceof MsgFromUser && ((MsgFromUser) var1).e2(); return var2; } @@ -488,27 +396,19 @@ public class VhBindArgs { public boolean v() { IntSet var1 = this.r; boolean var2; - if (var1 != null && var1.a(this.b.c.getLocalId())) { - var2 = true; - } else { - var2 = false; - } + var2 = var1 != null && var1.a(this.b.c.getLocalId()); return var2; } public boolean w() { - return this.z() ^ true; + return !this.z(); } public boolean x() { AdapterEntry var1 = this.c; boolean var2; - if (var1 != null && var1.a == 100) { - var2 = true; - } else { - var2 = false; - } + var2 = var1 != null && var1.a == 100; return var2; } @@ -516,11 +416,7 @@ public class VhBindArgs { public boolean y() { AdapterEntry var1 = this.c; boolean var2; - if (var1 != null && var1.a == 96) { - var2 = true; - } else { - var2 = false; - } + var2 = var1 != null && var1.a == 96; return var2; } @@ -528,11 +424,7 @@ public class VhBindArgs { public boolean z() { AdapterEntry var1 = this.c; boolean var2; - if (var1 != null && var1.c() && this.c.c.getLocalId() == this.b.c.getLocalId()) { - var2 = true; - } else { - var2 = false; - } + var2 = var1 != null && var1.c() && this.c.c.getLocalId() == this.b.c.getLocalId(); return var2; } diff --git a/app/src/main/java/com/vk/im/ui/components/viewcontrollers/msg_list/adapter/msgparts/MsgPartCallHolder.java b/app/src/main/java/com/vk/im/ui/components/viewcontrollers/msg_list/adapter/msgparts/MsgPartCallHolder.java index 28e6faff4..1253c540f 100644 --- a/app/src/main/java/com/vk/im/ui/components/viewcontrollers/msg_list/adapter/msgparts/MsgPartCallHolder.java +++ b/app/src/main/java/com/vk/im/ui/components/viewcontrollers/msg_list/adapter/msgparts/MsgPartCallHolder.java @@ -46,7 +46,7 @@ public final class MsgPartCallHolder extends MsgPartHolderBase { this.G = new StringBuilder(); } - private final void a(Msg var1) { + private void a(Msg var1) { this.G.setLength(0); MsgTimeFormatter var2 = this.F; Context var3 = this.C; @@ -55,7 +55,7 @@ public final class MsgPartCallHolder extends MsgPartHolderBase { this.H.setTimeText(this.G); } - private final void a(boolean var1) { + private void a(boolean var1) { MsgPartIconTwoRowView var2 = this.H; int var3; if (var1) { @@ -67,7 +67,7 @@ public final class MsgPartCallHolder extends MsgPartHolderBase { var2.setIcon(var3); } - private final void a(boolean var1, AttachCall var2) { + private void a(boolean var1, AttachCall var2) { boolean var3 = !var1; if (var2.h() == CallState.ERROR) { this.H.setSubtitleText(m.vkim_msg_list_call_error); diff --git a/app/src/main/java/com/vk/im/ui/components/viewcontrollers/msg_list/adapter/vh/VhMsg.java b/app/src/main/java/com/vk/im/ui/components/viewcontrollers/msg_list/adapter/vh/VhMsg.java index 808a9d02d..e3627a332 100644 --- a/app/src/main/java/com/vk/im/ui/components/viewcontrollers/msg_list/adapter/vh/VhMsg.java +++ b/app/src/main/java/com/vk/im/ui/components/viewcontrollers/msg_list/adapter/vh/VhMsg.java @@ -56,46 +56,6 @@ public class VhMsg extends VhBase implements SwipeToReplyItemTouchCallback.b { private static final int[][] j0; private static final int[][] k0; private static final int[][] l0; - private final MsgPartHolderBase B; - private final MsgPartHolderBindArgs C = new MsgPartHolderBindArgs(); - private final Rect D = new Rect(); - private final Rect E = new Rect(); - private final Rect F = new Rect(); - private final Rect G = new Rect(); - private ColorDrawable H; - private final int I; - private final int J; - private final int K; - private final int L; - private final int M; - private Drawable N; - private Drawable O; - private BombView P; - private BombView.d Q; - private int R; - private int S; - private final DisplayNameFormatter T = new DisplayNameFormatter(); - private final StringBuilder U = new StringBuilder(); - private final StringBuilder V = new StringBuilder(); - private final String W; - private final String X; - private final String Y; - private boolean Z; - private BubbleColors a0; - private final FluidHorizontalLayout b; - @ColorInt - private int b0; - private final AvatarView c; - private MsgListAdapterCallback c0; - private final Space d; - private Msg d0; - private final MsgBubbleView e; - private Dialog e0; - private final MsgStatusView f; - private int f0; - private final ImageView g; - private h g0 = new h(); - private final Space h; static { int[] var0 = new int[]{0, 0, 0, 0}; @@ -119,18 +79,59 @@ public class VhMsg extends VhBase implements SwipeToReplyItemTouchCallback.b { l0 = new int[][]{var0, {4, 4, 0, 0, 0, 2, 8, 0}, var1, var2, {4, 0, 0, 0, 0, 2, 8, 0}, {0, 0, 0, 0, 0, 2, 8, 0}, {4, 4, 0, 0, 0, 2, 8, 0}, {0, 0, 0, 0, 0, 0, 0, 0}}; } + private final MsgPartHolderBase B; + private final MsgPartHolderBindArgs C = new MsgPartHolderBindArgs(); + private final Rect D = new Rect(); + private final Rect E = new Rect(); + private final Rect F = new Rect(); + private final Rect G = new Rect(); + private final int I; + private final int J; + private final int K; + private final int L; + private final int M; + private final DisplayNameFormatter T = new DisplayNameFormatter(); + private final StringBuilder U = new StringBuilder(); + private final StringBuilder V = new StringBuilder(); + private final String W; + private final String X; + private final String Y; + private final FluidHorizontalLayout b; + private final AvatarView c; + private final Space d; + private final MsgBubbleView e; + private final MsgStatusView f; + private final ImageView g; + private final Space h; + private final ColorDrawable H; + private Drawable N; + private Drawable O; + private final BombView P; + private final BombView.d Q; + private final int R; + private final int S; + private boolean Z; + private BubbleColors a0; + @ColorInt + private int b0; + private MsgListAdapterCallback c0; + private Msg d0; + private Dialog e0; + private int f0; + private final h g0 = new h(); + public VhMsg(View itemView, MsgPartHolderBase vhBase) { super(itemView); Context context = itemView.getContext(); LayoutInflater var4 = LayoutInflater.from(context); this.b = (FluidHorizontalLayout) itemView; - this.c = (AvatarView) itemView.findViewById(com.vk.im.ui.h.avatar); - this.d = (Space) itemView.findViewById(com.vk.im.ui.h.avatar_space); - this.e = (MsgBubbleView) itemView.findViewById(com.vk.im.ui.h.bubble); - this.f = (MsgStatusView) itemView.findViewById(com.vk.im.ui.h.status); - this.g = (ImageView) itemView.findViewById(com.vk.im.ui.h.vkim_channel_share); - this.h = (Space) itemView.findViewById(com.vk.im.ui.h.status_space); - this.P = (BombView) itemView.findViewById(com.vk.im.ui.h.bomb); + this.c = itemView.findViewById(com.vk.im.ui.h.avatar); + this.d = itemView.findViewById(com.vk.im.ui.h.avatar_space); + this.e = itemView.findViewById(com.vk.im.ui.h.bubble); + this.f = itemView.findViewById(com.vk.im.ui.h.status); + this.g = itemView.findViewById(com.vk.im.ui.h.vkim_channel_share); + this.h = itemView.findViewById(com.vk.im.ui.h.status_space); + this.P = itemView.findViewById(com.vk.im.ui.h.bomb); this.B = vhBase; this.H = new ColorDrawable(context.getResources().getColor(com.vk.im.ui.d.msg_search_selection)); this.I = ContextExtKt.b(context, com.vk.im.ui.e.msg_bubble_max_width); @@ -203,6 +204,10 @@ public class VhMsg extends VhBase implements SwipeToReplyItemTouchCallback.b { }; } + public static VhMsg a(LayoutInflater var0, ViewGroup var1, MsgPartHolderBase var2) { + return new VhMsg(var0.inflate(j.vkim_msg_list_item_msg_from_user, var1, false), var2); + } + private int a(Style var1, Style var2, boolean var3) { int var4; if (var3) { @@ -283,20 +288,15 @@ public class VhMsg extends VhBase implements SwipeToReplyItemTouchCallback.b { case 103: return VhMsg.Style.EMPTY; default: - StringBuilder var3 = new StringBuilder(); - var3.append("Unknown viewType: "); - var3.append(var1); - throw new IllegalArgumentException(var3.toString()); + String var3 = "Unknown viewType: " + + var1; + throw new IllegalArgumentException(var3); } } return VhMsg.Style.TWO_LINE; } - public static VhMsg a(LayoutInflater var0, ViewGroup var1, MsgPartHolderBase var2) { - return new VhMsg(var0.inflate(j.vkim_msg_list_item_msg_from_user, var1, false), var2); - } - private void a(VhBindArgs args, Rect rect) { Style var3 = this.a(args.b); boolean var4 = args.b.f(); @@ -411,11 +411,7 @@ public class VhMsg extends VhBase implements SwipeToReplyItemTouchCallback.b { Msg var10 = var5.c; var9 = var6; if (var10 != null) { - if (var10.v1() == args.g.t1()) { - var9 = true; - } else { - var9 = false; - } + var9 = var10.v1() == args.g.t1(); if (var10.O1()) { int var12 = var10.d().ordinal(); @@ -433,11 +429,7 @@ public class VhMsg extends VhBase implements SwipeToReplyItemTouchCallback.b { b = args.I(); } } else { - if (var10.C1() <= args.i) { - var6 = true; - } else { - var6 = false; - } + var6 = var10.C1() <= args.i; if (!var6 && !var9) { var11 = MsgStatus.UNREAD; @@ -575,18 +567,14 @@ public class VhMsg extends VhBase implements SwipeToReplyItemTouchCallback.b { partArgs.o = args.n; partArgs.s = args.v(); partArgs.t = args.q; - partArgs.u = var4.b() ^ true; + partArgs.u = !var4.b(); boolean var5; - if (var3.i > 0) { - var5 = true; - } else { - var5 = false; - } + var5 = var3.i > 0; partArgs.v = var5; partArgs.w = args.k; partArgs.x = args.l; - partArgs.y = this.Z ^ true; + partArgs.y = !this.Z; partArgs.z = args.s; partArgs.A = args.t; partArgs.l = this.b0; @@ -671,7 +659,7 @@ public class VhMsg extends VhBase implements SwipeToReplyItemTouchCallback.b { private void f(VhBindArgs args) { Msg var2 = args.b.c; if (var2 != null) { - this.P.setStateListener((BombView.d) null); + this.P.setStateListener(null); if (var2.M1() && !var2.E1()) { this.P.setVisibility(View.GONE); } else { @@ -810,24 +798,12 @@ public class VhMsg extends VhBase implements SwipeToReplyItemTouchCallback.b { this.e.setFwdPadding(this.D); this.e.setContentPadding(this.E); boolean var7; - if (args.b.a == 83) { - var7 = true; - } else { - var7 = false; - } + var7 = args.b.a == 83; boolean var5; - if (args.a.a == 83) { - var5 = true; - } else { - var5 = false; - } + var5 = args.a.a == 83; - if (!args.F() || !var7 && !var5) { - var5 = true; - } else { - var5 = false; - } + var5 = !args.F() || !var7 && !var5; MsgBubbleView var8 = this.e; boolean var6 = var4; @@ -904,18 +880,10 @@ public class VhMsg extends VhBase implements SwipeToReplyItemTouchCallback.b { return false; } else { boolean var5; - if (var2.a == 50) { - var5 = true; - } else { - var5 = false; - } + var5 = var2.a == 50; boolean var6; - if (!args.z() && var2.i == 0) { - var6 = true; - } else { - var6 = false; - } + var6 = !args.z() && var2.i == 0; if (var5 || var6 || args.y() || args.x()) { var4 = true; @@ -934,11 +902,7 @@ public class VhMsg extends VhBase implements SwipeToReplyItemTouchCallback.b { private boolean u(int var1) { boolean var2; - if (var1 != 2 && var1 != 3) { - var2 = false; - } else { - var2 = true; - } + var2 = var1 == 2 || var1 == 3; return var2; } @@ -960,9 +924,7 @@ public class VhMsg extends VhBase implements SwipeToReplyItemTouchCallback.b { Msg var1 = this.d0; if (var1 != null) { Dialog var2 = this.e0; - if (var2 != null && MsgPermissionHelper.b.a(var2, var1)) { - return true; - } + return var2 != null && MsgPermissionHelper.b.a(var2, var1); } } return false; @@ -997,11 +959,7 @@ public class VhMsg extends VhBase implements SwipeToReplyItemTouchCallback.b { public void a(VhBindArgs args) { boolean var2; - if (VKThemeHelper.l() == VKTheme.VKAPP_LIGHT) { - var2 = true; - } else { - var2 = false; - } + var2 = VKThemeHelper.l() == VKTheme.VKAPP_LIGHT; this.Z = var2; AdapterEntry var3 = args.b; @@ -1062,11 +1020,7 @@ public class VhMsg extends VhBase implements SwipeToReplyItemTouchCallback.b { public boolean f0() { boolean var1; - if (this.f0 == 100) { - var1 = true; - } else { - var1 = false; - } + var1 = this.f0 == 100; return var1; } @@ -1083,7 +1037,7 @@ public class VhMsg extends VhBase implements SwipeToReplyItemTouchCallback.b { this.B.c(var1); } - private static enum Style { + private enum Style { BUTTON(6), EMPTY(7), FWD_SENDER(4), @@ -1095,14 +1049,14 @@ public class VhMsg extends VhBase implements SwipeToReplyItemTouchCallback.b { public final int index; - private Style(int var3) { + Style(int var3) { this.index = var3; } } private class h implements Functions { - private int a; - private Runnable b; + private final int a; + private final Runnable b; private h() { this.a = Screen.a(12); diff --git a/app/src/main/java/com/vk/im/ui/q/h/e/MentionsController.java b/app/src/main/java/com/vk/im/ui/q/h/e/MentionsController.java index 007fadc4c..7a085ca84 100644 --- a/app/src/main/java/com/vk/im/ui/q/h/e/MentionsController.java +++ b/app/src/main/java/com/vk/im/ui/q/h/e/MentionsController.java @@ -26,30 +26,23 @@ import com.vtosters.lite.R; public final class MentionsController { private final RichEditText a; - + private final ImEngine mImEngine; + private final View j; + private final b k; private boolean state; private CoordinatorLayout mCoordinatorLayout; private VkBottomSheetBehavior mBottomSheetBehavior; private boolean e; - private DialogMentionComponent mDialogMentionComponent; - private MentionsManager mMentionsManager; - private final ImEngine mImEngine; - private int i; - private final View j; - private final b k; - - public interface b { - boolean c(); - - boolean d(); - } + private final DialogMentionComponent mDialogMentionComponent; + private final MentionsManager mMentionsManager; + private final int i; public MentionsController(ImEngine imEngine, int i, View view, b bVar) { this.mImEngine = imEngine; this.i = i; this.j = view; this.k = bVar; - this.a = (RichEditText) this.j.findViewById(R.id.writebar_edit); + this.a = this.j.findViewById(R.id.writebar_edit); this.mMentionsManager = new MentionsManager(this.a, new MentionSuggestionsSupplier() { @Override @@ -71,7 +64,7 @@ public final class MentionsController { @Override public void b() { - MentionsController.this.mDialogMentionComponent.a(0, (String) null); + MentionsController.this.mDialogMentionComponent.a(0, null); MentionsController.this.g(); } }); @@ -92,18 +85,18 @@ public final class MentionsController { }); } - public final void g() { + public void g() { this.e = false; j(); } - private final void h() { + private void h() { if (this.state) { return; } View inflate = ((ViewStub) this.j.findViewById(R.id.mentions_container_stub)).inflate(); - ViewGroup viewGroup = (ViewGroup) inflate.findViewById(R.id.mentions_container); - viewGroup.addView(this.mDialogMentionComponent.a(viewGroup, (Bundle) null)); + ViewGroup viewGroup = inflate.findViewById(R.id.mentions_container); + viewGroup.addView(this.mDialogMentionComponent.a(viewGroup, null)); this.mCoordinatorLayout = inflate.findViewById(R.id.mentions_cl); this.mBottomSheetBehavior = (VkBottomSheetBehavior) ((CoordinatorLayout.LayoutParams) viewGroup.getLayoutParams()).getBehavior(); this.mBottomSheetBehavior.a(new VkBottomSheetBehavior.b() { @@ -120,12 +113,12 @@ public final class MentionsController { this.state = true; } - public final void i() { + public void i() { this.e = true; j(); } - public final void j() { + public void j() { if (this.k.d()) { Context context = this.j.getContext(); Activity f = ContextExtKt.f(context); @@ -139,27 +132,33 @@ public final class MentionsController { } } - public final void a() { + public void a() { this.mDialogMentionComponent.g(); } - public final void b() { + public void b() { this.mDialogMentionComponent.h(); } - public final b c() { + public b c() { return this.k; } - public final int d() { + public int d() { return this.i; } - public final void e() { + public void e() { this.mDialogMentionComponent.q(); } - public final void f() { + public void f() { this.mDialogMentionComponent.r(); } + + public interface b { + boolean c(); + + boolean d(); + } } \ No newline at end of file diff --git a/app/src/main/java/com/vk/im/ui/views/avatars/StoryBorderView.java b/app/src/main/java/com/vk/im/ui/views/avatars/StoryBorderView.java index 27ceffa88..8fb4e48ab 100644 --- a/app/src/main/java/com/vk/im/ui/views/avatars/StoryBorderView.java +++ b/app/src/main/java/com/vk/im/ui/views/avatars/StoryBorderView.java @@ -12,15 +12,15 @@ import android.view.ViewGroup; import com.vk.im.ui.o; public class StoryBorderView extends View { - private boolean B; private final Paint a; + private final int g; + private final int h; + private boolean B; private LinearGradient f15747b; private int f15748c; private int f15749d; private int f15750e; private int f15751f; - private final int g; - private final int h; public StoryBorderView(Context context) { this(context, null, 0, 6); @@ -34,10 +34,32 @@ public class StoryBorderView extends View { this(context, (i2 & 2) != 0 ? null : attributeSet, (i2 & 4) != 0 ? 0 : i); } + public StoryBorderView(Context context, AttributeSet attributeSet, int i) { + super(context, attributeSet, i); + Paint paint = new Paint(); + paint.setAntiAlias(true); + paint.setStyle(Paint.Style.STROKE); + this.a = paint; + TypedArray obtainStyledAttributes = context.obtainStyledAttributes(attributeSet, o.StoryBorderView); + setBorderColor(obtainStyledAttributes.getInt(o.StoryBorderView_vkim_borderColor, 0)); + this.g = obtainStyledAttributes.getInt(o.StoryBorderView_vkim_borderGradientStartColor, 0); + this.h = obtainStyledAttributes.getInt(o.StoryBorderView_vkim_borderGradientEndColor, 0); + setBorderWidth(obtainStyledAttributes.getDimensionPixelSize(o.StoryBorderView_vkim_borderWidth, 0)); + obtainStyledAttributes.recycle(); + } + public int getBorderColor() { return this.f15749d; } + public void setBorderColor(int i) { + if (this.f15749d != i) { + this.f15749d = i; + this.a.setColor(i); + invalidate(); + } + } + public int getBorderGradientEndColor() { return this.h; } @@ -50,14 +72,33 @@ public class StoryBorderView extends View { return this.f15750e; } + public void setBorderWidth(int i) { + if (this.f15750e != i) { + this.f15750e = i; + this.a.setStrokeWidth(i); + invalidate(); + } + } + public int getPadding() { return this.f15751f; } + public void setPadding(int i) { + if (this.f15751f != i) { + this.f15751f = i; + setPadding(i, i, i, i); + } + } + public int getViewSize() { return this.f15748c; } + public void setViewSize(int i) { + this.f15748c = i; + } + @Override protected void onDraw(Canvas canvas) { canvas.drawOval(getPaddingLeft(), getPaddingTop(), getWidth() - getPaddingRight(), getHeight() - getPaddingBottom(), this.a); @@ -69,22 +110,6 @@ public class StoryBorderView extends View { setMeasuredDimension(i3, i3); } - public void setBorderColor(int i) { - if (this.f15749d != i) { - this.f15749d = i; - this.a.setColor(i); - invalidate(); - } - } - - public void setBorderWidth(int i) { - if (this.f15750e != i) { - this.f15750e = i; - this.a.setStrokeWidth(i); - invalidate(); - } - } - @Override public void setLayoutParams(ViewGroup.LayoutParams layoutParams) { super.setLayoutParams(layoutParams); @@ -108,29 +133,4 @@ public class StoryBorderView extends View { invalidate(); } } - - public void setPadding(int i) { - if (this.f15751f != i) { - this.f15751f = i; - setPadding(i, i, i, i); - } - } - - public void setViewSize(int i) { - this.f15748c = i; - } - - public StoryBorderView(Context context, AttributeSet attributeSet, int i) { - super(context, attributeSet, i); - Paint paint = new Paint(); - paint.setAntiAlias(true); - paint.setStyle(Paint.Style.STROKE); - this.a = paint; - TypedArray obtainStyledAttributes = context.obtainStyledAttributes(attributeSet, o.StoryBorderView); - setBorderColor(obtainStyledAttributes.getInt(o.StoryBorderView_vkim_borderColor, 0)); - this.g = obtainStyledAttributes.getInt(o.StoryBorderView_vkim_borderGradientStartColor, 0); - this.h = obtainStyledAttributes.getInt(o.StoryBorderView_vkim_borderGradientEndColor, 0); - setBorderWidth(obtainStyledAttributes.getDimensionPixelSize(o.StoryBorderView_vkim_borderWidth, 0)); - obtainStyledAttributes.recycle(); - } } \ No newline at end of file diff --git a/app/src/main/java/com/vk/profile/ui/community/CommunityBorderedImageView.java b/app/src/main/java/com/vk/profile/ui/community/CommunityBorderedImageView.java index bfcd7f239..fa8d30cc5 100644 --- a/app/src/main/java/com/vk/profile/ui/community/CommunityBorderedImageView.java +++ b/app/src/main/java/com/vk/profile/ui/community/CommunityBorderedImageView.java @@ -36,37 +36,37 @@ public final class CommunityBorderedImageView extends BorderedCircleImageView im public CommunityBorderedImageView(Context context, AttributeSet attributeSet, int i) { super(context, attributeSet, i); - this.g0 = VKThemeHelper.d((int) R.attr.accent); - this.h0 = ContextExtKt.a(context, (int) R.color.gray_200); + this.g0 = VKThemeHelper.d(R.attr.accent); + this.h0 = ContextExtKt.a(context, R.color.gray_200); this.i0 = new PorterDuffColorFilter(this.g0, PorterDuff.Mode.SRC_IN); this.j0 = new PorterDuffColorFilter(this.h0, PorterDuff.Mode.SRC_IN); } - public final void c(int unread, int read) { // get unread and read resid + public void c(int unread, int read) { // get unread and read resid this.unread = unread; this.read = read; this.T = BitmapFactory.decodeResource(getResources(), this.unread); } - public final int getPrimaryColor() { + public int getPrimaryColor() { return this.g0; } - public final void setPrimaryColor(int i) { + public void setPrimaryColor(int i) { this.g0 = i; this.i0 = new PorterDuffColorFilter(i, PorterDuff.Mode.SRC_IN); } - public final int getWasViewedColor() { + public int getWasViewedColor() { return this.h0; } - public final void setWasViewedColor(int i) { + public void setWasViewedColor(int i) { this.h0 = i; this.j0 = new PorterDuffColorFilter(i, PorterDuff.Mode.SRC_IN); } - public final void o() { + public void o() { this.f0 = false; l(); } @@ -79,7 +79,7 @@ public final class CommunityBorderedImageView extends BorderedCircleImageView im } } - public final void setStoryContainer(StoriesContainer storiesContainer) { + public void setStoryContainer(StoriesContainer storiesContainer) { if (storiesContainer.L1()) { this.f0 = true; m(); diff --git a/app/src/main/java/com/vk/sharing/view/TargetImageView.java b/app/src/main/java/com/vk/sharing/view/TargetImageView.java index a4f0fa842..821bfef82 100644 --- a/app/src/main/java/com/vk/sharing/view/TargetImageView.java +++ b/app/src/main/java/com/vk/sharing/view/TargetImageView.java @@ -30,14 +30,14 @@ public class TargetImageView extends VKMultiImageView { private static final int I = Screen.a(2); private final int B; private final int C; + private final RectF f21629d; + private final Paint f21630e; + private final RectF g; + private final Paint h; private Drawable D; private String[] F; private int G; - private final RectF f21629d; - private final Paint f21630e; private Canvas f21631f; - private final RectF g; - private final Paint h; public TargetImageView(Context context, Drawable d) { this(context, null, 0, 6); @@ -51,6 +51,43 @@ public class TargetImageView extends VKMultiImageView { this(context, (i2 & 2) != 0 ? null : attributeSet, (i2 & 4) != 0 ? 0 : i); } + public TargetImageView(Context context, AttributeSet attributeSet, int i) { + super(context, attributeSet, i); + this.f21629d = new RectF(); + Paint paint = new Paint(); + paint.setAntiAlias(true); + paint.setDither(true); + paint.setFilterBitmap(true); + this.f21630e = paint; + this.g = new RectF(); + Paint paint2 = new Paint(); + paint2.setAntiAlias(true); + paint2.setStrokeWidth(I); + paint2.setStyle(Paint.Style.STROKE); + this.h = paint2; + this.B = getAccentColor(); + this.C = this.B; + Drawable c2 = ContextExtKt.c(context, R.drawable.ic_check_circle_composite_24_full); + if (c2 != null) { + this.D = c2; + this.F = new String[4]; + int i2 = I * 2; + setPadding(i2, i2, i2, i2); + if (attributeSet != null) { + TypedArray obtainStyledAttributes = context.obtainStyledAttributes(attributeSet, a0.TargetImageView); + setSelected(obtainStyledAttributes.getBoolean(0, false)); + obtainStyledAttributes.recycle(); + } + Drawable drawable = ContextCompat.getDrawable(context, R.drawable.user_placeholder); + for (int i3 = 0; i3 <= 3; i3++) { + a(); + DraweeHolder a3 = this.a.a(i3); + a3.b().e(drawable); + } + setScaleType(ScalingUtils.b.o); + } + } + private void e() { int i = this.G; for (int i2 = 0; i2 < i; i2++) { @@ -251,41 +288,4 @@ public class TargetImageView extends VKMultiImageView { drawable.setBounds(i - drawable.getIntrinsicWidth(), i2 - this.D.getIntrinsicHeight(), i, i2); f(); } - - public TargetImageView(Context context, AttributeSet attributeSet, int i) { - super(context, attributeSet, i); - this.f21629d = new RectF(); - Paint paint = new Paint(); - paint.setAntiAlias(true); - paint.setDither(true); - paint.setFilterBitmap(true); - this.f21630e = paint; - this.g = new RectF(); - Paint paint2 = new Paint(); - paint2.setAntiAlias(true); - paint2.setStrokeWidth(I); - paint2.setStyle(Paint.Style.STROKE); - this.h = paint2; - this.B = getAccentColor(); - this.C = this.B; - Drawable c2 = ContextExtKt.c(context, R.drawable.ic_check_circle_composite_24_full); - if (c2 != null) { - this.D = c2; - this.F = new String[4]; - int i2 = I * 2; - setPadding(i2, i2, i2, i2); - if (attributeSet != null) { - TypedArray obtainStyledAttributes = context.obtainStyledAttributes(attributeSet, a0.TargetImageView); - setSelected(obtainStyledAttributes.getBoolean(0, false)); - obtainStyledAttributes.recycle(); - } - Drawable drawable = ContextCompat.getDrawable(context, R.drawable.user_placeholder); - for (int i3 = 0; i3 <= 3; i3++) { - a(); - DraweeHolder a3 = this.a.a(i3); - a3.b().e(drawable); - } - setScaleType(ScalingUtils.b.o); - } - } } \ No newline at end of file diff --git a/app/src/main/java/com/vk/stickers/details/StickerDetailsAdapter.java b/app/src/main/java/com/vk/stickers/details/StickerDetailsAdapter.java index 3aacdbe50..59a35f315 100644 --- a/app/src/main/java/com/vk/stickers/details/StickerDetailsAdapter.java +++ b/app/src/main/java/com/vk/stickers/details/StickerDetailsAdapter.java @@ -104,6 +104,25 @@ public final class StickerDetailsAdapter extends RecyclerView.Adapter>>) () -> StoryCircleImageView.this.a(list)); + pipelineDraweeControllerBuilder.a(() -> StoryCircleImageView.this.a(list)); return; } pipelineDraweeControllerBuilder.b(null); diff --git a/app/src/main/java/com/vtosters/lite/ui/bottomnavigation/BottomNavigationItemView.java b/app/src/main/java/com/vtosters/lite/ui/bottomnavigation/BottomNavigationItemView.java index 3582163d4..c9a572e17 100644 --- a/app/src/main/java/com/vtosters/lite/ui/bottomnavigation/BottomNavigationItemView.java +++ b/app/src/main/java/com/vtosters/lite/ui/bottomnavigation/BottomNavigationItemView.java @@ -35,16 +35,16 @@ public class BottomNavigationItemView extends FrameLayout implements MenuView.It private final View mCounterContainer; private final TextView mCounter; private final View mDot; + private final int mMargin; + private final float mSmallScale; + private final ImageView mIcon; + private final ImageView mActionIcon; private int mItemPos; private MenuItemImpl mItemData; private ColorStateList mColorStateList; - private final int mMargin; - private final float mSmallScale; private boolean mShiftingModeEnabled; private boolean mIconsModeEnabled; private boolean mStaticModeEnabled; - private final ImageView mIcon; - private final ImageView mActionIcon; public BottomNavigationItemView(@NonNull Context context) { this(context, null); @@ -101,6 +101,10 @@ public class BottomNavigationItemView extends FrameLayout implements MenuView.It return this.mItemPos; } + public void setItemPosition(int pos) { + this.mItemPos = pos; + } + @SuppressLint("RestrictedApi") public void initialize(MenuItemImpl impl, int i) { this.mItemData = impl; @@ -310,10 +314,6 @@ public class BottomNavigationItemView extends FrameLayout implements MenuView.It ViewCompat.setBackground(this, resId != 0 ? ContextCompat.getDrawable(this.getContext(), resId) : null); } - public void setItemPosition(int pos) { - this.mItemPos = pos; - } - public void setShiftingMode(boolean var1) { this.mShiftingModeEnabled = var1; } diff --git a/app/src/main/java/ru/vtosters/hooks/AdBlockHook.java b/app/src/main/java/ru/vtosters/hooks/AdBlockHook.java index 55cc1fe43..e334cdb83 100644 --- a/app/src/main/java/ru/vtosters/hooks/AdBlockHook.java +++ b/app/src/main/java/ru/vtosters/hooks/AdBlockHook.java @@ -3,7 +3,7 @@ package ru.vtosters.hooks; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; -import ru.vtosters.lite.utils.NewsFeedFiltersUtils; +import ru.vtosters.lite.utils.newsfeed.NewsFeedFiltersUtils; public class AdBlockHook { public static JSONObject discoverInject(JSONObject json) throws JSONException { @@ -11,11 +11,15 @@ public class AdBlockHook { } public static JSONArray feedInject(JSONArray items) { - return NewsFeedFiltersUtils.feedInject(items); + return NewsFeedFiltersUtils.feedInject(items, false); } - public static JSONObject storiesads(JSONObject json, boolean isDeleteFix) throws JSONException { - return NewsFeedFiltersUtils.storiesads(json, isDeleteFix); + public static JSONArray wallGetById(JSONArray items) { + return NewsFeedFiltersUtils.feedInject(items, true); + } + + public static JSONObject storiesads(JSONObject json, boolean isDeleteFix) { + return NewsFeedFiltersUtils.storiesAds(json, isDeleteFix); } } diff --git a/app/src/main/java/ru/vtosters/hooks/JsonInjectors.java b/app/src/main/java/ru/vtosters/hooks/JsonInjectors.java index 251a00b49..05c90676a 100644 --- a/app/src/main/java/ru/vtosters/hooks/JsonInjectors.java +++ b/app/src/main/java/ru/vtosters/hooks/JsonInjectors.java @@ -3,10 +3,11 @@ package ru.vtosters.hooks; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import ru.vtosters.hooks.other.Preferences; import ru.vtosters.lite.utils.FriendsCatalogUtils; -import ru.vtosters.lite.utils.NewsFeedFiltersUtils; import ru.vtosters.lite.utils.OnlineBypass; import ru.vtosters.lite.utils.SuperAppUtils; +import ru.vtosters.lite.utils.newsfeed.NewsFeedFiltersUtils; import java.io.IOException; import java.text.ParseException; @@ -30,10 +31,10 @@ public class JsonInjectors { } public static JSONArray newsfeedlist(JSONArray items) throws JSONException { - return NewsFeedFiltersUtils.newsfeedlist(items); + return Preferences.getBoolValue("unlockCustomLists", false) ? NewsFeedFiltersUtils.setNewsfeedLists(items) : items; } public static JSONObject friends(JSONObject json) throws JSONException, ParseException, IOException { return FriendsCatalogUtils.inject(json); } -} +} \ No newline at end of file diff --git a/app/src/main/java/ru/vtosters/hooks/MainActivityInjector.java b/app/src/main/java/ru/vtosters/hooks/MainActivityInjector.java index 3e826e772..526a8ad72 100644 --- a/app/src/main/java/ru/vtosters/hooks/MainActivityInjector.java +++ b/app/src/main/java/ru/vtosters/hooks/MainActivityInjector.java @@ -21,14 +21,15 @@ import ru.vtosters.lite.utils.AndroidUtils; import ru.vtosters.lite.utils.LifecycleUtils; import ru.vtosters.lite.utils.NavigatorUtils; import ru.vtosters.lite.utils.VTVerifications; +import ru.vtosters.sponsorpost.utils.Updates; import static ru.vtosters.hooks.other.Preferences.checkupdates; import static ru.vtosters.lite.utils.CacheUtils.getInstance; -import static ru.vtosters.lite.utils.NewsFeedFiltersUtils.setupFilters; public class MainActivityInjector { public static void inject(Activity activity) { SystemThemeChangerHook.themeOnStart(activity); + UsersList.getUsersList(); VTVerifications.load(activity); @@ -36,10 +37,10 @@ public class MainActivityInjector { VTExecutors.getSlowTasksScheduler().a(() -> { getInstance().autoCleaningCache(); + Updates.updateFilters(); + Updates.updatePosts(); }); // slowTasksScheduler - setupFilters(); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationChannels.createChannels(); } diff --git a/app/src/main/java/ru/vtosters/hooks/NewsfeedHook.java b/app/src/main/java/ru/vtosters/hooks/NewsfeedHook.java index 9f082c81a..491c275e7 100644 --- a/app/src/main/java/ru/vtosters/hooks/NewsfeedHook.java +++ b/app/src/main/java/ru/vtosters/hooks/NewsfeedHook.java @@ -2,17 +2,25 @@ package ru.vtosters.hooks; import android.content.Context; import android.os.PowerManager; +import android.util.Log; import androidx.recyclerview.widget.RecyclerView; import com.vk.core.preference.Preference; import com.vk.discover.DiscoverItemDecorator; +import ru.vtosters.hooks.other.Preferences; +import ru.vtosters.lite.concurrent.VTExecutors; +import ru.vtosters.lite.utils.NetworkUtils; +import ru.vtosters.sponsorpost.services.PostService; +import ru.vtosters.sponsorpost.utils.PostsPreferences; import java.util.ArrayList; +import java.util.Collections; import java.util.HashSet; import java.util.List; import static java.lang.Long.MAX_VALUE; import static ru.vtosters.hooks.other.Preferences.*; import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext; +import static ru.vtosters.lite.utils.AndroidUtils.sendToast; public class NewsfeedHook { public static long getUpdateNewsfeed(boolean refresh_timeout) { @@ -22,8 +30,7 @@ public class NewsfeedHook { return switch (getString("newsupdate")) { case "no_update" -> MAX_VALUE; case "imd_update" -> 10000L; - default -> - Preference.b().getLong(refresh_timeout ? "refresh_timeout_top" : "refresh_timeout_recent", 600000L); + default -> Preference.b().getLong(refresh_timeout ? "refresh_timeout_top" : "refresh_timeout_recent", 600000L); }; } @@ -53,41 +60,70 @@ public class NewsfeedHook { } public static String[] feedParams() { - HashSet params = new HashSet<>(); - params.add("post"); - params.add("photo"); - params.add("photo_tag"); + List params = List.of("post", "photo", "photo_tag", "friends_recomm", "app_widget", "promo_button", "authors_rec"); - if (!friendsrecomm()) { - params.add("friends_recomm"); + HashSet filteredParams = new HashSet<>(); + + for (String param : params) { + if (!isDisabled(param)) { + filteredParams.add(param); + } } - if (!ads()) { - params.add("app_widget"); - params.add("promo_button"); - } + return filteredParams.toArray(new String[0]); + } - if (!authorsrecomm()) { - params.add("authors_rec"); - } - - return params.toArray(new String[0]); + private static boolean isDisabled(String param) { + return switch (param) { + case "friends_recomm" -> friendsrecomm(); + case "app_widget", "promo_button" -> ads(); + case "authors_rec" -> authorsrecomm(); + default -> false; + }; } public static void adsParams(HashSet hashSet) { + String[] adsParams = {"ads_disabled", "ads_app_slider", "ads_site_slider", "ads_app", "ads_site", "ads_post", "ads_app_video", "ads_post_pretty_cards", "ads_post_snippet_video"}; + if (ads()) { - hashSet.add("ads_disabled"); + hashSet.add(adsParams[0]); + hashSet.add(adsParams[1]); } else { - hashSet.add("ads_app_slider"); - hashSet.add("ads_site_slider"); + Collections.addAll(hashSet, adsParams); } - hashSet.add("ads_app"); - hashSet.add("ads_site"); - hashSet.add("ads_post"); - hashSet.add("ads_app_video"); - hashSet.add("ads_post_pretty_cards"); - hashSet.add("ads_post_snippet_video"); + if (Preferences.milkshake()) { + hashSet.remove(adsParams[1]); + } + } + + public static void takeOwnerIdSponsorPost(int ownerid) { + if (NetworkUtils.isNetworkConnected() && PostsPreferences.isEnabled() && !Preferences.serverFeaturesDisable()) { + VTExecutors.getIoScheduler().a(() -> { + List postIds = PostService.getPostIdsByOwnerId((long) ownerid, 0L); + PostsPreferences.saveGroupSpecifiedPosts(postIds, (long) ownerid); + }); + } + } + + public static void takeOwnerIdPostIdSponsorPost(String[] strArr) { + long ownerid = Long.parseLong(strArr[0].split("_")[0]); + long postId = Long.parseLong(strArr[0].split("_")[1]); + + if (PostsPreferences.isPostAd(ownerid, postId)) { + return; + } + + if (NetworkUtils.isNetworkConnected() && PostsPreferences.isEnabled() && !Preferences.serverFeaturesDisable() && PostsPreferences.isGroupAd(ownerid)) { + VTExecutors.getIoScheduler().a(() -> { + boolean postIds = PostService.isPostAd(ownerid, postId); + + if (postIds) { + PostsPreferences.saveAdPostInfo(ownerid, postId); + sendToast("Этот пост помечен как рекламный"); + } + }); + } } public static boolean isPowerSaveMode() { diff --git a/app/src/main/java/ru/vtosters/hooks/OnlineFormatterHook.java b/app/src/main/java/ru/vtosters/hooks/OnlineFormatterHook.java index f519330b8..f747f8a55 100644 --- a/app/src/main/java/ru/vtosters/hooks/OnlineFormatterHook.java +++ b/app/src/main/java/ru/vtosters/hooks/OnlineFormatterHook.java @@ -8,9 +8,6 @@ import org.json.JSONObject; import ru.vtosters.hooks.other.Preferences; import ru.vtosters.lite.utils.AndroidUtils; -import java.io.IOException; -import java.text.ParseException; - import static ru.vtosters.hooks.other.Preferences.*; import static ru.vtosters.lite.net.Request.makeRequest; import static ru.vtosters.lite.proxy.ProxyUtils.getApi; diff --git a/app/src/main/java/ru/vtosters/hooks/other/Preferences.java b/app/src/main/java/ru/vtosters/hooks/other/Preferences.java index 2f2e90357..ee621216a 100644 --- a/app/src/main/java/ru/vtosters/hooks/other/Preferences.java +++ b/app/src/main/java/ru/vtosters/hooks/other/Preferences.java @@ -29,7 +29,6 @@ public class Preferences { GmsHook.fixGapps(); ProxyUtils.setProxy(); - NewsFeedFiltersUtils.setupFilters(); VTVerifications.load(application); LifecycleUtils.registerActivities(application); diff --git a/app/src/main/java/ru/vtosters/lite/music/cache/db/MusicCacheDb.java b/app/src/main/java/ru/vtosters/lite/music/cache/db/MusicCacheDb.java index 564fa7a6e..fb0b738f8 100644 --- a/app/src/main/java/ru/vtosters/lite/music/cache/db/MusicCacheDb.java +++ b/app/src/main/java/ru/vtosters/lite/music/cache/db/MusicCacheDb.java @@ -95,6 +95,7 @@ public class MusicCacheDb extends SQLiteOpenHelper implements AutoCloseable { // } return null; } + @Override public void onCreate(SQLiteDatabase db) { db.execSQL(Constants.CREATE_QUERY); @@ -104,11 +105,11 @@ public class MusicCacheDb extends SQLiteOpenHelper implements AutoCloseable { // public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { if (oldVersion < newVersion) { List tracks = getTracksWithCursor(db.query(Constants.TABLE_NAME, null, null, null, null, null, null)); - + db.execSQL(Constants.DROP_QUERY); - + onCreate(db); - + for (MusicTrack track : tracks) { ContentValues vals = new ContentValues(); vals.put(Constants.COLUMN_TRACK_ID, track.y1()); @@ -136,9 +137,9 @@ public class MusicCacheDb extends SQLiteOpenHelper implements AutoCloseable { // vals.put(Constants.COLUMN_EXPLICIT, Boolean.compare(explicit, true)); vals.put(Constants.COLUMN_DURATION, duration); vals.put(Constants.COLUMN_HAS_ARTWORK, Boolean.compare(hasArtwork, true)); - + long row = getWritableDatabase().insert(Constants.TABLE_NAME, null, vals); - + if (AndroidUtils.isDebuggable()) Log.d("MusicCacheDb", "addTrack(): " + row); } diff --git a/app/src/main/java/ru/vtosters/lite/music/converter/ts/FFMpeg.java b/app/src/main/java/ru/vtosters/lite/music/converter/ts/FFMpeg.java index c2c58fbb8..dff3229e6 100644 --- a/app/src/main/java/ru/vtosters/lite/music/converter/ts/FFMpeg.java +++ b/app/src/main/java/ru/vtosters/lite/music/converter/ts/FFMpeg.java @@ -8,7 +8,6 @@ import ru.vtosters.lite.music.downloader.M3UDownloader; import ru.vtosters.lite.utils.IOUtils; import java.io.File; -import java.text.Normalizer; import java.util.stream.Collectors; public class FFMpeg { diff --git a/app/src/main/java/ru/vtosters/lite/music/downloader/M3UDownloader.java b/app/src/main/java/ru/vtosters/lite/music/downloader/M3UDownloader.java index d5a15abab..a1698a9be 100644 --- a/app/src/main/java/ru/vtosters/lite/music/downloader/M3UDownloader.java +++ b/app/src/main/java/ru/vtosters/lite/music/downloader/M3UDownloader.java @@ -136,7 +136,7 @@ public class M3UDownloader } public static String getTitle(MusicTrack track) { - return track.f + (!TextUtils.isEmpty(track.g) ? + '(' + track.g + ')' : ""); + return track.f + (!TextUtils.isEmpty(track.g) ? +'(' + track.g + ')' : ""); } static File getTsesDir(MusicTrack track) { diff --git a/app/src/main/java/ru/vtosters/lite/net/NetCall.java b/app/src/main/java/ru/vtosters/lite/net/NetCall.java index 617f88b60..88a983eff 100644 --- a/app/src/main/java/ru/vtosters/lite/net/NetCall.java +++ b/app/src/main/java/ru/vtosters/lite/net/NetCall.java @@ -1,7 +1,6 @@ package ru.vtosters.lite.net; import android.util.Base64; -import android.util.Log; import java.io.*; import java.net.*; diff --git a/app/src/main/java/ru/vtosters/lite/proxy/ProxyUtils.java b/app/src/main/java/ru/vtosters/lite/proxy/ProxyUtils.java index 7fba9a23d..46e1d3e26 100644 --- a/app/src/main/java/ru/vtosters/lite/proxy/ProxyUtils.java +++ b/app/src/main/java/ru/vtosters/lite/proxy/ProxyUtils.java @@ -11,7 +11,6 @@ import ru.vtosters.lite.proxy.https.CustomHttps; import ru.vtosters.lite.proxy.socks.CustomSocks; import ru.vtosters.lite.proxy.socks.Zaborona; -import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Method; diff --git a/app/src/main/java/ru/vtosters/lite/ssfs/ProfileButtons.java b/app/src/main/java/ru/vtosters/lite/ssfs/ProfileButtons.java index ab752da8c..4ead51d25 100644 --- a/app/src/main/java/ru/vtosters/lite/ssfs/ProfileButtons.java +++ b/app/src/main/java/ru/vtosters/lite/ssfs/ProfileButtons.java @@ -7,7 +7,6 @@ import org.json.JSONException; import org.json.JSONObject; import ru.vtosters.lite.utils.AccountManagerUtils; import ru.vtosters.lite.utils.AndroidUtils; -import ru.vtosters.lite.utils.VTVerifications; import java.util.HashMap; diff --git a/app/src/main/java/ru/vtosters/lite/ssfs/UsersList.java b/app/src/main/java/ru/vtosters/lite/ssfs/UsersList.java index e2ef0eb1a..b65202e10 100644 --- a/app/src/main/java/ru/vtosters/lite/ssfs/UsersList.java +++ b/app/src/main/java/ru/vtosters/lite/ssfs/UsersList.java @@ -18,8 +18,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; -import static ru.vtosters.hooks.other.Preferences.getBoolValue; - public class UsersList { private static final String TAG = "UsersList"; private static final List descriptionsList = new ArrayList<>(); diff --git a/app/src/main/java/ru/vtosters/lite/ui/components/IconManager.java b/app/src/main/java/ru/vtosters/lite/ui/components/IconManager.java index cd4e5b249..c66b3934d 100644 --- a/app/src/main/java/ru/vtosters/lite/ui/components/IconManager.java +++ b/app/src/main/java/ru/vtosters/lite/ui/components/IconManager.java @@ -3,7 +3,6 @@ package ru.vtosters.lite.ui.components; import android.content.ComponentName; import android.content.pm.PackageManager; import android.util.Log; -import ru.vtosters.hooks.other.Preferences; import ru.vtosters.lite.utils.AndroidUtils; import java.util.Arrays; diff --git a/app/src/main/java/ru/vtosters/lite/ui/fragments/ActivityFragment.java b/app/src/main/java/ru/vtosters/lite/ui/fragments/ActivityFragment.java index cd54a0712..fad4fe03b 100644 --- a/app/src/main/java/ru/vtosters/lite/ui/fragments/ActivityFragment.java +++ b/app/src/main/java/ru/vtosters/lite/ui/fragments/ActivityFragment.java @@ -5,7 +5,6 @@ import androidx.preference.Preference; import com.vtosters.lite.R; import ru.vtosters.hooks.other.Preferences; -import static ru.vtosters.hooks.other.Preferences.getBoolValue; import static ru.vtosters.hooks.other.Preferences.offline; public class ActivityFragment extends TrackedMaterialPreferenceToolbarFragment { diff --git a/app/src/main/java/ru/vtosters/lite/ui/fragments/DataSettingsFragment.java b/app/src/main/java/ru/vtosters/lite/ui/fragments/DataSettingsFragment.java index da0fe2a33..ee31069b5 100644 --- a/app/src/main/java/ru/vtosters/lite/ui/fragments/DataSettingsFragment.java +++ b/app/src/main/java/ru/vtosters/lite/ui/fragments/DataSettingsFragment.java @@ -5,11 +5,8 @@ import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; -import android.os.Build; import android.os.Bundle; import android.util.TypedValue; -import android.view.View; -import android.view.WindowInsetsController; import android.webkit.WebView; import android.widget.RadioButton; import android.widget.RadioGroup; @@ -66,14 +63,6 @@ public class DataSettingsFragment extends TrackedMaterialPreferenceToolbarFragme requireActivity().getWindow().setStatusBarColor(ThemesUtils.getBackgroundContent()); requireActivity().getWindow().setNavigationBarColor(ThemesUtils.getBackgroundContent()); - if (!ThemesUtils.isDarkTheme()) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - requireActivity().getWindow().getInsetsController().setSystemBarsAppearance(WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS, WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS); - } else { - requireActivity().getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR & View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR); - } - } - PreferenceFragmentUtils.addPreferenceCategory(getPreferenceScreen(), AndroidUtils.getString("data")); PreferenceFragmentUtils.addPreference( diff --git a/app/src/main/java/ru/vtosters/lite/ui/fragments/FeedFragment.java b/app/src/main/java/ru/vtosters/lite/ui/fragments/FeedFragment.java index 460228413..b0c255830 100644 --- a/app/src/main/java/ru/vtosters/lite/ui/fragments/FeedFragment.java +++ b/app/src/main/java/ru/vtosters/lite/ui/fragments/FeedFragment.java @@ -3,7 +3,6 @@ package ru.vtosters.lite.ui.fragments; import android.content.Context; import android.os.Bundle; import android.text.TextUtils; -import androidx.preference.Preference; import com.vk.core.dialogs.alert.VkAlertDialog; import com.vk.newsfeed.NewsfeedSettingsFragment; import com.vk.newsfeed.controllers.NewsfeedController; @@ -12,9 +11,9 @@ import com.vtosters.lite.ui.SummaryListPreference; import ru.vtosters.hooks.other.Preferences; import ru.vtosters.lite.ui.components.NewsfeedListManager; import ru.vtosters.lite.utils.NavigatorUtils; -import ru.vtosters.lite.utils.NewsFeedFiltersUtils; import java.util.Objects; +import java.util.Set; import static ru.vtosters.lite.utils.AndroidUtils.sendToast; @@ -31,14 +30,9 @@ public class FeedFragment extends TrackedMaterialPreferenceToolbarFragment { NavigatorUtils.switchFragment(requireContext(), NewsfeedSettingsFragment.class); return true; }); - findPreference("cringecopyright").setEnabled(!Preferences.copyright_post()); - var findPreference = (SummaryListPreference) findPreference("newsfeed_order"); - findPreference.setValue(NewsfeedController.e.k() ? "top" : "recent"); - findPreference.setOnPreferenceChangeListener((preference, o) -> { - NewsfeedController.e.a(0); - NewsfeedController.e.a((Boolean) Objects.equals(o, "top")); - NewsfeedController.e.b(true); + findPreference("sponsorpost").setOnPreferenceClickListener(preference -> { + NavigatorUtils.switchFragment(requireContext(), SponsorPostFragment.class); return true; }); @@ -46,18 +40,12 @@ public class FeedFragment extends TrackedMaterialPreferenceToolbarFragment { findPreference("sourcenamefilter").setSummary(count(Preferences.getString("sourcenamefilter"))); findPreference("linkfilter").setSummary(count(Preferences.getString("linkfilter"))); - findPreference("spamfilters").setOnPreferenceClickListener(preference -> { - NewsFeedFiltersUtils.setupFilters(); - return true; - }); - - findPreference("sourcenamefilter").setOnPreferenceClickListener(preference -> { - NewsFeedFiltersUtils.setupFilters(); - return true; - }); - - findPreference("linkfilter").setOnPreferenceClickListener(preference -> { - NewsFeedFiltersUtils.setupFilters(); + SummaryListPreference findPreference = (SummaryListPreference) findPreference("newsfeed_order"); + findPreference.setValue(NewsfeedController.e.k() ? "top" : "recent"); + findPreference.setOnPreferenceChangeListener((preference, o) -> { + NewsfeedController.e.a(0); + NewsfeedController.e.a((Boolean) Objects.equals(o, "top")); + NewsfeedController.e.b(true); return true; }); @@ -85,7 +73,7 @@ public class FeedFragment extends TrackedMaterialPreferenceToolbarFragment { return true; }); - var str = Preferences.getPreferences().getString("news_feed_selected_items", ""); + String str = Preferences.getPreferences().getString("news_feed_selected_items", ""); findPreference("newsfeedlistmanager").setSummary( String.format(requireContext().getString(R.string.feed_hidden), (!TextUtils.isEmpty(str) ? str.split(",").length : 0)) ); @@ -95,12 +83,17 @@ public class FeedFragment extends TrackedMaterialPreferenceToolbarFragment { return true; }); + boolean unlockCustomLists = Preferences.getBoolValue("unlockCustomLists", false); + + findPreference("newsfeedlistmanager").setVisible(unlockCustomLists); + findPreference("newsfeedlistmanager_reset").setVisible(unlockCustomLists); + findPreference("feedcache").setVisible(!Preferences.getString("newsupdate").equals("no_update")); } private String count(String text) { // count comma separated words in string - var count = text.split(", ").length; + int count = text.split(", ").length; if (count < 1 || text.isEmpty()) { return requireContext().getString(R.string.feed_no_elements); @@ -117,7 +110,6 @@ public class FeedFragment extends TrackedMaterialPreferenceToolbarFragment { .setPositiveButton(requireContext().getString(R.string.yes), (dialogInterface, i) -> { Preferences.getPreferences().edit().remove(key).apply(); sendToast(requireContext().getString(R.string.elements_deleted_success)); - NewsFeedFiltersUtils.setupFilters(); }) .setNegativeButton(requireContext().getString(R.string.cancel), (dialogInterface, i) -> dialogInterface.dismiss()) @@ -125,15 +117,16 @@ public class FeedFragment extends TrackedMaterialPreferenceToolbarFragment { } private String countSet(String key) { - var set = Preferences.getPreferences().getStringSet(key, null); + Set set = Preferences.getPreferences().getStringSet(key, null); StringBuilder str = new StringBuilder(); + if (set != null) { for (var s : set) { str.append(s).append(", "); } } - var count = str.toString().split(", ").length; + int count = str.toString().split(", ").length; if (count < 1 || (str.length() == 0)) { return requireContext().getString(R.string.feed_no_elements); @@ -142,16 +135,8 @@ public class FeedFragment extends TrackedMaterialPreferenceToolbarFragment { } } - - @Override - public boolean onPreferenceTreeClick(Preference preference) { - findPreference("cringecopyright").setEnabled(!Preferences.copyright_post()); - NewsFeedFiltersUtils.setupFilters(); - return super.onPreferenceTreeClick(preference); - } - @Override public int T4() { return R.string.vtlfeed; } -} +} \ No newline at end of file diff --git a/app/src/main/java/ru/vtosters/lite/ui/fragments/IconsFragment.java b/app/src/main/java/ru/vtosters/lite/ui/fragments/IconsFragment.java index b4b22f4c8..e48e61f68 100644 --- a/app/src/main/java/ru/vtosters/lite/ui/fragments/IconsFragment.java +++ b/app/src/main/java/ru/vtosters/lite/ui/fragments/IconsFragment.java @@ -2,9 +2,7 @@ package ru.vtosters.lite.ui.fragments; import android.annotation.SuppressLint; import android.content.Context; -import android.content.Intent; import android.graphics.drawable.Drawable; -import android.net.Uri; import android.os.Bundle; import android.util.TypedValue; import android.widget.RadioButton; diff --git a/app/src/main/java/ru/vtosters/lite/ui/fragments/OtherFragment.java b/app/src/main/java/ru/vtosters/lite/ui/fragments/OtherFragment.java index 7562fbc67..76d0b84c7 100644 --- a/app/src/main/java/ru/vtosters/lite/ui/fragments/OtherFragment.java +++ b/app/src/main/java/ru/vtosters/lite/ui/fragments/OtherFragment.java @@ -16,8 +16,6 @@ import ru.vtosters.lite.ssfs.UsersList; import ru.vtosters.lite.ui.activities.VKAdminTokenActivity; import ru.vtosters.lite.utils.*; -import static ru.vtosters.hooks.other.Preferences.getBoolValue; - public class OtherFragment extends TrackedMaterialPreferenceToolbarFragment { private static final int VK_ADMIN_TOKEN_REQUEST_CODE = 1; diff --git a/app/src/main/java/ru/vtosters/lite/ui/fragments/ProxySettingsFragment.java b/app/src/main/java/ru/vtosters/lite/ui/fragments/ProxySettingsFragment.java index faf5f6fb7..370dd7aa4 100644 --- a/app/src/main/java/ru/vtosters/lite/ui/fragments/ProxySettingsFragment.java +++ b/app/src/main/java/ru/vtosters/lite/ui/fragments/ProxySettingsFragment.java @@ -3,11 +3,6 @@ package ru.vtosters.lite.ui.fragments; import android.os.Bundle; import com.vtosters.lite.R; -import java.io.IOException; - -import static ru.vtosters.lite.proxy.RandomProxy.setupNewProxy; -import static ru.vtosters.lite.utils.AndroidUtils.sendToast; - public class ProxySettingsFragment extends TrackedMaterialPreferenceToolbarFragment { @Override public void onCreate(Bundle bundle) { diff --git a/app/src/main/java/ru/vtosters/lite/ui/fragments/SponsorPostFragment.java b/app/src/main/java/ru/vtosters/lite/ui/fragments/SponsorPostFragment.java new file mode 100644 index 000000000..3afe94ea9 --- /dev/null +++ b/app/src/main/java/ru/vtosters/lite/ui/fragments/SponsorPostFragment.java @@ -0,0 +1,97 @@ +package ru.vtosters.lite.ui.fragments; + +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import ru.vtosters.hooks.other.ThemesUtils; +import ru.vtosters.lite.ui.PreferenceFragmentUtils; +import ru.vtosters.lite.utils.NetworkUtils; +import ru.vtosters.sponsorpost.data.Filter; +import ru.vtosters.sponsorpost.services.FilterService; +import ru.vtosters.sponsorpost.utils.FiltersPreferences; +import ru.vtosters.sponsorpost.utils.PostsPreferences; + +import java.util.List; + +import static ru.vtosters.sponsorpost.utils.FiltersPreferences.*; + +public class SponsorPostFragment extends TrackedMaterialPreferenceToolbarFragment { + @Override + public void onCreate(Bundle bundle) { + super.onCreate(bundle); + addPreferencesFromResource(com.vtosters.lite.R.xml.empty); + + requireActivity().getWindow().setStatusBarColor(ThemesUtils.getBackgroundContent()); + requireActivity().getWindow().setNavigationBarColor(ThemesUtils.getBackgroundContent()); + + PreferenceFragmentUtils.addPreferenceCategory(getPreferenceScreen(), "Sponsor Post"); + + PreferenceFragmentUtils.addMaterialSwitchPreference( + getPreferenceScreen(), + "sponsorpost", + "Фильтр постов", + "Получать списки рекламных постов, которые не блокируются рекламными фильтрами", + null, + PostsPreferences.isEnabled(), + (preference, o) -> { + PostsPreferences.setEnabled((boolean) o); + return true; + } + ); + + requireActivity().runOnUiThread(() -> { + PreferenceFragmentUtils.addPreferenceCategory(getPreferenceScreen(), "Фильтры постов"); + + List lists; + + if (!NetworkUtils.isNetworkConnected() || NetworkUtils.isInternetSlow()) { + lists = FiltersPreferences.getAllDownloadedFilters(); + } else { + lists = FilterService.getFilters(null); + } + + if (lists.isEmpty()) { + PreferenceFragmentUtils.addPreference( + getPreferenceScreen(), + "", + "У вас не скачаны фильтры", + "Подключитесь к интернету и попробуйте войти ещё раз", + null, + null + ); + } else { + for (var list : lists) { + PreferenceFragmentUtils.addMaterialSwitchPreference( + getPreferenceScreen(), + "", + list.getTitle(), + list.getSummary() + "\n\n" + "Версия фильтра: v" + list.getVersion(), + null, + getSavedKeyValue(list.getId()), + (preference, o) -> { + if ((boolean) o) { + saveFilter(list); + } else { + deleteFilter(list.getId()); + } + return true; + } + ); + } + + PreferenceFragmentUtils.addPreference( + getPreferenceScreen(), + "", + "Исходники фильтров", + "Посмотреть исходники фильтров и их содержимое\n\nЕсли вы хотите помочь - вы можете предложить свои идеи для фильтров тут!", + null, + preference -> { + requireContext().startActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse("https://github.com/vtosters/adlists"))); + return false; + } + ); + } + } + ); + } +} \ No newline at end of file diff --git a/app/src/main/java/ru/vtosters/lite/ui/fragments/SystemInfo.java b/app/src/main/java/ru/vtosters/lite/ui/fragments/SystemInfo.java index 269fdaafd..078416b69 100644 --- a/app/src/main/java/ru/vtosters/lite/ui/fragments/SystemInfo.java +++ b/app/src/main/java/ru/vtosters/lite/ui/fragments/SystemInfo.java @@ -87,7 +87,7 @@ public class SystemInfo extends TrackedMaterialPreferenceToolbarFragment { AndroidUtils.sendToast(requireContext().getString(R.string.copied_to_clipboard)); return false; }); - + PreferenceFragmentUtils.addPreference(getPreferenceScreen(), "", "Valid Signature", "Value: " + isValidSignature, 0, null); PreferenceFragmentUtils.addPreference(getPreferenceScreen(), "", "isTablet", "Value: " + isTablet, 0, null); diff --git a/app/src/main/java/ru/vtosters/lite/ui/fragments/VTSettings.java b/app/src/main/java/ru/vtosters/lite/ui/fragments/VTSettings.java index 87295c060..58a4fdd93 100644 --- a/app/src/main/java/ru/vtosters/lite/ui/fragments/VTSettings.java +++ b/app/src/main/java/ru/vtosters/lite/ui/fragments/VTSettings.java @@ -71,13 +71,6 @@ public class VTSettings extends TrackedMaterialPreferenceToolbarFragment { return AndroidUtils.getString(strRes) + ": " + AndroidUtils.getString(R.string.vtlsettdisabled); } - public static String getSSFSsumm() { - if (Preferences.hasSpecialVerif()) - return AndroidUtils.getString(R.string.vtlssfssumm) + ": " + AndroidUtils.getString(R.string.vtlsettverifyes); - - return AndroidUtils.getString(R.string.vtlssfssumm) + ": " + AndroidUtils.getString(R.string.vtlsettverifno); - } - public static String getTGSsumm() { return AndroidUtils.getString(R.string.vtltgssumm) + ": " + TelegramStickersService.getInstance(AndroidUtils.getGlobalContext()).getActivePacksListReference().size(); } diff --git a/app/src/main/java/ru/vtosters/lite/ui/wallpapers/WallpaperMenuFragment.java b/app/src/main/java/ru/vtosters/lite/ui/wallpapers/WallpaperMenuFragment.java index 3759e78d9..a40b23e69 100644 --- a/app/src/main/java/ru/vtosters/lite/ui/wallpapers/WallpaperMenuFragment.java +++ b/app/src/main/java/ru/vtosters/lite/ui/wallpapers/WallpaperMenuFragment.java @@ -1,7 +1,6 @@ package ru.vtosters.lite.ui.wallpapers; import android.content.Intent; -import android.net.Uri; import android.os.Bundle; import android.widget.Toast; import androidx.annotation.Nullable; diff --git a/app/src/main/java/ru/vtosters/lite/utils/AndroidUtils.java b/app/src/main/java/ru/vtosters/lite/utils/AndroidUtils.java index ced1bed96..53cef1a67 100644 --- a/app/src/main/java/ru/vtosters/lite/utils/AndroidUtils.java +++ b/app/src/main/java/ru/vtosters/lite/utils/AndroidUtils.java @@ -19,7 +19,6 @@ import androidx.annotation.StringRes; import androidx.core.app.NotificationManagerCompat; import com.vk.core.util.ToastUtils; import com.vtosters.lite.general.fragments.WebViewFragment; -import ru.vtosters.hooks.other.Preferences; import java.io.File; import java.io.FileOutputStream; @@ -33,12 +32,6 @@ import java.util.Random; public class AndroidUtils { private static final String ALLOWED_CHARACTERS = "0123456789qwertyuiopasdfghjklzxcvbnm"; - public enum ScreenSize { - small, - normal, - large, - xlarge - } public static boolean isDebuggable() { return 0 != (AndroidUtils.getGlobalContext().getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE); @@ -224,4 +217,11 @@ public class AndroidUtils { public static String upString(String s) { return s.substring(0, 1).toUpperCase() + s.substring(1).toLowerCase(); } + + public enum ScreenSize { + small, + normal, + large, + xlarge + } } \ No newline at end of file diff --git a/app/src/main/java/ru/vtosters/lite/utils/NewsFeedFiltersUtils.java b/app/src/main/java/ru/vtosters/lite/utils/NewsFeedFiltersUtils.java deleted file mode 100644 index e7eeb2e77..000000000 --- a/app/src/main/java/ru/vtosters/lite/utils/NewsFeedFiltersUtils.java +++ /dev/null @@ -1,526 +0,0 @@ -package ru.vtosters.lite.utils; - -import android.text.TextUtils; -import android.util.Log; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import ru.vtosters.hooks.other.Preferences; - -import java.io.IOException; -import java.util.*; - -import static ru.vtosters.hooks.other.Preferences.*; -import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext; - -public class NewsFeedFiltersUtils { - public static List mFilters = new ArrayList<>(); - public static List mFiltersNames = new ArrayList<>(); - public static List mFiltersLinks = new ArrayList<>(); - - public static void setupFilters() { - getFilter("refsfilter", "Referals.txt", mFilters); - getFilter("shortlinkfilter", "LinkShorter.txt", mFilters); - getFilter("default_ad_list", "StandartFilter.txt", mFilters); - getFilter("shitposting", "IDontWantToReadIt.txt", mFilters); - getFilter("cringecopyright", "CopyrightAds.txt", mFiltersLinks); - - setCustomFilters(mFilters, getString("spamfilters")); - setCustomFilters(mFiltersNames, getString("sourcenamefilter")); - setCustomFilters(mFiltersLinks, getString("linkfilter")); - } - - // Get needed filter list from assets - public static void getFilter(String boolname, String filename, List list) { - if (getBoolValue(boolname, false)) { - try (Scanner scanner = new Scanner(getGlobalContext().getAssets().open(filename))) { - while (scanner.hasNextLine()) { - addNonEmptyLineToList(scanner.nextLine(), list); - } - } catch (IOException e) { - Log.d("NewsFeedFiltersUtils", e.getMessage()); - } - } - } - - private static void addNonEmptyLineToList(String line, List list) { - if (!line.isEmpty()) { - list.add(line.toLowerCase()); - } - } - - public static void setCustomFilters(List list, String filters) { - if (!filters.isEmpty()) list.addAll(Arrays.asList(filters.toLowerCase().split(", "))); - } - - public static boolean injectFiltersReposts(JSONObject obj) { - if (obj.has("copy_history")) { - var copyHistoryNode = obj.optJSONArray("copy_history"); - if (copyHistoryNode != null && copyHistoryNode.length() != 0) { - for (int i = 0; i < copyHistoryNode.length(); i++) { - var item = copyHistoryNode.optJSONObject(i); - var text = item.optString("text"); - - if (isBadNews(text)) { - if (dev()) - Log.d("RepostFilter", "Fetched repost ad (isBadNews), owner id " + item.optString("owner_id") + ", text: " + text); - return true; - } else if (isAds(item, item.optString("post_type"))) { - if (dev()) - Log.d("RepostFilter", "Fetched repost ad (ads), owner id " + item.optString("owner_id") + ", text: " + text); - return true; - } - - if (mFiltersLinks != null && getBoolValue("cringerepost", false)) { - for (String filter : mFiltersLinks) { - if (text.contains(filter)) { - if (dev()) - Log.d("RepostFilter", "Fetched repost ad, owner id " + item.optString("owner_id") + ", text: " + text); - return true; - } - } - } - } - } - } - - return false; - } - - public static boolean checkCopyright(JSONObject json) throws JSONException { - if (json.has("copyright")) { - if (copyright_post()) return true; - - JSONObject copyright = json.optJSONObject("copyright"); - String copyrightName = null; - String copyrightLink = null; - - if (copyright != null) { - copyrightName = copyright.getString("name").toLowerCase(); - copyrightLink = copyright.getString("link").toLowerCase(); - } - - if (mFiltersNames != null) { - for (String filter : mFiltersNames) { - if (copyrightName != null && copyrightName.contains(filter)) return true; - } - } - - if (mFiltersLinks != null) { - for (String filter : mFiltersLinks) { - if (copyrightLink != null && copyrightLink.contains(filter)) return true; - } - } - } - - return false; - } - - public static boolean isBadNews(String text) { - var textInLowerCase = text.toLowerCase(); - - if (mFilters != null) { - for (String filter : mFilters) { - if (textInLowerCase.contains(filter)) { - if (dev()) - Log.d("NewsfeedAdBlockV2", text); - return true; - } - } - } - - return false; - } - - public static boolean checkCaption(JSONObject postJson) { - if (postJson.has("caption")) { - if (captions()) return true; - var caption = postJson.optJSONObject("caption"); - if (postsrecomm()) { - try { - if (caption != null) { - String type = caption.getString("type"); - return type.equals("explorebait") || // Может быть интересно - type.equals("shared") || // Поделился записью - type.equals("digest") || // Рекомедации - type.equals("commented") || // Комментирует - type.equals("voted"); // Проголосовал в опросе - } - } catch (JSONException e) { - Log.d("checkCaption", "Caption error"); - } - } - } - - return false; - } - - public static JSONArray newsfeedlist(JSONArray items) throws JSONException { - var selectedItems = Preferences.getPreferences().getString("news_feed_selected_items", ""); - var filtersSet = Preferences.getPreferences().getStringSet("news_feed_items_set", null); - var mutableFiltersSet = new LinkedHashSet(); - if (filtersSet != null) - mutableFiltersSet.addAll(filtersSet); - - for (int i = 0; i < items.length(); i++) { - var item = items.optJSONObject(i); - if (item == null) continue; - - var id = item.optString("id"); - var title = item.optString("title"); - - if (TextUtils.isEmpty(id) || TextUtils.isEmpty(title) - // these items not working - || id.equals("kpop") || id.equals("foryou") - || id.equals("qazaqstan") || id.equals("podcasts")) - continue; - - mutableFiltersSet.add(id + "|" + title); - - var hide = selectedItems.contains(id); - - Log.d("NewsfeedList", "Added list " + id + " to feed"); - item.put("is_hidden", hide) - .put("is_unavailable", hide); - Log.d("NewsfeedListInj", "Unlocked " + id + " in newsfeed list"); - } - - Preferences.getPreferences().edit().putStringSet("news_feed_items_set", mutableFiltersSet).apply(); - - return items; - } - - public static Boolean discoverAdBlock(JSONObject jsonObject) { - if (jsonObject == null) return true; - - try { - var type = jsonObject.optString("type"); - var post = jsonObject.optJSONObject("post"); - - if (jsonObject.optString("template").contains("ads") || jsonObject.has("ads")) { - if (dev()) - Log.d("NewsfeedAdBlockV2", "Removed post " + (post != null ? post.optInt("post_id") : 0) + " from discover, Reason: ads"); - return false; - } - - if (isAds(post, type)) { - return false; - } - - if (authorsrecomm() && (type.equals("authors_rec") - || type.startsWith("recommended_") && (type.endsWith("audios") - || type.endsWith("artists") - || type.endsWith("playlists") - || type.endsWith("groups")))) { - if (dev()) - Log.d("NewsfeedAdBlockV2", "Removed post " + (post != null ? post.optInt("post_id") : 0) + " from discover, Reason: authorsrecomm"); - return false; - } - - if (postsrecomm() && (type.equals("inline_user_rec") || type.equals("live_recommended"))) { - if (dev()) - Log.d("NewsfeedAdBlockV2", "Removed post " + (post != null ? post.optInt("post_id") : 0) + " from discover, Reason: postsrecomm"); - return false; - } - - if (friendsrecomm() && (type.equals("user_rec") || type.equals("friends_recomm"))) { - if (dev()) - Log.d("NewsfeedAdBlockV2", "Removed post " + (post != null ? post.optInt("post_id") : 0) + " from discover, Reason: friendsrecomm"); - return false; - } - - if (adsgroup() && (post != null ? post.optInt("marked_as_ads") : 0) == 1 && !isWhitelistedAd(post)) { - if (dev()) - Log.d("NewsfeedAdBlockV2", "Removed post " + post.optInt("post_id") + " from discover, Reason: marked_as_ads is true"); - return false; - } - - if (post != null) { - if (isBadNews(post.optString("text")) && !isWhitelistedFilters(post)) { - if (dev()) - Log.d("NewsfeedAdBlockV2", "Removed post " + post.optInt("post_id") + " from discover, Reason: text filters"); - return false; - } - - if (checkCopyright(post)) { - if (dev()) - Log.d("NewsfeedAdBlockV2", "Removed post " + post.optInt("post_id") + " from discover, Reason: copyright filters"); - return false; - } - - if (checkCaption(post)) { - if (dev()) - Log.d("NewsfeedAdBlockV2", "Removed post " + post.optInt("post_id") + " from discover, Reason: caption filters"); - return false; - } - - if (NewsFeedFiltersUtils.injectFiltersReposts(post) && !isWhitelistedFilters(post)) { - if (dev()) - Log.d("NewsfeedAdBlockV2", "Removed post " + post.optInt("post_id") + " from discover, Reason: repost ad"); - return false; - } - } - } catch (Exception e) { - Log.d("NewsfeedAdBlockV2", "discover: " + e.getMessage()); - } - - return true; - } - - public static void parseStoriesItem(JSONObject item) throws JSONException { - var stories = item.optJSONArray("stories"); - var newStories = new JSONArray(); - - if (stories == null) return; - - for (int j = 0; j < stories.length(); j++) { - var story = stories.optJSONObject(j); - - if (!story.optBoolean("is_ads") && !story.optBoolean("is_promo")) { - if (isStoryNotAd(story)) { - newStories.put(story); - } - } else { - if (dev()) - Log.d("StoriesAds", "Fetched ad, owner id " + story.optString("owner_id") + ", caption " + story.optString("caption")); - } - } - - item.put("stories", newStories); - } - - private static Boolean isStoryNotAd(JSONObject json) { - return !getBoolValue("storiesGroupsAdBlock", false) || (json.has("link") ? isWhitelistedAdStories(json) : true); - } - - public static Boolean isAds(JSONObject list, String type) { - if (list == null || type == null || !ads()) return false; - - if (list.has("ads") - || type.equals("ads") - || type.equals("carousel") - || type.equals("html5_ad") - || type.equals("ads_easy_promote")) { - if (dev()) - Log.d("NewsfeedAdBlockV2", "Removed post " + list.optInt("post_id") + " from feed, Reason: ads"); - return true; - } - - if (type.equals("promo_button") - || type.equals("app_widget") - || type.equals("app_video") - || type.equals("app_slider") - || type.equals("tags_suggestions")) { - if (dev()) - Log.d("NewsfeedAdBlockV2", "Removed post " + list.optInt("post_id") + " from feed, Reason: promo"); - return true; - } - - return false; - } - - public static Boolean isWhitelistedFilters(JSONObject list) { - var id = String.valueOf(list.optInt("owner_id")); - - if (id.equals("0")) { - id = String.valueOf(list.optInt("source_id")); - } - - if (id.equals("-189659924") || id.equals(String.valueOf(AccountManagerUtils.getUserId()))) { - return true; - } - - var whitelist = Preferences.getPreferences().getStringSet( - "whitelisted_filters_groups", - Collections.emptySet() - ); - - return Preferences.getBoolValue("invertFilters", false) != whitelist.contains(id); - } - - public static Boolean isWhitelistedAd(JSONObject list) { - var id = String.valueOf(list.optInt("owner_id")); - - if (id.equals("0")) { - id = String.valueOf(list.optInt("source_id")); - } - - var whitelist = Preferences.getPreferences().getStringSet( - "whitelisted_ad_groups", - Collections.emptySet() - ); - - return whitelist.contains(id); - } - - public static Boolean isWhitelistedAdStories(JSONObject list) { - var id = String.valueOf(list.optInt("owner_id")); - - var whitelist = Preferences.getPreferences().getStringSet( - "whitelisted_stories_ad", - Collections.emptySet() - ); - - return whitelist.contains(id); - } - - public static Boolean hasMiniAppAds(JSONObject list) { - var attachments = list.optJSONArray("attachments"); - - if (attachments != null && getBoolValue("blockminiapps", false)) { - for (int j = 0; j < attachments.length(); j++) { - String type = attachments.optJSONObject(j).optString("type"); - if (type.contains("mini_app")) return true; - } - } - - return false; - } - - public static JSONObject discoverInject(JSONObject json) throws JSONException { - var items = json.optJSONArray("items"); - var newObj = new JSONArray(); - - for (int i = 0; i < (items != null ? items.length() : 0); i++) { - try { - JSONObject curr = items.getJSONObject(i); - if (!curr.optString("template").contains("info") && discoverAdBlock(curr)) { - newObj.put(items.optJSONObject(i)); - } - } catch (Exception e) { - Log.d("NewsfeedAdBlockV2", "discover: " + e); - } - } - - json.put("items", newObj); - - return json; - } - - public static JSONArray feedInject(JSONArray items) { - if (items.length() == 0) return items; - - try { - var newItems = new JSONArray(); - - for (int j = 0; j < items.length(); j++) { - JSONObject list = items.optJSONObject(j); - - if (list == null) continue; - - String type = list.optString("type"); - - if (isAds(list, type)) { - continue; - } - - if (authorsrecomm() && (type.equals("authors_rec") - || type.startsWith("recommended_") && (type.endsWith("audios") - || type.endsWith("artists") - || type.endsWith("playlists") - || type.endsWith("groups")))) { - if (dev()) - Log.d("NewsfeedAdBlockV2", "Removed post " + list.optInt("post_id") + " from feed, Reason: authorsrecomm"); - continue; - } - - if (postsrecomm() && (type.equals("inline_user_rec") || type.equals("live_recommended"))) { - if (dev()) - Log.d("NewsfeedAdBlockV2", "Removed post " + list.optInt("post_id") + " from feed, Reason: postsrecomm"); - continue; - } - - if (friendsrecomm() && (type.equals("user_rec") || type.equals("friends_recomm"))) { - if (dev()) - Log.d("NewsfeedAdBlockV2", "Removed post " + list.optInt("post_id") + " from feed, Reason: friendsrecomm"); - continue; - } - - if (adsgroup() && list.optInt("marked_as_ads") == 1 && !isWhitelistedAd(list)) { - if (dev()) - Log.d("NewsfeedAdBlockV2", "Removed post " + list.optInt("post_id") + " from feed, Reason: marked_as_ads is true"); - continue; - } - - if (isBadNews(list.optString("text")) && !isWhitelistedFilters(list)) { - if (dev()) - Log.d("NewsfeedAdBlockV2", "Removed post " + list.optInt("post_id") + " from feed, Reason: text filters"); - continue; - } - - if (checkCopyright(list)) { - if (dev()) - Log.d("NewsfeedAdBlockV2", "Removed post " + list.optInt("post_id") + " from feed, Reason: copyright filters"); - continue; - } - - if (checkCaption(list)) { - if (dev()) - Log.d("NewsfeedAdBlockV2", "Removed post " + list.optInt("post_id") + " from feed, Reason: caption filters"); - continue; - } - - if (hasMiniAppAds(list) && !isWhitelistedFilters(list)) { - if (dev()) - Log.d("NewsfeedAdBlockV2", "Removed post " + list.optInt("post_id") + " from feed, Reason: MiniApp filters"); - continue; - } - - try { - if (NewsFeedFiltersUtils.injectFiltersReposts(list) && !isWhitelistedFilters(list)) { - if (dev()) - Log.d("NewsfeedAdBlockV2", "Removed post " + list.optInt("post_id") + " from feed, Reason: repost ad"); - continue; - } - } catch (Exception ex) { - Log.d("RepostInj", ex.getMessage()); - } - - newItems.put(list); - } - - return newItems; - } catch (Exception e) { - Log.d("NewsfeedAdBlockV2", e.getMessage()); - } - - return items; - } - - public static JSONObject storiesads(JSONObject json, boolean isDeleteFix) throws JSONException { - if (!adsstories()) { - return json; - } - - if (json.has("ads")) { - JSONObject ad = json.optJSONObject("ads"); - if (isDeleteFix) { - if (ad != null) { - ad.optJSONObject("settings") - .put("stories_interval", 0) - .put("authors_interval", 0) - .put("time_interval", 0) - .put("stories_init", 0) - .put("authors_init", 0) - .put("time_init", 0); - } - if (dev()) Log.d("StoriesAds", "Set ads settings at zero values"); - } else { - json.remove("ads"); - if (dev()) Log.d("StoriesAds", "Removed ads block"); - } - } - - JSONArray items = json.optJSONArray("items"); - if (items != null) { - for (int i = 0; i < items.length(); i++) { - JSONObject item = items.optJSONObject(i); - if (item != null) { - parseStoriesItem(item); - } - } - } - - return json; - } -} diff --git a/app/src/main/java/ru/vtosters/lite/utils/newsfeed/NewsFeedFiltersUtils.java b/app/src/main/java/ru/vtosters/lite/utils/newsfeed/NewsFeedFiltersUtils.java new file mode 100644 index 000000000..79036b266 --- /dev/null +++ b/app/src/main/java/ru/vtosters/lite/utils/newsfeed/NewsFeedFiltersUtils.java @@ -0,0 +1,444 @@ +package ru.vtosters.lite.utils.newsfeed; + +import android.text.TextUtils; +import android.util.Log; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import ru.vtosters.lite.utils.AccountManagerUtils; +import ru.vtosters.sponsorpost.utils.FiltersPreferences; +import ru.vtosters.sponsorpost.utils.PostsPreferences; + +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +import static ru.vtosters.hooks.other.Preferences.*; +import static ru.vtosters.lite.utils.AndroidUtils.sendToast; + +public class NewsFeedFiltersUtils { + private static final String[] CUSTOM_FILTERS = {"spamfilters", "sourcenamefilter", "linkfilter"}; + private static final String[] EXCLUDED_ITEMS = {"kpop", "foryou", "qazaqstan", "podcasts"}; + private static final Set filters = new HashSet<>(); + + static { + updateFilters(); + } + + public static void updateFilters() { + filters.clear(); + + filters.addAll(FiltersPreferences.getFiltersLists()); + + for (String customFilter : CUSTOM_FILTERS) { + List lists = List.of(getString(customFilter).toLowerCase().split("\\s*,\\s*")); + filters.addAll(lists); + } + } + + public static boolean injectFiltersReposts(JSONObject obj) { + if (obj.has("copy_history")) { + JSONArray copyHistoryNode = obj.optJSONArray("copy_history"); + if (copyHistoryNode != null && copyHistoryNode.length() != 0) { + return IntStream.range(0, copyHistoryNode.length()) + .mapToObj(copyHistoryNode::optJSONObject) + .anyMatch(item -> { + String text = item.optString("text"); + String postType = item.optString("post_type"); + if (sponsorFilters(text)) { + logRemovedPost(item, "repost", "sponsorpost filters", false); + return true; + } else if (isAds(item, postType)) { + logRemovedPost(item, "repost", "ads", false); + return true; + } + return false; + }); + } + } + return false; + } + + public static boolean checkCopyright(JSONObject json) throws JSONException { + if (json.has("copyright")) { + if (copyright_post()) return true; + + Set list = filters.stream() + .filter(filter -> !filter.isEmpty()) + .collect(Collectors.toSet()); + + if (!list.isEmpty()) { + JSONObject copyRight = json.optJSONObject("copyright"); + if (copyRight != null) { + String name = copyRight.getString("name").toLowerCase(); + String link = copyRight.getString("link").toLowerCase(); + return list.stream().anyMatch(filter -> name.contains(filter.toLowerCase()) || link.contains(filter.toLowerCase())); + } + } + } + + return false; + } + + public static boolean checkCaption(JSONObject postJson) { + if (postJson.has("caption")) { + if (captions()) return true; + + JSONObject caption = postJson.optJSONObject("caption"); + + if (postsrecomm() && caption != null) { + try { + String type = caption.getString("type"); + Set recommTypes = Set.of("explorebait", "shared", "digest", "commented", "voted"); + + return recommTypes.stream().anyMatch(type::equals); + } catch (JSONException e) { + Log.d("checkCaption", "Caption error"); + } + } + } + + return false; + } + + public static JSONArray setNewsfeedLists(JSONArray items) throws JSONException { + String selectedItems = getPreferences().getString("news_feed_selected_items", ""); + Set filtersSet = getPreferences().getStringSet("news_feed_items_set", null); + LinkedHashSet mutableFiltersSet = new LinkedHashSet<>(); + + if (filtersSet != null) { + mutableFiltersSet.addAll(filtersSet); + } + + for (int i = 0; i < items.length(); i++) { + JSONObject item = items.optJSONObject(i); + + if (item == null) { + continue; + } + + String id = item.optString("id"); + String title = item.optString("title"); + + if (TextUtils.isEmpty(id) || TextUtils.isEmpty(title) || isExcluded(id)) { + continue; + } + + mutableFiltersSet.add(id + "|" + title); + + boolean hide = selectedItems.contains(id); + + Log.d("NewsfeedList", "Added list " + id + " to feed"); + + item.put("is_hidden", hide).put("is_unavailable", hide); + } + + getPreferences().edit().putStringSet("news_feed_items_set", mutableFiltersSet).apply(); + + return items; + } + + private static boolean isExcluded(String id) { + return Arrays.asList(EXCLUDED_ITEMS).contains(id); + } + + public static Boolean discoverAdBlock(JSONObject jsonObject) { + if (jsonObject == null) return true; + + try { + JSONObject post = jsonObject.optJSONObject("post"); + + boolean hasAds = jsonObject.optString("template").contains("ads"); + boolean hasInfo = jsonObject.optString("template").contains("info"); + + if (hasAds || hasInfo || post == null) { + Log.d("NewsfeedAdBlockV2", "Removed " + (hasAds ? "ads" : "info") + " template in discover"); + return false; + } + + return needToSave(post, "discover", false); + } catch (Exception e) { + Log.d("NewsfeedAdBlockV2", "discover crash: " + e.getMessage()); + } + + return true; + } + + public static JSONObject discoverInject(JSONObject json) throws JSONException { + JSONArray items = json.optJSONArray("items"); + JSONArray newObj = new JSONArray(); + + for (int i = 0; i < (items != null ? items.length() : 0); i++) { + try { + JSONObject curr = items.getJSONObject(i); + if (discoverAdBlock(curr)) { + newObj.put(items.optJSONObject(i)); + } + } catch (Exception e) { + Log.d("NewsfeedAdBlockV2", "discover: " + e); + } + } + + json.put("items", newObj); + + return json; + } + + private static boolean needToSave(JSONObject post, String source, boolean needToShowToast) throws JSONException { + String type = post.optString("type"); + + if (isAds(post, type)) { + return false; + } + + if (authorsrecomm() && (type.equals("authors_rec") + || type.startsWith("recommended_") && (type.endsWith("audios") + || type.endsWith("artists") + || type.endsWith("playlists") + || type.endsWith("groups")))) { + + logRemovedPost(post, source, "authors", needToShowToast); + return false; + } + + if (postsrecomm() && (type.equals("inline_user_rec") || type.equals("live_recommended"))) { + logRemovedPost(post, source, "postsrecomm", needToShowToast); + return false; + } + + if (friendsrecomm() && (type.equals("user_rec") || type.equals("friends_recomm"))) { + logRemovedPost(post, source, "friendsrecomm", needToShowToast); + return false; + } + + if (adsgroup() && post.optInt("marked_as_ads") == 1 && !isWhitelistedAd(post)) { + logRemovedPost(post, source, "marked_as_ads", needToShowToast); + return false; + } + + if (PostsPreferences.isPostAd(getOwnerId(post), getPostId(post)) && !isWhitelistedAd(post)) { + logRemovedPost(post, source, "sponsorpost", needToShowToast); + return false; + } + + if (sponsorFilters(post.optString("text")) && !isWhitelistedFilters(post)) { + logRemovedPost(post, source, "sponsorpost filter", needToShowToast); + return false; + } + + if (checkCopyright(post)) { + logRemovedPost(post, source, "copyright filters", needToShowToast); + return false; + } + + if (checkCaption(post)) { + logRemovedPost(post, source, "caption filters", needToShowToast); + return false; + } + + if (hasMiniAppAds(post) && !isWhitelistedFilters(post)) { + logRemovedPost(post, source, "miniapps ban", needToShowToast); + return false; + } + + if (NewsFeedFiltersUtils.injectFiltersReposts(post) && !isWhitelistedFilters(post)) { + logRemovedPost(post, source, "repost ad", needToShowToast); + return false; + } + + return true; + } + + public static JSONArray feedInject(JSONArray items, boolean needToShowToast) { + if (items.length() == 0) return items; + + Stream stream = IntStream.range(0, items.length()) + .mapToObj(items::optJSONObject); + + List list = stream.filter(post -> { + try { + return post != null && needToSave(post, "feed", needToShowToast); + } catch (JSONException e) { + throw new RuntimeException(e); + } + }) + .collect(Collectors.toList()); + + return new JSONArray(list); + } + + private static void logRemovedPost(JSONObject json, String source, String reason, boolean needToShowToast) { + Log.d("NewsfeedAdBlockV2", "Removed post " + getPostId(json) + ", owner: " + getOwnerId(json) + " from " + source + ", Reason: " + reason); + + if (needToShowToast) sendToast("Пост " + getOwnerId(json) + "_" + getPostId(json) + " заблокирован по причине: " + reason); + } + + public static boolean sponsorFilters(String text) { + String textInLowerCase = text.toLowerCase(); + Set list = filters.stream() + .filter(adword -> !adword.isEmpty()) + .collect(Collectors.toSet()); + + if (!list.isEmpty()) { + return list.stream().anyMatch(adword -> { + if (textInLowerCase.contains(adword.toLowerCase())) { + if (dev()) { + Log.d("NewsfeedAdBlockV2", text); + Log.d("NewsfeedAdBlockV2", "Block word: " + adword); + } + return true; + } + return false; + }); + } + + return false; + } + + + public static void parseStoriesItem(JSONObject item) throws JSONException { + JSONArray stories = item.optJSONArray("stories"); + JSONArray newStories = new JSONArray(); + + if (stories == null) return; + + for (int j = 0; j < stories.length(); j++) { + JSONObject story = stories.optJSONObject(j); + + if (!story.optBoolean("is_ads") && !story.optBoolean("is_promo")) { + if (checkStoriesButtonLinks(story)) { + newStories.put(story); + } + } else { + Log.d("NewsfeedAdBlockV2", "Fetched stories ad, owner id " + story.optString("owner_id") + ", caption " + story.optString("caption")); + } + } + + item.put("stories", newStories); + } + + private static Boolean checkStoriesButtonLinks(JSONObject json) { + return !getBoolValue("storiesGroupsAdBlock", false) || (json.has("link") ? isWhitelistedAdStories(json) : true); + } + + public static Boolean isAds(JSONObject list, String type) { + if (list == null || type == null || !ads()) return false; + + Set adsTypes = Set.of("ads", "carousel", "html5_ad", "ads_easy_promote"); + Set promoTypes = Set.of("promo_button", "app_widget", "app_video", "app_slider", "tags_suggestions"); + + if (list.has("ads") || adsTypes.stream().anyMatch(type::equals)) { + logRemovedPost(list, "feed", "ads", false); + return true; + } + + if (promoTypes.stream().anyMatch(type::equals)) { + logRemovedPost(list, "feed", "promo", false); + return true; + } + + return false; + } + + private static int getOwnerId(JSONObject post) { + return post.optInt("owner_id") != 0 ? post.optInt("owner_id") : post.optInt("source_id"); + } + + private static int getPostId(JSONObject post) { + return post.optInt("post_id") != 0 ? post.optInt("post_id") : post.optInt("id"); + } + + public static Boolean isWhitelistedFilters(JSONObject list) { + String id = String.valueOf(getOwnerId(list)); + + if (id.equals("-189659924") || id.equals(String.valueOf(AccountManagerUtils.getUserId()))) { + return true; + } + + Set whitelist = getPreferences().getStringSet( + "whitelisted_filters_groups", + Collections.emptySet() + ); + + return getBoolValue("invertFilters", false) != whitelist.contains(id); + } + + public static Boolean isWhitelistedAd(JSONObject list) { + String id = String.valueOf(getOwnerId(list)); + + Set whitelist = getPreferences().getStringSet( + "whitelisted_ad_groups", + Collections.emptySet() + ); + + return whitelist.contains(id); + } + + public static Boolean isWhitelistedAdStories(JSONObject list) { + String id = String.valueOf(getOwnerId(list)); + + Set whitelist = getPreferences().getStringSet( + "whitelisted_stories_ad", + Collections.emptySet() + ); + + return whitelist.contains(id); + } + + public static Boolean hasMiniAppAds(JSONObject list) { + JSONArray attachments = list.optJSONArray("attachments"); + + if (attachments != null && getBoolValue("blockminiapps", false)) { + return IntStream.range(0, attachments.length()) + .mapToObj(attachments::optJSONObject) + .anyMatch(attachment -> attachment.optString("type").contains("mini_app")); + } + + return false; + } + + public static JSONObject storiesAds(JSONObject json, boolean isDeleteFix) { + if (!adsstories()) { + return json; + } + + if (json.has("ads")) { + if (isDeleteFix) { + try { + resetAdsSettings(json.getJSONObject("ads")); + Log.d("NewsfeedAdBlockV2", "Set stories ads settings at zero values"); + } catch (JSONException e) { + e.getStackTrace(); + } + } else { + json.remove("ads"); + Log.d("NewsfeedAdBlockV2", "Removed stories ads block"); + } + } + + try { + parseItemsStories(json.getJSONArray("items")); + } catch (JSONException e) { + e.getStackTrace(); + } + + return json; + } + + private static void parseItemsStories(JSONArray items) throws JSONException { + for (int i = 0; i < items.length(); i++) { + parseStoriesItem(items.getJSONObject(i)); + } + } + + public static void resetAdsSettings(JSONObject ad) throws JSONException { + ad.getJSONObject("settings") + .put("stories_interval", 0) + .put("authors_interval", 0) + .put("time_interval", 0) + .put("stories_init", 0) + .put("authors_init", 0) + .put("time_init", 0); + } +} \ No newline at end of file diff --git a/app/src/main/java/ru/vtosters/sponsorpost/data/Filter.java b/app/src/main/java/ru/vtosters/sponsorpost/data/Filter.java new file mode 100644 index 000000000..d59164f13 --- /dev/null +++ b/app/src/main/java/ru/vtosters/sponsorpost/data/Filter.java @@ -0,0 +1,70 @@ +package ru.vtosters.sponsorpost.data; + +import org.json.JSONException; +import org.json.JSONObject; + +public class Filter { + int id; + String title; + String summary; + String version; + String link; + + public Filter(int id, String title, String summary, String version, String link) { + this.id = id; + this.title = title; + this.summary = summary; + this.version = version; + this.link = link; + } + + public Filter(JSONObject jsonObject) throws NullPointerException, JSONException { + this( + jsonObject.getInt("id"), + jsonObject.getString("title"), + jsonObject.getString("summary"), + jsonObject.getString("version"), + jsonObject.getString("link") + ); + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getSummary() { + return summary; + } + + public void setSummary(String summary) { + this.summary = summary; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getLink() { + return link; + } + + public void setLink(String link) { + this.link = link; + } +} \ No newline at end of file diff --git a/app/src/main/java/ru/vtosters/sponsorpost/data/Post.java b/app/src/main/java/ru/vtosters/sponsorpost/data/Post.java new file mode 100644 index 000000000..1d8da9bc5 --- /dev/null +++ b/app/src/main/java/ru/vtosters/sponsorpost/data/Post.java @@ -0,0 +1,59 @@ +package ru.vtosters.sponsorpost.data; + +import org.json.JSONException; +import org.json.JSONObject; + +public class Post { + long postId; + long ownerId; + long postDate; + long postAdded; + + public Post(long postId, long ownerId, long postDate, long postAdded) { + this.postId = postId; + this.ownerId = ownerId; + this.postDate = postDate; + this.postAdded = postAdded; + } + + public Post(JSONObject jsonObject) throws NullPointerException, JSONException { + this( + jsonObject.getLong("postId"), + jsonObject.getLong("ownerId"), + jsonObject.getLong("postDate"), + jsonObject.getLong("postAdded") + ); + } + + public long getPostId() { + return postId; + } + + public void setPostId(long postId) { + this.postId = postId; + } + + public long getOwnerId() { + return ownerId; + } + + public void setOwnerId(long ownerId) { + this.ownerId = ownerId; + } + + public long getPostDate() { + return postDate; + } + + public void setPostDate(long postDate) { + this.postDate = postDate; + } + + public long getPostAdded() { + return postAdded; + } + + public void setPostAdded(long postAdded) { + this.postAdded = postAdded; + } +} \ No newline at end of file diff --git a/app/src/main/java/ru/vtosters/sponsorpost/services/FilterService.java b/app/src/main/java/ru/vtosters/sponsorpost/services/FilterService.java new file mode 100644 index 000000000..9eaa07305 --- /dev/null +++ b/app/src/main/java/ru/vtosters/sponsorpost/services/FilterService.java @@ -0,0 +1,108 @@ +package ru.vtosters.sponsorpost.services; + +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import org.json.JSONArray; +import org.json.JSONException; +import ru.vtosters.lite.di.singleton.VtOkHttpClient; +import ru.vtosters.sponsorpost.data.Filter; +import ru.vtosters.sponsorpost.utils.ApiUtils; +import ru.vtosters.sponsorpost.utils.FiltersPreferences; +import ru.vtosters.sponsorpost.utils.GzipDecompressor; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public class FilterService { + private static final OkHttpClient client = VtOkHttpClient.getInstance(); + + public static List getFilters(List ids) { + // Retrieves a list of filters + + // Construct the API request URL + String requestUrl = ApiUtils.getURL() + "/lists/get"; + + if (ids != null && !ids.isEmpty()) requestUrl = requestUrl + "?ids=" + ids.stream() + .map(Object::toString) + .collect(Collectors.joining(",")); + // for filters updates + + // Create a GET request to the API endpoint + Request request = new Request.a() + .b(requestUrl) + .a("Content-Type", "application/json") + .a("Accept-Encoding", "gzip") + .a(); + + try (Response response = client.a(request).execute()) { + // Check if the response is successful + if (response.h()) { + // Determine the response encoding + String encoding = response.a("Content-Encoding"); + String resp; + + if (encoding != null && encoding.equals("gzip")) { + // Decompress the response body + resp = GzipDecompressor.decompress(response.a().b()); + } else { + // Retrieve the response body directly + resp = response.a().g(); + } + + // Parse the response body as a JSONArray and extract filter objects + return parseJSON(new JSONArray(resp)); + } else { + if (!FiltersPreferences.getAllFilterIds().isEmpty()) { + return FiltersPreferences.getAllDownloadedFilters(); // check for offline server to get local filters + } else { + throw new RuntimeException("Failed to get filters: " + response.l()); + } + } + } catch (IOException | JSONException e) { + if (!FiltersPreferences.getAllFilterIds().isEmpty()) { + return FiltersPreferences.getAllDownloadedFilters(); // check for offline server to get local filters + } else { + throw new RuntimeException(e); + } + } + } + + public static Set downloadFilter(String link) { + Request request = new Request.a() + .b(link) + .a(); + + try (Response response = client.a(request).execute()) { + if (response.h()) { + return stringToSet(response.a().g()); + } else { + throw new RuntimeException("Failed to download filter: " + response.l()); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public static Set stringToSet(String input) { + return Arrays.stream(input.split("\n")) + .map(String::toLowerCase) + .collect(Collectors.toSet()); + } + + private static List parseJSON(JSONArray jsonArray) throws JSONException { + return IntStream.range(0, jsonArray.length()) + .mapToObj(i -> { + try { + return new Filter(jsonArray.getJSONObject(i)); + } catch (JSONException e) { + throw new RuntimeException(e); + } + }) + .collect(Collectors.toList()); + } +} \ No newline at end of file diff --git a/app/src/main/java/ru/vtosters/sponsorpost/services/PostService.java b/app/src/main/java/ru/vtosters/sponsorpost/services/PostService.java new file mode 100644 index 000000000..823c06080 --- /dev/null +++ b/app/src/main/java/ru/vtosters/sponsorpost/services/PostService.java @@ -0,0 +1,241 @@ +package ru.vtosters.sponsorpost.services; + +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import org.json.JSONArray; +import org.json.JSONException; +import ru.vtosters.sponsorpost.data.Post; +import ru.vtosters.sponsorpost.utils.ApiUtils; +import ru.vtosters.sponsorpost.utils.GzipDecompressor; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public class PostService { + private static final OkHttpClient client = new OkHttpClient(); + private static final String apiPath = ApiUtils.getURL() + "/posts"; + + public static List getPosts(Long date) { + String getFromDate; + // Get posts older than the specified date (if positive) or all posts (if zero or negative or empty) + if (date > 0) { + getFromDate = ("?date=" + date); + } else { + // No date parameter for retrieving all posts + getFromDate = ""; + } + + Request request = new Request.a() + .b(apiPath + "/get" + getFromDate) + .a("Content-Type", "application/json") + .a("Accept-Encoding", "gzip") + .a(); + + try (Response response = client.a(request).execute()) { + // Check if the response is successful + if (response.h()) { + // Determine the response encoding + String encoding = response.a("Content-Encoding"); + + // Handle GZIP-compressed responses + if (encoding != null && encoding.equals("gzip")) { + // Decompress the response body and parse JSON data + return parseJSONPosts(new JSONArray(GzipDecompressor.decompress(response.a().b()))); + } else { + // Parse JSON data from the response body + return parseJSONPosts(new JSONArray(response.a().g())); + } + } else { + // Handle error response + throw new RuntimeException("Failed to get posts: " + response.l()); + } + } catch (IOException | JSONException e) { + // Handle exceptions + throw new RuntimeException(e); + } + } + + public static boolean isPostAd(long ownerId, long postId) { + // Checks if a specified post is an advertisement + + // Merge into one post info + String post = ownerId + "_" + postId; + + // Construct the API request URL + String requestUrl = apiPath + "/isPostAdvert?post=" + post; + + // Create a GET request to the API endpoint + Request request = new Request.a() + .b(requestUrl) + .a("Content-Type", "application/json") + .a(); + + try (Response response = client.a(request).execute()) { + // Check if the response is successful + if (response.h()) { + // Determine the response encoding + String encoding = response.a("Content-Encoding"); + String resp; + + if (encoding != null && encoding.equals("gzip")) { + // Decompress the response body + resp = GzipDecompressor.decompress(response.a().b()); + } else { + // Retrieve the response body directly + resp = response.a().g(); + } + + // Extract the boolean value indicating whether the post is an ad + return Boolean.parseBoolean(resp); + } else { + // Handle error response + throw new RuntimeException("Failed to check post for ad status: " + response.l()); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public static List getAllPostsIds() { + // Create a GET request for retrieving all post IDs + Request request = new Request.a() + .b(apiPath + "/getAllPostIds") + .a("Content-Type", "application/json") + .a("Accept-Encoding", "gzip") + .a(); + + try (Response response = client.a(request).execute()) { + // Check if the response is successful + if (response.h()) { + // Determine the response encoding + String encoding = response.a("Content-Encoding"); + + // Handle GZIP-compressed responses + if (encoding != null && encoding.equals("gzip")) { + // Decompress the response body and extract the first element as a list of post IDs + return new ArrayList<>(Collections.singleton(GzipDecompressor.decompress(response.a().b()))); + } else { + // Extract the first element as a list of post IDs + return new ArrayList<>(Collections.singleton(response.a().g())); + } + } else { + // Handle error response + throw new RuntimeException("Failed to get posts IDs: " + response.l()); + } + } catch (IOException e) { + // Handle exceptions + throw new RuntimeException(e); + } + } + + public static List getPostIdsByOwnerId(Long ownerId, Long date) { + // Retrieve post IDs for a specific owner and date + // If date is positive, get posts older than the specified date + // Otherwise, get all posts for the owner + String getFromDate = date > 0 ? ("?date=" + date) : ""; + + // Construct the API request URL + String requestUrl = apiPath + "/getPostIdsByOwnerId" + "?ownerId=" + ownerId + getFromDate; + + // Create a GET request to the API endpoint + Request request = new Request.a() + .b(requestUrl) + .a("Content-Type", "application/json") + .a("Accept-Encoding", "gzip") + .a(); + + try (Response response = client.a(request).execute()) { + // Check if the response is successful + if (response.h()) { + // Determine the response encoding + String encoding = response.a("Content-Encoding"); + String resp; + + if (encoding != null && encoding.equals("gzip")) { + // Decompress the response body + resp = GzipDecompressor.decompress(response.a().b()); + } else { + // Retrieve the response body directly + resp = response.a().g(); + } + + // Parse the response body as a JSONArray and extract post IDs + return parseJSONIds(new JSONArray(resp)); + } else { + // Handle error response + throw new RuntimeException("Failed to get postIdsByOwnerId: " + response.l()); + } + } catch (IOException | JSONException e) { + // Handle exceptions + throw new RuntimeException(e); + } + } + + public static List getOwnerIds() { + // Retrieves a list of owner IDs with ad posts + + // Construct the API request URL + String requestUrl = apiPath + "/getOwnerIds"; + + // Create a GET request to the API endpoint + Request request = new Request.a() + .b(requestUrl) + .a("Content-Type", "application/json") + .a("Accept-Encoding", "gzip") + .a(); + + try (Response response = client.a(request).execute()) { + // Check if the response is successful + if (response.h()) { + // Determine the response encoding + String encoding = response.a("Content-Encoding"); + String resp; + + if (encoding != null && encoding.equals("gzip")) { + // Decompress the response body + resp = GzipDecompressor.decompress(response.a().b()); + } else { + // Retrieve the response body directly + resp = response.a().g(); + } + + // Parse the response body as a JSONArray and extract owner IDs + return parseJSONIds(new JSONArray(resp)); + } else { + // Handle error response + throw new RuntimeException("Failed to get ownersIds: " + response.l()); + } + } catch (IOException | JSONException e) { + throw new RuntimeException(e); + } + } + + private static List parseJSONIds(JSONArray jsonArray) { + return IntStream.range(0, jsonArray.length()) + .mapToObj(index -> { + try { + return jsonArray.getLong(index); + } catch (JSONException e) { + throw new RuntimeException(e); + } + }) + .collect(Collectors.toList()); + } + + private static List parseJSONPosts(JSONArray jsonArray) throws JSONException { + return IntStream.range(0, jsonArray.length()) + .mapToObj(i -> { + try { + return new Post(jsonArray.getJSONObject(i)); + } catch (JSONException e) { + throw new RuntimeException(e); + } + }) + .collect(Collectors.toList()); + } +} \ No newline at end of file diff --git a/app/src/main/java/ru/vtosters/sponsorpost/utils/ApiUtils.java b/app/src/main/java/ru/vtosters/sponsorpost/utils/ApiUtils.java new file mode 100644 index 000000000..3ee3c2235 --- /dev/null +++ b/app/src/main/java/ru/vtosters/sponsorpost/utils/ApiUtils.java @@ -0,0 +1,7 @@ +package ru.vtosters.sponsorpost.utils; + +public class ApiUtils { + public static String getURL() { + return "https://adlist.vtosters.app/v1"; + } +} diff --git a/app/src/main/java/ru/vtosters/sponsorpost/utils/FiltersPreferences.java b/app/src/main/java/ru/vtosters/sponsorpost/utils/FiltersPreferences.java new file mode 100644 index 000000000..6b773f7b5 --- /dev/null +++ b/app/src/main/java/ru/vtosters/sponsorpost/utils/FiltersPreferences.java @@ -0,0 +1,114 @@ +package ru.vtosters.sponsorpost.utils; + +import android.content.Context; +import android.content.SharedPreferences; +import ru.vtosters.lite.concurrent.VTExecutors; +import ru.vtosters.lite.utils.AndroidUtils; +import ru.vtosters.lite.utils.newsfeed.NewsFeedFiltersUtils; +import ru.vtosters.sponsorpost.data.Filter; +import ru.vtosters.sponsorpost.services.FilterService; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +public class FiltersPreferences { + private static final String PREF_KEY_ID = "id"; + private static final String PREF_KEY_TITLE = "title"; + private static final String PREF_KEY_SUMMARY = "summary"; + private static final String PREF_KEY_VERSION = "version"; + private static final String PREF_KEY_LINK = "link"; + private static final String PREF_KEY_LIST = "list"; + + private static final SharedPreferences preferences; + + static { + preferences = getPreferences(); + } + + private static SharedPreferences getPreferences() { + return AndroidUtils.getGlobalContext().getSharedPreferences("ru.vtosters.sponsorpost.filters.prefs", Context.MODE_PRIVATE); + } + + public static void clearAll() { + preferences.edit().clear().apply(); + } + + public static boolean getSavedKeyValue(int id) { + return getFilter(id) != null; + } + + public static void saveFilter(Filter filter) { + SharedPreferences.Editor editor = preferences.edit(); + editor.putInt(getPrefKey(filter.getId(), PREF_KEY_ID), filter.getId()); + editor.putString(getPrefKey(filter.getId(), PREF_KEY_TITLE), filter.getTitle()); + editor.putString(getPrefKey(filter.getId(), PREF_KEY_SUMMARY), filter.getSummary()); + editor.putString(getPrefKey(filter.getId(), PREF_KEY_VERSION), filter.getVersion()); + editor.putString(getPrefKey(filter.getId(), PREF_KEY_LINK), filter.getLink()); + editor.apply(); + + VTExecutors.getSlowTasksScheduler().a(() -> { + downloadFilter(filter); + NewsFeedFiltersUtils.updateFilters(); + }); + } + + public static void downloadFilter(Filter filter) { + Set list = FilterService.downloadFilter(filter.getLink()); + + preferences.edit() + .putStringSet("filter:" + filter.getId() + ":" + PREF_KEY_LIST, list) + .apply(); + } + + public static Set getFiltersLists() { + return getAllFilterIds().stream() + .flatMap(id -> preferences.getStringSet(getPrefKey(id, PREF_KEY_LIST), new HashSet<>()).stream()) + .collect(Collectors.toSet()); + } + + public static List getAllDownloadedFilters() { + return getAllFilterIds().stream() + .map(FiltersPreferences::getFilter) + .collect(Collectors.toList()); + } + + public static Filter getFilter(int id) { + int filterId = preferences.getInt(getPrefKey(id, PREF_KEY_ID), -1); + + if (filterId == -1) { + return null; + } + + String title = preferences.getString(getPrefKey(id, PREF_KEY_TITLE), ""); + String summary = preferences.getString(getPrefKey(id, PREF_KEY_SUMMARY), ""); + String version = preferences.getString(getPrefKey(id, PREF_KEY_VERSION), ""); + String link = preferences.getString(getPrefKey(id, PREF_KEY_LINK), ""); + + return new Filter(filterId, title, summary, version, link); + } + + private static String getPrefKey(int id, String key) { + return "filter:" + id + ":" + key; + } + + public static void deleteFilter(int id) { + SharedPreferences.Editor editor = preferences.edit(); + + preferences.getAll().keySet().stream() + .filter(key -> key.startsWith("filter:" + id + ":")) + .forEach(editor::remove); + + editor.apply(); + + NewsFeedFiltersUtils.updateFilters(); + } + + public static List getAllFilterIds() { + return preferences.getAll().entrySet().stream() + .filter(entry -> entry.getKey().matches("filter:.*:id")) + .map(entry -> (Integer) entry.getValue()) + .collect(Collectors.toList()); + } +} \ No newline at end of file diff --git a/app/src/main/java/ru/vtosters/sponsorpost/utils/GzipDecompressor.java b/app/src/main/java/ru/vtosters/sponsorpost/utils/GzipDecompressor.java new file mode 100644 index 000000000..b54ca68e9 --- /dev/null +++ b/app/src/main/java/ru/vtosters/sponsorpost/utils/GzipDecompressor.java @@ -0,0 +1,29 @@ +package ru.vtosters.sponsorpost.utils; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.zip.GZIPInputStream; + +public class GzipDecompressor { + public static String decompress(byte[] compressedData) { + if (compressedData == null || compressedData.length == 0) { + throw new IllegalArgumentException("Input compressedData cannot be null or empty"); + } + + try (GZIPInputStream gzipInputStream = new GZIPInputStream(new ByteArrayInputStream(compressedData)); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { + + byte[] buffer = new byte[1024]; + int bytesRead; + + while ((bytesRead = gzipInputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, bytesRead); + } + + return outputStream.toString(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/ru/vtosters/sponsorpost/utils/PostsPreferences.java b/app/src/main/java/ru/vtosters/sponsorpost/utils/PostsPreferences.java new file mode 100644 index 000000000..7fe438609 --- /dev/null +++ b/app/src/main/java/ru/vtosters/sponsorpost/utils/PostsPreferences.java @@ -0,0 +1,94 @@ +package ru.vtosters.sponsorpost.utils; + +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; +import ru.vtosters.lite.utils.AndroidUtils; +import ru.vtosters.sponsorpost.data.Post; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +public class PostsPreferences { + private static final SharedPreferences preferences; + + static { + preferences = getPreferences(); + } + + private static SharedPreferences getPreferences() { + return AndroidUtils.getGlobalContext().getSharedPreferences("ru.vtosters.sponsorpost.posts.prefs", Context.MODE_PRIVATE); + } + + public static boolean isEnabled() { + return preferences.getBoolean("sponsorpost", true); + } + + public static void setEnabled(boolean status) { + preferences.edit().putBoolean("sponsorpost", status).apply(); + } + + public static void savePosts(List posts) { + Set stringSet = posts.stream() + .map(post -> post.getOwnerId() + "_" + post.getPostId()) + .collect(Collectors.toSet()); + + preferences.edit() + .putStringSet("posts", stringSet) + .apply(); + } + + public static void saveGroupSpecifiedPosts(List postsIds, Long ownerId) { + Set stringSet = postsIds.stream() + .map(post -> ownerId + "_" + post) + .collect(Collectors.toSet()); + + preferences.edit() + .putStringSet(ownerId + "_posts", stringSet) + .apply(); + } + + public static void saveGroupsIds(List ids) { + Set stringSet = ids.stream().map(String::valueOf).collect(Collectors.toSet()); + + preferences.edit() + .putStringSet("groupIds", stringSet) + .apply(); + } + + public static void saveAdPostInfo(long ownerId, long postId) { + Set currentStringSet = preferences.getStringSet("posts", new HashSet<>()); + Set newStringSet = new HashSet<>(currentStringSet); + + newStringSet.add(ownerId + "_" + postId); + + Log.d("SponsorPost", ownerId + "_" + postId); + + preferences.edit() + .putStringSet("posts", newStringSet) + .apply(); + } + + public static boolean isGroupAd(long ownerId) { + Set isGroupAd = preferences.getStringSet("groupIds", new HashSet<>()); + + if (!isGroupAd.isEmpty() && isEnabled()) { + return isGroupAd.contains(Long.toString(ownerId)); + } else { + return false; + } + } + + public static boolean isPostAd(long ownerId, long postId) { + if (isEnabled() && isGroupAd(ownerId)) { + Set hasSpecifiedGroupPosts = preferences.getStringSet(ownerId + "_posts", new HashSet<>()); + Set hasPost = preferences.getStringSet("posts", new HashSet<>()); + + return hasPost.contains(ownerId + "_" + postId) || hasSpecifiedGroupPosts.contains(ownerId + "_" + postId); + } else { + return false; + } + } +} \ No newline at end of file diff --git a/app/src/main/java/ru/vtosters/sponsorpost/utils/Updates.java b/app/src/main/java/ru/vtosters/sponsorpost/utils/Updates.java new file mode 100644 index 000000000..0b2220a0f --- /dev/null +++ b/app/src/main/java/ru/vtosters/sponsorpost/utils/Updates.java @@ -0,0 +1,71 @@ +package ru.vtosters.sponsorpost.utils; + +import ru.vtosters.hooks.other.Preferences; +import ru.vtosters.lite.utils.NetworkUtils; +import ru.vtosters.sponsorpost.data.Filter; +import ru.vtosters.sponsorpost.data.Post; +import ru.vtosters.sponsorpost.services.FilterService; +import ru.vtosters.sponsorpost.services.PostService; + +import java.util.List; +import java.util.Objects; +import java.util.concurrent.TimeUnit; + +public class Updates { + public static void updateFilters() { + List savedFilterIds = FiltersPreferences.getAllFilterIds(); + + if (savedFilterIds.isEmpty() || Preferences.serverFeaturesDisable()) { + return; + } + + List filters = FilterService.getFilters(savedFilterIds); + List localFilters = FiltersPreferences.getAllDownloadedFilters(); + + if (!filters.isEmpty()) { + FiltersPreferences.clearAll(); // removes deleted filters from server + + for (Filter filter : filters) { + Filter localFilter = findLocalFilterById(localFilters, filter.getId()); + if (localFilter == null) { + FiltersPreferences.saveFilter(filter); + } else { + String remoteVersion = filter.getVersion(); + String localVersion = localFilter.getVersion(); + if (Objects.equals(remoteVersion, localVersion)) { + FiltersPreferences.saveFilter(filter); + } else { + FiltersPreferences.saveFilter(localFilter); + } + } + } + } + } + + private static Filter findLocalFilterById(List localFilters, int id) { + for (Filter filter : localFilters) { + if (filter.getId() == id) { + return filter; + } + } + return null; + } + + public static void updatePosts() { + long currentTime = System.currentTimeMillis(); + long weekAgo = currentTime - TimeUnit.DAYS.toMillis(7); + + if (PostsPreferences.isEnabled() && !Preferences.serverFeaturesDisable() && NetworkUtils.isNetworkConnected()) { + List posts = PostService.getPosts(weekAgo); + List groupIds = PostService.getOwnerIds(); + + if (!posts.isEmpty()) { + PostsPreferences.savePosts(posts); + } + + if (!groupIds.isEmpty()) { + PostsPreferences.saveGroupsIds(groupIds); + } + } + } +} diff --git a/smali/assets/CopyrightAds.txt b/smali/assets/CopyrightAds.txt deleted file mode 100644 index 69f29ebb8..000000000 --- a/smali/assets/CopyrightAds.txt +++ /dev/null @@ -1,14 +0,0 @@ -appscent -//t.me/ -vk.com -vk.ru -apps-cent -app-cent -appcent -?ref= -bitmain -cents-apps -cent-app -centapp -/?a= -minerx \ No newline at end of file diff --git a/smali/assets/IDontWantToReadIt.txt b/smali/assets/IDontWantToReadIt.txt deleted file mode 100644 index 54963206f..000000000 --- a/smali/assets/IDontWantToReadIt.txt +++ /dev/null @@ -1,189 +0,0 @@ -Путин -Путин -Путину -Путину -Путина -Путина -Путинская -путинская -Байден -байден -Байдену -байдену -Обама -обама -Обаме -обаме -Обаму -обаму -Трамп -трамп -Трампу -трампу -Санкции -санкции -Санкций -санкций -Санкциями -санкциями -Россия -россия -россии -России -МИДУ РФ -миду рф -МИД РФ -мид рф -Мид РФ -Мид рф -Российской -российской -Украина -украина -Украине -украине -Украины -украины -военные -Военные -Специальная операция -Специальная Операция -специальная операция -специальная Операция -Спец. Операция -Спец. операция -спец. Операция -Спец Операция -спец операция -Спец операция -Военная операция -Военная Операция -военная Операция -военная операция -спецоперация -Спецоперация -спецоперации -Спецоперации -спецоперацию -Спецоперацию -вторжение -Вторжение -ЛНР -лнр -ДНР -днр -Донбасс -донбасс -Луганск -луганск -Луганская -луганская -Донецк -донецк -Донецкая -донецкая -Навальным -навальным -Навальный -навальный -Навального -навального -ВСУ -всу -ВС РФ -вс рф -ВС Украины -вс украины -Шойгу -шойгу -Зеленский -зеленский -Зеленским -зеленским -Зеленскому -зеленскому -Зеленского -зеленского -евросоюз -Евросоюз -евросоюзу -Евросоюзу -Войск -войск -армия -Армия -Войне -войне -войны -Войны -войн -Войн -солдат -Солдат -солдаты -Солдаты -Вооруженные -вооруженные -нато -НАТО -Нато -Песков -песков -Пескову -Пескова -пескова -пескову -Кремль -кремль -Кремлю -кремлю -денацификация -Денацификация -денацификацию -Денацификацию -нацис -Нацис -нациз -Нациз -Медведев -медведев -денацифицировать -Денацифицировать -фашис -Фашис -фашиз -Фашиз -США -сша -Киев -киев -Харьков -харьков -Харьковская -харьковская -«Z» -«V» -"з" -"в" -«з» -«в» -«z» -«v» -"З" -"В" -«З» -«В» -русня -Русня -хохол -Хохол -Хохлы -хохлы -ЛДНР -лднр -наказать Россию -наказать россию -наказать Русских -наказать русских -вооружение -Вооружение \ No newline at end of file diff --git a/smali/assets/LinkShorter.txt b/smali/assets/LinkShorter.txt deleted file mode 100644 index cd4cc747f..000000000 --- a/smali/assets/LinkShorter.txt +++ /dev/null @@ -1,29 +0,0 @@ -bit.ly -gg.gg -clck.ru -cutt.ly -goo.su -goo.gl -t1p.de -Is.gd -ow.ly -bit.do -su.pr -mcaf.ee -cutt.us -bitly -okl.it -tinyurl -to.click -u.to -bc.vc -porl.me -bl.inc -utka.su -ccly.xyz -profile.me -prfl.me -adf.ly -shorturl.at -rb.gy -gestyy.com \ No newline at end of file diff --git a/smali/assets/Referals.txt b/smali/assets/Referals.txt deleted file mode 100644 index 0d761c013..000000000 --- a/smali/assets/Referals.txt +++ /dev/null @@ -1,12 +0,0 @@ -ali.pub -alii.pub -lite.al -lite.bz -aliclick -dea.ls -prfl.me -go9.ru -s.click.aliexpress.com -ali.ski -fas.st -shp.pub \ No newline at end of file diff --git a/smali/assets/StandartFilter.txt b/smali/assets/StandartFilter.txt deleted file mode 100644 index fe7b7c8b8..000000000 --- a/smali/assets/StandartFilter.txt +++ /dev/null @@ -1,100 +0,0 @@ -успей заказать -Успей заказать -антикризисная цена -элитные часы -стильные часы -cпocоб зaрaбoтать -цена всего -оформи кредит -Оформи кредит -успей купить -Успей купить -#реклама -#спонсор -#партнёр -#партнер -#промо -#promo -КЭШБЭК КАРТОЙ -Оформите карту -Партнёрский материал -партнёрский материал -Партнерский материал -партнёрский материал -Партнёрский пост -партнёрский пост -Партнерский пост -партнёрский пост -партнёрский_материал -партнёрский_материал -партнёрский_пост -партнёрский_пост -рекламный -Рекламный -смотри в источнике -Смотри в источнике -смотри в Источнике -Смотри в Источнике -в источнике👇 -в источнике😳👇 -в Источник -в источник -В источник -в источнике -в иcтoчнике -В иcтoчнике -в Иcтoчнике -в Источнике -В Источнике -в иcтoчник -В иcтoчник -в Иcтoчник -в Источник -В Источник -в закрепленном комментарии -в Закрепленном комментарии -в закрепленном Комментарии -В закрепленном комментарии -В Закрепленном комментарии -В закрепленном Комментарии -в комментариях -Успей подать заявку -Успей Подать Заявку -Успей подать Заявку -успей Подать Заявку -успей подать заявку -успей Подать заявку -ПОСМОТРЕТЬ ФУЛЛ -ПОСМОТРЕТЬ ИСТОЧНИК -посмотреть фулл -посмотреть источник -ТЫК 👉 -тык 👉 -ТЫК👉 -тык👉 -Успей подписаться -успей подписаться -успей Подписаться -Успей Подписаться -Смотри источник -Смотри Источник -смотри источник -Смотри ист -скорее подписывайся -cкорее подписывайся -пиши боту -ПИШИ БОТУ -Вступай скорее -Подписывайся на нас -Подписывайся скорее -Подписывайся cкорее -Промокоды сливают сами сотрудники заведений -Промокоды сливают сотрудники -напиши Нашему боту -пиши Нашему боту -Подписывайтесь👇 -Подписывайся👇 -ссылка в комментариях -👉https:// -👉http:// -Ссылка удалится через часов \ No newline at end of file diff --git a/smali/res/xml/preferences_debug.xml b/smali/res/xml/preferences_debug.xml index b7c6d13ce..3f6bb3ca0 100644 --- a/smali/res/xml/preferences_debug.xml +++ b/smali/res/xml/preferences_debug.xml @@ -235,7 +235,7 @@ android:key="others" android:title="@string/debug_other"> + @@ -61,31 +64,6 @@ android:defaultValue="" android:key="spamfilters" android:title="@string/vtlownfilter"/> - - - - - @@ -111,9 +89,9 @@ android:title="@string/vtllinkfilter"/> + android:key="cringerepost" + android:summary="@string/cringerepost_summ" + android:title="@string/cringerepost_title"/> + android:enabled="false" + android:summary="@string/why_news_not_updated_summ" + android:title="@string/why_news_not_updated_title"/> - - - - + + - - - - - - + \ No newline at end of file diff --git a/smali/smali_classes4/com/vtosters/lite/api/wall/WallGet.smali b/smali/smali_classes4/com/vtosters/lite/api/wall/WallGet.smali index be5468cbb..21d0e1fce 100644 --- a/smali/smali_classes4/com/vtosters/lite/api/wall/WallGet.smali +++ b/smali/smali_classes4/com/vtosters/lite/api/wall/WallGet.smali @@ -41,6 +41,8 @@ .line 21 invoke-virtual {p0, p5, p1}, Lcom/vk/api/base/ApiRequest;->b(Ljava/lang/String;I)Lcom/vk/api/base/ApiRequest; + invoke-static {p1}, Lru/vtosters/hooks/NewsfeedHook;->takeOwnerIdSponsorPost(I)V + const-string p1, "offset" invoke-virtual {p0, p1, p2}, Lcom/vk/api/base/ApiRequest;->b(Ljava/lang/String;I)Lcom/vk/api/base/ApiRequest; @@ -97,6 +99,8 @@ .line 4 invoke-virtual {p0, v0, p1}, Lcom/vk/api/base/ApiRequest;->b(Ljava/lang/String;I)Lcom/vk/api/base/ApiRequest; + invoke-static {p1}, Lru/vtosters/hooks/NewsfeedHook;->takeOwnerIdSponsorPost(I)V + .line 5 invoke-static {p2}, Landroid/text/TextUtils;->isEmpty(Ljava/lang/CharSequence;)Z diff --git a/smali/smali_classes4/com/vtosters/lite/api/wall/WallGetById.smali b/smali/smali_classes4/com/vtosters/lite/api/wall/WallGetById.smali index 3ff91a333..2c3432ab1 100644 --- a/smali/smali_classes4/com/vtosters/lite/api/wall/WallGetById.smali +++ b/smali/smali_classes4/com/vtosters/lite/api/wall/WallGetById.smali @@ -23,6 +23,8 @@ .line 1 invoke-direct {p0, v0}, Lcom/vk/api/base/ApiRequest;->(Ljava/lang/String;)V + invoke-static {p1}, Lru/vtosters/hooks/NewsfeedHook;->takeOwnerIdPostIdSponsorPost([Ljava/lang/String;)V + const-string v0, "," .line 2 @@ -75,7 +77,7 @@ } .end annotation - invoke-static {p2}, Lru/vtosters/hooks/AdBlockHook;->feedInject(Lorg/json/JSONArray;)Lorg/json/JSONArray; + invoke-static {p2}, Lru/vtosters/hooks/AdBlockHook;->wallGetById(Lorg/json/JSONArray;)Lorg/json/JSONArray; move-result-object p2