Handle camera statusbar rendering

This commit is contained in:
ajp_anton
2026-06-20 18:50:03 +00:00
parent f36e42c649
commit 67b82ebd4e
3 changed files with 81 additions and 10 deletions
@@ -1,5 +1,6 @@
package se.ajpanton.statusbartweak.runtime.features.battery; package se.ajpanton.statusbartweak.runtime.features.battery;
import android.app.KeyguardManager;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
@@ -394,6 +395,7 @@ final class BatteryBarController {
} }
BatteryBarGeometry.Scenario scenario = scenarioForRoot(root); BatteryBarGeometry.Scenario scenario = scenarioForRoot(root);
boolean transientStatusBarReveal = isFullscreenScenario(scenario) boolean transientStatusBarReveal = isFullscreenScenario(scenario)
&& !isLockedPhoneStatusBarRoot(root)
&& shouldRenderVisibleFullscreenBar(root); && shouldRenderVisibleFullscreenBar(root);
if (transientStatusBarReveal) { if (transientStatusBarReveal) {
scenario = visibleStatusBarScenarioForRoot(root); scenario = visibleStatusBarScenarioForRoot(root);
@@ -557,7 +559,7 @@ final class BatteryBarController {
return BatteryBarGeometry.Scenario.LOCKSCREEN; return BatteryBarGeometry.Scenario.LOCKSCREEN;
} }
boolean fullscreen = isPhoneRoot(root) boolean fullscreen = isPhoneRoot(root)
&& isUnlockedScene() && (isUnlockedScene() || isLockedPhoneFullscreenRoot(root))
&& (isStatusBarSurfaceHidden(root) || isFullscreenSystemBarState()); && (isStatusBarSurfaceHidden(root) || isFullscreenSystemBarState());
boolean landscape = isLandscapeForRoot(root, fullscreen); boolean landscape = isLandscapeForRoot(root, fullscreen);
if (fullscreen) { if (fullscreen) {
@@ -598,7 +600,10 @@ final class BatteryBarController {
return scene == null || !scene.isUnlocked(); return scene == null || !scene.isUnlocked();
} }
if (isPhoneRoot(root)) { if (isPhoneRoot(root)) {
return scene == null || scene.isUnlocked(); if (isLockedPhoneStatusBarRoot(root)) {
return isLockedPhoneFullscreenRoot(root);
}
return scene == null || scene.isUnlocked() || isLockedPhoneFullscreenRoot(root);
} }
return true; return true;
} }
@@ -624,6 +629,23 @@ final class BatteryBarController {
return root != null && root.getClass().getName().contains("KeyguardStatusBarView"); 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) { private boolean isHiddenKeyguardRoot(View root) {
return isKeyguardRoot(root) && !root.isShown(); return isKeyguardRoot(root) && !root.isShown();
} }
@@ -966,6 +988,7 @@ final class BatteryBarController {
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
| WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
PixelFormat.TRANSLUCENT); PixelFormat.TRANSLUCENT);
@@ -1,5 +1,7 @@
package se.ajpanton.statusbartweak.runtime.render; package se.ajpanton.statusbartweak.runtime.render;
import android.app.KeyguardManager;
import android.content.Context;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.TextView; import android.widget.TextView;
@@ -71,6 +73,11 @@ public final class UnlockedIconSnapshotRenderController {
clearAll(); clearAll();
return new RenderResult(true, true, true); 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()); SbtSettings settings = RuntimeSettingsCache.get(root.getContext());
setStatusBarTintTargetEnabled(scene.isUnlocked()); setStatusBarTintTargetEnabled(scene.isUnlocked());
layoutHostToRoot(root, clockHost); layoutHostToRoot(root, clockHost);
@@ -392,6 +399,14 @@ public final class UnlockedIconSnapshotRenderController {
notificationRenderer.clear(notificationHost); 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) { private void layoutHostToRoot(View root, ViewGroup host) {
if (root == null || host == null || root.getWidth() <= 0 || root.getHeight() <= 0) { if (root == null || host == null || root.getWidth() <= 0 || root.getHeight() <= 0) {
return; return;
@@ -289,7 +289,7 @@ final class UnlockedStockSourceCollector {
return; return;
} }
if (isStatusChipMetricCandidate(root, source.view(), true) if (isStatusChipMetricCandidate(root, source.view(), true)
&& hasVisibleStatusChipContent(source.view())) { && hasRenderableStatusChipContent(source.view())) {
metricOut.add(source); metricOut.add(source);
return; return;
} }
@@ -1192,7 +1192,7 @@ final class UnlockedStockSourceCollector {
|| !ViewGeometry.isDescendantOf(view, root) || !ViewGeometry.isDescendantOf(view, root)
|| ReflectionSupport.getBooleanField(view, "sbtStatusChipForcedHidden", false) || ReflectionSupport.getBooleanField(view, "sbtStatusChipForcedHidden", false)
|| !isStatusChipCandidate(view) || !isStatusChipCandidate(view)
|| !hasVisibleStatusChipContent(view)) { || !hasRenderableStatusChipContent(view)) {
return false; return false;
} }
Bounds bounds = source.boundsOverride() != null Bounds bounds = source.boundsOverride() != null
@@ -1210,7 +1210,7 @@ final class UnlockedStockSourceCollector {
if (view == null || view == root || view.getVisibility() != View.VISIBLE) { if (view == null || view == root || view.getVisibility() != View.VISIBLE) {
return false; return false;
} }
if (!allowHidden && view.getAlpha() <= 0f && !hasVisibleStatusChipContent(view)) { if (!allowHidden && view.getAlpha() <= 0f && !hasRenderableStatusChipContent(view)) {
return false; return false;
} }
if (ReflectionSupport.getBooleanField(view, "sbtStatusChipForcedHidden", false)) { if (ReflectionSupport.getBooleanField(view, "sbtStatusChipForcedHidden", false)) {
@@ -1225,7 +1225,7 @@ final class UnlockedStockSourceCollector {
if (bounds == null || bounds.top < 0 || bounds.top > root.getHeight()) { if (bounds == null || bounds.top < 0 || bounds.top > root.getHeight()) {
return false; return false;
} }
if (!isStatusChipCandidate(view)) { if (!isStatusChipCandidate(view) || !hasRenderableStatusChipContent(view)) {
return false; return false;
} }
Object parent = view.getParent(); Object parent = view.getParent();
@@ -1238,6 +1238,39 @@ final class UnlockedStockSourceCollector {
return true; return true;
} }
private boolean hasRenderableStatusChipContent(View source) {
if (!(source instanceof ViewGroup group)) {
return false;
}
ArrayDeque<View> 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) { private boolean hasVisibleStatusChipContent(View source) {
if (!(source instanceof ViewGroup group)) { if (!(source instanceof ViewGroup group)) {
return false; return false;
@@ -1271,7 +1304,7 @@ final class UnlockedStockSourceCollector {
if (view == null || view == root || root == null) { if (view == null || view == root || root == null) {
return false; return false;
} }
if (!allowHidden && view.getAlpha() <= 0f && !hasVisibleStatusChipContent(view)) { if (!allowHidden && view.getAlpha() <= 0f && !hasRenderableStatusChipContent(view)) {
return false; return false;
} }
int width = view.getWidth() > 0 ? view.getWidth() : view.getMeasuredWidth(); 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()) { if (bounds == null || bounds.top < 0 || bounds.top > root.getHeight()) {
return false; return false;
} }
if (!isStatusChipCandidate(view)) { if (!isStatusChipCandidate(view) || !hasRenderableStatusChipContent(view)) {
return false; return false;
} }
Object parent = view.getParent(); Object parent = view.getParent();
@@ -1482,7 +1515,7 @@ final class UnlockedStockSourceCollector {
queue.add(root); queue.add(root);
while (!queue.isEmpty()) { while (!queue.isEmpty()) {
View view = queue.removeFirst(); View view = queue.removeFirst();
if (view != root && isStatusChipCandidate(view) && hasVisibleStatusChipContent(view)) { if (view != root && isStatusChipCandidate(view) && hasRenderableStatusChipContent(view)) {
result = 31 * result + chipViewLayoutSignature(view); result = 31 * result + chipViewLayoutSignature(view);
} }
if (view instanceof ViewGroup group) { if (view instanceof ViewGroup group) {
@@ -1502,7 +1535,7 @@ final class UnlockedStockSourceCollector {
result = 31 * result + sources.size(); result = 31 * result + sources.size();
for (SnapshotSource source : sources) { for (SnapshotSource source : sources) {
result = 31 * result + source.mode().ordinal(); 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()); result = 31 * result + chipViewLayoutSignature(source.view());
} }
return result; return result;