From d4710663ff7accdb9cb55d7631fe1f86f0a787a2 Mon Sep 17 00:00:00 2001 From: gdlbo <41114720+gdlbo@users.noreply.github.com> Date: Fri, 16 Feb 2024 03:58:30 +0300 Subject: [PATCH 1/9] disabler force traffic saver v2 --- app/src/main/java/ru/vtosters/hooks/NewsfeedHook.java | 10 ++++++++++ .../smali_classes2/com/vk/core/util/DeviceState.smali | 4 ++-- .../vk/httpexecutor/api/utils/RoamingDetector.smali | 4 ++-- .../com/vk/reef/trackers/ReefNetworkInfoTracker.smali | 2 +- .../org/chromium/net/AndroidNetworkLibrary.smali | 2 +- .../smali_classes5/ru/mail/libverify/accounts/f.smali | 2 +- smali/smali_classes5/ru/mail/libverify/utils/n.smali | 2 +- .../libverify/utils/network/NetworkStateReceiver.smali | 2 +- smali/smali_classes5/vigo/sdk/Vigo.smali | 2 +- 9 files changed, 20 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/ru/vtosters/hooks/NewsfeedHook.java b/app/src/main/java/ru/vtosters/hooks/NewsfeedHook.java index 491c275e7..28e895457 100644 --- a/app/src/main/java/ru/vtosters/hooks/NewsfeedHook.java +++ b/app/src/main/java/ru/vtosters/hooks/NewsfeedHook.java @@ -1,7 +1,9 @@ package ru.vtosters.hooks; import android.content.Context; +import android.net.NetworkInfo; import android.os.PowerManager; +import android.telephony.TelephonyManager; import android.util.Log; import androidx.recyclerview.widget.RecyclerView; import com.vk.core.preference.Preference; @@ -132,4 +134,12 @@ public class NewsfeedHook { // return !getBoolValue("force_disable_psm", false) && pw.isPowerSaveMode(); return false; } + + public static boolean isRoaming(NetworkInfo networkInfo) { + return !Preferences.disableForceTrafficSaver() && networkInfo.isRoaming(); + } + + public static boolean isNetworkRoaming(TelephonyManager telephonyManager) { + return !Preferences.disableForceTrafficSaver() && telephonyManager.isNetworkRoaming(); + } } diff --git a/smali/smali_classes2/com/vk/core/util/DeviceState.smali b/smali/smali_classes2/com/vk/core/util/DeviceState.smali index 35f60eddc..0b2d10cc1 100644 --- a/smali/smali_classes2/com/vk/core/util/DeviceState.smali +++ b/smali/smali_classes2/com/vk/core/util/DeviceState.smali @@ -1101,7 +1101,7 @@ if-eqz v0, :cond_0 - invoke-virtual {v0}, Landroid/net/NetworkInfo;->isRoaming()Z + invoke-static {v0}, Lru/vtosters/hooks/NewsfeedHook;->isRoaming(Landroid/net/NetworkInfo;)Z move-result v0 @@ -1125,7 +1125,7 @@ move-result-object v0 - invoke-virtual {v0}, Landroid/telephony/TelephonyManager;->isNetworkRoaming()Z + invoke-static {v0}, Lru/vtosters/hooks/NewsfeedHook;->isNetworkRoaming(Landroid/telephony/TelephonyManager;)Z move-result v0 diff --git a/smali/smali_classes2/com/vk/httpexecutor/api/utils/RoamingDetector.smali b/smali/smali_classes2/com/vk/httpexecutor/api/utils/RoamingDetector.smali index a748c888f..f91c06a0f 100644 --- a/smali/smali_classes2/com/vk/httpexecutor/api/utils/RoamingDetector.smali +++ b/smali/smali_classes2/com/vk/httpexecutor/api/utils/RoamingDetector.smali @@ -163,7 +163,7 @@ if-eqz v0, :cond_0 - invoke-virtual {v0}, Landroid/net/NetworkInfo;->isRoaming()Z + invoke-static {v0}, Lru/vtosters/hooks/NewsfeedHook;->isRoaming(Landroid/net/NetworkInfo;)Z move-result v0 @@ -187,7 +187,7 @@ move-result-object v0 - invoke-virtual {v0}, Landroid/telephony/TelephonyManager;->isNetworkRoaming()Z + invoke-static {v0}, Lru/vtosters/hooks/NewsfeedHook;->isNetworkRoaming(Landroid/telephony/TelephonyManager;)Z move-result v0 diff --git a/smali/smali_classes4/com/vk/reef/trackers/ReefNetworkInfoTracker.smali b/smali/smali_classes4/com/vk/reef/trackers/ReefNetworkInfoTracker.smali index c43293986..cf78f1afe 100644 --- a/smali/smali_classes4/com/vk/reef/trackers/ReefNetworkInfoTracker.smali +++ b/smali/smali_classes4/com/vk/reef/trackers/ReefNetworkInfoTracker.smali @@ -400,7 +400,7 @@ if-eqz v1, :cond_8 - invoke-virtual {v1}, Landroid/telephony/TelephonyManager;->isNetworkRoaming()Z + invoke-static {v1}, Lru/vtosters/hooks/NewsfeedHook;->isNetworkRoaming(Landroid/telephony/TelephonyManager;)Z move-result v1 diff --git a/smali/smali_classes5/org/chromium/net/AndroidNetworkLibrary.smali b/smali/smali_classes5/org/chromium/net/AndroidNetworkLibrary.smali index 0385461b5..e5d924299 100644 --- a/smali/smali_classes5/org/chromium/net/AndroidNetworkLibrary.smali +++ b/smali/smali_classes5/org/chromium/net/AndroidNetworkLibrary.smali @@ -794,7 +794,7 @@ .line 3 :cond_0 - invoke-virtual {v0}, Landroid/net/NetworkInfo;->isRoaming()Z + invoke-static {v0}, Lru/vtosters/hooks/NewsfeedHook;->isRoaming(Landroid/net/NetworkInfo;)Z move-result v0 diff --git a/smali/smali_classes5/ru/mail/libverify/accounts/f.smali b/smali/smali_classes5/ru/mail/libverify/accounts/f.smali index 20befc798..56a55be9f 100644 --- a/smali/smali_classes5/ru/mail/libverify/accounts/f.smali +++ b/smali/smali_classes5/ru/mail/libverify/accounts/f.smali @@ -277,7 +277,7 @@ iput-object v2, v1, Lru/mail/libverify/accounts/e;->m:Ljava/lang/String; - invoke-virtual {p0}, Landroid/telephony/TelephonyManager;->isNetworkRoaming()Z + invoke-static {p0}, Lru/vtosters/hooks/NewsfeedHook;->isNetworkRoaming(Landroid/telephony/TelephonyManager;)Z move-result v2 diff --git a/smali/smali_classes5/ru/mail/libverify/utils/n.smali b/smali/smali_classes5/ru/mail/libverify/utils/n.smali index 994aa4d57..e2de0b1b9 100644 --- a/smali/smali_classes5/ru/mail/libverify/utils/n.smali +++ b/smali/smali_classes5/ru/mail/libverify/utils/n.smali @@ -1419,7 +1419,7 @@ check-cast p0, Landroid/telephony/TelephonyManager; - invoke-virtual {p0}, Landroid/telephony/TelephonyManager;->isNetworkRoaming()Z + invoke-static {p0}, Lru/vtosters/hooks/NewsfeedHook;->isNetworkRoaming(Landroid/telephony/TelephonyManager;)Z move-result p0 diff --git a/smali/smali_classes5/ru/mail/libverify/utils/network/NetworkStateReceiver.smali b/smali/smali_classes5/ru/mail/libverify/utils/network/NetworkStateReceiver.smali index 416946800..4a62932ca 100644 --- a/smali/smali_classes5/ru/mail/libverify/utils/network/NetworkStateReceiver.smali +++ b/smali/smali_classes5/ru/mail/libverify/utils/network/NetworkStateReceiver.smali @@ -441,7 +441,7 @@ goto :goto_1 :cond_1 - invoke-virtual {v0}, Landroid/net/NetworkInfo;->isRoaming()Z + invoke-static {v0}, Lru/vtosters/hooks/NewsfeedHook;->isRoaming(Landroid/net/NetworkInfo;)Z move-result v0 diff --git a/smali/smali_classes5/vigo/sdk/Vigo.smali b/smali/smali_classes5/vigo/sdk/Vigo.smali index f0f811141..33c7577e4 100644 --- a/smali/smali_classes5/vigo/sdk/Vigo.smali +++ b/smali/smali_classes5/vigo/sdk/Vigo.smali @@ -4055,7 +4055,7 @@ iget-object v1, p0, Lvigo/sdk/Vigo;->tm:Landroid/telephony/TelephonyManager; .line 13 - invoke-virtual {v1}, Landroid/telephony/TelephonyManager;->isNetworkRoaming()Z + invoke-static {v1}, Lru/vtosters/hooks/NewsfeedHook;->isNetworkRoaming(Landroid/telephony/TelephonyManager;)Z move-result v1 From b5ae2662dba155da40d9e4e94126c12e2a3f2eb8 Mon Sep 17 00:00:00 2001 From: gdlbo <41114720+gdlbo@users.noreply.github.com> Date: Sat, 17 Feb 2024 22:27:56 +0300 Subject: [PATCH 2/9] fix noad --- .../main/java/ru/vtosters/hooks/NewsfeedHook.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/ru/vtosters/hooks/NewsfeedHook.java b/app/src/main/java/ru/vtosters/hooks/NewsfeedHook.java index 28e895457..874a65503 100644 --- a/app/src/main/java/ru/vtosters/hooks/NewsfeedHook.java +++ b/app/src/main/java/ru/vtosters/hooks/NewsfeedHook.java @@ -85,18 +85,18 @@ public class NewsfeedHook { } 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"}; + String[] adsParams = {"ads_app_slider", "ads_site_slider", "ads_app", "ads_site", "ads_post", "ads_app_video", "ads_post_pretty_cards", "ads_post_snippet_video"}; + String noAdParam = "ads_disabled"; if (ads()) { - hashSet.add(adsParams[0]); - hashSet.add(adsParams[1]); + hashSet.add(noAdParam); + + if (!Preferences.milkshake()) { + hashSet.add(adsParams[0]); + } } else { Collections.addAll(hashSet, adsParams); } - - if (Preferences.milkshake()) { - hashSet.remove(adsParams[1]); - } } public static void takeOwnerIdSponsorPost(int ownerid) { From e19ed8845d4cf9169af8490194305b6e2d5194fd Mon Sep 17 00:00:00 2001 From: gdlbo <41114720+gdlbo@users.noreply.github.com> Date: Sun, 18 Feb 2024 02:08:16 +0300 Subject: [PATCH 3/9] fix #1343 --- .../java/ru/vtosters/lite/utils/VKAccountDB.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/ru/vtosters/lite/utils/VKAccountDB.java b/app/src/main/java/ru/vtosters/lite/utils/VKAccountDB.java index 3c3cad1b6..d353c0de3 100644 --- a/app/src/main/java/ru/vtosters/lite/utils/VKAccountDB.java +++ b/app/src/main/java/ru/vtosters/lite/utils/VKAccountDB.java @@ -70,19 +70,22 @@ public class VKAccountDB { LifecycleUtils.getCurrentActivity().requestPermissions(new String[]{"android.permission.WRITE_EXTERNAL_STORAGE"}, 228); } - var db = getDatabase().getReadableDatabase(); - var dateFormat = new SimpleDateFormat("yyyy-MM-dd.HH-mm-ss", Locale.getDefault()); - var dir = new File(getExternalStoragePublicDirectory(DIRECTORY_DOWNLOADS), "/VTLBackups/"); - var file = new File(dir, "saved_accounts_" + dateFormat.format(new Date()) + ".vtl"); + SQLiteDatabase db = getDatabase().getReadableDatabase(); + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd.HH-mm-ss", Locale.getDefault()); + File dir = new File(getExternalStoragePublicDirectory(DIRECTORY_DOWNLOADS), "/VTLBackups/"); + File file = new File(dir, "saved_accounts_" + dateFormat.format(new Date()) + ".vtl"); try (InputStream inputStream = new FileInputStream(db.getPath())) { - dir.mkdirs(); + if (!dir.exists()) { + dir.mkdirs(); + } FileOutputStream outputStream = new FileOutputStream(file); byte[] buff = new byte[1024]; int read; - while ((read = inputStream.read(buff, 0, buff.length)) > 0) + while ((read = inputStream.read(buff, 0, buff.length)) > 0) { outputStream.write(buff, 0, read); + } inputStream.close(); outputStream.close(); From 8959558c64d1f9747b9bce0b79586b8156eee2cb Mon Sep 17 00:00:00 2001 From: gdlbo <41114720+gdlbo@users.noreply.github.com> Date: Sun, 18 Feb 2024 14:52:22 +0300 Subject: [PATCH 4/9] Fixed 5.1 false coloring and improved coloring speed/app performance (#1566) --- .../msg_list/adapter/vh/VhMsg.java | 67 +++++------ .../BottomNavigationItemView.java | 4 +- .../ru/vtosters/hooks/DockBarInjector.java | 4 +- .../ru/vtosters/hooks/other/ThemesUtils.java | 9 +- .../ru/vtosters/lite/themes/ThemesHacks.java | 16 ++- .../vtosters/lite/themes/ThemesManager.java | 100 +++++++++------- .../ru/vtosters/lite/themes/VTLResources.java | 54 +++++---- .../ru/vtosters/lite/themes/ViewInjector.java | 18 ++- .../lite/themes/hooks/TextViewHook.java | 2 +- .../lite/themes/hooks/ToolbarHook.java | 16 ++- .../lite/themes/items/VTLPalette.java | 63 ++++++---- .../themes/loaders/AssetManagerHelper.java | 12 -- .../lite/themes/loaders/ResourcesLoader.java | 29 ----- .../lite/themes/palettes/PalettesManager.java | 73 ++++++------ .../lite/themes/utils/ArscEditor.java | 41 +++---- .../lite/themes/utils/RecolorUtils.java | 112 ++++++++++++++---- .../lite/themes/utils/VkUiThemer.java | 2 +- .../lite/ui/fragments/ThemesFragment.java | 2 +- 18 files changed, 349 insertions(+), 275 deletions(-) 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 e3627a332..2f33420bd 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 @@ -49,6 +49,7 @@ import com.vk.im.ui.views.msg.bubble.MsgBubbleView; import com.vk.im.ui.views.sticker.StickerAnimationState; import kotlin.Unit; import kotlin.jvm.b.Functions; +import ru.vtosters.lite.themes.ThemesHacks; public class VhMsg extends VhBase implements SwipeToReplyItemTouchCallback.b { public static final int h0 = Screen.a(124); @@ -133,7 +134,7 @@ public class VhMsg extends VhBase implements SwipeToReplyItemTouchCallback.b { 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.H = new ColorDrawable(ThemesHacks.getColors(context, com.vk.im.ui.d.msg_search_selection)); this.I = ContextExtKt.b(context, com.vk.im.ui.e.msg_bubble_max_width); this.J = ContextExtKt.b(context, com.vk.im.ui.e.msg_reply_max_width); this.K = ContextExtKt.b(context, com.vk.im.ui.e.msg_sticker_max_width); @@ -150,49 +151,39 @@ public class VhMsg extends VhBase implements SwipeToReplyItemTouchCallback.b { var6.right = var7.rightMargin; var6.top = var7.topMargin; var6.bottom = var7.bottomMargin; - ViewExtKt.b(this.c, new View.OnClickListener() { - public void onClick(View var1) { - if (VhMsg.this.c0 != null && VhMsg.this.d0 != null) { - VhMsg.this.c0.a(VhMsg.this.d0.getFrom()); - } - + ViewExtKt.b(this.c, var1 -> { + if (VhMsg.this.c0 != null && VhMsg.this.d0 != null) { + VhMsg.this.c0.a(VhMsg.this.d0.getFrom()); } - }); - this.c.setOnLongClickListener(new View.OnLongClickListener() { - public boolean onLongClick(View var1) { - if (VhMsg.this.c0 != null && VhMsg.this.d0 != null) { - VhMsg.this.c0.a(VhMsg.this.d0.getFrom()); - return true; - } else { - return false; - } - } - }); - ViewExtKt.b(this.g, new View.OnClickListener() { - public void onClick(View var1) { - if (VhMsg.this.c0 != null && VhMsg.this.d0 != null) { - VhMsg.this.c0.a(VhMsg.this.d0); - } - } }); - ViewExtKt.b(this.itemView, new View.OnClickListener() { - public void onClick(View var1) { - if (VhMsg.this.c0 != null && VhMsg.this.d0 != null) { - VhMsg.this.c0.a(VhMsg.this.d0.getLocalId()); - } - - } - }); - this.itemView.setOnLongClickListener(new View.OnLongClickListener() { - public boolean onLongClick(View var1) { - if (VhMsg.this.c0 != null && VhMsg.this.d0 != null) { - VhMsg.this.c0.b(VhMsg.this.d0.getLocalId()); - } - + this.c.setOnLongClickListener(var1 -> { + if (VhMsg.this.c0 != null && VhMsg.this.d0 != null) { + VhMsg.this.c0.a(VhMsg.this.d0.getFrom()); return true; + } else { + return false; } }); + ViewExtKt.b(this.g, var1 -> { + if (VhMsg.this.c0 != null && VhMsg.this.d0 != null) { + VhMsg.this.c0.a(VhMsg.this.d0); + } + + }); + ViewExtKt.b(this.itemView, (View.OnClickListener) var1 -> { + if (VhMsg.this.c0 != null && VhMsg.this.d0 != null) { + VhMsg.this.c0.a(VhMsg.this.d0.getLocalId()); + } + + }); + this.itemView.setOnLongClickListener((View.OnLongClickListener) var1 -> { + if (VhMsg.this.c0 != null && VhMsg.this.d0 != null) { + VhMsg.this.c0.b(VhMsg.this.d0.getLocalId()); + } + + return true; + }); this.R = ContextExtKt.i(context, com.vk.im.ui.c.im_msg_part_corner_radius_small); this.S = ContextExtKt.i(context, com.vk.im.ui.c.im_msg_part_corner_radius_big); this.c0 = 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 c9a572e17..04634a897 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 @@ -69,10 +69,10 @@ public class BottomNavigationItemView extends FrameLayout implements MenuView.It this.mIcon.getLayoutParams().height = V.a(28.0F); this.mSmallLabel = this.findViewById(R.id.smallLabel); - mSmallLabel.setTextColor(getCSTDock()); + mSmallLabel.setTextColor(getCSTDock(this.getContext())); this.mLargeLabel = this.findViewById(R.id.largeLabel); - mLargeLabel.setTextColor(getCSTDock()); + mLargeLabel.setTextColor(getCSTDock(this.getContext())); LayoutInflater.from(this.getContext()).inflate(R.layout.navigation_bottom_counter, this, true); this.mCounterContainer = this.findViewById(R.id.counter_container); diff --git a/app/src/main/java/ru/vtosters/hooks/DockBarInjector.java b/app/src/main/java/ru/vtosters/hooks/DockBarInjector.java index 08557a531..84a942586 100644 --- a/app/src/main/java/ru/vtosters/hooks/DockBarInjector.java +++ b/app/src/main/java/ru/vtosters/hooks/DockBarInjector.java @@ -65,7 +65,7 @@ public class DockBarInjector { for (DockBarTab tab : sManager.getSelectedTabs()) { MenuItem add = menu.add(0, tab.id, 0, tab.titleID); - add.setIcon(new RecoloredDrawable(getResources().getDrawable(tab.iconID), getCSTDock())); + add.setIcon(new RecoloredDrawable(getResources().getDrawable(tab.iconID), getCSTDock(navigationView.getContext()))); add.setTitle(getGlobalContext().getString(tab.titleID)); add.setCheckable(true); } @@ -76,7 +76,7 @@ public class DockBarInjector { item.setStaticMode(true); item.setIconsMode(false); item.setShiftingMode(false); - item.setTextColor(getCSTDock()); + item.setTextColor(getCSTDock(item.getContext())); } } } diff --git a/app/src/main/java/ru/vtosters/hooks/other/ThemesUtils.java b/app/src/main/java/ru/vtosters/hooks/other/ThemesUtils.java index 184e709b4..2a63789b6 100644 --- a/app/src/main/java/ru/vtosters/hooks/other/ThemesUtils.java +++ b/app/src/main/java/ru/vtosters/hooks/other/ThemesUtils.java @@ -2,6 +2,7 @@ package ru.vtosters.hooks.other; import android.annotation.SuppressLint; import android.app.Activity; +import android.content.Context; import android.content.res.ColorStateList; import android.content.res.Resources; import android.graphics.Color; @@ -73,7 +74,7 @@ public class ThemesUtils { } public static boolean isMonetTheme() { - return getBoolValue("monettheme", false) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S; + return getBoolValue("monettheme", false); } public static boolean isAmoledTheme() { @@ -340,7 +341,7 @@ public class ThemesUtils { } public static int getColor(int i) { - return ThemesHacks.getHackedColor(getGlobalContext(), i); + return ThemesHacks.getHackedColor(LifecycleUtils.getCurrentActivity(), i); } // Android Support color injector + accent color checker public static int getAlertStyle() { @@ -391,14 +392,14 @@ public class ThemesUtils { return vkme() ? R.dimen.app_minimumsize_h : Default; } - public static ColorStateList getCSTDock() { + public static ColorStateList getCSTDock(Context ctx) { return new ColorStateList( new int[][]{ new int[]{android.R.attr.state_checked}, new int[]{-android.R.attr.state_checked} }, new int[]{ - dockbar_accent() ? getAccentColor() : (isDarkTheme() ? getResources().getColor(R.color.white) : getResources().getColor(R.color.gray_700)), + dockbar_accent() ? getAccentColor() : (isDarkTheme() ? ThemesHacks.getColors(ctx, R.color.white) : ThemesHacks.getColors(ctx, R.color.gray_700)), getColorFromAttr(R.attr.tabbar_inactive_icon) } ); diff --git a/app/src/main/java/ru/vtosters/lite/themes/ThemesHacks.java b/app/src/main/java/ru/vtosters/lite/themes/ThemesHacks.java index 958ea2ed1..5936b0a34 100644 --- a/app/src/main/java/ru/vtosters/lite/themes/ThemesHacks.java +++ b/app/src/main/java/ru/vtosters/lite/themes/ThemesHacks.java @@ -31,22 +31,30 @@ public class ThemesHacks { } } - if (ThemesCore.isCachedAccents() && ColorReferences.isAccentedColor(context.getResources().getColor(color))) { + if (ThemesCore.isCachedAccents() && ColorReferences.isAccentedColor(getColors(context, color))) { return ThemesUtils.getAccentColor(); } - if (ThemesCore.isCachedAccents() && ColorReferences.isMutedAccentedColor(context.getResources().getColor(color))) { + if (ThemesCore.isCachedAccents() && ColorReferences.isMutedAccentedColor(getColors(context, color))) { return ThemesUtils.getMutedAccentColor(); } } - return Build.VERSION.SDK_INT > 23 ? context.getColor(color) : context.getResources().getColor(color); + return getColors(context, color); + } + + public static int getColors(Context context, int color) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + return context.getColor(color); + } else { + return context.getResources().getColor(color); + } } // Фиксит селектор (все/свои/архив) в профиле public static void fixProfileSelector(View view) { if (!ThemesUtils.isMilkshake()) return; - var id = view.getId(); + int id = view.getId(); if (id == R.id.profile_wall_owner_posts || id == R.id.profile_wall_all_posts || id == R.id.profile_wall_archived_posts) { StateListDrawable states = (StateListDrawable) ((LayerDrawable) view.getBackground()).getDrawable(0); diff --git a/app/src/main/java/ru/vtosters/lite/themes/ThemesManager.java b/app/src/main/java/ru/vtosters/lite/themes/ThemesManager.java index 6dd0684fb..5989ea17f 100644 --- a/app/src/main/java/ru/vtosters/lite/themes/ThemesManager.java +++ b/app/src/main/java/ru/vtosters/lite/themes/ThemesManager.java @@ -3,6 +3,7 @@ package ru.vtosters.lite.themes; import android.app.Application; import android.content.Context; import android.graphics.Color; +import android.os.Build; import com.google.devrel.gmscore.tools.apk.arsc.BinaryResourceFile; import com.vtosters.lite.R; import ru.vtosters.hooks.other.Preferences; @@ -12,6 +13,8 @@ import ru.vtosters.lite.themes.utils.ArscEditor; import ru.vtosters.lite.utils.IOUtils; import java.io.*; +import java.util.Arrays; +import java.util.Enumeration; import java.util.zip.CRC32; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; @@ -123,7 +126,7 @@ public class ThemesManager { ResourcesLoader.load(app, modApk.getAbsolutePath(), false); } } catch (Exception e) { - e.printStackTrace(); + // } } @@ -152,61 +155,72 @@ public class ThemesManager { } public static void generateModApk(int accentColor) throws Throwable { - try (var apk = new ZipFile(baseApkPath)) { - var arscEntry = apk.getEntry("resources.arsc"); - var arscBis = new BufferedInputStream(apk.getInputStream(arscEntry)); - var arsc = BinaryResourceFile.fromInputStream(arscBis); + try (ZipFile apk = new ZipFile(baseApkPath); + ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(modApk)))) { + + ZipEntry arscEntry = apk.getEntry("resources.arsc"); + BufferedInputStream arscBis = new BufferedInputStream(apk.getInputStream(arscEntry)); + BinaryResourceFile arsc = BinaryResourceFile.fromInputStream(arscBis); ArscEditor.changeColors(arsc, ACCENT_COLORS, accentColor); - try (var zos = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(modApk)))) { - var arscBuff = arsc.toByteArray(); - var newArscEntry = new ZipEntry("resources.arsc"); + byte[] arscBuff = arsc.toByteArray(); + ZipEntry newArscEntry = new ZipEntry("resources.arsc"); - var crc = new CRC32(); - crc.update(arscBuff); + CRC32 crc = new CRC32(); + crc.update(arscBuff); - newArscEntry.setSize(arscBuff.length); - newArscEntry.setMethod(ZipEntry.STORED); - newArscEntry.setCrc(crc.getValue()); + newArscEntry.setSize(arscBuff.length); + newArscEntry.setMethod(ZipEntry.STORED); + newArscEntry.setCrc(crc.getValue()); - zos.putNextEntry(newArscEntry); - zos.write(arscBuff); - zos.closeEntry(); + zos.putNextEntry(newArscEntry); + zos.write(arscBuff); + zos.closeEntry(); - var entries = apk.entries(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + apk.stream() + .filter(entry -> entry.getName().startsWith("res/") || entry.getName().startsWith("assets/") && !entry.getName().equals("resources.arsc")) + .forEach(entry -> { + try { + String name = entry.getName(); + workWithApk(zos, name, apk.getInputStream(entry), entry.getSize(), entry.getCrc()); + } catch (IOException e) { + e.fillInStackTrace(); + } + }); + } else { + Enumeration entries = apk.entries(); while (entries.hasMoreElements()) { - var entry = entries.nextElement(); - var name = entry.getName(); - - if (!name.startsWith("res/") && !name.startsWith("assets/") || name.equals("resources.arsc")) - continue; - - var doNotCompress = false; - for (var suffix : DO_NOT_COMPRESS) { - if (name.endsWith(suffix)) { - doNotCompress = true; - break; - } + ZipEntry entry = entries.nextElement(); + String name = entry.getName(); + if (name.startsWith("res/") || name.startsWith("assets/") && !name.equals("resources.arsc")) { + workWithApk(zos, name, apk.getInputStream(entry), entry.getSize(), entry.getCrc()); } - - var entryBis = new BufferedInputStream(apk.getInputStream(entry)); - var newEntry = new ZipEntry(name); - - if (doNotCompress) { - newEntry.setMethod(ZipEntry.STORED); - newEntry.setSize(entry.getSize()); - newEntry.setCrc(entry.getCrc()); - } else newEntry.setMethod(ZipEntry.DEFLATED); - - zos.putNextEntry(newEntry); - IOUtils.copy(entryBis, zos); - entryBis.close(); - zos.closeEntry(); } } } } + private static void workWithApk(ZipOutputStream zos, String name, InputStream inputStream, long size, long crc) throws IOException { + boolean doNotCompress = Arrays.stream(DO_NOT_COMPRESS).anyMatch(name::endsWith); + + BufferedInputStream entryBis = new BufferedInputStream(inputStream); + ZipEntry newEntry = new ZipEntry(name); + + if (doNotCompress) { + newEntry.setMethod(ZipEntry.STORED); + newEntry.setSize(size); + newEntry.setCrc(crc); + } else { + newEntry.setMethod(ZipEntry.DEFLATED); + } + + zos.putNextEntry(newEntry); + IOUtils.copy(entryBis, zos); + entryBis.close(); + zos.closeEntry(); + } + public static void deleteModification() { modApk.delete(); } diff --git a/app/src/main/java/ru/vtosters/lite/themes/VTLResources.java b/app/src/main/java/ru/vtosters/lite/themes/VTLResources.java index 97f5265cf..328043365 100644 --- a/app/src/main/java/ru/vtosters/lite/themes/VTLResources.java +++ b/app/src/main/java/ru/vtosters/lite/themes/VTLResources.java @@ -13,6 +13,7 @@ import ru.vtosters.hooks.other.ThemesUtils; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; +import java.util.stream.IntStream; public class VTLResources extends Resources { private static final String TAG = "VTLResources"; @@ -32,12 +33,8 @@ public class VTLResources extends Resources { attributesToTheme.add(16843173); } - private final Context context; - public VTLResources(Context context, Resources parent) { super(parent.getAssets(), parent.getDisplayMetrics(), parent.getConfiguration()); - this.context = context; -// Log.d(TAG, "VTLResources: init"); } private static boolean isAttrThemeable(int attrID) { @@ -49,42 +46,49 @@ public class VTLResources extends Resources { return (int[]) typedArrayField.get(arr); } catch (IllegalAccessException e) { Log.e(TAG, "getArrayData: ", e); - e.printStackTrace(); + e.fillInStackTrace(); return new int[0]; } } @Override public TypedArray obtainAttributes(AttributeSet set, int[] attrs) { - var typedArray = super.obtainAttributes(set, attrs); - var data = getArrayData(typedArray); - for (int i = 0; i < attrs.length; i++) { - try { - int attrID = attrs[i]; - if (attributesToTheme.contains(attrID)) { - int type = data[i * 6]; - int cnt = data[(i * 6) + 1]; + TypedArray typedArray = super.obtainAttributes(set, attrs); - if (type == TypedValue.TYPE_ATTRIBUTE && isAttrThemeable(cnt)) { - data[i * 6] = TypedValue.TYPE_INT_COLOR_RGB8; - data[(i * 6) + 1] = ThemesUtils.getAccentColor(); - data[(i * 6) + 2] = 0; // clear reference content + if (ThemesUtils.isMonetTheme()) { + int[] data = getArrayData(typedArray); + IntStream.range(0, attrs.length).forEach(i -> { + try { + int attrID = attrs[i]; + if (attributesToTheme.contains(attrID)) { + int type = data[i * 6]; + int cnt = data[(i * 6) + 1]; + + if (type == TypedValue.TYPE_ATTRIBUTE && isAttrThemeable(cnt)) { + data[i * 6] = TypedValue.TYPE_INT_COLOR_RGB8; + data[(i * 6) + 1] = ThemesUtils.getAccentColor(); + data[(i * 6) + 2] = 0; // clear reference content + } } + } catch (Exception e) { + Log.e(TAG, "TAVzlom failed! (obtainAttributes)"); + e.fillInStackTrace(); } - } catch (Exception e) { - Log.e(TAG, "TAVzlom failed! (obtainAttributes)"); - e.printStackTrace(); - } + }); } return typedArray; } @Override public Drawable getDrawable(int id, @Nullable Theme theme) throws NotFoundException { - var drawable = super.getDrawable(id, theme); - if (id == com.vtosters.lite.R.drawable.newsfeed_tab_dropdown_16) { - ThemesHacks.fixDropdown(drawable); - } + Drawable drawable = super.getDrawable(id, theme); + fixDropdown(id, drawable); return drawable; } + + private void fixDropdown(int id, Drawable drawable) { + if (id == com.vtosters.lite.R.drawable.newsfeed_tab_dropdown_16 && ThemesUtils.isMonetTheme()) { + ThemesHacks.fixDropdown(drawable); + } + } } \ No newline at end of file diff --git a/app/src/main/java/ru/vtosters/lite/themes/ViewInjector.java b/app/src/main/java/ru/vtosters/lite/themes/ViewInjector.java index e00ed0151..275cbf917 100644 --- a/app/src/main/java/ru/vtosters/lite/themes/ViewInjector.java +++ b/app/src/main/java/ru/vtosters/lite/themes/ViewInjector.java @@ -1,11 +1,13 @@ package ru.vtosters.lite.themes; +import android.os.Build; import android.view.View; import android.view.ViewGroup; import ru.vtosters.hooks.other.ThemesUtils; import ru.vtosters.lite.themes.hooks.*; import java.util.ArrayList; +import java.util.stream.IntStream; public class ViewInjector { public static ArrayList hooks = new ArrayList<>(); @@ -22,15 +24,19 @@ public class ViewInjector { public static View inject(View view, int i, boolean z) { if (ThemesUtils.isMonetTheme()) { - for (BaseHook hook : hooks) { - hook.inject(view, i, z); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + hooks.forEach(hook -> hook.inject(view, i, z)); + } else { + for (BaseHook hook : hooks) { + hook.inject(view, i, z); + } } if (view instanceof ViewGroup) { - var viewGroup = (ViewGroup) view; - for (int i2 = 0; i2 < viewGroup.getChildCount(); i2++) { - inject(viewGroup.getChildAt(i2), i, false); - } + ViewGroup viewGroup = (ViewGroup) view; + IntStream.range(0, viewGroup.getChildCount()) + .mapToObj(viewGroup::getChildAt) + .forEach(child -> inject(child, i, false)); } } return view; diff --git a/app/src/main/java/ru/vtosters/lite/themes/hooks/TextViewHook.java b/app/src/main/java/ru/vtosters/lite/themes/hooks/TextViewHook.java index f7036c076..3d2d28498 100644 --- a/app/src/main/java/ru/vtosters/lite/themes/hooks/TextViewHook.java +++ b/app/src/main/java/ru/vtosters/lite/themes/hooks/TextViewHook.java @@ -43,7 +43,7 @@ public class TextViewHook implements BaseHook { @SuppressLint("RestrictedApi") @Override public void inject(View view, int i, boolean z) { - if (view instanceof TextView) { + if (view instanceof TextView && ThemesUtils.isMonetTheme()) { var textView = (TextView) view; if (ColorReferences.isAccentedColor(textView.getCurrentTextColor())) { diff --git a/app/src/main/java/ru/vtosters/lite/themes/hooks/ToolbarHook.java b/app/src/main/java/ru/vtosters/lite/themes/hooks/ToolbarHook.java index 7617a48ba..77aa36153 100644 --- a/app/src/main/java/ru/vtosters/lite/themes/hooks/ToolbarHook.java +++ b/app/src/main/java/ru/vtosters/lite/themes/hooks/ToolbarHook.java @@ -1,5 +1,8 @@ package ru.vtosters.lite.themes.hooks; +import android.graphics.drawable.Drawable; +import android.view.Menu; +import android.view.MenuItem; import android.view.View; import androidx.appcompat.widget.Toolbar; import com.vk.core.drawable.RecoloredDrawable; @@ -9,16 +12,17 @@ public class ToolbarHook implements BaseHook { @Override public void inject(View view, int i, boolean z) { if (view instanceof Toolbar) { - var color = (ThemesUtils.isMilkshake() && !ThemesUtils.isDarkTheme()) ? ThemesUtils.getAccentColor() : ThemesUtils.getHeaderText(); - var menu = ((Toolbar) view).getMenu(); + int color = (ThemesUtils.isMilkshake() && !ThemesUtils.isDarkTheme()) ? ThemesUtils.getAccentColor() : ThemesUtils.getHeaderText(); + Menu menu = ((Toolbar) view).getMenu(); for (int j = 0; j < menu.size(); ++j) { - var item = menu.getItem(j); - var icon = item.getIcon(); + MenuItem item = menu.getItem(j); + Drawable icon = item.getIcon(); if (icon != null) { - if (icon instanceof RecoloredDrawable) + if (icon instanceof RecoloredDrawable) { ((RecoloredDrawable) icon).a(color); - else + } else { icon = new RecoloredDrawable(icon, color); + } item.setIcon(icon); } } diff --git a/app/src/main/java/ru/vtosters/lite/themes/items/VTLPalette.java b/app/src/main/java/ru/vtosters/lite/themes/items/VTLPalette.java index b7bdb8a1b..94ff7b104 100644 --- a/app/src/main/java/ru/vtosters/lite/themes/items/VTLPalette.java +++ b/app/src/main/java/ru/vtosters/lite/themes/items/VTLPalette.java @@ -1,11 +1,13 @@ package ru.vtosters.lite.themes.items; import android.graphics.Color; +import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.util.ArrayList; import java.util.List; +import java.util.stream.IntStream; public class VTLPalette { public String id; @@ -25,29 +27,38 @@ public class VTLPalette { } public static VTLPalette fromJson(JSONObject json) throws JSONException { - var palette = new VTLPalette() + VTLPalette palette = new VTLPalette() .setId(json.optString("palette_id")) .setName(json.optString("name")) .setAuthor(json.optString("author")); - var paletteNode = json.getJSONArray("palette"); - for (int i = 0; i < paletteNode.length(); i++) { - var colorNode = paletteNode.getJSONObject(i); - var name = colorNode.getString("name"); - if (colorNode.has("colors")) { - var colorsNode = colorNode.getJSONArray("colors"); - for (int j = 0; j < colorsNode.length(); j++) { - var subColorNode = colorsNode.getJSONObject(j); - var index = subColorNode.getString("index"); - var subColor = subColorNode.getString("color"); - if (!subColor.startsWith("#")) subColor = "#" + subColor; - palette.setColor(name + " " + index, Color.parseColor(subColor)); - } - } else { - var color = colorNode.getString("color"); - if (!color.startsWith("#")) color = "#" + color; - palette.setColor(name, Color.parseColor(color)); - } - } + JSONArray paletteNode = json.getJSONArray("palette"); + IntStream.range(0, paletteNode.length()) + .mapToObj(paletteNode::optJSONObject) + .forEach(colorNode -> { + String name = colorNode.optString("name"); + if (colorNode.has("colors")) { + JSONArray colorsNode; + try { + colorsNode = colorNode.getJSONArray("colors"); + } catch (JSONException e) { + throw new RuntimeException(e); + } + IntStream.range(0, colorsNode.length()) + .mapToObj(colorsNode::optJSONObject) + .forEach(subColorNode -> { + String index = subColorNode.optString("index"); + String subColor = subColorNode.optString("color"); + if (!subColor.startsWith("#")) subColor = "#" + subColor; + palette.setColor(name + " " + index, Color.parseColor(subColor)); + }); + } else { + String color = colorNode.optString("color"); + if (!color.startsWith("#")) { + color = "#" + color; + } + palette.setColor(name, Color.parseColor(color)); + } + }); return palette; } @@ -79,15 +90,15 @@ public class VTLPalette { return this; } - public VTLPalette setColor(String name, int color) { + public void setColor(String name, int color) { this.colors.add(new VTLColor(name, 0, color)); - return this; } public int getColor(String name) { - for (var item : colors) - if (name.equals(item.resName)) - return item.color; - return -1; + return colors.stream() + .filter(item -> name.equals(item.resName)) + .map(item -> item.color) + .findFirst() + .orElse(-1); } } diff --git a/app/src/main/java/ru/vtosters/lite/themes/loaders/AssetManagerHelper.java b/app/src/main/java/ru/vtosters/lite/themes/loaders/AssetManagerHelper.java index 2ce6d8f94..a187b08eb 100644 --- a/app/src/main/java/ru/vtosters/lite/themes/loaders/AssetManagerHelper.java +++ b/app/src/main/java/ru/vtosters/lite/themes/loaders/AssetManagerHelper.java @@ -2,23 +2,11 @@ package ru.vtosters.lite.themes.loaders; import android.annotation.SuppressLint; import android.content.res.AssetManager; -import ru.vtosters.lite.utils.ReflectionUtils; import java.lang.reflect.InvocationTargetException; @SuppressLint("PrivateApi") public class AssetManagerHelper { - public static String getApkPath(Object assetManager, String packagename) throws InvocationTargetException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException { - Object[] apkAssetsArr = (Object[]) ReflectionUtils.findMethod(Class.forName("android.content.res.ApkAssets"), "getAssetPath").invoke(assetManager); - // By default, base apk is the last element of array if is not, for execution speed, we should iterate array from the end to the beginning - for (int i = apkAssetsArr.length - 1; i >= 0; i--) { - String pathname = (String) ReflectionUtils.findMethod(AssetManager.class, "getApkAssets").invoke(apkAssetsArr[i]); - if (pathname != null && pathname.contains(packagename)) return pathname; - } - - throw new NullPointerException(); - } - //region Uses for adding own assets or getting existing cookies public static void addAssetPath(AssetManager manager, String path) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { manager.getClass().getMethod("addAssetPath", String.class).invoke(manager, path); diff --git a/app/src/main/java/ru/vtosters/lite/themes/loaders/ResourcesLoader.java b/app/src/main/java/ru/vtosters/lite/themes/loaders/ResourcesLoader.java index eecf4d755..83ca828d0 100644 --- a/app/src/main/java/ru/vtosters/lite/themes/loaders/ResourcesLoader.java +++ b/app/src/main/java/ru/vtosters/lite/themes/loaders/ResourcesLoader.java @@ -171,8 +171,6 @@ public class ResourcesLoader { implAssets.set(resourceImpl, sAssetManager); } - clearPreloadTypedArrayIssue(resources); - resources.updateConfiguration(resources.getConfiguration(), resources.getDisplayMetrics()); } @@ -235,33 +233,6 @@ public class ResourcesLoader { } } - /** - * Why must I do these? - * Resource has mTypedArrayPool field, which just like Message Poll to reduce gc - * MiuiResource change TypedArray to MiuiTypedArray, but it get string block from offset instead of assetManager - */ - private static void clearPreloadTypedArrayIssue(Resources resources) { - // Perform this trick not only in Miui system since we can't predict if any other - // manufacturer would do the same modification to Android. - // if (!isMiuiSystem) { - // return; - // } - Log.w("ResourcesLoader", "try to clear typedArray cache!"); - // Clear typedArray cache. - try { - Field typedArrayPoolField = ReflectionUtils.findField(Resources.class, "mTypedArrayPool"); - Object origTypedArrayPool = typedArrayPoolField.get(resources); - Method acquireMethod = ReflectionUtils.findMethod(origTypedArrayPool, "acquire"); - while (true) { - if (acquireMethod.invoke(origTypedArrayPool) == null) { - break; - } - } - } catch (Throwable ignored) { - Log.e("ResourcesLoader", "clearPreloadTypedArrayIssue failed, ignore error: " + ignored); - } - } - private static boolean shouldAddSharedLibraryAssets(ApplicationInfo applicationInfo) { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && applicationInfo != null && applicationInfo.sharedLibraryFiles != null; diff --git a/app/src/main/java/ru/vtosters/lite/themes/palettes/PalettesManager.java b/app/src/main/java/ru/vtosters/lite/themes/palettes/PalettesManager.java index 87db482e0..82cdbdf2c 100644 --- a/app/src/main/java/ru/vtosters/lite/themes/palettes/PalettesManager.java +++ b/app/src/main/java/ru/vtosters/lite/themes/palettes/PalettesManager.java @@ -1,8 +1,8 @@ package ru.vtosters.lite.themes.palettes; +import android.content.res.AssetManager; import android.os.Build; import android.os.Environment; -import android.util.Log; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -15,8 +15,7 @@ import ru.vtosters.lite.utils.LifecycleUtils; import java.io.File; import java.io.IOException; -import java.util.ArrayList; -import java.util.List; +import java.util.*; import static android.widget.Toast.makeText; import static ru.vtosters.lite.utils.AndroidUtils.getGlobalContext; @@ -51,7 +50,7 @@ public class PalettesManager { return; } - var palettes = PALETTES_DIR.listFiles((dir, name) -> name.endsWith(".json")); + File[] palettes = PALETTES_DIR.listFiles((dir, name) -> name.endsWith(".json")); if (palettes == null || palettes.length == 0) copyPaletteFromAssets(); parsePalettes(); @@ -59,45 +58,49 @@ public class PalettesManager { private void copyPaletteFromAssets() { try { - var manager = AndroidUtils.getGlobalContext().getAssets(); - var assets = manager.list(ASSETS_DIR); - if (assets == null || assets.length == 0) return; - for (var asset : assets) { - try { - IOUtils.copy(manager.open(ASSETS_DIR + asset), new File(PALETTES_DIR, asset)); - } catch (IOException e) { - e.printStackTrace(); - } - } + AssetManager manager = getGlobalContext().getAssets(); + Arrays.stream(manager.list(ASSETS_DIR)) + .filter(Objects::nonNull) + .forEach(asset -> { + try { + IOUtils.copy(manager.open(ASSETS_DIR + asset), new File(PALETTES_DIR, asset)); + } catch (IOException e) { + e.fillInStackTrace(); + } + }); } catch (IOException e) { - e.printStackTrace(); + e.fillInStackTrace(); } } private void parsePalettes() { - var arr = PALETTES_DIR.listFiles((dir, name) -> name.endsWith(".json")); - - if (arr == null || arr.length == 0) { - Log.d("PalettesManager", "arr.length null"); - return; - } - - for (var file : arr) { - try { - var json = new JSONObject(IOUtils.readAllLines(file)); - mPalettes.add(VTLPalette.fromJson(json)); - } catch (IOException | JSONException e) { - e.printStackTrace(); - } - } + Optional.ofNullable(PALETTES_DIR.listFiles((dir, name) -> name.endsWith(".json"))) + .ifPresent(arr -> Arrays.stream(arr) + .map(file -> { + try { + return new JSONObject(IOUtils.readAllLines(file)); + } catch (IOException | JSONException e) { + e.printStackTrace(); + return null; + } + }) + .filter(Objects::nonNull) + .map(json -> { + try { + return json != null ? VTLPalette.fromJson(json) : null; + } catch (JSONException e) { + throw new RuntimeException(e); + } + }) + .forEach(mPalettes::add)); } @Nullable public VTLPalette getPalette(String id) { - for (var palette : mPalettes) - if (id.equals(palette.id)) - return palette; - return null; + return mPalettes.stream() + .filter(palette -> id.equals(palette.id)) + .findFirst() + .orElse(null); } @NonNull @@ -108,4 +111,4 @@ public class PalettesManager { public int getPalettesCount() { return mPalettes.size(); } -} +} \ No newline at end of file diff --git a/app/src/main/java/ru/vtosters/lite/themes/utils/ArscEditor.java b/app/src/main/java/ru/vtosters/lite/themes/utils/ArscEditor.java index 4541c0dee..af0f958b0 100644 --- a/app/src/main/java/ru/vtosters/lite/themes/utils/ArscEditor.java +++ b/app/src/main/java/ru/vtosters/lite/themes/utils/ArscEditor.java @@ -4,29 +4,30 @@ import com.google.devrel.gmscore.tools.apk.arsc.BinaryResourceFile; import com.google.devrel.gmscore.tools.apk.arsc.BinaryResourceValue; import com.google.devrel.gmscore.tools.apk.arsc.ResourceTableChunk; +import java.util.AbstractMap; +import java.util.Arrays; + public class ArscEditor { public static void changeColors(BinaryResourceFile arsc, int[] colorIds, int color) { - for (var chunk : arsc.getChunks()) { - var resTableChunk = (ResourceTableChunk) chunk; - for (var packageChunk : resTableChunk.getPackages()) { - for (var typeChunk : packageChunk.getTypeChunks("color")) { - for (var entry : typeChunk.getEntries().entrySet()) { - var value = entry.getValue(); - if (value.isComplex()) continue; - var binValue = value.value(); - if (!isColorResourceValue(binValue)) continue; - var resId = packageChunk.getId() << 24 | typeChunk.getId() << 16 | entry.getKey(); - for (var colodId : colorIds) { - if (resId == colodId) { - binValue.data = color; - break; + arsc.getChunks().stream() + .filter(chunk -> chunk instanceof ResourceTableChunk) + .map(chunk -> (ResourceTableChunk) chunk) + .flatMap(resTableChunk -> resTableChunk.getPackages().stream()) + .flatMap(packageChunk -> packageChunk.getTypeChunks("color").stream() + .map(typeChunk -> new AbstractMap.SimpleEntry<>(packageChunk, typeChunk))) + .forEach(entry -> entry.getValue().getEntries().entrySet().stream() + .filter(e -> !e.getValue().isComplex()) + .filter(e -> isColorResourceValue(e.getValue().value())) + .forEach(e -> { + BinaryResourceValue binValue = e.getValue().value(); + int resId = entry.getKey().getId() << 24 | entry.getValue().getId() << 16 | e.getKey(); + if (Arrays.stream(colorIds).anyMatch(colorId -> resId == colorId)) { + if (binValue != null) { + binValue.data = color; + } } - } - } - } - } - } + })); } private static boolean isColorResourceValue(BinaryResourceValue value) { @@ -35,4 +36,4 @@ public class ArscEditor { || value.type == BinaryResourceValue.Type.INT_COLOR_ARGB4 || value.type == BinaryResourceValue.Type.INT_COLOR_RGB4; } -} +} \ No newline at end of file diff --git a/app/src/main/java/ru/vtosters/lite/themes/utils/RecolorUtils.java b/app/src/main/java/ru/vtosters/lite/themes/utils/RecolorUtils.java index 131e7b9e7..1dae9af0e 100644 --- a/app/src/main/java/ru/vtosters/lite/themes/utils/RecolorUtils.java +++ b/app/src/main/java/ru/vtosters/lite/themes/utils/RecolorUtils.java @@ -3,27 +3,55 @@ package ru.vtosters.lite.themes.utils; import android.annotation.SuppressLint; import android.content.Context; import android.content.res.ColorStateList; +import android.content.res.Configuration; +import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Color; import android.graphics.drawable.Drawable; import android.os.Build; +import android.util.SparseArray; +import android.util.TypedValue; import android.widget.TextView; +import androidx.annotation.ColorRes; +import androidx.annotation.NonNull; +import androidx.core.content.res.ColorStateListInflaterCompat; import com.vk.core.drawable.RecoloredDrawable; import ru.vtosters.hooks.other.ThemesUtils; import ru.vtosters.lite.themes.ColorReferences; import ru.vtosters.lite.themes.ThemesManager; import ru.vtosters.lite.utils.AndroidUtils; +import java.util.WeakHashMap; + public class RecolorUtils { - public static Drawable recolorDrawableToolbar(Drawable drawable) { - if (drawable == null) return null; + private static final ThreadLocal TL_TYPED_VALUE = new ThreadLocal<>(); + private static final WeakHashMap> sColorStateCaches = new WeakHashMap<>(0); + private static final Object sColorStateCacheLock = new Object(); - return new RecoloredDrawable(drawable, ThemesUtils.getHeaderText()); - } // Recolor toolbar drawable to accent color + private static void addColorStateListToCache(@NonNull Context context, @ColorRes int i, @NonNull ColorStateList colorStateList) { + synchronized (sColorStateCacheLock) { + SparseArray sparseArray = sColorStateCaches.get(context); + if (sparseArray == null) { + sparseArray = new SparseArray<>(); + sColorStateCaches.put(context, sparseArray); + } + sparseArray.append(i, new ColorStateListCacheEntry(colorStateList, context.getResources().getConfiguration())); + } + } - public static Drawable recolorDrawableInt(int drawable) { - return recolorDrawable(drawable, ThemesUtils.getAccentColor()); - } // Get res drawable via id and coloring to accent + private static ColorStateList getCachedColorStateList(@NonNull Context context, @ColorRes int i) { + ColorStateListCacheEntry colorStateListCacheEntry; + synchronized (sColorStateCacheLock) { + SparseArray sparseArray = sColorStateCaches.get(context); + if (sparseArray != null && sparseArray.size() > 0 && (colorStateListCacheEntry = sparseArray.get(i)) != null) { + if (colorStateListCacheEntry.configuration.equals(context.getResources().getConfiguration())) { + return colorStateListCacheEntry.value; + } + sparseArray.remove(i); + } + return null; + } + } public static Drawable recolorDrawable(int drawable, int color) { return new RecoloredDrawable(AndroidUtils.getResources().getDrawable(drawable), color); @@ -34,19 +62,19 @@ public class RecolorUtils { } public static int getColor(TypedArray ta, int index, int defval) { - return recolorHexColor(ta.getColor(index, defval)); + return ThemesUtils.isMonetTheme() ? ta.getColor(index, defval) : recolorHexColor(ta.getColor(index, defval)); } public static void recolorTextView(TextView tw) { - if (ColorReferences.isAccentedColor(tw.getTextColors())) { + if (ColorReferences.isAccentedColor(tw.getTextColors()) && ThemesUtils.isMonetTheme()) { tw.setTextColor(ThemesUtils.getAccentColor()); } } public static int recolorHexColor(int i) { if (!ThemesUtils.isMonetTheme() || !ThemesManager.canApplyCustomAccent()) return i; - var accented = ColorReferences.isAccentedColor(i); - var mutedaccented = ColorReferences.isMutedAccentedColor(i); + boolean accented = ColorReferences.isAccentedColor(i); + boolean mutedaccented = ColorReferences.isMutedAccentedColor(i); return (accented || mutedaccented) ? (accented ? ThemesUtils.getAccentColor() : ThemesUtils.getMutedAccentColor()) : i; } @@ -56,9 +84,51 @@ public class RecolorUtils { return ColorStateList.valueOf(ThemesUtils.getAccentColor()); } // Recolor ColorStateList to accent color + @SuppressLint("RestrictedApi") + private static ColorStateList inflateColorStateList(Context context, int i) { + if (isColorInt(context, i)) { + return null; + } + Resources resources = context.getResources(); + try { + return ColorStateListInflaterCompat.createFromXml(resources, resources.getXml(i), context.getTheme()); + } catch (Exception e) { + return null; + } + } + + private static boolean isColorInt(@NonNull Context context, @ColorRes int i) { + Resources resources = context.getResources(); + TypedValue typedValue = getTypedValue(); + resources.getValue(i, typedValue, true); + int i2 = typedValue.type; + return i2 >= 28 && i2 <= 31; + } + + private static TypedValue getTypedValue() { + TypedValue typedValue = TL_TYPED_VALUE.get(); + if (typedValue == null) { + TypedValue typedValue2 = new TypedValue(); + TL_TYPED_VALUE.set(typedValue2); + return typedValue2; + } + return typedValue; + } + @SuppressLint("UseCompatLoadingForColorStateLists") public static ColorStateList themeCSL(Context context, int color) { if (!ThemesUtils.isMonetTheme()) { + ColorStateList cachedColorStateList = getCachedColorStateList(context, color); + if (cachedColorStateList != null) { + return cachedColorStateList; + } + + ColorStateList inflateColorStateList = inflateColorStateList(context, color); + if (inflateColorStateList != null) { + addColorStateListToCache(context, color, inflateColorStateList); + return inflateColorStateList; + } + if (Build.VERSION.SDK_INT >= 23) { return context.getColorStateList(color); } else { @@ -72,15 +142,7 @@ public class RecolorUtils { return ColorStateList.valueOf(ThemesUtils.getMutedAccentColor()); } - ColorStateList csl; - - if (Build.VERSION.SDK_INT >= 23) { - csl = context.getColorStateList(color); - } else { - csl = context.getResources().getColorStateList(color); - } - - return themeCSL(csl); + return themeCSL(context.getColorStateList(color)); } // Recolor ColorStateList public static ColorStateList themeCSL(ColorStateList csl) { @@ -120,4 +182,14 @@ public class RecolorUtils { return null; } } + + static class ColorStateListCacheEntry { + final Configuration configuration; + final ColorStateList value; + + ColorStateListCacheEntry(@NonNull ColorStateList colorStateList, @NonNull Configuration configuration) { + this.value = colorStateList; + this.configuration = configuration; + } + } } diff --git a/app/src/main/java/ru/vtosters/lite/themes/utils/VkUiThemer.java b/app/src/main/java/ru/vtosters/lite/themes/utils/VkUiThemer.java index 64716a393..349a9248b 100644 --- a/app/src/main/java/ru/vtosters/lite/themes/utils/VkUiThemer.java +++ b/app/src/main/java/ru/vtosters/lite/themes/utils/VkUiThemer.java @@ -74,7 +74,7 @@ public class VkUiThemer { } } catch (Exception e) { // This must go wrong, so we ignore any exceptions that may occur - e.printStackTrace(); // REMOVE THIS! + e.fillInStackTrace(); // REMOVE THIS! } } } \ No newline at end of file diff --git a/app/src/main/java/ru/vtosters/lite/ui/fragments/ThemesFragment.java b/app/src/main/java/ru/vtosters/lite/ui/fragments/ThemesFragment.java index 5961d092e..6455ce836 100644 --- a/app/src/main/java/ru/vtosters/lite/ui/fragments/ThemesFragment.java +++ b/app/src/main/java/ru/vtosters/lite/ui/fragments/ThemesFragment.java @@ -109,7 +109,7 @@ public class ThemesFragment extends TrackedMaterialPreferenceToolbarFragment { newsfeedNotificationsPreference.setVisible(Preferences.milkshake()); - findPreference("accentprefs").setVisible(!ThemesUtils.isMonetTheme()); + findPreference("accentprefs").setVisible(!ThemesUtils.isMonetTheme() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M); findPreference("systememoji").setOnPreferenceClickListener(preference -> { restart(); From b05a239b9009b98cb5d60c888f82a6d66d477dcd Mon Sep 17 00:00:00 2001 From: Tahgolov Date: Sun, 18 Feb 2024 23:05:31 +0300 Subject: [PATCH 5/9] improve code readability, remove redundant constructions --- .../ru/vtosters/lite/themes/VTLResources.java | 86 ++++++++++--------- 1 file changed, 46 insertions(+), 40 deletions(-) diff --git a/app/src/main/java/ru/vtosters/lite/themes/VTLResources.java b/app/src/main/java/ru/vtosters/lite/themes/VTLResources.java index 328043365..120c0f5e6 100644 --- a/app/src/main/java/ru/vtosters/lite/themes/VTLResources.java +++ b/app/src/main/java/ru/vtosters/lite/themes/VTLResources.java @@ -1,5 +1,6 @@ package ru.vtosters.lite.themes; +import android.annotation.SuppressLint; import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; @@ -7,30 +8,35 @@ import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.util.Log; import android.util.TypedValue; + import androidx.annotation.Nullable; -import ru.vtosters.hooks.other.ThemesUtils; import java.lang.reflect.Field; -import java.util.ArrayList; +import java.util.Arrays; import java.util.List; -import java.util.stream.IntStream; +import ru.vtosters.hooks.other.ThemesUtils; + +@SuppressLint("DiscouragedPrivateApi") public class VTLResources extends Resources { private static final String TAG = "VTLResources"; - private static final List attributesToTheme = new ArrayList<>(); - private static Field typedArrayField; + private static final List attributesToTheme = + Arrays.asList( + 0x1010121, + android.R.attr.backgroundTint, + 0x10101a5 + ); + private static final int STYLE_NUM_ENTRIES = 6; + + private static Field typedArrayDataFld = null; static { try { - typedArrayField = TypedArray.class.getDeclaredField("mData"); - typedArrayField.setAccessible(true); - } catch (NoSuchFieldException e) { + typedArrayDataFld = TypedArray.class.getDeclaredField("mData"); + typedArrayDataFld.setAccessible(true); + } catch (final NoSuchFieldException e) { e.printStackTrace(); } - - attributesToTheme.add(16843041); - attributesToTheme.add(android.R.attr.backgroundTint); - attributesToTheme.add(16843173); } public VTLResources(Context context, Resources parent) { @@ -41,42 +47,42 @@ public class VTLResources extends Resources { return !ThemesUtils.isDarkTheme() && attrID == com.vtosters.lite.R.attr.button_primary_background; } - private static int[] getArrayData(TypedArray arr) { - try { - return (int[]) typedArrayField.get(arr); - } catch (IllegalAccessException e) { - Log.e(TAG, "getArrayData: ", e); - e.fillInStackTrace(); - return new int[0]; - } + private static int[] getArrayData(final TypedArray ta) { + if (typedArrayDataFld != null) + try { + return (int[]) typedArrayDataFld.get(ta); + } catch (final IllegalAccessException e) { + Log.e(TAG, "getArrayData: ", e); + e.fillInStackTrace(); + } + return null; } @Override public TypedArray obtainAttributes(AttributeSet set, int[] attrs) { - TypedArray typedArray = super.obtainAttributes(set, attrs); - + final var ta = super.obtainAttributes(set, attrs); if (ThemesUtils.isMonetTheme()) { - int[] data = getArrayData(typedArray); - IntStream.range(0, attrs.length).forEach(i -> { - try { - int attrID = attrs[i]; - if (attributesToTheme.contains(attrID)) { - int type = data[i * 6]; - int cnt = data[(i * 6) + 1]; + final var mData = getArrayData(ta); + if (mData != null) + for (var i = 0; i < attrs.length; ++i) { + final var attr = attrs[i]; + if (attributesToTheme.contains(attr)) continue; - if (type == TypedValue.TYPE_ATTRIBUTE && isAttrThemeable(cnt)) { - data[i * 6] = TypedValue.TYPE_INT_COLOR_RGB8; - data[(i * 6) + 1] = ThemesUtils.getAccentColor(); - data[(i * 6) + 2] = 0; // clear reference content - } - } - } catch (Exception e) { - Log.e(TAG, "TAVzlom failed! (obtainAttributes)"); - e.fillInStackTrace(); + final var index = i * STYLE_NUM_ENTRIES; + final var typeIndex = index; + final var dataIndex = index + 1; + final var resourceIdIndex = index + 2; + + if(mData[typeIndex] == TypedValue.TYPE_ATTRIBUTE + || isAttrThemeable(mData[dataIndex])) + continue; + + mData[typeIndex] = TypedValue.TYPE_INT_COLOR_ARGB8; + mData[dataIndex] = ThemesUtils.getAccentColor(); + mData[resourceIdIndex] = 0; } - }); } - return typedArray; + return ta; } @Override From 84cf9ba10a35ff7ced2fa2e0f19c64d6421965c8 Mon Sep 17 00:00:00 2001 From: Tahgolov Date: Sun, 18 Feb 2024 23:07:19 +0300 Subject: [PATCH 6/9] rollback to for-loops with improvements --- .../lite/themes/utils/ArscEditor.java | 54 +++++++++---------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/app/src/main/java/ru/vtosters/lite/themes/utils/ArscEditor.java b/app/src/main/java/ru/vtosters/lite/themes/utils/ArscEditor.java index af0f958b0..0d7525089 100644 --- a/app/src/main/java/ru/vtosters/lite/themes/utils/ArscEditor.java +++ b/app/src/main/java/ru/vtosters/lite/themes/utils/ArscEditor.java @@ -1,39 +1,37 @@ package ru.vtosters.lite.themes.utils; import com.google.devrel.gmscore.tools.apk.arsc.BinaryResourceFile; -import com.google.devrel.gmscore.tools.apk.arsc.BinaryResourceValue; +import com.google.devrel.gmscore.tools.apk.arsc.BinaryResourceIdentifier; import com.google.devrel.gmscore.tools.apk.arsc.ResourceTableChunk; -import java.util.AbstractMap; -import java.util.Arrays; +import ru.vtosters.lite.utils.AndroidUtils; public class ArscEditor { - public static void changeColors(BinaryResourceFile arsc, int[] colorIds, int color) { - arsc.getChunks().stream() - .filter(chunk -> chunk instanceof ResourceTableChunk) - .map(chunk -> (ResourceTableChunk) chunk) - .flatMap(resTableChunk -> resTableChunk.getPackages().stream()) - .flatMap(packageChunk -> packageChunk.getTypeChunks("color").stream() - .map(typeChunk -> new AbstractMap.SimpleEntry<>(packageChunk, typeChunk))) - .forEach(entry -> entry.getValue().getEntries().entrySet().stream() - .filter(e -> !e.getValue().isComplex()) - .filter(e -> isColorResourceValue(e.getValue().value())) - .forEach(e -> { - BinaryResourceValue binValue = e.getValue().value(); - int resId = entry.getKey().getId() << 24 | entry.getValue().getId() << 16 | e.getKey(); - if (Arrays.stream(colorIds).anyMatch(colorId -> resId == colorId)) { - if (binValue != null) { - binValue.data = color; - } - } - })); - } + public static void changeColors(final BinaryResourceFile arsc, final int[] colorResIds, final int color) { + for (var chunk : arsc.getChunks()) { + if (!(chunk instanceof ResourceTableChunk)) continue; - private static boolean isColorResourceValue(BinaryResourceValue value) { - return value.type == BinaryResourceValue.Type.INT_COLOR_ARGB8 - || value.type == BinaryResourceValue.Type.INT_COLOR_RGB8 - || value.type == BinaryResourceValue.Type.INT_COLOR_ARGB4 - || value.type == BinaryResourceValue.Type.INT_COLOR_RGB4; + final var resTableChunk = (ResourceTableChunk) chunk; + final var pacChunk = resTableChunk.getPackage(AndroidUtils.getPackageName()); + if (pacChunk == null) continue; + + for (var typeChunk : pacChunk.getTypeChunks("color")) + for (var resId : colorResIds) { + final var binResId = BinaryResourceIdentifier.create(resId); + + final var pacId = pacChunk.getId(); + final var typeId = typeChunk.getId(); + if (pacId != binResId.packageId() + || typeId != binResId.typeId()) + continue; + + final var entry = typeChunk.getEntries().getOrDefault(binResId.entryId(), null); + if (entry == null || entry.isComplex()) continue; + + final var binResVal = entry.value(); + binResVal.data = color; + } + } } } \ No newline at end of file From 18ef4eda2196b9d296bca7c4e42367e665833342 Mon Sep 17 00:00:00 2001 From: gdlbo <41114720+gdlbo@users.noreply.github.com> Date: Mon, 19 Feb 2024 11:38:10 +0300 Subject: [PATCH 7/9] Revert "rollback to for-loops with improvements" This reverts commit 84cf9ba10a35ff7ced2fa2e0f19c64d6421965c8. --- .../lite/themes/utils/ArscEditor.java | 54 ++++++++++--------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/app/src/main/java/ru/vtosters/lite/themes/utils/ArscEditor.java b/app/src/main/java/ru/vtosters/lite/themes/utils/ArscEditor.java index 0d7525089..af0f958b0 100644 --- a/app/src/main/java/ru/vtosters/lite/themes/utils/ArscEditor.java +++ b/app/src/main/java/ru/vtosters/lite/themes/utils/ArscEditor.java @@ -1,37 +1,39 @@ package ru.vtosters.lite.themes.utils; import com.google.devrel.gmscore.tools.apk.arsc.BinaryResourceFile; -import com.google.devrel.gmscore.tools.apk.arsc.BinaryResourceIdentifier; +import com.google.devrel.gmscore.tools.apk.arsc.BinaryResourceValue; import com.google.devrel.gmscore.tools.apk.arsc.ResourceTableChunk; -import ru.vtosters.lite.utils.AndroidUtils; +import java.util.AbstractMap; +import java.util.Arrays; public class ArscEditor { - public static void changeColors(final BinaryResourceFile arsc, final int[] colorResIds, final int color) { - for (var chunk : arsc.getChunks()) { - if (!(chunk instanceof ResourceTableChunk)) continue; + public static void changeColors(BinaryResourceFile arsc, int[] colorIds, int color) { + arsc.getChunks().stream() + .filter(chunk -> chunk instanceof ResourceTableChunk) + .map(chunk -> (ResourceTableChunk) chunk) + .flatMap(resTableChunk -> resTableChunk.getPackages().stream()) + .flatMap(packageChunk -> packageChunk.getTypeChunks("color").stream() + .map(typeChunk -> new AbstractMap.SimpleEntry<>(packageChunk, typeChunk))) + .forEach(entry -> entry.getValue().getEntries().entrySet().stream() + .filter(e -> !e.getValue().isComplex()) + .filter(e -> isColorResourceValue(e.getValue().value())) + .forEach(e -> { + BinaryResourceValue binValue = e.getValue().value(); + int resId = entry.getKey().getId() << 24 | entry.getValue().getId() << 16 | e.getKey(); + if (Arrays.stream(colorIds).anyMatch(colorId -> resId == colorId)) { + if (binValue != null) { + binValue.data = color; + } + } + })); + } - final var resTableChunk = (ResourceTableChunk) chunk; - final var pacChunk = resTableChunk.getPackage(AndroidUtils.getPackageName()); - if (pacChunk == null) continue; - - for (var typeChunk : pacChunk.getTypeChunks("color")) - for (var resId : colorResIds) { - final var binResId = BinaryResourceIdentifier.create(resId); - - final var pacId = pacChunk.getId(); - final var typeId = typeChunk.getId(); - if (pacId != binResId.packageId() - || typeId != binResId.typeId()) - continue; - - final var entry = typeChunk.getEntries().getOrDefault(binResId.entryId(), null); - if (entry == null || entry.isComplex()) continue; - - final var binResVal = entry.value(); - binResVal.data = color; - } - } + private static boolean isColorResourceValue(BinaryResourceValue value) { + return value.type == BinaryResourceValue.Type.INT_COLOR_ARGB8 + || value.type == BinaryResourceValue.Type.INT_COLOR_RGB8 + || value.type == BinaryResourceValue.Type.INT_COLOR_ARGB4 + || value.type == BinaryResourceValue.Type.INT_COLOR_RGB4; } } \ No newline at end of file From 67f1477907fb8c6c6c26f827885210ca4d015674 Mon Sep 17 00:00:00 2001 From: gdlbo <41114720+gdlbo@users.noreply.github.com> Date: Mon, 19 Feb 2024 11:38:11 +0300 Subject: [PATCH 8/9] Revert "improve code readability, remove redundant constructions" This reverts commit b05a239b9009b98cb5d60c888f82a6d66d477dcd. --- .../ru/vtosters/lite/themes/VTLResources.java | 90 +++++++++---------- 1 file changed, 42 insertions(+), 48 deletions(-) diff --git a/app/src/main/java/ru/vtosters/lite/themes/VTLResources.java b/app/src/main/java/ru/vtosters/lite/themes/VTLResources.java index 120c0f5e6..328043365 100644 --- a/app/src/main/java/ru/vtosters/lite/themes/VTLResources.java +++ b/app/src/main/java/ru/vtosters/lite/themes/VTLResources.java @@ -1,6 +1,5 @@ package ru.vtosters.lite.themes; -import android.annotation.SuppressLint; import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; @@ -8,35 +7,30 @@ import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.util.Log; import android.util.TypedValue; - import androidx.annotation.Nullable; - -import java.lang.reflect.Field; -import java.util.Arrays; -import java.util.List; - import ru.vtosters.hooks.other.ThemesUtils; -@SuppressLint("DiscouragedPrivateApi") +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.IntStream; + public class VTLResources extends Resources { private static final String TAG = "VTLResources"; - private static final List attributesToTheme = - Arrays.asList( - 0x1010121, - android.R.attr.backgroundTint, - 0x10101a5 - ); - private static final int STYLE_NUM_ENTRIES = 6; - - private static Field typedArrayDataFld = null; + private static final List attributesToTheme = new ArrayList<>(); + private static Field typedArrayField; static { try { - typedArrayDataFld = TypedArray.class.getDeclaredField("mData"); - typedArrayDataFld.setAccessible(true); - } catch (final NoSuchFieldException e) { + typedArrayField = TypedArray.class.getDeclaredField("mData"); + typedArrayField.setAccessible(true); + } catch (NoSuchFieldException e) { e.printStackTrace(); } + + attributesToTheme.add(16843041); + attributesToTheme.add(android.R.attr.backgroundTint); + attributesToTheme.add(16843173); } public VTLResources(Context context, Resources parent) { @@ -47,42 +41,42 @@ public class VTLResources extends Resources { return !ThemesUtils.isDarkTheme() && attrID == com.vtosters.lite.R.attr.button_primary_background; } - private static int[] getArrayData(final TypedArray ta) { - if (typedArrayDataFld != null) - try { - return (int[]) typedArrayDataFld.get(ta); - } catch (final IllegalAccessException e) { - Log.e(TAG, "getArrayData: ", e); - e.fillInStackTrace(); - } - return null; + private static int[] getArrayData(TypedArray arr) { + try { + return (int[]) typedArrayField.get(arr); + } catch (IllegalAccessException e) { + Log.e(TAG, "getArrayData: ", e); + e.fillInStackTrace(); + return new int[0]; + } } @Override public TypedArray obtainAttributes(AttributeSet set, int[] attrs) { - final var ta = super.obtainAttributes(set, attrs); + TypedArray typedArray = super.obtainAttributes(set, attrs); + if (ThemesUtils.isMonetTheme()) { - final var mData = getArrayData(ta); - if (mData != null) - for (var i = 0; i < attrs.length; ++i) { - final var attr = attrs[i]; - if (attributesToTheme.contains(attr)) continue; + int[] data = getArrayData(typedArray); + IntStream.range(0, attrs.length).forEach(i -> { + try { + int attrID = attrs[i]; + if (attributesToTheme.contains(attrID)) { + int type = data[i * 6]; + int cnt = data[(i * 6) + 1]; - final var index = i * STYLE_NUM_ENTRIES; - final var typeIndex = index; - final var dataIndex = index + 1; - final var resourceIdIndex = index + 2; - - if(mData[typeIndex] == TypedValue.TYPE_ATTRIBUTE - || isAttrThemeable(mData[dataIndex])) - continue; - - mData[typeIndex] = TypedValue.TYPE_INT_COLOR_ARGB8; - mData[dataIndex] = ThemesUtils.getAccentColor(); - mData[resourceIdIndex] = 0; + if (type == TypedValue.TYPE_ATTRIBUTE && isAttrThemeable(cnt)) { + data[i * 6] = TypedValue.TYPE_INT_COLOR_RGB8; + data[(i * 6) + 1] = ThemesUtils.getAccentColor(); + data[(i * 6) + 2] = 0; // clear reference content + } + } + } catch (Exception e) { + Log.e(TAG, "TAVzlom failed! (obtainAttributes)"); + e.fillInStackTrace(); } + }); } - return ta; + return typedArray; } @Override From d10d5eca4b64a610053f99609e843bc48fe34a94 Mon Sep 17 00:00:00 2001 From: gdlbo <41114720+gdlbo@users.noreply.github.com> Date: Mon, 19 Feb 2024 15:39:41 +0300 Subject: [PATCH 9/9] fixed auto updating filters --- .../vtosters/sponsorpost/utils/FiltersPreferences.java | 10 ++++++++-- .../java/ru/vtosters/sponsorpost/utils/Updates.java | 5 ++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/ru/vtosters/sponsorpost/utils/FiltersPreferences.java b/app/src/main/java/ru/vtosters/sponsorpost/utils/FiltersPreferences.java index 6b773f7b5..a8ff8bf46 100644 --- a/app/src/main/java/ru/vtosters/sponsorpost/utils/FiltersPreferences.java +++ b/app/src/main/java/ru/vtosters/sponsorpost/utils/FiltersPreferences.java @@ -31,8 +31,14 @@ public class FiltersPreferences { return AndroidUtils.getGlobalContext().getSharedPreferences("ru.vtosters.sponsorpost.filters.prefs", Context.MODE_PRIVATE); } - public static void clearAll() { - preferences.edit().clear().apply(); + public static void clearAllCachedLists() { + SharedPreferences.Editor editor = preferences.edit(); + + preferences.getAll().keySet().stream() + .filter(key -> key.endsWith(":" + PREF_KEY_LIST)) + .forEach(editor::remove); + + editor.apply(); } public static boolean getSavedKeyValue(int id) { diff --git a/app/src/main/java/ru/vtosters/sponsorpost/utils/Updates.java b/app/src/main/java/ru/vtosters/sponsorpost/utils/Updates.java index 91c665e95..734e8f291 100644 --- a/app/src/main/java/ru/vtosters/sponsorpost/utils/Updates.java +++ b/app/src/main/java/ru/vtosters/sponsorpost/utils/Updates.java @@ -2,6 +2,7 @@ package ru.vtosters.sponsorpost.utils; import ru.vtosters.hooks.other.Preferences; import ru.vtosters.lite.utils.NetworkUtils; +import ru.vtosters.lite.utils.newsfeed.NewsFeedFiltersUtils; import ru.vtosters.sponsorpost.data.Filter; import ru.vtosters.sponsorpost.data.Post; import ru.vtosters.sponsorpost.services.FilterService; @@ -23,7 +24,7 @@ public class Updates { List localFilters = FiltersPreferences.getAllDownloadedFilters(); if (!filters.isEmpty()) { - FiltersPreferences.clearAll(); // removes deleted filters from server + FiltersPreferences.clearAllCachedLists(); // removes deleted filters from server and cache for (Filter filter : filters) { Filter localFilter = findLocalFilterById(localFilters, filter.getId()); @@ -39,6 +40,8 @@ public class Updates { } } } + + NewsFeedFiltersUtils.updateFilters(); } }