refactor code

This commit is contained in:
gdlbo
2023-02-19 16:49:02 +03:00
parent 9fd01db880
commit 44aff4f30d
11 changed files with 182 additions and 186 deletions
@@ -20,7 +20,7 @@ public class ColorReferences {
Color.parseColor("#5c9ce6"),
Color.parseColor("#518bcc"),
Color.parseColor("#74a2d6")
);
);
public static List<Integer> mutedAccentColors = Arrays.asList(
Color.parseColor("#663f8ae0"),
@@ -4,9 +4,7 @@ import android.annotation.SuppressLint;
import android.content.Context;
import android.util.SparseBooleanArray;
import android.util.SparseIntArray;
import androidx.annotation.IdRes;
import com.vtosters.lite.R;
import ru.vtosters.lite.utils.ThemesUtils;
@@ -94,7 +92,7 @@ public class ThemesCore {
themedColors.put(R.attr.accentColor, accentColor);
themedColors.put(R.attr.text_name, accentColor);
themedColors.put(R.attr.tabbar_active_icon, accentColor);
// themedColors.put(com.vtosters.lite.R.attr.header_background, accentColor);
// themedColors.put(com.vtosters.lite.R.attr.header_alternate_background, accentColor);
// themedColors.put(com.vtosters.lite.R.attr.header_background_before_blur, accentColor);
@@ -172,13 +170,13 @@ public class ThemesCore {
if (ThemesUtils.isDarkTheme()) {
return (themedColors.get(attrID) != 0 && ACCENT_THEME_ONLY_DARK.get(attrID, true) && (
ThemesUtils.isMilkshake() ?
ACCENT_THEME_ONLY_MILK_DARK.get(attrID, true) :
ACCENT_THEME_ONLY_NOMILK_DARK.get(attrID, true)));
ACCENT_THEME_ONLY_MILK_DARK.get(attrID, true) :
ACCENT_THEME_ONLY_NOMILK_DARK.get(attrID, true)));
} else {
return (themedColors.get(attrID) != 0 && ACCENT_THEME_ONLY_LIGHT.get(attrID, true) && (
ThemesUtils.isMilkshake() ?
ACCENT_THEME_ONLY_MILK_LIGHT.get(attrID, true) :
ACCENT_THEME_ONLY_NOMILK_LIGHT.get(attrID, true)));
ACCENT_THEME_ONLY_MILK_LIGHT.get(attrID, true) :
ACCENT_THEME_ONLY_NOMILK_LIGHT.get(attrID, true)));
}
} else {
return themedColors.get(attrID) != 0;
@@ -10,7 +10,10 @@ import ru.vtosters.lite.themes.utils.ArscEditor;
import ru.vtosters.lite.utils.IOUtils;
import ru.vtosters.lite.utils.ThemesUtils;
import java.io.*;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
@@ -129,24 +132,24 @@ public class ThemesManager {
Log.d("ThemesManager", "init paths");
initPaths(app);
if(hasTmpArchive() && !ThemesUtils.isMonetTheme()) {
if (hasTmpArchive() && !ThemesUtils.isMonetTheme()) {
ResourcesLoader.init(app);
ResourcesLoader.load(app, resTmpZipFile.getAbsolutePath(), assetsZipFile.getAbsolutePath(), false);
}
} catch(Exception e) {
Log.e("ThemesManager", e+"");
} catch (Exception e) {
Log.e("ThemesManager", String.valueOf(e));
}
}
private static void initPaths(Context context) {
mainDir = new File(context.getFilesDir(), "VTLThemes");
if(!mainDir.exists()) mainDir.mkdir();
if (!mainDir.exists()) mainDir.mkdir();
binDir = new File(mainDir, "bin");
if(!binDir.exists()) mainDir.mkdir();
if (!binDir.exists()) mainDir.mkdir();
palettesDir = new File(mainDir, "palettes");
if(!palettesDir.exists()) palettesDir.mkdir();
if (!palettesDir.exists()) palettesDir.mkdir();
assetsZipFile = new File(binDir, "assets.zip");
resZipFile = new File(binDir, "res.zip");
@@ -155,32 +158,32 @@ public class ThemesManager {
}
public static void generateBins(Context context)
throws IOException {
try(final var apk = new ZipFile(context.getApplicationInfo().sourceDir)) {
for(var filename : NAMES) {
throws IOException {
try (final var apk = new ZipFile(context.getApplicationInfo().sourceDir)) {
for (var filename : NAMES) {
final var bin = new File(binDir, filename);
if(!bin.exists())
if(filename.contains(".")) extractFile(apk, filename, bin);
if (!bin.exists())
if (filename.contains(".")) extractFile(apk, filename, bin);
else extractAndCompressDirectory(apk, filename, new File(binDir, filename + ".zip"));
}
}
}
private static void extractFile(ZipFile apk, String name, File out)
throws IOException {
throws IOException {
final var is = apk.getInputStream(apk.getEntry(name));
if(!out.exists()) out.getParentFile().mkdirs();
if (!out.exists()) out.getParentFile().mkdirs();
IOUtils.copy(is, out);
}
private static void extractAndCompressDirectory(ZipFile apk, String dirName, File out)
throws IOException {
throws IOException {
final var zos = new ZipOutputStream(new FileOutputStream(out));
try(zos) {
try (zos) {
final var entries = apk.entries();
while(entries.hasMoreElements()) {
while (entries.hasMoreElements()) {
final var entry = entries.nextElement();
if(!entry.getName().startsWith(dirName + "/")) continue;
if (!entry.getName().startsWith(dirName + "/")) continue;
zos.putNextEntry(new ZipEntry(entry.getName()));
@@ -202,12 +205,12 @@ public class ThemesManager {
}
public static void generateTempResArchive(int accentColor)
throws IOException {
throws IOException {
final var resZip = new ZipFile(resZipFile);
final var zos = new ZipOutputStream(new FileOutputStream(resTmpZipFile));
try(zos) {
try (zos) {
final var entries = resZip.entries();
while(entries.hasMoreElements()) {
while (entries.hasMoreElements()) {
final var entry = entries.nextElement();
final var is = resZip.getInputStream(entry);
@@ -219,7 +222,7 @@ public class ThemesManager {
}
final var arsc = new BinaryResourceFile(IOUtils.readFully(resourcesArscFile));
if(!ArscEditor.changeColors(arsc, ACCENT_COLORS, accentColor)) {
if (!ArscEditor.changeColors(arsc, ACCENT_COLORS, accentColor)) {
resZip.close();
resTmpZipFile.delete();
throw new IOException("Error while generating res.tmp.res");
@@ -7,21 +7,17 @@ import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import androidx.annotation.Nullable;
import ru.vtosters.lite.utils.ThemesUtils;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import ru.vtosters.lite.utils.ThemesUtils;
public class VTLResources extends Resources {
private static final String TAG = "VTLResources";
private final Context context;
private static Field typedArrayField;
private static final List<Integer> attributesToTheme = new ArrayList<>();
private static Field typedArrayField;
static {
try {
@@ -36,12 +32,28 @@ 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) {
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.printStackTrace();
return new int[0];
}
}
@Override
public TypedArray obtainAttributes(AttributeSet set, int[] attrs) {
var typedArray = super.obtainAttributes(set, attrs);
@@ -50,13 +62,13 @@ public class VTLResources extends Resources {
try {
int attrID = attrs[i];
if (attributesToTheme.contains(attrID)) {
int type = data[i*6];
int cnt = data[(i*6)+1];
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
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) {
@@ -75,18 +87,4 @@ public class VTLResources extends Resources {
}
return drawable;
}
private static boolean isAttrThemeable(int attrID) {
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.printStackTrace();
return new int[0];
}
}
}
@@ -10,6 +10,7 @@ public class VTLColor {
this.id = id;
this.color = color;
}
public VTLColor(String resName, int id, int color) {
this.resName = resName;
this.id = id;
@@ -1,7 +1,6 @@
package ru.vtosters.lite.themes.items;
import android.graphics.Color;
import org.json.JSONException;
import org.json.JSONObject;
@@ -25,38 +24,6 @@ public class VTLPalette {
this.colors = colors;
}
public VTLPalette setId(String id) {
this.id = id;
return this;
}
public VTLPalette setName(String name) {
this.name = name;
return this;
}
public VTLPalette setAuthor(String author) {
this.author = author;
return this;
}
public VTLPalette setColors(List<VTLColor> colors) {
this.colors = colors;
return this;
}
public VTLPalette 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;
}
public static VTLPalette fromJson(JSONObject json) throws JSONException {
var palette = new VTLPalette()
.setId(json.optString("palette_id"))
@@ -91,4 +58,36 @@ public class VTLPalette {
.setAuthor(author)
.setColors(colors);
}
public VTLPalette setId(String id) {
this.id = id;
return this;
}
public VTLPalette setName(String name) {
this.name = name;
return this;
}
public VTLPalette setAuthor(String author) {
this.author = author;
return this;
}
public VTLPalette setColors(List<VTLColor> colors) {
this.colors = colors;
return this;
}
public VTLPalette 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;
}
}
@@ -15,6 +15,7 @@ public class AssetManagerHelper {
private final static Method addAssetPathMtd;
private final static Method addAssetPathAsSharedLibraryMtd;
private final static Method addOverlayPathMtd;
static {
try {
getAssetPathMtd = ReflectionUtils.findMethod(Class.forName("android.content.res.ApkAssets"), "getAssetPath");
@@ -22,7 +23,7 @@ public class AssetManagerHelper {
addAssetPathMtd = AssetManager.class.getMethod("addAssetPath", String.class);
addAssetPathAsSharedLibraryMtd = AssetManager.class.getMethod("addAssetPathAsSharedLibrary", String.class);
addOverlayPathMtd = AssetManager.class.getMethod("addOverlayPath", String.class);
} catch(ClassNotFoundException | NoSuchMethodException e) {
} catch (ClassNotFoundException | NoSuchMethodException e) {
throw new RuntimeException();
}
}
@@ -31,9 +32,9 @@ public class AssetManagerHelper {
throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Object[] apkAssetsArr = (Object[]) getAssetPathMtd.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--) {
for (int i = apkAssetsArr.length - 1; i >= 0; i--) {
final String pathname = (String) getApkAssetsMtd.invoke(apkAssetsArr[i]);
if(pathname.contains(packagename)) return pathname;
if (pathname.contains(packagename)) return pathname;
}
throw new NullPointerException();
@@ -13,7 +13,6 @@ import ru.vtosters.lite.utils.ReflectionUtils;
import java.io.File;
import java.lang.ref.WeakReference;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collection;
@@ -47,22 +46,22 @@ public class ResourcesLoader {
Class<?> loadedApkClz;
try {
loadedApkClz = Class.forName("android.app.LoadedApk");
} catch(ClassNotFoundException ignored) {
} catch (ClassNotFoundException ignored) {
loadedApkClz = Class.forName("android.app.ActivityThread$PackagenInfo");
}
resDirFld = ReflectionUtils.findField(loadedApkClz, "mResDir");
packagesFld = ReflectionUtils.findField(activityThreadClz, "mPackages");
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.O_MR1)
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O_MR1)
resourcePackagesFld = ReflectionUtils.findField(activityThreadClz, "mResourcePackages");
// fix jianGuo pro has private field 'mAssets' with Resource
// try use mResourcesImpl first
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
try {
// N moved the mAssets inside an mResourcesImpl field
resourcesImplFld = ReflectionUtils.findField(Resources.class, "mResourcesImpl");
} catch(Throwable ignored) {
} catch (Throwable ignored) {
// for safety
assetsFld = ReflectionUtils.findField(Resources.class, "mAssets");
}
@@ -83,8 +82,8 @@ public class ResourcesLoader {
} catch (Throwable ignored) {
// Ignored.
}
} catch(Throwable e) {
Log.d("WTF", e+"");
} catch (Throwable e) {
Log.d("WTF", String.valueOf(e));
}
}
@@ -114,18 +113,18 @@ public class ResourcesLoader {
final ApplicationInfo appInfo = context.getApplicationInfo();
final Field[] packagesFlds = Build.VERSION.SDK_INT < Build.VERSION_CODES.O_MR1
? new Field[] { packagesFld, resourcePackagesFld }
: new Field[] { packagesFld };
for(var fld : packagesFlds) {
? new Field[]{packagesFld, resourcePackagesFld}
: new Field[]{packagesFld};
for (var fld : packagesFlds) {
final var value = fld.get(sCurrentActivityThread);
for(var entry
for (var entry
: ((Map<String, WeakReference<?>>) value).entrySet()) {
final var loadedApk = entry.getValue().get();
if(loadedApk == null) continue;
if (loadedApk == null) continue;
final var resDirPath = (String) resDirFld.get(loadedApk);
if(appInfo.sourceDir.equals(resDirPath))
if (appInfo.sourceDir.equals(resDirPath))
resDirFld.set(loadedApk, resPath);
}
}
@@ -137,16 +136,16 @@ public class ResourcesLoader {
sAssetManager = AssetManager.class.newInstance();
// Create a new AssetManager instance and point it to the resources installed under
if(AssetManagerHelper.addAssetPath(sAssetManager, resPath) == 0
|| AssetManagerHelper.addAssetPath(sAssetManager, assetsPath) == 0)
if (AssetManagerHelper.addAssetPath(sAssetManager, resPath) == 0
|| AssetManagerHelper.addAssetPath(sAssetManager, assetsPath) == 0)
throw new IllegalStateException("Could not create new AssetManager");
// Add SharedLibraries to AssetManager for resolve system resources not found issue
// This influence SharedLibrary Package ID
if(shouldAddSharedLibraryAssets(appInfo)) {
for(var sharedLibrary : appInfo.sharedLibraryFiles) {
if(sharedLibrary.endsWith(".apk")) continue;
if(AssetManagerHelper.addAssetPathAsSharedLibrary(sAssetManager, sharedLibrary) == 0)
if (shouldAddSharedLibraryAssets(appInfo)) {
for (var sharedLibrary : appInfo.sharedLibraryFiles) {
if (sharedLibrary.endsWith(".apk")) continue;
if (AssetManagerHelper.addAssetPathAsSharedLibrary(sAssetManager, sharedLibrary) == 0)
throw new IllegalStateException("AssetManager add SharedLibrary Fail");
Log.i("ResourcesLoader", "addAssetPathAsSharedLibrary " + sharedLibrary);
}
@@ -158,9 +157,9 @@ public class ResourcesLoader {
stringBlocksFld.set(sAssetManager, null);
ensureStringBlocksMtd.invoke(sAssetManager);
}
for(var wr : sResourceReferences) {
for (var wr : sResourceReferences) {
final var resources = wr.get();
if(resources == null) continue;
if (resources == null) continue;
// Set the AssetManager of the Resources instance to our brand new one
try {
@@ -215,6 +214,61 @@ public class ResourcesLoader {
}
}
private static boolean isPatchedResModifiedAfterLastLoad(String patchedResPath) {
long patchedResModifiedTime;
try {
patchedResModifiedTime = new File(patchedResPath).lastModified();
} catch (Throwable thr) {
thr.printStackTrace();
patchedResModifiedTime = 0L;
}
if (patchedResModifiedTime == 0) {
return false;
}
return patchedResModifiedTime != storedPatchedResModifiedTime;
}
private static void recordCurrentPatchedResModifiedTime(String patchedResPath) {
try {
storedPatchedResModifiedTime = new File(patchedResPath).lastModified();
} catch (Throwable thr) {
thr.printStackTrace();
storedPatchedResModifiedTime = 0L;
}
}
/**
* 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 {
final Field typedArrayPoolField = ReflectionUtils.findField(Resources.class, "mTypedArrayPool");
final Object origTypedArrayPool = typedArrayPoolField.get(resources);
final 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;
}
private static final class ResourceInsuranceHandlerCallback implements Handler.Callback {
private static final String LAUNCH_ACTIVITY_LIFECYCLE_ITEM_CLASSNAME = "android.app.servertransaction.LaunchActivityItem";
@@ -240,7 +294,7 @@ public class ResourcesLoader {
RELAUNCH_ACTIVITY = fetchMessageId(hClazz, "RELAUNCH_ACTIVITY", 126);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
EXECUTE_TRANSACTION = fetchMessageId(hClazz, "EXECUTE_TRANSACTION ", 159);
EXECUTE_TRANSACTION = fetchMessageId(hClazz, "EXECUTE_TRANSACTION ", 159);
} else {
EXECUTE_TRANSACTION = -1;
}
@@ -319,62 +373,4 @@ public class ResourcesLoader {
return false;
}
}
private static boolean isPatchedResModifiedAfterLastLoad(String patchedResPath) {
long patchedResModifiedTime;
try {
patchedResModifiedTime = new File(patchedResPath).lastModified();
} catch (Throwable thr) {
thr.printStackTrace();
patchedResModifiedTime = 0L;
}
if (patchedResModifiedTime == 0) {
return false;
}
if (patchedResModifiedTime == storedPatchedResModifiedTime) {
return false;
}
return true;
}
private static void recordCurrentPatchedResModifiedTime(String patchedResPath) {
try {
storedPatchedResModifiedTime = new File(patchedResPath).lastModified();
} catch (Throwable thr) {
thr.printStackTrace();
storedPatchedResModifiedTime = 0L;
}
}
/**
* 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 {
final Field typedArrayPoolField = ReflectionUtils.findField(Resources.class, "mTypedArrayPool");
final Object origTypedArrayPool = typedArrayPoolField.get(resources);
final 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;
}
}
@@ -30,16 +30,16 @@ public class PalettesManager {
private final List<VTLPalette> mPalettes = new ArrayList<>();
public PalettesManager() {
load();
}
public static PalettesManager getInstance() {
if (sInstance == null)
sInstance = new PalettesManager();
return sInstance;
}
public PalettesManager() {
load();
}
public void load() {
mPalettes.clear();
if (!PALETTES_DIR.exists())
@@ -6,21 +6,21 @@ public class ArscEditor {
public static boolean changeColors(BinaryResourceFile arsc, int[] colorIds, int color /*int[] colors*/) {
int q = 0;
for(var chunk : arsc.getChunks()) {
for (var chunk : arsc.getChunks()) {
final var resourceTableChunk = (ResourceTableChunk) chunk;
for(PackageChunk packageChunk : resourceTableChunk.getPackages()) {
for(TypeSpecChunk typeSpecChunk : packageChunk.getTypeSpecChunks()) {
for(TypeChunk typeChunk : packageChunk.getTypeChunks(typeSpecChunk.getId())) {
if(!"color".equals(typeChunk.getTypeName())) continue;
for (PackageChunk packageChunk : resourceTableChunk.getPackages()) {
for (TypeSpecChunk typeSpecChunk : packageChunk.getTypeSpecChunks()) {
for (TypeChunk typeChunk : packageChunk.getTypeChunks(typeSpecChunk.getId())) {
if (!"color".equals(typeChunk.getTypeName())) continue;
for(var entry : typeChunk.getEntries().entrySet()) {
if(entry.getValue().isComplex()) continue;
for (var entry : typeChunk.getEntries().entrySet()) {
if (entry.getValue().isComplex()) continue;
final var id = BinaryResourceIdentifier.create(packageChunk.getId(), typeSpecChunk.getId(), entry.getKey());
for(int i = 0; i < colorIds.length; ++i) {
if(colorIds[i] != id.resId()) continue;
for (int i = 0; i < colorIds.length; ++i) {
if (colorIds[i] != id.resId()) continue;
final var value = entry.getValue();
value.updateValue(new BinaryResourceValue(8, value.value().type(), color /*colors[i]*/));
@@ -25,7 +25,7 @@ public class RecolorUtils {
return new RecoloredDrawable(res, ThemesUtils.getAccentColor());
} // Get res drawable via id and coloring to accent
public static int recolorHexColor(int i){
public static int recolorHexColor(int i) {
var accented = ColorReferences.isAccentedColor(i);
var mutedaccented = ColorReferences.isMutedAccentedColor(i);
return (accented || mutedaccented) ? (accented ? ThemesUtils.getAccentColor() : ThemesUtils.getMutedAccentColor()) : i;
@@ -56,7 +56,7 @@ public class RecolorUtils {
return themeCSL(csl);
} // Recolor ColorStateList
public static ColorStateList themeCSL(ColorStateList csl){
public static ColorStateList themeCSL(ColorStateList csl) {
try {
int unsel = csl.getColorForState(new int[]{-android.R.attr.state_selected}, Color.BLACK);
int sel = csl.getColorForState(new int[]{android.R.attr.state_selected}, Color.BLACK);