Handle app surfaces over lockscreen
This commit is contained in:
+16
-3
@@ -566,6 +566,15 @@ final class BatteryBarController {
|
||||
if (isKeyguardRoot(root)) {
|
||||
return BatteryBarGeometry.Scenario.LOCKSCREEN;
|
||||
}
|
||||
SceneKey scene = runtimeContext.getModeStateRepository().getActiveScene();
|
||||
if (isPhoneRoot(root)
|
||||
&& scene != null
|
||||
&& scene.isLockscreen()
|
||||
&& isKeyguardLocked(root.getContext())
|
||||
&& !isStatusBarSurfaceHidden(root)
|
||||
&& !isFullscreenSystemBarState()) {
|
||||
return BatteryBarGeometry.Scenario.LOCKSCREEN;
|
||||
}
|
||||
boolean fullscreen = isPhoneRoot(root)
|
||||
&& (isUnlockedScene() || isLockedPhoneFullscreenRoot(root))
|
||||
&& (isStatusBarSurfaceHidden(root) || isFullscreenSystemBarState());
|
||||
@@ -623,10 +632,14 @@ final class BatteryBarController {
|
||||
return scene == null || !scene.isUnlocked();
|
||||
}
|
||||
if (isPhoneRoot(root)) {
|
||||
if (isLockedPhoneStatusBarRoot(root)) {
|
||||
return isLockedPhoneFullscreenRoot(root);
|
||||
if (scene == null || scene.isUnlocked()) {
|
||||
return true;
|
||||
}
|
||||
return scene == null || scene.isUnlocked() || isLockedPhoneFullscreenRoot(root);
|
||||
if (isLockedPhoneStatusBarRoot(root)) {
|
||||
return isLockedPhoneFullscreenRoot(root)
|
||||
|| (!isStatusBarSurfaceHidden(root) && !isFullscreenSystemBarState());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
+16
-1
@@ -17,6 +17,7 @@ import se.ajpanton.statusbartweak.runtime.render.StatusBarTintTarget;
|
||||
final class DarkIconDispatcherGuard {
|
||||
private final RuntimeContext runtimeContext;
|
||||
private final BooleanSupplier lockscreenSceneSupplier;
|
||||
private final BooleanSupplier lockscreenDarkIconsSupplier;
|
||||
private final Runnable refreshAllRoots;
|
||||
private final Set<Object> dispatchers =
|
||||
Collections.newSetFromMap(new WeakHashMap<>());
|
||||
@@ -25,10 +26,12 @@ final class DarkIconDispatcherGuard {
|
||||
DarkIconDispatcherGuard(
|
||||
RuntimeContext runtimeContext,
|
||||
BooleanSupplier lockscreenSceneSupplier,
|
||||
BooleanSupplier lockscreenDarkIconsSupplier,
|
||||
Runnable refreshAllRoots
|
||||
) {
|
||||
this.runtimeContext = runtimeContext;
|
||||
this.lockscreenSceneSupplier = lockscreenSceneSupplier;
|
||||
this.lockscreenDarkIconsSupplier = lockscreenDarkIconsSupplier;
|
||||
this.refreshAllRoots = refreshAllRoots;
|
||||
}
|
||||
|
||||
@@ -48,7 +51,7 @@ final class DarkIconDispatcherGuard {
|
||||
chain -> {
|
||||
Object dispatcher = chain.getThisObject();
|
||||
track(dispatcher);
|
||||
if (isLockscreenScene()) {
|
||||
if (isLockscreenScene() && !shouldUseDarkLockscreenIcons()) {
|
||||
forceLightState(dispatcher);
|
||||
}
|
||||
Object result = chain.proceed();
|
||||
@@ -63,7 +66,11 @@ final class DarkIconDispatcherGuard {
|
||||
return;
|
||||
}
|
||||
for (Object dispatcher : new ArrayList<>(dispatchers)) {
|
||||
if (shouldUseDarkLockscreenIcons()) {
|
||||
restoreState(dispatcher, forcedStates.remove(dispatcher));
|
||||
} else {
|
||||
forceLightState(dispatcher);
|
||||
}
|
||||
ReflectionSupport.invokeMethod(dispatcher, "applyIconTint");
|
||||
}
|
||||
}
|
||||
@@ -85,6 +92,10 @@ final class DarkIconDispatcherGuard {
|
||||
return lockscreenSceneSupplier.getAsBoolean();
|
||||
}
|
||||
|
||||
private boolean shouldUseDarkLockscreenIcons() {
|
||||
return lockscreenDarkIconsSupplier.getAsBoolean();
|
||||
}
|
||||
|
||||
private void track(Object dispatcher) {
|
||||
if (dispatcher != null) {
|
||||
dispatchers.add(dispatcher);
|
||||
@@ -92,6 +103,10 @@ final class DarkIconDispatcherGuard {
|
||||
}
|
||||
|
||||
private void updateTintTarget(Object dispatcher) {
|
||||
if (isLockscreenScene() && shouldUseDarkLockscreenIcons()) {
|
||||
StatusBarTintTarget.setDarkIcons(true);
|
||||
return;
|
||||
}
|
||||
Object intensity = ReflectionSupport.getFieldValue(dispatcher, "mDarkIntensity");
|
||||
if (intensity instanceof Number number) {
|
||||
StatusBarTintTarget.setDarkIcons(number.floatValue() > 0.5f);
|
||||
|
||||
+70
-10
@@ -80,6 +80,7 @@ final class StockLayoutCanvasController {
|
||||
"mEntries",
|
||||
"entries"
|
||||
};
|
||||
private static final int APPEARANCE_LIGHT_STATUS_BARS = 8;
|
||||
private static final Set<String> TARGET_ID_NAMES = Set.of(
|
||||
"clock",
|
||||
"left_clock_container",
|
||||
@@ -198,6 +199,7 @@ final class StockLayoutCanvasController {
|
||||
private int notificationDrawerCloseGeneration;
|
||||
private boolean notificationDrawerClosePending;
|
||||
private int aodVisualAlphaGeneration;
|
||||
private int systemBarAppearance;
|
||||
private int systemBarRequestedVisibleTypes = WindowInsets.Type.statusBars();
|
||||
private boolean statusBarTransientShown;
|
||||
|
||||
@@ -207,6 +209,7 @@ final class StockLayoutCanvasController {
|
||||
darkIconDispatcherGuard = new DarkIconDispatcherGuard(
|
||||
runtimeContext,
|
||||
this::isLockscreenScene,
|
||||
this::shouldUseDarkLockscreenStatusbarTint,
|
||||
this::scheduleUnlockedAppearanceRefreshForAllRoots);
|
||||
lockscreenCardsNotificationStripRenderer =
|
||||
new LockscreenCardsNotificationStripRenderer();
|
||||
@@ -247,29 +250,39 @@ final class StockLayoutCanvasController {
|
||||
"onSystemBarAttributesChanged",
|
||||
chain -> {
|
||||
Object result = chain.proceed();
|
||||
updateSystemBarRequestedVisibleTypes(chain.getArgs());
|
||||
updateSystemBarAttributes(chain.getArgs());
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
private void updateSystemBarRequestedVisibleTypes(List<Object> args) {
|
||||
if (args == null || args.size() <= 5) {
|
||||
private void updateSystemBarAttributes(List<Object> args) {
|
||||
if (args == null || args.size() < 2) {
|
||||
return;
|
||||
}
|
||||
Integer displayId = asInteger(args.get(0));
|
||||
Integer requestedVisibleTypes = asInteger(args.get(5));
|
||||
if (displayId == null || displayId != 0 || requestedVisibleTypes == null) {
|
||||
return;
|
||||
}
|
||||
if (systemBarRequestedVisibleTypes == requestedVisibleTypes) {
|
||||
Integer appearance = asInteger(args.get(1));
|
||||
Integer requestedVisibleTypes = args.size() > 5 ? asInteger(args.get(5)) : null;
|
||||
if (displayId == null || displayId != 0 || appearance == null) {
|
||||
return;
|
||||
}
|
||||
boolean appearanceChanged = systemBarAppearance != appearance;
|
||||
systemBarAppearance = appearance;
|
||||
if (requestedVisibleTypes != null
|
||||
&& systemBarRequestedVisibleTypes != requestedVisibleTypes) {
|
||||
systemBarRequestedVisibleTypes = requestedVisibleTypes;
|
||||
if (statusBarsRequestedVisible()) {
|
||||
releaseSuppressedHiddenStatusBarRoots();
|
||||
privacyOverlayHiddenStatusBarRoots.clear();
|
||||
}
|
||||
}
|
||||
if (appearanceChanged) {
|
||||
darkIconDispatcherGuard.forceLightStateForAll();
|
||||
requestUnlockedLayoutRefreshForAllRoots();
|
||||
} else if (statusBarsRequestedVisible()) {
|
||||
releaseSuppressedHiddenStatusBarRoots();
|
||||
privacyOverlayHiddenStatusBarRoots.clear();
|
||||
}
|
||||
}
|
||||
|
||||
private void installTransientBarListener(ClassLoader classLoader) {
|
||||
Class<?> commandQueueClass = ReflectionSupport.findClassIfExists(
|
||||
@@ -1807,9 +1820,18 @@ final class StockLayoutCanvasController {
|
||||
return;
|
||||
}
|
||||
dirtyUnlockedLayoutRoots.add(root);
|
||||
Runnable refresh = () -> {
|
||||
if (root.isAttachedToWindow()) {
|
||||
root.requestLayout();
|
||||
root.invalidate();
|
||||
}
|
||||
};
|
||||
if (isViewThread(root)) {
|
||||
refresh.run();
|
||||
} else if (root.getHandler() != null) {
|
||||
root.getHandler().post(refresh);
|
||||
}
|
||||
}
|
||||
|
||||
private View rootForShadeTarget(Object target) {
|
||||
if (!(target instanceof View view)) {
|
||||
@@ -2157,6 +2179,15 @@ final class StockLayoutCanvasController {
|
||||
return scene != null && scene.isLockscreen();
|
||||
}
|
||||
|
||||
private boolean statusBarTintTargetEnabledForScene(SceneKey scene) {
|
||||
return scene != null && (scene.isUnlocked() || shouldUseDarkLockscreenStatusbarTint());
|
||||
}
|
||||
|
||||
private boolean shouldUseDarkLockscreenStatusbarTint() {
|
||||
return isLockscreenScene()
|
||||
&& (systemBarAppearance & APPEARANCE_LIGHT_STATUS_BARS) != 0;
|
||||
}
|
||||
|
||||
private void scheduleUnlockedAppearanceRefreshForRoot(View root) {
|
||||
scheduleUnlockedAppearanceRefreshForRoot(root, false);
|
||||
}
|
||||
@@ -2282,7 +2313,8 @@ final class StockLayoutCanvasController {
|
||||
if (unlockedIconRenderController.refreshUnlockedClockText(
|
||||
root,
|
||||
unlockedHosts.clockHost,
|
||||
activeScene)) {
|
||||
activeScene,
|
||||
statusBarTintTargetEnabledForScene(activeScene))) {
|
||||
bringUnlockedHostsAndDebugOverlayToFront(root);
|
||||
}
|
||||
}
|
||||
@@ -2491,6 +2523,7 @@ final class StockLayoutCanvasController {
|
||||
unlockedHosts.statusHost,
|
||||
unlockedHosts.notificationHost,
|
||||
activeScene,
|
||||
statusBarTintTargetEnabledForScene(activeScene),
|
||||
rootDirty,
|
||||
lockedCarrierTextSource());
|
||||
boolean shouldShowUnlockedHosts = unlockedScene
|
||||
@@ -3493,8 +3526,13 @@ final class StockLayoutCanvasController {
|
||||
boolean shelfSurface = isCardsNotificationIconSurface(view);
|
||||
boolean shelfBackgroundSurface = isCardsNotificationShelfBackgroundSurface(view);
|
||||
boolean shadeIconOnlySurface = "keyguard_icononly_container_view".equals(idName);
|
||||
boolean clockSurface = "clock".equals(idName)
|
||||
|| "left_clock_container".equals(idName)
|
||||
|| viewClassName.contains("QSClockIndicatorView")
|
||||
|| viewClassName.contains("statusbar.policy.Clock");
|
||||
if (!("system_icons".equals(idName)
|
||||
|| carrierSurface
|
||||
|| clockSurface
|
||||
|| "system_icon_area".equals(idName)
|
||||
|| "statusIcons".equals(idName)
|
||||
|| "battery".equals(idName)
|
||||
@@ -4916,7 +4954,8 @@ final class StockLayoutCanvasController {
|
||||
lockscreenCardsNotificationRenderGenerationByRoot.remove(root);
|
||||
return;
|
||||
}
|
||||
if (runtimeContext.getModeStateRepository().isSystemUiShadeLocked()) {
|
||||
if (runtimeContext.getModeStateRepository().isSystemUiShadeLocked()
|
||||
|| hasVisibleLockscreenShadeHeader(root)) {
|
||||
removeLockscreenCardsNotificationHost(root);
|
||||
lockscreenCardsNotificationRenderGenerationByRoot.remove(root);
|
||||
return;
|
||||
@@ -4956,6 +4995,27 @@ final class StockLayoutCanvasController {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasVisibleLockscreenShadeHeader(View root) {
|
||||
if (root == null || !isNotificationShadeWindowRoot(root)) {
|
||||
return false;
|
||||
}
|
||||
final boolean[] found = {false};
|
||||
walkTree(root, view -> {
|
||||
if (found[0] || !(view instanceof TextView textView)) {
|
||||
return;
|
||||
}
|
||||
if (!textView.isShown() || textView.getAlpha() <= 0f) {
|
||||
return;
|
||||
}
|
||||
String idName = ViewIdNames.idName(textView);
|
||||
String className = textView.getClass().getName();
|
||||
if ("header_clock".equals(idName) || className.contains("QSClockHeaderView")) {
|
||||
found[0] = true;
|
||||
}
|
||||
});
|
||||
return found[0];
|
||||
}
|
||||
|
||||
private void renderAodCardsNotificationStripIfNeeded(
|
||||
View root,
|
||||
SbtSettings settings,
|
||||
|
||||
@@ -484,4 +484,13 @@ final class LayoutPlan {
|
||||
notificationPlacements,
|
||||
carrierPlacement);
|
||||
}
|
||||
|
||||
LayoutPlan withCarrierPlacement(ClockPlacement placement) {
|
||||
return new LayoutPlan(
|
||||
clockPlacement,
|
||||
chipPlacements,
|
||||
statusPlacements,
|
||||
notificationPlacements,
|
||||
placement);
|
||||
}
|
||||
}
|
||||
|
||||
+24
-3
@@ -65,6 +65,7 @@ public final class UnlockedIconSnapshotRenderController {
|
||||
ViewGroup statusHost,
|
||||
ViewGroup notificationHost,
|
||||
SceneKey scene,
|
||||
boolean statusBarTintTargetEnabled,
|
||||
boolean forceStockRefresh,
|
||||
TextView externalCarrierView
|
||||
) {
|
||||
@@ -80,7 +81,7 @@ public final class UnlockedIconSnapshotRenderController {
|
||||
return new RenderResult(true, true, true);
|
||||
}
|
||||
SbtSettings settings = RuntimeSettingsCache.get(root.getContext());
|
||||
setStatusBarTintTargetEnabled(scene.isUnlocked());
|
||||
setStatusBarTintTargetEnabled(statusBarTintTargetEnabled);
|
||||
layoutHostToRoot(root, clockHost);
|
||||
layoutHostToRoot(root, carrierHost);
|
||||
layoutHostToRoot(root, chipHost);
|
||||
@@ -235,6 +236,7 @@ public final class UnlockedIconSnapshotRenderController {
|
||||
lastClockSourceGeometryByRoot.put(root, currentClockSourceGeometry);
|
||||
layoutPlan = withCurrentDotColors(layoutPlan, collectedIcons);
|
||||
layoutPlan = withCurrentClockAppearance(root, layoutPlan, collectedIcons, settings);
|
||||
layoutPlan = withCurrentCarrierAppearance(layoutPlan);
|
||||
lastLayoutPlanByRoot.put(root, layoutPlan);
|
||||
if (clockEnabledForScene(settings, scene) && layoutPlan.clockPlacement != null) {
|
||||
clockRenderer.render(clockHost, layoutPlan.clockPlacement);
|
||||
@@ -347,7 +349,8 @@ public final class UnlockedIconSnapshotRenderController {
|
||||
public boolean refreshUnlockedClockText(
|
||||
View root,
|
||||
ViewGroup clockHost,
|
||||
SceneKey scene
|
||||
SceneKey scene,
|
||||
boolean statusBarTintTargetEnabled
|
||||
) {
|
||||
if (root == null
|
||||
|| clockHost == null
|
||||
@@ -361,7 +364,7 @@ public final class UnlockedIconSnapshotRenderController {
|
||||
return false;
|
||||
}
|
||||
SbtSettings settings = RuntimeSettingsCache.get(root.getContext());
|
||||
setStatusBarTintTargetEnabled(scene.isUnlocked());
|
||||
setStatusBarTintTargetEnabled(statusBarTintTargetEnabled);
|
||||
if (!clockEnabledForScene(settings, scene)) {
|
||||
return false;
|
||||
}
|
||||
@@ -595,6 +598,24 @@ public final class UnlockedIconSnapshotRenderController {
|
||||
return plan.withClockPlacement(updatedClock);
|
||||
}
|
||||
|
||||
private LayoutPlan withCurrentCarrierAppearance(LayoutPlan plan) {
|
||||
int targetColor = statusBarTintTargetColor();
|
||||
if (plan == null
|
||||
|| plan.carrierPlacement == null
|
||||
|| !hasAlpha(targetColor)
|
||||
|| plan.carrierPlacement.textColorOverride == targetColor) {
|
||||
return plan;
|
||||
}
|
||||
ClockPlacement previous = plan.carrierPlacement;
|
||||
return plan.withCarrierPlacement(new ClockPlacement(
|
||||
previous.source,
|
||||
previous.contentDescription,
|
||||
previous.rows,
|
||||
previous.bounds,
|
||||
targetColor,
|
||||
previous.textSizePx));
|
||||
}
|
||||
|
||||
private int clockReferenceColor(ClockPlacement placement, CollectedIcons icons) {
|
||||
int targetColor = statusBarTintTargetColor();
|
||||
if (hasAlpha(targetColor)) {
|
||||
|
||||
Reference in New Issue
Block a user