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;
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);
@@ -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;
@@ -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<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) {
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;