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 c5b1a04..f0170c9 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 @@ -406,6 +406,9 @@ final class StockLayoutCanvasController { Object target = chain.getThisObject(); Object alphaArg = firstArg(chain.getArgs()); if (target instanceof View view && alphaArg instanceof Float alpha) { + if (shouldSuppressPrivacyOverlayStatusBarAlpha(view, alpha)) { + return null; + } if (shouldSuppressConflictingShadeHeaderAlpha(view, alpha)) { return null; } @@ -451,6 +454,16 @@ final class StockLayoutCanvasController { } return chain.proceed(); }); + XposedHookSupport.hookAllMethodsIfExists(runtimeContext.getFramework(), viewClass, "setTranslationX", chain -> { + Object target = chain.getThisObject(); + Object translationArg = firstArg(chain.getArgs()); + if (target instanceof View view && translationArg instanceof Float translationX) { + if (shouldSuppressPrivacyOverlayStatusBarTranslationX(view, translationX)) { + return null; + } + } + return chain.proceed(); + }); XposedHookSupport.hookAllMethodsIfExists(runtimeContext.getFramework(), viewClass, "layout", chain -> { Object target = chain.getThisObject(); List args = chain.getArgs(); @@ -3350,6 +3363,60 @@ final class StockLayoutCanvasController { return true; } + private boolean shouldSuppressPrivacyOverlayStatusBarAlpha(View view, float alpha) { + if (alpha >= 0.99f + || ownHiddenViewAlphaWriteDepth > 0 + || !isPhoneStatusBarRoot(view) + || !isLayoutEnabled(view.getContext()) + || ongoingPrivacyChipInRoot(view) == null) { + return false; + } + return true; + } + + private boolean shouldSuppressPrivacyOverlayStatusBarTranslationX(View view, float translationX) { + if (Math.abs(translationX) < 0.5f + || ownHiddenViewAlphaWriteDepth > 0 + || !isPhoneStatusBarRoot(view) + || !isLayoutEnabled(view.getContext()) + || ongoingPrivacyChipInRoot(view) == null) { + return false; + } + return true; + } + + private boolean isPhoneStatusBarRoot(View view) { + return view != null + && view.getClass().getName().contains("PhoneStatusBarView"); + } + + private boolean isOngoingPrivacyChip(View view) { + return view != null + && view.getClass().getName().contains("OngoingPrivacyChip") + && "privacy_chip".equals(ViewIdNames.idName(view)); + } + + private View ongoingPrivacyChipInRoot(View view) { + View root = view != null ? view.getRootView() : null; + if (!(root instanceof ViewGroup group)) { + return null; + } + ArrayDeque queue = new ArrayDeque<>(); + queue.add(group); + while (!queue.isEmpty()) { + View current = queue.removeFirst(); + if (isOngoingPrivacyChip(current)) { + return current; + } + if (current instanceof ViewGroup childGroup) { + for (int i = 0; i < childGroup.getChildCount(); i++) { + queue.addLast(childGroup.getChildAt(i)); + } + } + } + return null; + } + private boolean isStatusChipSource(View view) { if (view == null || view.getVisibility() != View.VISIBLE) { return false;