diff --git a/app/src/main/java/se/ajpanton/statusbartweak/runtime/features/battery/BatteryBarController.java b/app/src/main/java/se/ajpanton/statusbartweak/runtime/features/battery/BatteryBarController.java index d138a5f..29498e9 100644 --- a/app/src/main/java/se/ajpanton/statusbartweak/runtime/features/battery/BatteryBarController.java +++ b/app/src/main/java/se/ajpanton/statusbartweak/runtime/features/battery/BatteryBarController.java @@ -154,8 +154,17 @@ final class BatteryBarController { return result; }); XposedHookSupport.hookAllMethodsIfExists(framework, View.class, "setAlpha", chain -> { - Object result = chain.proceed(); Object target = chain.getThisObject(); + Object alphaArg = chain.getArgs() != null && !chain.getArgs().isEmpty() + ? chain.getArgs().get(0) + : null; + if (target instanceof View root + && alphaArg instanceof Float alpha + && roots.contains(root) + && shouldBlockChargingChipRootAlpha(root, alpha)) { + return null; + } + Object result = chain.proceed(); if (target instanceof View root && roots.contains(root)) { applyBatteryBarAfterRootTransform(root); } @@ -271,6 +280,7 @@ final class BatteryBarController { } int result = 17; result = 31 * result + root.getVisibility(); + result = 31 * result + Float.floatToIntBits(root.getAlpha()); result = 31 * result + Float.floatToIntBits(root.getY()); result = 31 * result + Float.floatToIntBits(root.getTranslationY()); result = 31 * result + root.getWidth(); @@ -378,11 +388,11 @@ final class BatteryBarController { return; } int color = resolveBarColor(root, settings); - BatteryBarGeometry.Scenario scenario = scenarioForRoot(root); if (!shouldRenderOnRoot(root)) { removeBatteryBarView(root); return; } + BatteryBarGeometry.Scenario scenario = scenarioForRoot(root); boolean transientStatusBarReveal = isFullscreenScenario(scenario) && shouldRenderVisibleFullscreenBar(root); if (transientStatusBarReveal) { @@ -593,6 +603,14 @@ final class BatteryBarController { return true; } + private boolean shouldBlockChargingChipRootAlpha(View root, float alpha) { + return alpha < 0.99f + && isPhoneRoot(root) + && isUnlockedScene() + && !isFullscreenSystemBarState() + && hasSamsungBatteryStatusChip(root); + } + private boolean isUnlockedScene() { SceneKey scene = runtimeContext.getModeStateRepository().getActiveScene(); return scene == null || scene.isUnlocked(); @@ -758,6 +776,32 @@ final class BatteryBarController { return bottom <= 0f || top >= screenHeight || right <= 0f || left >= screenWidth; } + private boolean hasSamsungBatteryStatusChip(View root) { + if (!(root != null && root.getRootView() instanceof ViewGroup rootView)) { + return false; + } + return findSamsungBatteryStatusChip(rootView) != null; + } + + private View findSamsungBatteryStatusChip(View view) { + if (view == null) { + return null; + } + if (view.getClass().getName().contains("SamsungBatteryStatusChip")) { + return view; + } + if (!(view instanceof ViewGroup group)) { + return null; + } + for (int i = 0; i < group.getChildCount(); i++) { + View found = findSamsungBatteryStatusChip(group.getChildAt(i)); + if (found != null) { + return found; + } + } + return null; + } + private static Integer asInteger(Object value) { return value instanceof Integer integer ? integer : null; } diff --git a/app/src/main/java/se/ajpanton/statusbartweak/runtime/layout/StockLayoutCanvasController.java b/app/src/main/java/se/ajpanton/statusbartweak/runtime/layout/StockLayoutCanvasController.java index d109179..ac6f7d9 100644 --- a/app/src/main/java/se/ajpanton/statusbartweak/runtime/layout/StockLayoutCanvasController.java +++ b/app/src/main/java/se/ajpanton/statusbartweak/runtime/layout/StockLayoutCanvasController.java @@ -414,6 +414,9 @@ final class StockLayoutCanvasController { if (shouldSuppressTrackedStatusChipAlpha(view, alpha)) { return null; } + if (shouldSuppressSamsungBatteryStatusChipAlpha(view, alpha)) { + return null; + } if (shouldCaptureAodVisualAlpha(view)) { rememberAodPluginVisualAlpha(view, alpha); } @@ -424,6 +427,9 @@ final class StockLayoutCanvasController { Object target = chain.getThisObject(); Object visibilityArg = firstArg(chain.getArgs()); if (target instanceof View view && visibilityArg instanceof Integer visibility) { + if (shouldSuppressSamsungBatteryStatusChipVisibility(view, visibility)) { + return null; + } if (shouldSuppressTrackedStatusChipVisibility(view, visibility)) { return null; } @@ -3286,6 +3292,9 @@ final class StockLayoutCanvasController { if (confirmedAodPluginViews.contains(view)) { return true; } + if (isSamsungBatteryStatusChipSurface(view)) { + return true; + } String idName = ViewIdNames.idName(view); if (TARGET_ID_NAMES.contains(idName)) { return true; @@ -3300,6 +3309,41 @@ final class StockLayoutCanvasController { return containsAny(className, TARGET_CLASS_SUBSTRINGS); } + private boolean isSamsungBatteryStatusChipSurface(View view) { + return view != null && view.getClass().getName().contains("SamsungBatteryStatusChip"); + } + + private boolean shouldSuppressSamsungBatteryStatusChipAlpha(View view, float alpha) { + if (alpha <= 0f || ownHiddenViewAlphaWriteDepth > 0 || !isSamsungBatteryStatusChipSurface(view)) { + return false; + } + if (!shouldSuppressSamsungBatteryStatusChip(view)) { + return false; + } + hideView(view, true); + return true; + } + + private boolean shouldSuppressSamsungBatteryStatusChipVisibility(View view, int visibility) { + if (visibility != View.VISIBLE + || ownHiddenViewAlphaWriteDepth > 0 + || !isSamsungBatteryStatusChipSurface(view)) { + return false; + } + if (!shouldSuppressSamsungBatteryStatusChip(view)) { + return false; + } + hideView(view, true); + return true; + } + + private boolean shouldSuppressSamsungBatteryStatusChip(View view) { + if (view == null || !view.isAttachedToWindow() || !isLayoutEnabled(view.getContext())) { + return false; + } + return true; + } + private boolean isStatusChipSource(View view) { if (view == null || view.getVisibility() != View.VISIBLE) { return false; diff --git a/app/src/main/java/se/ajpanton/statusbartweak/runtime/render/SnapshotIconFilter.java b/app/src/main/java/se/ajpanton/statusbartweak/runtime/render/SnapshotIconFilter.java index 3e3f38b..e67b139 100644 --- a/app/src/main/java/se/ajpanton/statusbartweak/runtime/render/SnapshotIconFilter.java +++ b/app/src/main/java/se/ajpanton/statusbartweak/runtime/render/SnapshotIconFilter.java @@ -34,6 +34,10 @@ final class SnapshotIconFilter { } ArrayList filtered = new ArrayList<>(placements.size()); for (SnapshotPlacement placement : placements) { + if (isChargingBatteryChipPlacement(placement)) { + filtered.add(placement); + continue; + } if (!isStatusBlocked(placement, settings.systemIconBlockedModes, mode)) { filtered.add(placement); } @@ -109,6 +113,11 @@ final class SnapshotIconFilter { return false; } + private static boolean isChargingBatteryChipPlacement(SnapshotPlacement placement) { + return placement != null + && SnapshotKeys.CHARGING_BATTERY_CHIP.equals(placement.key); + } + private static AppIconRules.ExceptionRule matchingExceptionRule( SnapshotPlacement placement, ArrayList rules diff --git a/app/src/main/java/se/ajpanton/statusbartweak/runtime/render/SnapshotModels.java b/app/src/main/java/se/ajpanton/statusbartweak/runtime/render/SnapshotModels.java index 31b8dc2..25f248f 100644 --- a/app/src/main/java/se/ajpanton/statusbartweak/runtime/render/SnapshotModels.java +++ b/app/src/main/java/se/ajpanton/statusbartweak/runtime/render/SnapshotModels.java @@ -36,6 +36,7 @@ final class SnapshotKeys { static final String OVERFLOW_DOT = "statusbartweak:overflow_dot"; static final String EMPTY_CHIP = "statusbartweak:empty_chip"; static final String EMPTY_ICON_CONTAINER = "statusbartweak:empty_icon_container"; + static final String CHARGING_BATTERY_CHIP = "statusbartweak:charging_battery_chip"; private SnapshotKeys() { } diff --git a/app/src/main/java/se/ajpanton/statusbartweak/runtime/render/SnapshotRenderer.java b/app/src/main/java/se/ajpanton/statusbartweak/runtime/render/SnapshotRenderer.java index 8de3d60..1cfc5b8 100644 --- a/app/src/main/java/se/ajpanton/statusbartweak/runtime/render/SnapshotRenderer.java +++ b/app/src/main/java/se/ajpanton/statusbartweak/runtime/render/SnapshotRenderer.java @@ -1,15 +1,19 @@ package se.ajpanton.statusbartweak.runtime.render; import android.content.Context; +import android.content.Intent; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; +import android.graphics.Path; import android.graphics.PorterDuff; import android.graphics.Rect; +import android.graphics.RectF; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; +import android.os.BatteryManager; import android.text.TextUtils; import android.os.SystemClock; import android.view.View; @@ -34,6 +38,7 @@ import se.ajpanton.statusbartweak.runtime.NotificationKeyReflection; import se.ajpanton.statusbartweak.runtime.ViewIdNames; import se.ajpanton.statusbartweak.runtime.hooks.ReflectionSupport; import se.ajpanton.statusbartweak.runtime.layoutsolver.StatusBarLayoutSolver.Bounds; +import se.ajpanton.statusbartweak.runtime.settings.BroadcastReceiverSupport; final class SnapshotRenderer { private static final long TRANSITION_SIGNAL_HOLD_MS = 700L; @@ -336,6 +341,7 @@ final class SnapshotRenderer { private boolean shouldTrimContent(SnapshotSource source) { return trimViewContentForCollision && source != null + && !SnapshotKeys.CHARGING_BATTERY_CHIP.equals(source.keyHint()) && (source.mode() == SnapshotMode.VIEW || source.mode() == SnapshotMode.STATUS_CHIP); } @@ -713,6 +719,10 @@ final class SnapshotRenderer { if (offsetX != 0) { canvas.translate(-offsetX, 0); } + if (isChargingBatteryChipSource(source)) { + drawChargingBatteryChip(source, bitmap); + return; + } View sourceView = source.view(); if (sourceView == null) { return; @@ -823,6 +833,152 @@ final class SnapshotRenderer { && source.mode() != SnapshotMode.STATUS_CHIP; } + private boolean isChargingBatteryChipSource(SnapshotSource source) { + return source != null && SnapshotKeys.CHARGING_BATTERY_CHIP.equals(source.keyHint()); + } + + private void drawChargingBatteryChip(SnapshotSource source, Bitmap bitmap) { + if (source == null + || bitmap == null + || bitmap.isRecycled() + || bitmap.getWidth() <= 0 + || bitmap.getHeight() <= 0) { + return; + } + bitmap.eraseColor(Color.TRANSPARENT); + int width = bitmap.getWidth(); + int height = bitmap.getHeight(); + float inset = Math.max(1f, height * 0.05f); + RectF pill = new RectF(inset, inset, width - inset, height - inset); + float radius = pill.height() / 2f; + Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG); + paint.setColor(Color.argb(235, 42, 45, 49)); + Canvas canvas = new Canvas(bitmap); + canvas.drawRoundRect(pill, radius, radius, paint); + + int level = chargingBatteryLevel(source.view()); + float gaugeWidth = Math.min(pill.width(), Math.max(height * 1.35f, pill.width() * 0.42f)); + float fillRight = pill.left + gaugeWidth * Math.max(0f, Math.min(100f, level)) / 100f; + if (fillRight > pill.left) { + Path clip = new Path(); + clip.addRoundRect(pill, radius, radius, Path.Direction.CW); + int save = canvas.save(); + canvas.clipPath(clip); + paint.setColor(Color.rgb(42, 220, 103)); + canvas.drawRect(pill.left, pill.top, fillRight, pill.bottom, paint); + canvas.restoreToCount(save); + } + + paint.setStyle(Paint.Style.STROKE); + paint.setStrokeWidth(Math.max(1f, height * 0.035f)); + paint.setColor(Color.argb(120, 255, 255, 255)); + canvas.drawRoundRect(pill, radius, radius, paint); + paint.setStyle(Paint.Style.FILL); + + drawChargingBolt(canvas, paint, pill.left + height * 0.48f, height / 2f, height * 0.55f); + + String text = chargingBatteryText(source.view(), level); + paint.setTextAlign(Paint.Align.RIGHT); + paint.setFakeBoldText(true); + paint.setColor(Color.WHITE); + paint.setTextSize(Math.max(1f, height * 0.42f)); + Paint.FontMetrics metrics = paint.getFontMetrics(); + float baseline = height / 2f - (metrics.ascent + metrics.descent) / 2f; + canvas.drawText(text, pill.right - Math.max(2f, height * 0.18f), baseline, paint); + paint.setFakeBoldText(false); + } + + private void drawChargingBolt(Canvas canvas, Paint paint, float centerX, float centerY, float size) { + float half = size / 2f; + Path bolt = new Path(); + bolt.moveTo(centerX + half * 0.10f, centerY - half); + bolt.lineTo(centerX - half * 0.42f, centerY + half * 0.08f); + bolt.lineTo(centerX - half * 0.04f, centerY + half * 0.08f); + bolt.lineTo(centerX - half * 0.18f, centerY + half); + bolt.lineTo(centerX + half * 0.44f, centerY - half * 0.18f); + bolt.lineTo(centerX + half * 0.04f, centerY - half * 0.18f); + bolt.close(); + paint.setColor(Color.WHITE); + paint.setStyle(Paint.Style.FILL); + canvas.drawPath(bolt, paint); + } + + private String chargingBatteryText(View source, int fallbackLevel) { + CharSequence text = findChargingBatteryText(source); + if (text != null && text.length() > 0) { + return text.toString(); + } + return Math.max(0, Math.min(100, fallbackLevel)) + "%"; + } + + private int chargingBatteryLevel(View source) { + CharSequence text = findChargingBatteryText(source); + int parsed = parsePercent(text); + if (parsed >= 0) { + return parsed; + } + Integer stickyLevel = stickyBatteryLevel(source != null ? source.getContext() : null); + return stickyLevel != null ? stickyLevel : 100; + } + + private Integer stickyBatteryLevel(Context context) { + if (context == null) { + return null; + } + Intent intent = BroadcastReceiverSupport.readExportedSticky( + context, + BroadcastReceiverSupport.filter(Intent.ACTION_BATTERY_CHANGED)); + if (intent == null) { + return null; + } + int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); + int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100); + if (level < 0 || scale <= 0) { + return null; + } + return Math.max(0, Math.min(100, Math.round(level * 100f / scale))); + } + + private CharSequence findChargingBatteryText(View source) { + if (source == null) { + return null; + } + if (source instanceof TextView textView) { + CharSequence text = textView.getText(); + if (parsePercent(text) >= 0) { + return text; + } + } + if (!(source instanceof ViewGroup group)) { + return null; + } + for (int i = 0; i < group.getChildCount(); i++) { + CharSequence text = findChargingBatteryText(group.getChildAt(i)); + if (text != null && text.length() > 0) { + return text; + } + } + return null; + } + + private int parsePercent(CharSequence text) { + if (text == null) { + return -1; + } + int value = 0; + boolean found = false; + for (int i = 0; i < text.length(); i++) { + char c = text.charAt(i); + if (c >= '0' && c <= '9') { + value = value * 10 + c - '0'; + found = true; + } else if (found) { + break; + } + } + return found ? Math.max(0, Math.min(100, value)) : -1; + } + private boolean isTintableMonochrome(Bitmap bitmap) { int coloredPixels = 0; int monochromePixels = 0; diff --git a/app/src/main/java/se/ajpanton/statusbartweak/runtime/render/UnlockedLayoutPlanner.java b/app/src/main/java/se/ajpanton/statusbartweak/runtime/render/UnlockedLayoutPlanner.java index 1a17278..282e2f6 100644 --- a/app/src/main/java/se/ajpanton/statusbartweak/runtime/render/UnlockedLayoutPlanner.java +++ b/app/src/main/java/se/ajpanton/statusbartweak/runtime/render/UnlockedLayoutPlanner.java @@ -1112,7 +1112,9 @@ final class UnlockedLayoutPlanner { if (bounds == null || bounds.height <= 0) { continue; } - int width = Math.max(1, Math.round((float) bounds.width * targetHeight / bounds.height)); + int width = isChargingBatteryChipPlacement(placement) + ? chargingBatteryChipWidth(targetHeight) + : Math.max(1, Math.round((float) bounds.width * targetHeight / bounds.height)); int bottom = bounds.top + bounds.height; Bounds resized = new Bounds(bounds.left, bottom - targetHeight, width, targetHeight); result.add(new SnapshotPlacement( @@ -1130,6 +1132,15 @@ final class UnlockedLayoutPlanner { return result; } + private boolean isChargingBatteryChipPlacement(SnapshotPlacement placement) { + return placement != null + && SnapshotKeys.CHARGING_BATTERY_CHIP.equals(placement.key); + } + + private int chargingBatteryChipWidth(int height) { + return Math.max(1, Math.round(Math.max(1, height) * 2.7f)); + } + private Bounds sourceRenderBoundsForResize(SnapshotPlacement placement) { if (placement == null || placement.source == null || placement.bounds == null) { return placement != null ? placement.sourceRenderBounds : null; diff --git a/app/src/main/java/se/ajpanton/statusbartweak/runtime/render/UnlockedStockSourceCollector.java b/app/src/main/java/se/ajpanton/statusbartweak/runtime/render/UnlockedStockSourceCollector.java index a4e9373..21be8c4 100644 --- a/app/src/main/java/se/ajpanton/statusbartweak/runtime/render/UnlockedStockSourceCollector.java +++ b/app/src/main/java/se/ajpanton/statusbartweak/runtime/render/UnlockedStockSourceCollector.java @@ -1,7 +1,10 @@ package se.ajpanton.statusbartweak.runtime.render; +import android.content.Context; +import android.content.Intent; import android.graphics.Rect; import android.graphics.drawable.Drawable; +import android.os.BatteryManager; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; @@ -23,6 +26,7 @@ import se.ajpanton.statusbartweak.runtime.mode.NotificationDisplayStyle; import se.ajpanton.statusbartweak.runtime.mode.SceneKey; import se.ajpanton.statusbartweak.runtime.notifications.NotificationActiveKeyStore; import se.ajpanton.statusbartweak.runtime.notifications.NotificationUnreadTracker; +import se.ajpanton.statusbartweak.runtime.settings.BroadcastReceiverSupport; import se.ajpanton.statusbartweak.shell.settings.SbtDefaults; import se.ajpanton.statusbartweak.shell.settings.SbtSettings; @@ -74,6 +78,7 @@ final class UnlockedStockSourceCollector { if (anchors.battery != null && !ViewGeometry.isDescendantOf(anchors.battery, anchors.statusRoot)) { collectStatusSnapshotViews(anchors.battery, statusIcons); } + addSamsungBatteryStatusChipSource(root, statusIcons, settings); selectDualSimStatusSignals(statusIcons, settings); normalizeStatusIconSourceBounds(root, statusIcons); if (scene != null && scene.isAod()) { @@ -185,6 +190,7 @@ final class UnlockedStockSourceCollector { : 0; int statusSourceSignature = sourceLayoutListSignature( previousIcons != null ? previousIcons.statusIcons : null); + statusSourceSignature = 31 * statusSourceSignature + batteryChargingSignature(root); if (scene != null && scene.isAod()) { statusSourceSignature = 31 * statusSourceSignature + aodLayoutAnchorSignature(root, anchors, scene); @@ -880,6 +886,132 @@ final class UnlockedStockSourceCollector { } } + private void addSamsungBatteryStatusChipSource( + View root, + ArrayList sources, + SbtSettings settings + ) { + if (root == null + || sources == null + || settings == null + || settings.statusChipsHideAll + || settings.statusChipsHideBattery + || !isDevicePlugged(root.getContext())) { + return; + } + View chip = samsungBatteryStatusChip(root); + if (chip == null) { + return; + } + removeBatteryStatusSources(sources); + Bounds bounds = ViewGeometry.boundsRelativeTo(root, chip); + sources.add(new SnapshotSource( + chip, + SnapshotMode.STATUS_CHIP, + SnapshotKeys.CHARGING_BATTERY_CHIP, + validBounds(bounds) ? bounds : null)); + } + + private View samsungBatteryStatusChip(View root) { + if (root == null) { + return null; + } + ArrayDeque queue = new ArrayDeque<>(); + queue.add(root); + while (!queue.isEmpty()) { + View view = queue.removeFirst(); + if (isSamsungBatteryStatusChip(view) && hasUsableSamsungBatteryStatusChipBounds(root, view)) { + return view; + } + if (view instanceof ViewGroup group) { + for (int i = 0; i < group.getChildCount(); i++) { + View child = group.getChildAt(i); + if (child != null) { + queue.addLast(child); + } + } + } + } + return null; + } + + private boolean hasUsableSamsungBatteryStatusChipBounds(View root, View view) { + if (root == null + || view == null + || view == root + || !view.isAttachedToWindow() + || view.getVisibility() != View.VISIBLE + || (view.getAlpha() <= 0f && !hasVisibleStatusChipContent(view))) { + return false; + } + Bounds bounds = ViewGeometry.boundsRelativeTo(root, view); + return validBounds(bounds) + && bounds.top >= 0 + && bounds.top <= root.getHeight() + && bounds.width < root.getWidth() / 2; + } + + private boolean validBounds(Bounds bounds) { + return bounds != null && bounds.width > 0 && bounds.height > 0; + } + + private void removeBatteryStatusSources(ArrayList sources) { + if (sources == null || sources.isEmpty()) { + return; + } + for (int i = sources.size() - 1; i >= 0; i--) { + SnapshotSource source = sources.get(i); + if (isBatteryStatusSource(source)) { + sources.remove(i); + } + } + } + + private boolean isBatteryStatusSource(SnapshotSource source) { + View view = source != null ? source.view() : null; + StringBuilder sb = new StringBuilder(); + append(sb, source != null ? source.keyHint() : null); + append(sb, reflectString(view, "getSlot", "mSlot", "slot")); + append(sb, view != null ? ViewIdNames.idName(view) : null); + append(sb, view != null ? view.getClass().getName() : null); + return sb.toString().toLowerCase(Locale.ROOT).contains("battery"); + } + + private boolean isSamsungBatteryStatusChip(View view) { + return view != null && view.getClass().getName().contains("SamsungBatteryStatusChip"); + } + + private int batteryChargingSignature(View root) { + return root != null && isDevicePlugged(root.getContext()) ? 1 : 0; + } + + private boolean isDevicePlugged(Context context) { + Intent intent = batteryIntent(context); + if (intent == null) { + return false; + } + int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1); + return intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0 + || status == BatteryManager.BATTERY_STATUS_CHARGING + || status == BatteryManager.BATTERY_STATUS_FULL; + } + + private Intent batteryIntent(Context context) { + if (context == null) { + return null; + } + return BroadcastReceiverSupport.readExportedSticky( + context, + BroadcastReceiverSupport.filter(Intent.ACTION_BATTERY_CHANGED)); + } + + private void append(StringBuilder sb, String value) { + if (sb == null || value == null || value.isEmpty()) { + return; + } + sb.append(';').append(value); + } + private int normalizedStatusIconWidth(int drawableWidth, int iconHeight) { return Math.max(1, drawableWidth + statusIconHorizontalPadding(iconHeight)); } @@ -1556,7 +1688,8 @@ final class UnlockedStockSourceCollector { settings.statusChipsHideAll, settings.statusChipsHideMediaUnlocked, settings.statusChipsHideNavUnlocked, - settings.statusChipsHideCallUnlocked); + settings.statusChipsHideCallUnlocked, + settings.statusChipsHideBattery); } } diff --git a/app/src/main/java/se/ajpanton/statusbartweak/shell/settings/SbtSettings.java b/app/src/main/java/se/ajpanton/statusbartweak/shell/settings/SbtSettings.java index 7337bd2..89d9864 100644 --- a/app/src/main/java/se/ajpanton/statusbartweak/shell/settings/SbtSettings.java +++ b/app/src/main/java/se/ajpanton/statusbartweak/shell/settings/SbtSettings.java @@ -64,6 +64,7 @@ public final class SbtSettings { public static final String KEY_STATUS_CHIPS_HIDE_MEDIA_UNLOCKED = "status_chips_hide_media_unlocked"; public static final String KEY_STATUS_CHIPS_HIDE_NAV_UNLOCKED = "status_chips_hide_nav_unlocked"; public static final String KEY_STATUS_CHIPS_HIDE_CALL = "status_chips_hide_call"; + public static final String KEY_STATUS_CHIPS_HIDE_BATTERY = "status_chips_hide_battery"; public static final String KEY_AOD_KEEP_VISIBLE_DURING_CALL = "aod_keep_visible_during_call"; public static final String KEY_BATTERY_LOCKSCREEN_UNPLUGGED_PERCENT = "battery_lockscreen_unplugged_percent"; public static final String KEY_BATTERY_AOD_UNPLUGGED_PERCENT = "battery_aod_unplugged_percent"; @@ -408,6 +409,7 @@ public final class SbtSettings { public final boolean statusChipsHideMediaUnlocked; public final boolean statusChipsHideNavUnlocked; public final boolean statusChipsHideCallUnlocked; + public final boolean statusChipsHideBattery; public final Map appIconBlockedModes; public final Map> appIconExceptionRules; public final String lockedNotificationMode; @@ -540,6 +542,7 @@ public final class SbtSettings { boolean statusChipsHideMediaUnlocked, boolean statusChipsHideNavUnlocked, boolean statusChipsHideCallUnlocked, + boolean statusChipsHideBattery, Map appIconBlockedModes, Map> appIconExceptionRules, String lockedNotificationMode, @@ -827,6 +830,7 @@ public final class SbtSettings { this.statusChipsHideMediaUnlocked = statusChipsHideMediaUnlocked; this.statusChipsHideNavUnlocked = statusChipsHideNavUnlocked; this.statusChipsHideCallUnlocked = statusChipsHideCallUnlocked; + this.statusChipsHideBattery = statusChipsHideBattery; this.appIconBlockedModes = appIconBlockedModes != null ? Collections.unmodifiableMap(new HashMap<>(appIconBlockedModes)) : Collections.emptyMap(); @@ -975,6 +979,7 @@ public final class SbtSettings { false, false, false, + false, Collections.emptyMap(), Collections.emptyMap(), "dot", @@ -1422,6 +1427,7 @@ public final class SbtSettings { prefs.getBoolean(KEY_STATUS_CHIPS_HIDE_MEDIA_UNLOCKED, false), prefs.getBoolean(KEY_STATUS_CHIPS_HIDE_NAV_UNLOCKED, false), prefs.getBoolean(KEY_STATUS_CHIPS_HIDE_CALL, false), + prefs.getBoolean(KEY_STATUS_CHIPS_HIDE_BATTERY, false), AppIconRules.parseBlockedModes(readStringSetFromPrefs( prefs, KEY_APP_ICON_BLOCKED_MODES)), @@ -1740,6 +1746,7 @@ public final class SbtSettings { bundle.getBoolean(KEY_STATUS_CHIPS_HIDE_MEDIA_UNLOCKED, false), bundle.getBoolean(KEY_STATUS_CHIPS_HIDE_NAV_UNLOCKED, false), bundle.getBoolean(KEY_STATUS_CHIPS_HIDE_CALL, false), + bundle.getBoolean(KEY_STATUS_CHIPS_HIDE_BATTERY, false), AppIconRules.parseBlockedModes(readStringSetFromBundle( bundle, KEY_APP_ICON_BLOCKED_MODES)), diff --git a/app/src/main/java/se/ajpanton/statusbartweak/shell/settings/SbtSettingsProvider.java b/app/src/main/java/se/ajpanton/statusbartweak/shell/settings/SbtSettingsProvider.java index cfb3cb1..2ec312e 100644 --- a/app/src/main/java/se/ajpanton/statusbartweak/shell/settings/SbtSettingsProvider.java +++ b/app/src/main/java/se/ajpanton/statusbartweak/shell/settings/SbtSettingsProvider.java @@ -412,6 +412,8 @@ public class SbtSettingsProvider extends ContentProvider { prefs.getBoolean(SbtSettings.KEY_STATUS_CHIPS_HIDE_NAV_UNLOCKED, false)); out.putBoolean(SbtSettings.KEY_STATUS_CHIPS_HIDE_CALL, prefs.getBoolean(SbtSettings.KEY_STATUS_CHIPS_HIDE_CALL, false)); + out.putBoolean(SbtSettings.KEY_STATUS_CHIPS_HIDE_BATTERY, + prefs.getBoolean(SbtSettings.KEY_STATUS_CHIPS_HIDE_BATTERY, false)); putStringCollectionArrayList( out, SbtSettings.KEY_APP_ICON_BLOCKED_MODES, diff --git a/app/src/main/java/se/ajpanton/statusbartweak/shell/ui/StatusChipsFragment.java b/app/src/main/java/se/ajpanton/statusbartweak/shell/ui/StatusChipsFragment.java index bdb16e3..3638dea 100644 --- a/app/src/main/java/se/ajpanton/statusbartweak/shell/ui/StatusChipsFragment.java +++ b/app/src/main/java/se/ajpanton/statusbartweak/shell/ui/StatusChipsFragment.java @@ -45,6 +45,11 @@ public class StatusChipsFragment extends Fragment { SbtSettings.KEY_STATUS_CHIPS_HIDE_CALL, false, true); + ViewTreeSupport.bindBooleanPreference(requireContext(), prefs, root, + R.id.status_chips_hide_battery_switch, + SbtSettings.KEY_STATUS_CHIPS_HIDE_BATTERY, + false, + true); return root; } } diff --git a/app/src/main/res/layout/fragment_status_chips.xml b/app/src/main/res/layout/fragment_status_chips.xml index ccea677..718c423 100644 --- a/app/src/main/res/layout/fragment_status_chips.xml +++ b/app/src/main/res/layout/fragment_status_chips.xml @@ -47,6 +47,12 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/status_chips_hide_call_unlocked_label" /> + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c243446..84948fa 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -131,6 +131,7 @@ Hide media chip (unlocked) Hide navigation chip (unlocked) Hide call chip (unlocked) + Hide charging battery chip Misc Battery bar Master toggle