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 29498e9..0356624 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 @@ -1,5 +1,6 @@ package se.ajpanton.statusbartweak.runtime.features.battery; +import android.app.KeyguardManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -394,6 +395,7 @@ final class BatteryBarController { } BatteryBarGeometry.Scenario scenario = scenarioForRoot(root); boolean transientStatusBarReveal = isFullscreenScenario(scenario) + && !isLockedPhoneStatusBarRoot(root) && shouldRenderVisibleFullscreenBar(root); if (transientStatusBarReveal) { scenario = visibleStatusBarScenarioForRoot(root); @@ -557,7 +559,7 @@ final class BatteryBarController { return BatteryBarGeometry.Scenario.LOCKSCREEN; } boolean fullscreen = isPhoneRoot(root) - && isUnlockedScene() + && (isUnlockedScene() || isLockedPhoneFullscreenRoot(root)) && (isStatusBarSurfaceHidden(root) || isFullscreenSystemBarState()); boolean landscape = isLandscapeForRoot(root, fullscreen); if (fullscreen) { @@ -598,7 +600,10 @@ final class BatteryBarController { return scene == null || !scene.isUnlocked(); } if (isPhoneRoot(root)) { - return scene == null || scene.isUnlocked(); + if (isLockedPhoneStatusBarRoot(root)) { + return isLockedPhoneFullscreenRoot(root); + } + return scene == null || scene.isUnlocked() || isLockedPhoneFullscreenRoot(root); } return true; } @@ -624,6 +629,23 @@ final class BatteryBarController { return root != null && root.getClass().getName().contains("KeyguardStatusBarView"); } + private boolean isLockedPhoneStatusBarRoot(View root) { + return isPhoneRoot(root) && isKeyguardLocked(root.getContext()); + } + + private boolean isLockedPhoneFullscreenRoot(View root) { + return isLockedPhoneStatusBarRoot(root) + && (isStatusBarSurfaceHidden(root) || isFullscreenSystemBarState()); + } + + private boolean isKeyguardLocked(Context context) { + if (context == null) { + return false; + } + KeyguardManager keyguardManager = context.getSystemService(KeyguardManager.class); + return keyguardManager != null && keyguardManager.isKeyguardLocked(); + } + private boolean isHiddenKeyguardRoot(View root) { return isKeyguardRoot(root) && !root.isShown(); } @@ -966,6 +988,7 @@ final class BatteryBarController { WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL + | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, PixelFormat.TRANSLUCENT); diff --git a/app/src/main/java/se/ajpanton/statusbartweak/runtime/render/UnlockedIconSnapshotRenderController.java b/app/src/main/java/se/ajpanton/statusbartweak/runtime/render/UnlockedIconSnapshotRenderController.java index a2fa3a4..a208166 100644 --- a/app/src/main/java/se/ajpanton/statusbartweak/runtime/render/UnlockedIconSnapshotRenderController.java +++ b/app/src/main/java/se/ajpanton/statusbartweak/runtime/render/UnlockedIconSnapshotRenderController.java @@ -1,5 +1,7 @@ package se.ajpanton.statusbartweak.runtime.render; +import android.app.KeyguardManager; +import android.content.Context; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; @@ -71,6 +73,11 @@ public final class UnlockedIconSnapshotRenderController { clearAll(); return new RenderResult(true, true, true); } + if (scene.isUnlocked() && isKeyguardLocked(root.getContext())) { + clearLockscreenHosts(clockHost, carrierHost, chipHost, statusHost, notificationHost); + clearRoot(root); + return new RenderResult(true, true, true); + } SbtSettings settings = RuntimeSettingsCache.get(root.getContext()); setStatusBarTintTargetEnabled(scene.isUnlocked()); layoutHostToRoot(root, clockHost); @@ -392,6 +399,14 @@ public final class UnlockedIconSnapshotRenderController { notificationRenderer.clear(notificationHost); } + private boolean isKeyguardLocked(Context context) { + if (context == null) { + return false; + } + KeyguardManager keyguardManager = context.getSystemService(KeyguardManager.class); + return keyguardManager != null && keyguardManager.isKeyguardLocked(); + } + private void layoutHostToRoot(View root, ViewGroup host) { if (root == null || host == null || root.getWidth() <= 0 || root.getHeight() <= 0) { return; 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 483611c..cccf2f5 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 @@ -289,7 +289,7 @@ final class UnlockedStockSourceCollector { return; } if (isStatusChipMetricCandidate(root, source.view(), true) - && hasVisibleStatusChipContent(source.view())) { + && hasRenderableStatusChipContent(source.view())) { metricOut.add(source); return; } @@ -1192,7 +1192,7 @@ final class UnlockedStockSourceCollector { || !ViewGeometry.isDescendantOf(view, root) || ReflectionSupport.getBooleanField(view, "sbtStatusChipForcedHidden", false) || !isStatusChipCandidate(view) - || !hasVisibleStatusChipContent(view)) { + || !hasRenderableStatusChipContent(view)) { return false; } Bounds bounds = source.boundsOverride() != null @@ -1210,7 +1210,7 @@ final class UnlockedStockSourceCollector { if (view == null || view == root || view.getVisibility() != View.VISIBLE) { return false; } - if (!allowHidden && view.getAlpha() <= 0f && !hasVisibleStatusChipContent(view)) { + if (!allowHidden && view.getAlpha() <= 0f && !hasRenderableStatusChipContent(view)) { return false; } if (ReflectionSupport.getBooleanField(view, "sbtStatusChipForcedHidden", false)) { @@ -1225,7 +1225,7 @@ final class UnlockedStockSourceCollector { if (bounds == null || bounds.top < 0 || bounds.top > root.getHeight()) { return false; } - if (!isStatusChipCandidate(view)) { + if (!isStatusChipCandidate(view) || !hasRenderableStatusChipContent(view)) { return false; } Object parent = view.getParent(); @@ -1238,6 +1238,39 @@ final class UnlockedStockSourceCollector { return true; } + private boolean hasRenderableStatusChipContent(View source) { + if (!(source instanceof ViewGroup group)) { + return false; + } + ArrayDeque queue = new ArrayDeque<>(); + for (int i = 0; i < group.getChildCount(); i++) { + queue.addLast(group.getChildAt(i)); + } + while (!queue.isEmpty()) { + View view = queue.removeFirst(); + if (view == null) { + continue; + } + if (view instanceof TextView textView + && view.getVisibility() == View.VISIBLE + && view.getAlpha() > 0f + && textView.getText() != null + && textView.getText().length() > 0) { + int width = view.getWidth() > 0 ? view.getWidth() : view.getMeasuredWidth(); + int height = view.getHeight() > 0 ? view.getHeight() : view.getMeasuredHeight(); + if (width > 0 && height > 0) { + return true; + } + } + if (view instanceof ViewGroup childGroup) { + for (int i = 0; i < childGroup.getChildCount(); i++) { + queue.addLast(childGroup.getChildAt(i)); + } + } + } + return false; + } + private boolean hasVisibleStatusChipContent(View source) { if (!(source instanceof ViewGroup group)) { return false; @@ -1271,7 +1304,7 @@ final class UnlockedStockSourceCollector { if (view == null || view == root || root == null) { return false; } - if (!allowHidden && view.getAlpha() <= 0f && !hasVisibleStatusChipContent(view)) { + if (!allowHidden && view.getAlpha() <= 0f && !hasRenderableStatusChipContent(view)) { return false; } int width = view.getWidth() > 0 ? view.getWidth() : view.getMeasuredWidth(); @@ -1283,7 +1316,7 @@ final class UnlockedStockSourceCollector { if (bounds == null || bounds.top < 0 || bounds.top > root.getHeight()) { return false; } - if (!isStatusChipCandidate(view)) { + if (!isStatusChipCandidate(view) || !hasRenderableStatusChipContent(view)) { return false; } Object parent = view.getParent(); @@ -1482,7 +1515,7 @@ final class UnlockedStockSourceCollector { queue.add(root); while (!queue.isEmpty()) { View view = queue.removeFirst(); - if (view != root && isStatusChipCandidate(view) && hasVisibleStatusChipContent(view)) { + if (view != root && isStatusChipCandidate(view) && hasRenderableStatusChipContent(view)) { result = 31 * result + chipViewLayoutSignature(view); } if (view instanceof ViewGroup group) { @@ -1502,7 +1535,7 @@ final class UnlockedStockSourceCollector { result = 31 * result + sources.size(); for (SnapshotSource source : sources) { result = 31 * result + source.mode().ordinal(); - result = 31 * result + (hasVisibleStatusChipContent(source.view()) ? 1 : 0); + result = 31 * result + (hasRenderableStatusChipContent(source.view()) ? 1 : 0); result = 31 * result + chipViewLayoutSignature(source.view()); } return result;