Fix unlocked tint refresh

This commit is contained in:
ajp_anton
2026-05-04 14:03:10 +00:00
parent 3f187e911b
commit 1425012932
11 changed files with 496 additions and 20 deletions
@@ -22,21 +22,30 @@ public final class ClockLayoutTextFactory {
}
public static Model build(TextView source, SbtSettings settings) {
return build(source, settings, source != null ? source.getCurrentTextColor() : 0);
}
public static Model build(TextView source, SbtSettings settings, int referenceColor) {
Context context = source != null ? source.getContext() : null;
if (context == null || settings == null) {
return Model.empty();
}
CacheKey cacheKey = cacheKey(context, source, settings);
CacheKey cacheKey = cacheKey(context, source, settings, referenceColor);
CachedModel cached = MODEL_CACHE.get(source);
if (cached != null && cached.key.equals(cacheKey)) {
return cached.model;
}
Model model = buildUncached(context, source, settings);
Model model = buildUncached(context, source, settings, referenceColor);
MODEL_CACHE.put(source, new CachedModel(cacheKey, model));
return model;
}
private static Model buildUncached(Context context, TextView source, SbtSettings settings) {
private static Model buildUncached(
Context context,
TextView source,
SbtSettings settings,
int referenceColor
) {
if (!hasCustomClockTextEnabled(settings)) {
ArrayList<Row> rows = new ArrayList<>();
CharSequence text = source.getText();
@@ -49,7 +58,7 @@ public final class ClockLayoutTextFactory {
&& !settings.clockCustomFormat.isEmpty()) {
ClockParsedPattern parsedPattern = PATTERN_PARSER.parse(settings.clockCustomFormat);
ArrayList<ClockTextRenderer.LayoutRowResult> renderedRows =
TEXT_RENDERER.renderLayoutRows(context, parsedPattern, source.getCurrentTextColor());
TEXT_RENDERER.renderLayoutRows(context, parsedPattern, referenceColor);
ArrayList<Row> rows = new ArrayList<>();
StringBuilder description = new StringBuilder();
for (int i = 0; i < renderedRows.size(); i++) {
@@ -73,7 +82,12 @@ public final class ClockLayoutTextFactory {
return new Model(rows, text != null ? text.toString() : "", settings.clockShowSeconds);
}
private static CacheKey cacheKey(Context context, TextView source, SbtSettings settings) {
private static CacheKey cacheKey(
Context context,
TextView source,
SbtSettings settings,
int referenceColor
) {
String pattern = settings.clockCustomFormat != null ? settings.clockCustomFormat : "";
boolean customPattern = settings.clockCustomFormatEnabled && !pattern.isEmpty();
boolean generatedText = hasCustomClockTextEnabled(settings);
@@ -85,7 +99,7 @@ public final class ClockLayoutTextFactory {
return new CacheKey(
localeFor(context).toLanguageTag(),
System.currentTimeMillis() / divisor,
source.getCurrentTextColor(),
referenceColor,
settings.clockShowSeconds,
settings.clockShowDatePrefix,
customPattern,
@@ -193,6 +193,16 @@ final class StockLayoutCanvasController {
removeDebugOverlay(root);
}
hideTrackedUnlockedStockSurfaces(root);
UnlockedHosts unlockedHosts = unlockedHostsByRoot.get(root);
if (unlockedHosts != null) {
unlockedIconRenderController.refreshUnlockedAppearance(
root,
unlockedHosts.clockHost,
unlockedHosts.chipHost,
unlockedHosts.statusHost,
unlockedHosts.notificationHost,
activeScene);
}
}
}
@@ -1,5 +1,7 @@
package se.ajpanton.statusbartweak.runtime.render;
import android.text.Spanned;
import android.text.style.ForegroundColorSpan;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
@@ -47,7 +49,7 @@ final class ClockProxyRenderer {
if (copyTextStyleIfChanged(placement.source, view)) {
hostChanged = true;
}
if (!String.valueOf(view.getText()).contentEquals(row.text)) {
if (!sameTextAndColorSpans(view.getText(), row.text)) {
view.setText(row.text);
hostChanged = true;
}
@@ -87,6 +89,31 @@ final class ClockProxyRenderer {
}
}
private static boolean sameTextAndColorSpans(CharSequence current, CharSequence desired) {
if (!String.valueOf(current).contentEquals(String.valueOf(desired))) {
return false;
}
return colorSpanSignature(current) == colorSpanSignature(desired);
}
private static int colorSpanSignature(CharSequence text) {
if (!(text instanceof Spanned spanned)) {
return 0;
}
ForegroundColorSpan[] spans = spanned.getSpans(0, spanned.length(), ForegroundColorSpan.class);
if (spans == null || spans.length == 0) {
return 0;
}
int result = 17;
for (ForegroundColorSpan span : spans) {
result = 31 * result + span.getForegroundColor();
result = 31 * result + spanned.getSpanStart(span);
result = 31 * result + spanned.getSpanEnd(span);
result = 31 * result + spanned.getSpanFlags(span);
}
return result;
}
void clear(ViewGroup host) {
if (host == null) {
return;
@@ -0,0 +1,131 @@
package se.ajpanton.statusbartweak.runtime.render;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import se.ajpanton.statusbartweak.runtime.hooks.ReflectionSupport;
final class SnapshotAppearanceSignature {
private static final int NO_COLOR = 0;
private static final String[] COLOR_FIELD_NAMES = {
"mIconColor",
"mDecorColor",
"mStaticDrawableColor",
"mIconTint",
"mTint",
"mTintColor",
"mCurrentColor",
"mCurrentIconColor"
};
private SnapshotAppearanceSignature() {
}
static int view(View view) {
if (view == null) {
return 0;
}
int result = 17;
result = 31 * result + java.util.Arrays.hashCode(view.getDrawableState());
if (view instanceof TextView textView) {
result = 31 * result + textView.getCurrentTextColor();
result = 31 * result + textView.getTextColors().hashCode();
}
if (view instanceof ImageView imageView) {
result = 31 * result + drawable(imageView.getDrawable());
result = 31 * result + colorStateList(imageView.getImageTintList());
PorterDuff.Mode tintMode = imageView.getImageTintMode();
result = 31 * result + (tintMode != null ? tintMode.hashCode() : 0);
ColorFilter colorFilter = imageView.getColorFilter();
result = 31 * result + (colorFilter != null ? System.identityHashCode(colorFilter) : 0);
}
result = 31 * result + reflectedColor(view, COLOR_FIELD_NAMES);
return result;
}
static int drawable(Drawable drawable) {
if (drawable == null) {
return 0;
}
int result = 17;
result = 31 * result + System.identityHashCode(drawable);
result = 31 * result + drawable.getLevel();
result = 31 * result + drawable.getAlpha();
result = 31 * result + java.util.Arrays.hashCode(drawable.getState());
ColorFilter colorFilter = drawable.getColorFilter();
result = 31 * result + (colorFilter != null ? System.identityHashCode(colorFilter) : 0);
return result;
}
static int preferredColor(View view, int fallbackColor) {
if (view == null) {
return fallbackColor;
}
if (view instanceof TextView textView) {
return textView.getCurrentTextColor();
}
if (view instanceof ImageView imageView) {
int tintColor = colorStateListColor(imageView.getImageTintList(), view, NO_COLOR);
if (isOpaqueColor(tintColor)) {
return tintColor;
}
}
int reflectedColor = reflectedColor(view, COLOR_FIELD_NAMES);
if (isOpaqueColor(reflectedColor)) {
return reflectedColor;
}
return fallbackColor;
}
private static int reflectedColor(Object target, String[] fieldNames) {
for (String fieldName : fieldNames) {
Object value = ReflectionSupport.getFieldValue(target, fieldName);
int color = colorValue(value, NO_COLOR);
if (isOpaqueColor(color)) {
return color;
}
}
return NO_COLOR;
}
private static int colorValue(Object value, int fallbackColor) {
if (value instanceof Integer integer) {
return integer;
}
if (value instanceof ColorStateList colorStateList) {
return colorStateList.getDefaultColor();
}
return fallbackColor;
}
private static int colorStateListColor(ColorStateList colorStateList, View view, int fallbackColor) {
if (colorStateList == null) {
return fallbackColor;
}
return colorStateList.getColorForState(
view != null ? view.getDrawableState() : null,
colorStateList.getDefaultColor());
}
private static boolean isOpaqueColor(int color) {
return Color.alpha(color) != 0;
}
private static int colorStateList(ColorStateList colorStateList) {
if (colorStateList == null) {
return 0;
}
int result = 17;
result = 31 * result + colorStateList.getDefaultColor();
result = 31 * result + (colorStateList.isStateful() ? 1 : 0);
result = 31 * result + colorStateList.hashCode();
return result;
}
}
@@ -1,6 +1,7 @@
package se.ajpanton.statusbartweak.runtime.render;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.view.View;
import android.widget.TextView;
@@ -34,6 +35,7 @@ final class SnapshotPlacement {
final String key;
final boolean signal;
final boolean overflowDot;
final int overflowDotColor;
final HeldSignal heldSignal;
final Bounds contentBounds;
final int sourceOffsetX;
@@ -47,12 +49,36 @@ final class SnapshotPlacement {
HeldSignal heldSignal,
Bounds contentBounds,
int sourceOffsetX
) {
this(
source,
bounds,
key,
signal,
overflowDot,
Color.WHITE,
heldSignal,
contentBounds,
sourceOffsetX);
}
SnapshotPlacement(
SnapshotSource source,
Bounds bounds,
String key,
boolean signal,
boolean overflowDot,
int overflowDotColor,
HeldSignal heldSignal,
Bounds contentBounds,
int sourceOffsetX
) {
this.source = source;
this.bounds = bounds;
this.key = key;
this.signal = signal;
this.overflowDot = overflowDot;
this.overflowDotColor = overflowDotColor;
this.heldSignal = heldSignal;
this.contentBounds = contentBounds;
this.sourceOffsetX = sourceOffsetX;
@@ -78,6 +104,10 @@ final class SnapshotPlacement {
return overflowDot;
}
int overflowDotColor() {
return overflowDotColor;
}
HeldSignal heldSignal() {
return heldSignal;
}
@@ -102,6 +132,7 @@ record SnapshotRenderState(
int height,
boolean signal,
boolean overflowDot,
int overflowDotColor,
int sourceOffsetX,
String heldSignalKey,
int heldBitmapId,
@@ -176,7 +176,7 @@ final class SnapshotRenderer {
|| !desiredState.equals(statesByProxy.get(proxy));
if (bitmapChanged) {
if (placement.overflowDot()) {
drawOverflowDot(bitmap);
drawOverflowDot(bitmap, placement.overflowDotColor());
} else if (placement.heldSignal() != null) {
drawHeldSignal(placement.heldSignal(), bitmap);
} else if (placement.source() != null) {
@@ -471,6 +471,7 @@ final class SnapshotRenderer {
bounds.height,
placement.signal(),
placement.overflowDot(),
placement.overflowDotColor(),
placement.sourceOffsetX(),
placement.heldSignal() != null ? placement.heldSignal().key : "",
placement.heldSignal() != null ? System.identityHashCode(placement.heldSignal().bitmap) : 0,
@@ -493,6 +494,7 @@ final class SnapshotRenderer {
CharSequence contentDescription = view.getContentDescription();
result = 31 * result + (contentDescription != null ? contentDescription.toString().hashCode() : 0);
result = 31 * result + java.util.Arrays.hashCode(view.getDrawableState());
result = 31 * result + SnapshotAppearanceSignature.view(view);
if (view instanceof TextView textView) {
CharSequence text = textView.getText();
result = 31 * result + (text != null ? text.toString().hashCode() : 0);
@@ -500,7 +502,7 @@ final class SnapshotRenderer {
result = 31 * result + Float.floatToIntBits(textView.getTextSize());
}
if (view instanceof ImageView imageView) {
result = 31 * result + drawableSignature(imageView.getDrawable());
result = 31 * result + SnapshotAppearanceSignature.drawable(imageView.getDrawable());
}
if (view instanceof ViewGroup group) {
result = 31 * result + group.getChildCount();
@@ -516,10 +518,7 @@ final class SnapshotRenderer {
return 0;
}
int result = 17;
result = 31 * result + System.identityHashCode(drawable);
result = 31 * result + drawable.getLevel();
result = 31 * result + drawable.getAlpha();
result = 31 * result + java.util.Arrays.hashCode(drawable.getState());
result = 31 * result + SnapshotAppearanceSignature.drawable(drawable);
Rect bounds = drawable.getBounds();
result = 31 * result + bounds.left;
result = 31 * result + bounds.top;
@@ -570,7 +569,7 @@ final class SnapshotRenderer {
canvas.drawBitmap(heldSignal.bitmap, src, dst, null);
}
private void drawOverflowDot(Bitmap bitmap) {
private void drawOverflowDot(Bitmap bitmap, int color) {
bitmap.eraseColor(Color.TRANSPARENT);
int base = Math.min(bitmap.getWidth(), bitmap.getHeight());
if (base <= 0) {
@@ -578,7 +577,7 @@ final class SnapshotRenderer {
}
float radius = Math.max(1f, base * 0.16f);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.WHITE);
paint.setColor(color);
Canvas canvas = new Canvas(bitmap);
canvas.drawCircle(bitmap.getWidth() / 2f, bitmap.getHeight() / 2f, radius, paint);
}
@@ -190,6 +190,7 @@ final class UnlockedChipPlacementController {
placement.key,
false,
false,
placement.overflowDotColor,
null,
placement.contentBounds,
placement.sourceOffsetX));
@@ -211,6 +212,7 @@ final class UnlockedChipPlacementController {
placement.key,
placement.signal,
placement.overflowDot,
placement.overflowDotColor,
placement.heldSignal,
placement.contentBounds,
placement.sourceOffsetX));
@@ -34,6 +34,7 @@ public final class UnlockedIconSnapshotRenderController {
private final WeakHashMap<View, LayoutPlan> lastLayoutPlanByRoot = new WeakHashMap<>();
private final WeakHashMap<View, Integer> lastClockGeometryByRoot = new WeakHashMap<>();
private final WeakHashMap<View, Integer> lastClockSourceGeometryByRoot = new WeakHashMap<>();
private final WeakHashMap<View, Integer> lastClockAppearanceByRoot = new WeakHashMap<>();
public UnlockedIconSnapshotRenderController() {
statusRenderer = new SnapshotRenderer(true, true, false);
@@ -164,6 +165,8 @@ public final class UnlockedIconSnapshotRenderController {
lastLayoutPlanByRoot.put(root, layoutPlan);
lastClockGeometryByRoot.put(root, currentClockGeometry != null ? currentClockGeometry : 0);
lastClockSourceGeometryByRoot.put(root, currentClockSourceGeometry);
layoutPlan = withCurrentDotColors(layoutPlan, collectedIcons);
lastLayoutPlanByRoot.put(root, layoutPlan);
if (settings.clockEnabledUnlocked && layoutPlan.clockPlacement != null) {
clockRenderer.render(clockHost, layoutPlan.clockPlacement);
} else {
@@ -187,6 +190,47 @@ public final class UnlockedIconSnapshotRenderController {
return new RenderResult(true, stockSourcesChanged, chipSourcesChanged);
}
public void refreshUnlockedAppearance(
View root,
ViewGroup clockHost,
ViewGroup chipHost,
ViewGroup statusHost,
ViewGroup notificationHost,
SceneKey scene
) {
if (root == null || scene == null || !scene.isUnlocked() || !root.isAttachedToWindow()) {
return;
}
LayoutPlan layoutPlan = lastLayoutPlanByRoot.get(root);
if (layoutPlan == null) {
return;
}
SbtSettings settings = RuntimeSettingsCache.get(root.getContext());
CollectedIcons collectedIcons = lastCollectedIconsByRoot.get(root);
LayoutPlan updatedPlan = withCurrentDotColors(layoutPlan, collectedIcons);
if (updatedPlan != layoutPlan) {
lastLayoutPlanByRoot.put(root, updatedPlan);
layoutPlan = updatedPlan;
}
if (settings.layoutChipEnabledUnlocked && layoutPlan.chipPlacements != null) {
chipRenderer.renderPlacements(chipHost, layoutPlan.chipPlacements);
}
if (settings.layoutStatusEnabledUnlocked && layoutPlan.statusPlacements != null) {
statusRenderer.renderPlacements(statusHost, layoutPlan.statusPlacements);
}
if (settings.layoutNotifEnabledUnlocked && layoutPlan.notificationPlacements != null) {
notificationRenderer.renderPlacements(notificationHost, layoutPlan.notificationPlacements);
}
updatedPlan = withCurrentClockAppearance(root, layoutPlan, collectedIcons, settings);
if (updatedPlan != layoutPlan) {
lastLayoutPlanByRoot.put(root, updatedPlan);
layoutPlan = updatedPlan;
}
if (settings.clockEnabledUnlocked && layoutPlan.clockPlacement != null) {
clockRenderer.render(clockHost, layoutPlan.clockPlacement);
}
}
private void layoutHostToRoot(View root, ViewGroup host) {
if (root == null || host == null || root.getWidth() <= 0 || root.getHeight() <= 0) {
return;
@@ -205,6 +249,180 @@ public final class UnlockedIconSnapshotRenderController {
host.layout(0, 0, root.getWidth(), root.getHeight());
}
private LayoutPlan withCurrentDotColors(LayoutPlan plan, CollectedIcons icons) {
if (plan == null) {
return null;
}
ArrayList<SnapshotPlacement> status = withCurrentDotColors(
plan.statusPlacements,
icons != null ? icons.statusIcons : null);
ArrayList<SnapshotPlacement> notifications = withCurrentDotColors(
plan.notificationPlacements,
icons != null ? icons.notificationIcons : null);
if (status == plan.statusPlacements && notifications == plan.notificationPlacements) {
return plan;
}
return new LayoutPlan(
plan.clockPlacement,
plan.chipPlacements,
status,
notifications);
}
private ArrayList<SnapshotPlacement> withCurrentDotColors(
ArrayList<SnapshotPlacement> placements,
ArrayList<SnapshotSource> fallbackSources
) {
if (placements == null || placements.isEmpty()) {
return placements;
}
int color = dotColor(placements, fallbackSources);
if (color == 0) {
return placements;
}
ArrayList<SnapshotPlacement> updated = null;
for (int i = 0; i < placements.size(); i++) {
SnapshotPlacement placement = placements.get(i);
if (!placement.overflowDot || placement.overflowDotColor == color) {
continue;
}
if (updated == null) {
updated = new ArrayList<>(placements);
}
updated.set(i, new SnapshotPlacement(
placement.source,
placement.bounds,
placement.key,
placement.signal,
placement.overflowDot,
color,
placement.heldSignal,
placement.contentBounds,
placement.sourceOffsetX));
}
return updated != null ? updated : placements;
}
private int dotColor(
ArrayList<SnapshotPlacement> placements,
ArrayList<SnapshotSource> fallbackSources
) {
for (SnapshotPlacement placement : placements) {
if (placement != null && placement.source != null) {
int color = sourceColor(placement.source);
if (color != 0) {
return color;
}
}
}
if (fallbackSources != null) {
for (SnapshotSource source : fallbackSources) {
int color = sourceColor(source);
if (color != 0) {
return color;
}
}
}
return 0;
}
private int sourceColor(SnapshotSource source) {
if (source == null || source.view() == null) {
return 0;
}
int color = SnapshotAppearanceSignature.preferredColor(
source.view(),
android.graphics.Color.TRANSPARENT);
return android.graphics.Color.alpha(color) != 0 ? color : 0;
}
private LayoutPlan withCurrentClockAppearance(
View root,
LayoutPlan plan,
CollectedIcons icons,
SbtSettings settings
) {
if (root == null
|| plan == null
|| plan.clockPlacement == null
|| !settings.clockEnabledUnlocked) {
return plan;
}
ClockPlacement previous = plan.clockPlacement;
int referenceColor = clockReferenceColor(previous, icons);
int signature = clockAppearanceSignature(previous, referenceColor, settings);
Integer lastSignature = lastClockAppearanceByRoot.get(root);
if (lastSignature != null && lastSignature == signature) {
return plan;
}
ClockPlacement updatedClock = clockPlacementWithTextFromModel(
previous,
previous.source,
settings,
referenceColor);
lastClockAppearanceByRoot.put(root, signature);
if (updatedClock == null) {
return plan;
}
return plan.withClockPlacement(updatedClock);
}
private int clockReferenceColor(ClockPlacement placement, CollectedIcons icons) {
if (icons != null && icons.statusIcons != null) {
for (SnapshotSource source : icons.statusIcons) {
int color = sourceColor(source);
if (color != 0) {
return color;
}
}
}
if (icons != null && icons.notificationIcons != null) {
for (SnapshotSource source : icons.notificationIcons) {
int color = sourceColor(source);
if (color != 0) {
return color;
}
}
}
if (placement != null && placement.source != null) {
return placement.source.getCurrentTextColor();
}
return android.graphics.Color.WHITE;
}
private int clockAppearanceSignature(
ClockPlacement placement,
int referenceColor,
SbtSettings settings
) {
int result = 17;
result = 31 * result + referenceColor;
result = 31 * result + clockTextSettingsSignature(settings);
if (placement != null && placement.source != null) {
result = 31 * result + placement.source.getCurrentTextColor();
}
if (placement != null && placement.rows != null) {
result = 31 * result + placement.rows.size();
for (ClockRow row : placement.rows) {
result = 31 * result + row.rowIndex;
result = 31 * result + row.segment.ordinal();
result = 31 * result + (row.text != null ? row.text.toString().hashCode() : 0);
}
}
return result;
}
private int clockTextSettingsSignature(SbtSettings settings) {
if (settings == null) {
return 0;
}
return java.util.Objects.hash(
settings.clockShowSeconds,
settings.clockShowDatePrefix,
settings.clockCustomFormatEnabled,
settings.clockCustomFormat);
}
public void clearAll() {
clockRenderer.clearAll();
statusRenderer.clearAll();
@@ -218,6 +436,7 @@ public final class UnlockedIconSnapshotRenderController {
lastLayoutPlanByRoot.clear();
lastClockGeometryByRoot.clear();
lastClockSourceGeometryByRoot.clear();
lastClockAppearanceByRoot.clear();
chipPlacementController.clear();
}
@@ -228,6 +447,7 @@ public final class UnlockedIconSnapshotRenderController {
lastCollectedIconsByRoot.clear();
lastLayoutPlanByRoot.clear();
lastClockGeometryByRoot.clear();
lastClockAppearanceByRoot.clear();
}
private boolean isClockOnlySignatureChange(
@@ -368,6 +588,19 @@ public final class UnlockedIconSnapshotRenderController {
ClockPlacement previousPlacement,
TextView source,
SbtSettings settings
) {
return clockPlacementWithTextFromModel(
previousPlacement,
source,
settings,
source != null ? source.getCurrentTextColor() : 0);
}
private ClockPlacement clockPlacementWithTextFromModel(
ClockPlacement previousPlacement,
TextView source,
SbtSettings settings,
int referenceColor
) {
if (previousPlacement == null
|| previousPlacement.rows == null
@@ -375,7 +608,7 @@ public final class UnlockedIconSnapshotRenderController {
|| settings == null) {
return null;
}
ClockLayoutTextFactory.Model model = ClockLayoutTextFactory.build(source, settings);
ClockLayoutTextFactory.Model model = ClockLayoutTextFactory.build(source, settings, referenceColor);
if (model == null || model.isEmpty()) {
return null;
}
@@ -493,11 +493,40 @@ final class UnlockedLayoutBand extends StatusBarLayoutSolver.LayoutBand {
SnapshotKeys.OVERFLOW_DOT + ":" + kind.name().toLowerCase(java.util.Locale.ROOT),
false,
true,
dotColor(),
null,
new Bounds(0, 0, Math.max(1, width), Math.max(1, height)),
0);
}
private int dotColor() {
for (SnapshotPlacement placement : activePlacements()) {
int color = sourceColor(placement);
if (color != 0) {
return color;
}
}
if (rawPlacements != null) {
for (SnapshotPlacement placement : rawPlacements) {
int color = sourceColor(placement);
if (color != 0) {
return color;
}
}
}
return android.graphics.Color.WHITE;
}
private int sourceColor(SnapshotPlacement placement) {
if (placement == null || placement.source == null || placement.source.view() == null) {
return 0;
}
int color = SnapshotAppearanceSignature.preferredColor(
placement.source.view(),
android.graphics.Color.TRANSPARENT);
return android.graphics.Color.alpha(color) != 0 ? color : 0;
}
private SnapshotPlacement emptyIconContainerPlacement() {
int height = Math.max(1, dotHeight(activePlacements()));
return new SnapshotPlacement(
@@ -548,6 +577,7 @@ final class UnlockedLayoutBand extends StatusBarLayoutSolver.LayoutBand {
placement.key,
placement.signal,
placement.overflowDot,
placement.overflowDotColor,
placement.heldSignal,
clippedContent,
placement.sourceOffsetX + removeLeft);
@@ -218,6 +218,7 @@ final class UnlockedLayoutPlanner {
placement.key,
placement.signal,
placement.overflowDot,
placement.overflowDotColor,
placement.heldSignal,
placement.contentBounds,
placement.sourceOffsetX));
@@ -2,7 +2,6 @@ package se.ajpanton.statusbartweak.runtime.render;
import android.content.res.Resources;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
@@ -636,19 +635,18 @@ final class UnlockedStockSourceCollector {
: 0);
}
if (view instanceof ImageView imageView) {
result = 31 * result + drawableSignature(imageView.getDrawable());
result = 31 * result + drawableLayoutSignature(imageView.getDrawable());
}
return result;
}
private static int drawableSignature(Drawable drawable) {
private static int drawableLayoutSignature(android.graphics.drawable.Drawable drawable) {
if (drawable == null) {
return 0;
}
int result = 17;
result = 31 * result + System.identityHashCode(drawable);
result = 31 * result + drawable.getLevel();
result = 31 * result + drawable.getAlpha();
result = 31 * result + java.util.Arrays.hashCode(drawable.getState());
Rect bounds = drawable.getBounds();
result = 31 * result + bounds.left;