Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fa3341cbec | ||
|
|
988fbcebcd | ||
|
|
f20e214076 | ||
|
|
50fc608eae | ||
|
|
898e33ccfa | ||
|
|
38b1602fe8 | ||
|
|
560f4e19ba | ||
|
|
682782c232 |
@@ -9,12 +9,13 @@ public final class SystemUiCapabilities {
|
|||||||
public static final String PACKAGE_SYSTEM = "system";
|
public static final String PACKAGE_SYSTEM = "system";
|
||||||
public static final String PACKAGE_SYSTEMUI = "com.android.systemui";
|
public static final String PACKAGE_SYSTEMUI = "com.android.systemui";
|
||||||
public static final String PACKAGE_SAMSUNG_AOD_SERVICE = "com.samsung.android.app.aodservice";
|
public static final String PACKAGE_SAMSUNG_AOD_SERVICE = "com.samsung.android.app.aodservice";
|
||||||
|
private static final boolean SAMSUNG_ONE_UI = "samsung".equalsIgnoreCase(Build.MANUFACTURER);
|
||||||
|
|
||||||
private SystemUiCapabilities() {
|
private SystemUiCapabilities() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isSamsungOneUi() {
|
public static boolean isSamsungOneUi() {
|
||||||
return "samsung".equalsIgnoreCase(Build.MANUFACTURER);
|
return SAMSUNG_ONE_UI;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean supportsLockscreenShadeWindowRoot() {
|
public static boolean supportsLockscreenShadeWindowRoot() {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package se.ajpanton.statusbartweak.runtime;
|
package se.ajpanton.statusbartweak.runtime;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
@@ -7,6 +8,7 @@ public final class ViewIdNames {
|
|||||||
private ViewIdNames() {
|
private ViewIdNames() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("ResourceType") // Foreign SystemUI ids are opaque integers, not this app's R.id values.
|
||||||
public static String idName(View view) {
|
public static String idName(View view) {
|
||||||
if (view == null || view.getId() == View.NO_ID || (view.getId() >>> 24) == 0) {
|
if (view == null || view.getId() == View.NO_ID || (view.getId() >>> 24) == 0) {
|
||||||
return "";
|
return "";
|
||||||
|
|||||||
+78
-59
@@ -59,8 +59,8 @@ final class BatteryBarController {
|
|||||||
private final Map<View, OverlayBatteryBar> overlayBatteryBars = new WeakHashMap<>();
|
private final Map<View, OverlayBatteryBar> overlayBatteryBars = new WeakHashMap<>();
|
||||||
private final Map<View, View.OnLayoutChangeListener> rootLayoutListeners = new WeakHashMap<>();
|
private final Map<View, View.OnLayoutChangeListener> rootLayoutListeners = new WeakHashMap<>();
|
||||||
private final Set<View> pendingOverlayRetries = Collections.newSetFromMap(new WeakHashMap<>());
|
private final Set<View> pendingOverlayRetries = Collections.newSetFromMap(new WeakHashMap<>());
|
||||||
private final Map<View, String> lastSignatures = new WeakHashMap<>();
|
private final Map<View, RenderSignature> lastSignatures = new WeakHashMap<>();
|
||||||
private final Map<View, String> lastOverlaySignatures = new WeakHashMap<>();
|
private final Map<View, RenderSignature> lastOverlaySignatures = new WeakHashMap<>();
|
||||||
private final Map<View, Integer> lastRootTransformSignatures = new WeakHashMap<>();
|
private final Map<View, Integer> lastRootTransformSignatures = new WeakHashMap<>();
|
||||||
private int systemBarAppearance;
|
private int systemBarAppearance;
|
||||||
private int systemBarBehavior;
|
private int systemBarBehavior;
|
||||||
@@ -87,7 +87,7 @@ final class BatteryBarController {
|
|||||||
installRootTransformHooks();
|
installRootTransformHooks();
|
||||||
installSystemBarAttributeListener(classLoader);
|
installSystemBarAttributeListener(classLoader);
|
||||||
installTransientBarListener(classLoader);
|
installTransientBarListener(classLoader);
|
||||||
runtimeContext.getModeStateRepository().addSceneListener((previous, current) -> refreshAllRoots());
|
runtimeContext.getModeStateRepository().addSceneListener((previous, current) -> postRefreshAllRoots());
|
||||||
hooksInstalled = true;
|
hooksInstalled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,14 +149,6 @@ final class BatteryBarController {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
XposedHookSupport.hookAllMethodsIfExists(framework, View.class, "setY", chain -> {
|
|
||||||
Object result = chain.proceed();
|
|
||||||
Object target = chain.getThisObject();
|
|
||||||
if (target instanceof View root && roots.contains(root)) {
|
|
||||||
applyBatteryBarAfterRootTransform(root);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
});
|
|
||||||
XposedHookSupport.hookAllMethodsIfExists(framework, View.class, "setAlpha", chain -> {
|
XposedHookSupport.hookAllMethodsIfExists(framework, View.class, "setAlpha", chain -> {
|
||||||
Object target = chain.getThisObject();
|
Object target = chain.getThisObject();
|
||||||
Object alphaArg = chain.getArgs() != null && !chain.getArgs().isEmpty()
|
Object alphaArg = chain.getArgs() != null && !chain.getArgs().isEmpty()
|
||||||
@@ -374,10 +366,6 @@ final class BatteryBarController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void applyBatteryBar(View root) {
|
private void applyBatteryBar(View root) {
|
||||||
applyBatteryBarInternal(root);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void applyBatteryBarInternal(View root) {
|
|
||||||
if (!(root instanceof ViewGroup rootGroup)) {
|
if (!(root instanceof ViewGroup rootGroup)) {
|
||||||
removeBatteryBarView(root);
|
removeBatteryBarView(root);
|
||||||
return;
|
return;
|
||||||
@@ -414,15 +402,15 @@ final class BatteryBarController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
removeOverlayBatteryBar(root);
|
removeOverlayBatteryBar(root);
|
||||||
String signature = buildSignature(root, settings, color, geometry, scenario);
|
RenderSignature signature = RenderSignature.of(
|
||||||
|
root, scenario, batteryLevel, plugged, color, geometry, settings);
|
||||||
BatteryBarView existingView = batteryBarViews.get(root);
|
BatteryBarView existingView = batteryBarViews.get(root);
|
||||||
String lastSignature = lastSignatures.get(root);
|
RenderSignature lastSignature = lastSignatures.get(root);
|
||||||
if (signature.equals(lastSignature) && existingView != null && existingView.getParent() == rootGroup) {
|
if (signature.equals(lastSignature) && existingView != null && existingView.getParent() == rootGroup) {
|
||||||
existingView.bringToFront();
|
existingView.bringToFront();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
applyEmbeddedBatteryBar(rootGroup, settings, geometry, scenario, color);
|
applyEmbeddedBatteryBar(rootGroup, settings, geometry, scenario, color);
|
||||||
lastSignatures.put(root, signature);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyEmbeddedBatteryBar(
|
private void applyEmbeddedBatteryBar(
|
||||||
@@ -437,7 +425,9 @@ final class BatteryBarController {
|
|||||||
barView.update(rootGroup, rootGroup, settings, geometry, batteryLevel, plugged, color);
|
barView.update(rootGroup, rootGroup, settings, geometry, batteryLevel, plugged, color);
|
||||||
barView.bringToFront();
|
barView.bringToFront();
|
||||||
barView.invalidate();
|
barView.invalidate();
|
||||||
lastSignatures.put(rootGroup, buildSignature(rootGroup, settings, color, geometry, scenario));
|
lastSignatures.put(
|
||||||
|
rootGroup,
|
||||||
|
RenderSignature.of(rootGroup, scenario, batteryLevel, plugged, color, geometry, settings));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyOverlayBatteryBar(
|
private void applyOverlayBatteryBar(
|
||||||
@@ -447,7 +437,8 @@ final class BatteryBarController {
|
|||||||
BatteryBarGeometry.Scenario scenario,
|
BatteryBarGeometry.Scenario scenario,
|
||||||
int color
|
int color
|
||||||
) {
|
) {
|
||||||
String signature = buildSignature(root, settings, color, geometry, scenario);
|
RenderSignature signature = RenderSignature.of(
|
||||||
|
root, scenario, batteryLevel, plugged, color, geometry, settings);
|
||||||
OverlayBatteryBar overlay = overlayBatteryBars.get(root);
|
OverlayBatteryBar overlay = overlayBatteryBars.get(root);
|
||||||
if (overlay == null) {
|
if (overlay == null) {
|
||||||
overlay = new OverlayBatteryBar(root.getContext());
|
overlay = new OverlayBatteryBar(root.getContext());
|
||||||
@@ -534,38 +525,19 @@ final class BatteryBarController {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String buildSignature(
|
|
||||||
View root,
|
|
||||||
SbtSettings settings,
|
|
||||||
int color,
|
|
||||||
BatteryBarGeometry geometry,
|
|
||||||
BatteryBarGeometry.Scenario scenario
|
|
||||||
) {
|
|
||||||
return root.getWidth() + "|"
|
|
||||||
+ root.getHeight() + "|"
|
|
||||||
+ scenario + "|"
|
|
||||||
+ batteryLevel + "|"
|
|
||||||
+ plugged + "|"
|
|
||||||
+ color + "|"
|
|
||||||
+ settings.batteryBarEnabled + "|"
|
|
||||||
+ settings.batteryBarScenarioEnabled + "|"
|
|
||||||
+ settings.batteryBarPosition + "|"
|
|
||||||
+ settings.batteryBarAlignment + "|"
|
|
||||||
+ settings.batteryBarThicknessDp + "|"
|
|
||||||
+ settings.batteryBarEdgeOffsetDp + "|"
|
|
||||||
+ settings.batteryBarCurvedGeometryMode + "|"
|
|
||||||
+ (geometry != null ? geometry.signature() : "") + "|"
|
|
||||||
+ settings.batteryBarMinLevel + "|"
|
|
||||||
+ settings.batteryBarMaxLevel + "|"
|
|
||||||
+ settings.batteryBarDefaultDischargeColor + "|"
|
|
||||||
+ settings.batteryBarDefaultChargeColor + "|"
|
|
||||||
+ BatteryBarStyle.encodeThresholds(settings.batteryBarThresholds);
|
|
||||||
}
|
|
||||||
|
|
||||||
private BatteryBarGeometry.Scenario scenarioForRoot(View root) {
|
private BatteryBarGeometry.Scenario scenarioForRoot(View root) {
|
||||||
if (isKeyguardRoot(root)) {
|
if (isKeyguardRoot(root)) {
|
||||||
return BatteryBarGeometry.Scenario.LOCKSCREEN;
|
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)
|
boolean fullscreen = isPhoneRoot(root)
|
||||||
&& (isUnlockedScene() || isLockedPhoneFullscreenRoot(root))
|
&& (isUnlockedScene() || isLockedPhoneFullscreenRoot(root))
|
||||||
&& (isStatusBarSurfaceHidden(root) || isFullscreenSystemBarState());
|
&& (isStatusBarSurfaceHidden(root) || isFullscreenSystemBarState());
|
||||||
@@ -623,10 +595,14 @@ final class BatteryBarController {
|
|||||||
return scene == null || !scene.isUnlocked();
|
return scene == null || !scene.isUnlocked();
|
||||||
}
|
}
|
||||||
if (isPhoneRoot(root)) {
|
if (isPhoneRoot(root)) {
|
||||||
if (isLockedPhoneStatusBarRoot(root)) {
|
if (scene == null || scene.isUnlocked()) {
|
||||||
return isLockedPhoneFullscreenRoot(root);
|
return true;
|
||||||
}
|
}
|
||||||
return scene == null || scene.isUnlocked() || isLockedPhoneFullscreenRoot(root);
|
if (isLockedPhoneStatusBarRoot(root)) {
|
||||||
|
return isLockedPhoneFullscreenRoot(root)
|
||||||
|
|| (!isStatusBarSurfaceHidden(root) && !isFullscreenSystemBarState());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -695,7 +671,15 @@ final class BatteryBarController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean shouldRenderVisibleFullscreenBar(View root) {
|
private boolean shouldRenderVisibleFullscreenBar(View root) {
|
||||||
return root != null && isFullscreenSystemBarState() && statusBarTransientShown;
|
return root != null
|
||||||
|
&& isFullscreenSystemBarState()
|
||||||
|
&& statusBarTransientShown
|
||||||
|
&& isStatusBarWindowVisible(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isStatusBarWindowVisible(View root) {
|
||||||
|
WindowInsets insets = root.getRootWindowInsets();
|
||||||
|
return insets == null || insets.isVisible(WindowInsets.Type.statusBars());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateTransientBarState(java.util.List<Object> args, boolean visible) {
|
private void updateTransientBarState(java.util.List<Object> args, boolean visible) {
|
||||||
@@ -733,13 +717,7 @@ final class BatteryBarController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private OverlayBounds fullscreenOverlayBounds(View root) {
|
private OverlayBounds fullscreenOverlayBounds(View root) {
|
||||||
int width = root.getWidth();
|
return new OverlayBounds(root.getWidth(), root.getHeight());
|
||||||
int height = root.getHeight();
|
|
||||||
Rect bounds = currentWindowBounds(root.getContext());
|
|
||||||
if (bounds.width() > 0) {
|
|
||||||
width = bounds.width();
|
|
||||||
}
|
|
||||||
return new OverlayBounds(width, height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Rect currentWindowBounds(Context context) {
|
private static Rect currentWindowBounds(Context context) {
|
||||||
@@ -761,6 +739,47 @@ final class BatteryBarController {
|
|||||||
private record OverlayBounds(int width, int height) {
|
private record OverlayBounds(int width, int height) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private record RenderSignature(
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
BatteryBarGeometry.Scenario scenario,
|
||||||
|
int batteryLevel,
|
||||||
|
boolean plugged,
|
||||||
|
int color,
|
||||||
|
String position,
|
||||||
|
String alignment,
|
||||||
|
int thicknessDp,
|
||||||
|
int edgeOffsetDp,
|
||||||
|
String curvedGeometryMode,
|
||||||
|
int minLevel,
|
||||||
|
int maxLevel
|
||||||
|
) {
|
||||||
|
static RenderSignature of(
|
||||||
|
View root,
|
||||||
|
BatteryBarGeometry.Scenario scenario,
|
||||||
|
int batteryLevel,
|
||||||
|
boolean plugged,
|
||||||
|
int color,
|
||||||
|
BatteryBarGeometry geometry,
|
||||||
|
SbtSettings settings
|
||||||
|
) {
|
||||||
|
return new RenderSignature(
|
||||||
|
root.getWidth(),
|
||||||
|
root.getHeight(),
|
||||||
|
scenario,
|
||||||
|
batteryLevel,
|
||||||
|
plugged,
|
||||||
|
color,
|
||||||
|
geometry.position,
|
||||||
|
geometry.alignment,
|
||||||
|
geometry.thicknessDp,
|
||||||
|
geometry.edgeOffsetDp,
|
||||||
|
geometry.curvedGeometryMode,
|
||||||
|
settings.batteryBarMinLevel,
|
||||||
|
settings.batteryBarMaxLevel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void updateSystemBarState(java.util.List<Object> args) {
|
private void updateSystemBarState(java.util.List<Object> args) {
|
||||||
if (args == null || args.size() < 2) {
|
if (args == null || args.size() < 2) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
+26
@@ -104,6 +104,10 @@ final class DrawerClockTextController {
|
|||||||
untrackDisabledRoles(clockEnabled, dateEnabled);
|
untrackDisabledRoles(clockEnabled, dateEnabled);
|
||||||
|
|
||||||
SurfaceMode surfaceMode = scene != null ? scene.surfaceMode() : null;
|
SurfaceMode surfaceMode = scene != null ? scene.surfaceMode() : null;
|
||||||
|
if (!root.isLayoutRequested()
|
||||||
|
&& hasAttachedCachedCandidates(root, clockEnabled, dateEnabled, surfaceMode)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (hasValidTrackedCandidates(root, clockEnabled, dateEnabled, surfaceMode)) {
|
if (hasValidTrackedCandidates(root, clockEnabled, dateEnabled, surfaceMode)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -200,6 +204,28 @@ final class DrawerClockTextController {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean hasAttachedCachedCandidates(
|
||||||
|
View root,
|
||||||
|
boolean clockEnabled,
|
||||||
|
boolean dateEnabled,
|
||||||
|
SurfaceMode surfaceMode
|
||||||
|
) {
|
||||||
|
CandidateCache cache = candidateCacheByRoot.get(root);
|
||||||
|
if (cache == null || cache.surfaceMode != surfaceMode) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return (!clockEnabled || isAttachedCachedCandidate(cache.clockView, Role.CLOCK))
|
||||||
|
&& (!dateEnabled || isAttachedCachedCandidate(cache.dateView, Role.DATE));
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isAttachedCachedCandidate(WeakReference<TextView> reference, Role role) {
|
||||||
|
TextView textView = reference != null ? reference.get() : null;
|
||||||
|
return textView != null
|
||||||
|
&& textView.isAttachedToWindow()
|
||||||
|
&& trackedRoles.get(textView) == role
|
||||||
|
&& ownedTexts.contains(textView);
|
||||||
|
}
|
||||||
|
|
||||||
private void track(TextView textView, Role role) {
|
private void track(TextView textView, Role role) {
|
||||||
if (textView == null || role == null) {
|
if (textView == null || role == null) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,43 +0,0 @@
|
|||||||
package se.ajpanton.statusbartweak.runtime.hooks;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.WeakHashMap;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Replacement for legacy Xposed additional-instance-field helpers.
|
|
||||||
*/
|
|
||||||
public final class InstanceStateStore {
|
|
||||||
|
|
||||||
private final WeakHashMap<Object, Map<String, Object>> state = new WeakHashMap<>();
|
|
||||||
|
|
||||||
public synchronized Object get(Object target, String key) {
|
|
||||||
if (target == null || key == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
Map<String, Object> fields = state.get(target);
|
|
||||||
return fields != null ? fields.get(key) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void put(Object target, String key, Object value) {
|
|
||||||
if (target == null || key == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Map<String, Object> fields = state.computeIfAbsent(target, ignored -> new HashMap<>());
|
|
||||||
fields.put(key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void remove(Object target, String key) {
|
|
||||||
if (target == null || key == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Map<String, Object> fields = state.get(target);
|
|
||||||
if (fields == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
fields.remove(key);
|
|
||||||
if (fields.isEmpty()) {
|
|
||||||
state.remove(target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+16
-1
@@ -17,6 +17,7 @@ import se.ajpanton.statusbartweak.runtime.render.StatusBarTintTarget;
|
|||||||
final class DarkIconDispatcherGuard {
|
final class DarkIconDispatcherGuard {
|
||||||
private final RuntimeContext runtimeContext;
|
private final RuntimeContext runtimeContext;
|
||||||
private final BooleanSupplier lockscreenSceneSupplier;
|
private final BooleanSupplier lockscreenSceneSupplier;
|
||||||
|
private final BooleanSupplier lockscreenDarkIconsSupplier;
|
||||||
private final Runnable refreshAllRoots;
|
private final Runnable refreshAllRoots;
|
||||||
private final Set<Object> dispatchers =
|
private final Set<Object> dispatchers =
|
||||||
Collections.newSetFromMap(new WeakHashMap<>());
|
Collections.newSetFromMap(new WeakHashMap<>());
|
||||||
@@ -25,10 +26,12 @@ final class DarkIconDispatcherGuard {
|
|||||||
DarkIconDispatcherGuard(
|
DarkIconDispatcherGuard(
|
||||||
RuntimeContext runtimeContext,
|
RuntimeContext runtimeContext,
|
||||||
BooleanSupplier lockscreenSceneSupplier,
|
BooleanSupplier lockscreenSceneSupplier,
|
||||||
|
BooleanSupplier lockscreenDarkIconsSupplier,
|
||||||
Runnable refreshAllRoots
|
Runnable refreshAllRoots
|
||||||
) {
|
) {
|
||||||
this.runtimeContext = runtimeContext;
|
this.runtimeContext = runtimeContext;
|
||||||
this.lockscreenSceneSupplier = lockscreenSceneSupplier;
|
this.lockscreenSceneSupplier = lockscreenSceneSupplier;
|
||||||
|
this.lockscreenDarkIconsSupplier = lockscreenDarkIconsSupplier;
|
||||||
this.refreshAllRoots = refreshAllRoots;
|
this.refreshAllRoots = refreshAllRoots;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,7 +51,7 @@ final class DarkIconDispatcherGuard {
|
|||||||
chain -> {
|
chain -> {
|
||||||
Object dispatcher = chain.getThisObject();
|
Object dispatcher = chain.getThisObject();
|
||||||
track(dispatcher);
|
track(dispatcher);
|
||||||
if (isLockscreenScene()) {
|
if (isLockscreenScene() && !shouldUseDarkLockscreenIcons()) {
|
||||||
forceLightState(dispatcher);
|
forceLightState(dispatcher);
|
||||||
}
|
}
|
||||||
Object result = chain.proceed();
|
Object result = chain.proceed();
|
||||||
@@ -63,7 +66,11 @@ final class DarkIconDispatcherGuard {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (Object dispatcher : new ArrayList<>(dispatchers)) {
|
for (Object dispatcher : new ArrayList<>(dispatchers)) {
|
||||||
|
if (shouldUseDarkLockscreenIcons()) {
|
||||||
|
restoreState(dispatcher, forcedStates.remove(dispatcher));
|
||||||
|
} else {
|
||||||
forceLightState(dispatcher);
|
forceLightState(dispatcher);
|
||||||
|
}
|
||||||
ReflectionSupport.invokeMethod(dispatcher, "applyIconTint");
|
ReflectionSupport.invokeMethod(dispatcher, "applyIconTint");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -85,6 +92,10 @@ final class DarkIconDispatcherGuard {
|
|||||||
return lockscreenSceneSupplier.getAsBoolean();
|
return lockscreenSceneSupplier.getAsBoolean();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean shouldUseDarkLockscreenIcons() {
|
||||||
|
return lockscreenDarkIconsSupplier.getAsBoolean();
|
||||||
|
}
|
||||||
|
|
||||||
private void track(Object dispatcher) {
|
private void track(Object dispatcher) {
|
||||||
if (dispatcher != null) {
|
if (dispatcher != null) {
|
||||||
dispatchers.add(dispatcher);
|
dispatchers.add(dispatcher);
|
||||||
@@ -92,6 +103,10 @@ final class DarkIconDispatcherGuard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateTintTarget(Object dispatcher) {
|
private void updateTintTarget(Object dispatcher) {
|
||||||
|
if (isLockscreenScene() && shouldUseDarkLockscreenIcons()) {
|
||||||
|
StatusBarTintTarget.setDarkIcons(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
Object intensity = ReflectionSupport.getFieldValue(dispatcher, "mDarkIntensity");
|
Object intensity = ReflectionSupport.getFieldValue(dispatcher, "mDarkIntensity");
|
||||||
if (intensity instanceof Number number) {
|
if (intensity instanceof Number number) {
|
||||||
StatusBarTintTarget.setDarkIcons(number.floatValue() > 0.5f);
|
StatusBarTintTarget.setDarkIcons(number.floatValue() > 0.5f);
|
||||||
|
|||||||
+117
-10
@@ -1,8 +1,11 @@
|
|||||||
package se.ajpanton.statusbartweak.runtime.layout;
|
package se.ajpanton.statusbartweak.runtime.layout;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
import android.app.KeyguardManager;
|
import android.app.KeyguardManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
@@ -80,6 +83,7 @@ final class StockLayoutCanvasController {
|
|||||||
"mEntries",
|
"mEntries",
|
||||||
"entries"
|
"entries"
|
||||||
};
|
};
|
||||||
|
private static final int APPEARANCE_LIGHT_STATUS_BARS = 8;
|
||||||
private static final Set<String> TARGET_ID_NAMES = Set.of(
|
private static final Set<String> TARGET_ID_NAMES = Set.of(
|
||||||
"clock",
|
"clock",
|
||||||
"left_clock_container",
|
"left_clock_container",
|
||||||
@@ -198,6 +202,7 @@ final class StockLayoutCanvasController {
|
|||||||
private int notificationDrawerCloseGeneration;
|
private int notificationDrawerCloseGeneration;
|
||||||
private boolean notificationDrawerClosePending;
|
private boolean notificationDrawerClosePending;
|
||||||
private int aodVisualAlphaGeneration;
|
private int aodVisualAlphaGeneration;
|
||||||
|
private int systemBarAppearance;
|
||||||
private int systemBarRequestedVisibleTypes = WindowInsets.Type.statusBars();
|
private int systemBarRequestedVisibleTypes = WindowInsets.Type.statusBars();
|
||||||
private boolean statusBarTransientShown;
|
private boolean statusBarTransientShown;
|
||||||
|
|
||||||
@@ -207,6 +212,7 @@ final class StockLayoutCanvasController {
|
|||||||
darkIconDispatcherGuard = new DarkIconDispatcherGuard(
|
darkIconDispatcherGuard = new DarkIconDispatcherGuard(
|
||||||
runtimeContext,
|
runtimeContext,
|
||||||
this::isLockscreenScene,
|
this::isLockscreenScene,
|
||||||
|
this::shouldUseDarkLockscreenStatusbarTint,
|
||||||
this::scheduleUnlockedAppearanceRefreshForAllRoots);
|
this::scheduleUnlockedAppearanceRefreshForAllRoots);
|
||||||
lockscreenCardsNotificationStripRenderer =
|
lockscreenCardsNotificationStripRenderer =
|
||||||
new LockscreenCardsNotificationStripRenderer();
|
new LockscreenCardsNotificationStripRenderer();
|
||||||
@@ -247,29 +253,39 @@ final class StockLayoutCanvasController {
|
|||||||
"onSystemBarAttributesChanged",
|
"onSystemBarAttributesChanged",
|
||||||
chain -> {
|
chain -> {
|
||||||
Object result = chain.proceed();
|
Object result = chain.proceed();
|
||||||
updateSystemBarRequestedVisibleTypes(chain.getArgs());
|
updateSystemBarAttributes(chain.getArgs());
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateSystemBarRequestedVisibleTypes(List<Object> args) {
|
private void updateSystemBarAttributes(List<Object> args) {
|
||||||
if (args == null || args.size() <= 5) {
|
if (args == null || args.size() < 2) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Integer displayId = asInteger(args.get(0));
|
Integer displayId = asInteger(args.get(0));
|
||||||
Integer requestedVisibleTypes = asInteger(args.get(5));
|
Integer appearance = asInteger(args.get(1));
|
||||||
if (displayId == null || displayId != 0 || requestedVisibleTypes == null) {
|
Integer requestedVisibleTypes = args.size() > 5 ? asInteger(args.get(5)) : null;
|
||||||
return;
|
if (displayId == null || displayId != 0 || appearance == null) {
|
||||||
}
|
|
||||||
if (systemBarRequestedVisibleTypes == requestedVisibleTypes) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
boolean appearanceChanged = systemBarAppearance != appearance;
|
||||||
|
systemBarAppearance = appearance;
|
||||||
|
if (requestedVisibleTypes != null
|
||||||
|
&& systemBarRequestedVisibleTypes != requestedVisibleTypes) {
|
||||||
systemBarRequestedVisibleTypes = requestedVisibleTypes;
|
systemBarRequestedVisibleTypes = requestedVisibleTypes;
|
||||||
if (statusBarsRequestedVisible()) {
|
if (statusBarsRequestedVisible()) {
|
||||||
releaseSuppressedHiddenStatusBarRoots();
|
releaseSuppressedHiddenStatusBarRoots();
|
||||||
privacyOverlayHiddenStatusBarRoots.clear();
|
privacyOverlayHiddenStatusBarRoots.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (appearanceChanged) {
|
||||||
|
darkIconDispatcherGuard.forceLightStateForAll();
|
||||||
|
requestUnlockedLayoutRefreshForAllRoots();
|
||||||
|
} else if (statusBarsRequestedVisible()) {
|
||||||
|
releaseSuppressedHiddenStatusBarRoots();
|
||||||
|
privacyOverlayHiddenStatusBarRoots.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void installTransientBarListener(ClassLoader classLoader) {
|
private void installTransientBarListener(ClassLoader classLoader) {
|
||||||
Class<?> commandQueueClass = ReflectionSupport.findClassIfExists(
|
Class<?> commandQueueClass = ReflectionSupport.findClassIfExists(
|
||||||
@@ -1807,9 +1823,18 @@ final class StockLayoutCanvasController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dirtyUnlockedLayoutRoots.add(root);
|
dirtyUnlockedLayoutRoots.add(root);
|
||||||
|
Runnable refresh = () -> {
|
||||||
|
if (root.isAttachedToWindow()) {
|
||||||
root.requestLayout();
|
root.requestLayout();
|
||||||
root.invalidate();
|
root.invalidate();
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
if (isViewThread(root)) {
|
||||||
|
refresh.run();
|
||||||
|
} else if (root.getHandler() != null) {
|
||||||
|
root.getHandler().post(refresh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private View rootForShadeTarget(Object target) {
|
private View rootForShadeTarget(Object target) {
|
||||||
if (!(target instanceof View view)) {
|
if (!(target instanceof View view)) {
|
||||||
@@ -2157,6 +2182,15 @@ final class StockLayoutCanvasController {
|
|||||||
return scene != null && scene.isLockscreen();
|
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) {
|
private void scheduleUnlockedAppearanceRefreshForRoot(View root) {
|
||||||
scheduleUnlockedAppearanceRefreshForRoot(root, false);
|
scheduleUnlockedAppearanceRefreshForRoot(root, false);
|
||||||
}
|
}
|
||||||
@@ -2282,7 +2316,8 @@ final class StockLayoutCanvasController {
|
|||||||
if (unlockedIconRenderController.refreshUnlockedClockText(
|
if (unlockedIconRenderController.refreshUnlockedClockText(
|
||||||
root,
|
root,
|
||||||
unlockedHosts.clockHost,
|
unlockedHosts.clockHost,
|
||||||
activeScene)) {
|
activeScene,
|
||||||
|
statusBarTintTargetEnabledForScene(activeScene))) {
|
||||||
bringUnlockedHostsAndDebugOverlayToFront(root);
|
bringUnlockedHostsAndDebugOverlayToFront(root);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2402,6 +2437,16 @@ final class StockLayoutCanvasController {
|
|||||||
boolean unlockedScene = activeScene != null && activeScene.isUnlocked();
|
boolean unlockedScene = activeScene != null && activeScene.isUnlocked();
|
||||||
boolean aodScene = activeScene != null && activeScene.isAod();
|
boolean aodScene = activeScene != null && activeScene.isAod();
|
||||||
boolean rootDirty = dirtyUnlockedLayoutRoots.remove(root);
|
boolean rootDirty = dirtyUnlockedLayoutRoots.remove(root);
|
||||||
|
if (canSkipStableDrawOnlyApply(root, activeScene, rootDirty)) {
|
||||||
|
if (unlockedScene) {
|
||||||
|
syncUnlockedHostsToStockStatusBar(root, activeScene);
|
||||||
|
hideTrackedUnlockedStockSurfaces(root);
|
||||||
|
hideTrackedStatusChipSources(root);
|
||||||
|
} else {
|
||||||
|
bringUnlockedHostsAndDebugOverlayToFront(root);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
boolean aodLayoutRoot = aodScene && isAodLayoutRoot(root, activeScene);
|
boolean aodLayoutRoot = aodScene && isAodLayoutRoot(root, activeScene);
|
||||||
boolean hasAodLayoutPlan = aodScene && unlockedIconRenderController.hasLayoutPlan(root);
|
boolean hasAodLayoutPlan = aodScene && unlockedIconRenderController.hasLayoutPlan(root);
|
||||||
boolean layoutRoot = aodScene ? aodLayoutRoot : statusBarRoot;
|
boolean layoutRoot = aodScene ? aodLayoutRoot : statusBarRoot;
|
||||||
@@ -2481,6 +2526,7 @@ final class StockLayoutCanvasController {
|
|||||||
unlockedHosts.statusHost,
|
unlockedHosts.statusHost,
|
||||||
unlockedHosts.notificationHost,
|
unlockedHosts.notificationHost,
|
||||||
activeScene,
|
activeScene,
|
||||||
|
statusBarTintTargetEnabledForScene(activeScene),
|
||||||
rootDirty,
|
rootDirty,
|
||||||
lockedCarrierTextSource());
|
lockedCarrierTextSource());
|
||||||
boolean shouldShowUnlockedHosts = unlockedScene
|
boolean shouldShowUnlockedHosts = unlockedScene
|
||||||
@@ -2551,6 +2597,35 @@ final class StockLayoutCanvasController {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean canSkipStableDrawOnlyApply(
|
||||||
|
View root,
|
||||||
|
SceneKey scene,
|
||||||
|
boolean rootDirty
|
||||||
|
) {
|
||||||
|
if (root == null
|
||||||
|
|| scene == null
|
||||||
|
|| (!scene.isUnlocked() && !scene.isLockscreen())
|
||||||
|
|| root.isLayoutRequested()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (rootDirty) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!hasDirectUnlockedLayoutHost(root)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!unlockedIconRenderController.hasLayoutPlan(root)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (isKnownRootGeometryChanged(root)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (scene.isUnlocked() && !hasTrackedUnlockedStockSurfaces(root)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private void hideTrackedUnlockedStockSurfaces(View root) {
|
private void hideTrackedUnlockedStockSurfaces(View root) {
|
||||||
if (root == null || trackedUnlockedStockSurfaces.isEmpty()) {
|
if (root == null || trackedUnlockedStockSurfaces.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
@@ -3454,8 +3529,13 @@ final class StockLayoutCanvasController {
|
|||||||
boolean shelfSurface = isCardsNotificationIconSurface(view);
|
boolean shelfSurface = isCardsNotificationIconSurface(view);
|
||||||
boolean shelfBackgroundSurface = isCardsNotificationShelfBackgroundSurface(view);
|
boolean shelfBackgroundSurface = isCardsNotificationShelfBackgroundSurface(view);
|
||||||
boolean shadeIconOnlySurface = "keyguard_icononly_container_view".equals(idName);
|
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)
|
if (!("system_icons".equals(idName)
|
||||||
|| carrierSurface
|
|| carrierSurface
|
||||||
|
|| clockSurface
|
||||||
|| "system_icon_area".equals(idName)
|
|| "system_icon_area".equals(idName)
|
||||||
|| "statusIcons".equals(idName)
|
|| "statusIcons".equals(idName)
|
||||||
|| "battery".equals(idName)
|
|| "battery".equals(idName)
|
||||||
@@ -3860,10 +3940,15 @@ final class StockLayoutCanvasController {
|
|||||||
return hasVisibleStatusChipContent(view);
|
return hasVisibleStatusChipContent(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("MissingPermission") // The SystemUI process owns READ_PHONE_STATE; the explicit check below handles other hosts.
|
||||||
private boolean isPhoneCallActive(View view) {
|
private boolean isPhoneCallActive(View view) {
|
||||||
if (view == null || view.getContext() == null) {
|
if (view == null || view.getContext() == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (view.getContext().checkSelfPermission(Manifest.permission.READ_PHONE_STATE)
|
||||||
|
!= PackageManager.PERMISSION_GRANTED) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
TelecomManager telecomManager = view.getContext().getSystemService(TelecomManager.class);
|
TelecomManager telecomManager = view.getContext().getSystemService(TelecomManager.class);
|
||||||
return telecomManager != null && telecomManager.isInCall();
|
return telecomManager != null && telecomManager.isInCall();
|
||||||
@@ -4877,7 +4962,8 @@ final class StockLayoutCanvasController {
|
|||||||
lockscreenCardsNotificationRenderGenerationByRoot.remove(root);
|
lockscreenCardsNotificationRenderGenerationByRoot.remove(root);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (runtimeContext.getModeStateRepository().isSystemUiShadeLocked()) {
|
if (runtimeContext.getModeStateRepository().isSystemUiShadeLocked()
|
||||||
|
|| hasVisibleLockscreenShadeHeader(root)) {
|
||||||
removeLockscreenCardsNotificationHost(root);
|
removeLockscreenCardsNotificationHost(root);
|
||||||
lockscreenCardsNotificationRenderGenerationByRoot.remove(root);
|
lockscreenCardsNotificationRenderGenerationByRoot.remove(root);
|
||||||
return;
|
return;
|
||||||
@@ -4917,6 +5003,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(
|
private void renderAodCardsNotificationStripIfNeeded(
|
||||||
View root,
|
View root,
|
||||||
SbtSettings settings,
|
SbtSettings settings,
|
||||||
|
|||||||
@@ -484,4 +484,13 @@ final class LayoutPlan {
|
|||||||
notificationPlacements,
|
notificationPlacements,
|
||||||
carrierPlacement);
|
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 statusHost,
|
||||||
ViewGroup notificationHost,
|
ViewGroup notificationHost,
|
||||||
SceneKey scene,
|
SceneKey scene,
|
||||||
|
boolean statusBarTintTargetEnabled,
|
||||||
boolean forceStockRefresh,
|
boolean forceStockRefresh,
|
||||||
TextView externalCarrierView
|
TextView externalCarrierView
|
||||||
) {
|
) {
|
||||||
@@ -80,7 +81,7 @@ public final class UnlockedIconSnapshotRenderController {
|
|||||||
return new RenderResult(true, true, true);
|
return new RenderResult(true, true, true);
|
||||||
}
|
}
|
||||||
SbtSettings settings = RuntimeSettingsCache.get(root.getContext());
|
SbtSettings settings = RuntimeSettingsCache.get(root.getContext());
|
||||||
setStatusBarTintTargetEnabled(scene.isUnlocked());
|
setStatusBarTintTargetEnabled(statusBarTintTargetEnabled);
|
||||||
layoutHostToRoot(root, clockHost);
|
layoutHostToRoot(root, clockHost);
|
||||||
layoutHostToRoot(root, carrierHost);
|
layoutHostToRoot(root, carrierHost);
|
||||||
layoutHostToRoot(root, chipHost);
|
layoutHostToRoot(root, chipHost);
|
||||||
@@ -235,6 +236,7 @@ public final class UnlockedIconSnapshotRenderController {
|
|||||||
lastClockSourceGeometryByRoot.put(root, currentClockSourceGeometry);
|
lastClockSourceGeometryByRoot.put(root, currentClockSourceGeometry);
|
||||||
layoutPlan = withCurrentDotColors(layoutPlan, collectedIcons);
|
layoutPlan = withCurrentDotColors(layoutPlan, collectedIcons);
|
||||||
layoutPlan = withCurrentClockAppearance(root, layoutPlan, collectedIcons, settings);
|
layoutPlan = withCurrentClockAppearance(root, layoutPlan, collectedIcons, settings);
|
||||||
|
layoutPlan = withCurrentCarrierAppearance(layoutPlan);
|
||||||
lastLayoutPlanByRoot.put(root, layoutPlan);
|
lastLayoutPlanByRoot.put(root, layoutPlan);
|
||||||
if (clockEnabledForScene(settings, scene) && layoutPlan.clockPlacement != null) {
|
if (clockEnabledForScene(settings, scene) && layoutPlan.clockPlacement != null) {
|
||||||
clockRenderer.render(clockHost, layoutPlan.clockPlacement);
|
clockRenderer.render(clockHost, layoutPlan.clockPlacement);
|
||||||
@@ -347,7 +349,8 @@ public final class UnlockedIconSnapshotRenderController {
|
|||||||
public boolean refreshUnlockedClockText(
|
public boolean refreshUnlockedClockText(
|
||||||
View root,
|
View root,
|
||||||
ViewGroup clockHost,
|
ViewGroup clockHost,
|
||||||
SceneKey scene
|
SceneKey scene,
|
||||||
|
boolean statusBarTintTargetEnabled
|
||||||
) {
|
) {
|
||||||
if (root == null
|
if (root == null
|
||||||
|| clockHost == null
|
|| clockHost == null
|
||||||
@@ -361,7 +364,7 @@ public final class UnlockedIconSnapshotRenderController {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
SbtSettings settings = RuntimeSettingsCache.get(root.getContext());
|
SbtSettings settings = RuntimeSettingsCache.get(root.getContext());
|
||||||
setStatusBarTintTargetEnabled(scene.isUnlocked());
|
setStatusBarTintTargetEnabled(statusBarTintTargetEnabled);
|
||||||
if (!clockEnabledForScene(settings, scene)) {
|
if (!clockEnabledForScene(settings, scene)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -595,6 +598,24 @@ public final class UnlockedIconSnapshotRenderController {
|
|||||||
return plan.withClockPlacement(updatedClock);
|
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) {
|
private int clockReferenceColor(ClockPlacement placement, CollectedIcons icons) {
|
||||||
int targetColor = statusBarTintTargetColor();
|
int targetColor = statusBarTintTargetColor();
|
||||||
if (hasAlpha(targetColor)) {
|
if (hasAlpha(targetColor)) {
|
||||||
|
|||||||
+1
-5
@@ -859,7 +859,7 @@ final class UnlockedLayoutPlanner {
|
|||||||
}
|
}
|
||||||
if (style != NotificationDisplayStyle.ICONS
|
if (style != NotificationDisplayStyle.ICONS
|
||||||
&& !(style == NotificationDisplayStyle.UNKNOWN
|
&& !(style == NotificationDisplayStyle.UNKNOWN
|
||||||
&& isExperimentalGenericAod(settings))) {
|
&& SystemUiCapabilities.supportsExperimentalGenericAodStatusbarRoot(settings))) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return settings.layoutNotifEnabledAod ? settings.layoutNotifAodCount : 0;
|
return settings.layoutNotifEnabledAod ? settings.layoutNotifAodCount : 0;
|
||||||
@@ -873,10 +873,6 @@ final class UnlockedLayoutPlanner {
|
|||||||
&& scene.notificationDisplayStyle() == NotificationDisplayStyle.DOT;
|
&& scene.notificationDisplayStyle() == NotificationDisplayStyle.DOT;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isExperimentalGenericAod(SbtSettings settings) {
|
|
||||||
return SystemUiCapabilities.supportsExperimentalGenericAodStatusbarRoot(settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
private ArrayList<SnapshotPlacement> unreadNotificationPlacements(
|
private ArrayList<SnapshotPlacement> unreadNotificationPlacements(
|
||||||
ArrayList<SnapshotPlacement> placements
|
ArrayList<SnapshotPlacement> placements
|
||||||
) {
|
) {
|
||||||
|
|||||||
+2
-5
@@ -92,7 +92,8 @@ final class UnlockedStockSourceCollector {
|
|||||||
LockscreenCardsNotificationIconSourceStore
|
LockscreenCardsNotificationIconSourceStore
|
||||||
.snapshotAodNotificationPackageSources(root));
|
.snapshotAodNotificationPackageSources(root));
|
||||||
}
|
}
|
||||||
if (notificationIcons.isEmpty() && isExperimentalGenericAod(settings)) {
|
if (notificationIcons.isEmpty()
|
||||||
|
&& SystemUiCapabilities.supportsExperimentalGenericAodStatusbarRoot(settings)) {
|
||||||
View notificationRoot = anchors != null && anchors.notificationRoot != null
|
View notificationRoot = anchors != null && anchors.notificationRoot != null
|
||||||
? anchors.notificationRoot
|
? anchors.notificationRoot
|
||||||
: root;
|
: root;
|
||||||
@@ -146,10 +147,6 @@ final class UnlockedStockSourceCollector {
|
|||||||
&& SystemUiCapabilities.treatsUnknownAodNotificationStyleAsIcons(settings));
|
&& SystemUiCapabilities.treatsUnknownAodNotificationStyleAsIcons(settings));
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isExperimentalGenericAod(SbtSettings settings) {
|
|
||||||
return SystemUiCapabilities.supportsExperimentalGenericAodStatusbarRoot(settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String reflectString(View view, String methodName, String... fieldNames) {
|
private String reflectString(View view, String methodName, String... fieldNames) {
|
||||||
Object methodValue = ReflectionSupport.invokeMethod(view, methodName);
|
Object methodValue = ReflectionSupport.invokeMethod(view, methodName);
|
||||||
if (methodValue != null) {
|
if (methodValue != null) {
|
||||||
|
|||||||
@@ -107,10 +107,6 @@ public final class BatteryBarGeometry {
|
|||||||
return position + "|" + alignment + "|" + thicknessDp + "|" + edgeOffsetDp + "|" + curvedGeometryMode;
|
return position + "|" + alignment + "|" + thicknessDp + "|" + edgeOffsetDp + "|" + curvedGeometryMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String signature() {
|
|
||||||
return encode();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String enabledKey(Scenario scenario) {
|
public static String enabledKey(Scenario scenario) {
|
||||||
return SbtSettings.batteryBarGeometryOverrideEnabledKey(scenario.id);
|
return SbtSettings.batteryBarGeometryOverrideEnabledKey(scenario.id);
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -839,14 +839,14 @@ public final class BatteryBarFragment extends Fragment {
|
|||||||
final boolean[] updating = new boolean[]{false};
|
final boolean[] updating = new boolean[]{false};
|
||||||
if (minus != null) {
|
if (minus != null) {
|
||||||
minus.setOnClickListener(v -> {
|
minus.setOnClickListener(v -> {
|
||||||
int current = scenarioNumberValue(input, controls, prefs, edgeOffset);
|
int current = scenarioNumberValue(input, prefs, edgeOffset);
|
||||||
setScenarioNumberValue(input, current - 1, edgeOffset, updating);
|
setScenarioNumberValue(input, current - 1, edgeOffset, updating);
|
||||||
persistScenarioGeometry(prefs, scenarioGroup, geometryFromControls(controls, prefs));
|
persistScenarioGeometry(prefs, scenarioGroup, geometryFromControls(controls, prefs));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (plus != null) {
|
if (plus != null) {
|
||||||
plus.setOnClickListener(v -> {
|
plus.setOnClickListener(v -> {
|
||||||
int current = scenarioNumberValue(input, controls, prefs, edgeOffset);
|
int current = scenarioNumberValue(input, prefs, edgeOffset);
|
||||||
setScenarioNumberValue(input, current + 1, edgeOffset, updating);
|
setScenarioNumberValue(input, current + 1, edgeOffset, updating);
|
||||||
persistScenarioGeometry(prefs, scenarioGroup, geometryFromControls(controls, prefs));
|
persistScenarioGeometry(prefs, scenarioGroup, geometryFromControls(controls, prefs));
|
||||||
});
|
});
|
||||||
@@ -870,7 +870,7 @@ public final class BatteryBarFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
setScenarioNumberValue(
|
setScenarioNumberValue(
|
||||||
input,
|
input,
|
||||||
scenarioNumberValue(input, controls, prefs, edgeOffset),
|
scenarioNumberValue(input, prefs, edgeOffset),
|
||||||
edgeOffset,
|
edgeOffset,
|
||||||
updating);
|
updating);
|
||||||
persistScenarioGeometry(prefs, scenarioGroup, geometryFromControls(controls, prefs));
|
persistScenarioGeometry(prefs, scenarioGroup, geometryFromControls(controls, prefs));
|
||||||
@@ -882,7 +882,7 @@ public final class BatteryBarFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
setScenarioNumberValue(
|
setScenarioNumberValue(
|
||||||
input,
|
input,
|
||||||
scenarioNumberValue(input, controls, prefs, edgeOffset),
|
scenarioNumberValue(input, prefs, edgeOffset),
|
||||||
edgeOffset,
|
edgeOffset,
|
||||||
updating);
|
updating);
|
||||||
persistScenarioGeometry(prefs, scenarioGroup, geometryFromControls(controls, prefs));
|
persistScenarioGeometry(prefs, scenarioGroup, geometryFromControls(controls, prefs));
|
||||||
@@ -891,7 +891,6 @@ public final class BatteryBarFragment extends Fragment {
|
|||||||
|
|
||||||
private int scenarioNumberValue(
|
private int scenarioNumberValue(
|
||||||
EditText input,
|
EditText input,
|
||||||
GeometryControls controls,
|
|
||||||
SharedPreferences prefs,
|
SharedPreferences prefs,
|
||||||
boolean edgeOffset
|
boolean edgeOffset
|
||||||
) {
|
) {
|
||||||
@@ -950,8 +949,8 @@ public final class BatteryBarFragment extends Fragment {
|
|||||||
return new BatteryBarGeometry(
|
return new BatteryBarGeometry(
|
||||||
positionValue(checkedPosition),
|
positionValue(checkedPosition),
|
||||||
alignment,
|
alignment,
|
||||||
scenarioNumberValue(controls.thicknessInput, controls, prefs, false),
|
scenarioNumberValue(controls.thicknessInput, prefs, false),
|
||||||
scenarioNumberValue(controls.edgeOffsetInput, controls, prefs, true),
|
scenarioNumberValue(controls.edgeOffsetInput, prefs, true),
|
||||||
curvedGeometryValue(checkedPosition));
|
curvedGeometryValue(checkedPosition));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public final class LayoutFragment extends Fragment {
|
|||||||
View root = inflater.inflate(R.layout.fragment_layout, container, false);
|
View root = inflater.inflate(R.layout.fragment_layout, container, false);
|
||||||
SharedPreferences prefs = requireContext()
|
SharedPreferences prefs = requireContext()
|
||||||
.getSharedPreferences(SbtSettings.PREFS_NAME, Context.MODE_PRIVATE);
|
.getSharedPreferences(SbtSettings.PREFS_NAME, Context.MODE_PRIVATE);
|
||||||
hideUnlockedSubpageObsoleteControls(root);
|
configureUnlockedOnlyModeControls(root);
|
||||||
reorderItemCards(root, prefs);
|
reorderItemCards(root, prefs);
|
||||||
|
|
||||||
setupPositionSection(root,
|
setupPositionSection(root,
|
||||||
@@ -508,7 +508,7 @@ public final class LayoutFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void hideUnlockedSubpageObsoleteControls(View root) {
|
private void configureUnlockedOnlyModeControls(View root) {
|
||||||
hide(root, R.id.clock_position_mode_lockscreen);
|
hide(root, R.id.clock_position_mode_lockscreen);
|
||||||
hide(root, R.id.notif_position_mode_aod);
|
hide(root, R.id.notif_position_mode_aod);
|
||||||
hide(root, R.id.notif_position_mode_lockscreen);
|
hide(root, R.id.notif_position_mode_lockscreen);
|
||||||
|
|||||||
@@ -106,6 +106,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
|
android:baselineAligned="false"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
android:id="@+id/hidden_item_root"
|
android:id="@+id/hidden_item_root"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:baselineAligned="false"
|
||||||
android:foreground="?attr/selectableItemBackground"
|
android:foreground="?attr/selectableItemBackground"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:minHeight="56dp"
|
android:minHeight="56dp"
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
<color name="sbt_background_top">#FF110B07</color>
|
<color name="sbt_background_top">#FF110B07</color>
|
||||||
<color name="sbt_background_bottom">#FF1B0F08</color>
|
<color name="sbt_background_bottom">#FF1B0F08</color>
|
||||||
<color name="sbt_surface">#FF20140D</color>
|
<color name="sbt_surface">#FF20140D</color>
|
||||||
<color name="sbt_surface_variant">#FF302012</color>
|
|
||||||
<color name="sbt_on_primary">#FFFFFFFF</color>
|
<color name="sbt_on_primary">#FFFFFFFF</color>
|
||||||
<color name="sbt_on_surface">#FFEAF0F3</color>
|
<color name="sbt_on_surface">#FFEAF0F3</color>
|
||||||
<color name="sbt_on_surface_variant">#FFE3D3B6</color>
|
<color name="sbt_on_surface_variant">#FFE3D3B6</color>
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
|
||||||
<style name="Theme.StatusBarTweak" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
|
||||||
<item name="colorPrimary">@color/sbt_primary</item>
|
|
||||||
<item name="colorPrimaryVariant">@color/sbt_primary_dark</item>
|
|
||||||
<item name="colorOnPrimary">@color/sbt_on_primary</item>
|
|
||||||
<item name="colorSecondary">@color/sbt_accent</item>
|
|
||||||
<item name="colorSecondaryVariant">@color/sbt_accent_dark</item>
|
|
||||||
<item name="colorOnSecondary">@color/black</item>
|
|
||||||
<item name="colorSurface">@color/sbt_surface</item>
|
|
||||||
<item name="colorOnSurface">@color/sbt_on_surface</item>
|
|
||||||
<item name="android:colorAccent">@color/sbt_accent</item>
|
|
||||||
<item name="android:fontFamily">sans-serif</item>
|
|
||||||
<item name="android:windowBackground">@drawable/sbt_window_background</item>
|
|
||||||
<item name="android:navigationBarColor">@color/sbt_primary_dark</item>
|
|
||||||
<item name="android:statusBarColor">@color/sbt_primary_dark</item>
|
|
||||||
<item name="android:windowLightStatusBar">false</item>
|
|
||||||
<item name="materialCardViewStyle">@style/Widget.StatusBarTweak.Card</item>
|
|
||||||
<item name="materialButtonOutlinedStyle">@style/Widget.StatusBarTweak.OutlinedButton</item>
|
|
||||||
<item name="materialAlertDialogTheme">@style/ThemeOverlay.StatusBarTweak.MaterialAlertDialog</item>
|
|
||||||
<item name="sliderStyle">@style/Widget.StatusBarTweak.Slider</item>
|
|
||||||
<item name="switchStyle">@style/Widget.StatusBarTweak.Switch</item>
|
|
||||||
</style>
|
|
||||||
</resources>
|
|
||||||
@@ -8,12 +8,10 @@
|
|||||||
<color name="sbt_background_top">#FFFFF4E8</color>
|
<color name="sbt_background_top">#FFFFF4E8</color>
|
||||||
<color name="sbt_background_bottom">#FFF5E5D2</color>
|
<color name="sbt_background_bottom">#FFF5E5D2</color>
|
||||||
<color name="sbt_surface">#FFFFFFFF</color>
|
<color name="sbt_surface">#FFFFFFFF</color>
|
||||||
<color name="sbt_surface_variant">#FFFFF1E0</color>
|
|
||||||
<color name="sbt_on_primary">#FFFFFFFF</color>
|
<color name="sbt_on_primary">#FFFFFFFF</color>
|
||||||
<color name="sbt_on_surface">#FF111820</color>
|
<color name="sbt_on_surface">#FF111820</color>
|
||||||
<color name="sbt_on_surface_variant">#FF62553F</color>
|
<color name="sbt_on_surface_variant">#FF62553F</color>
|
||||||
<color name="black">#FF000000</color>
|
<color name="black">#FF000000</color>
|
||||||
<color name="white">#FFFFFFFF</color>
|
|
||||||
<color name="sbt_card_outline">#24000000</color>
|
<color name="sbt_card_outline">#24000000</color>
|
||||||
<color name="sbt_panel_outline">#4D000000</color>
|
<color name="sbt_panel_outline">#4D000000</color>
|
||||||
<color name="sbt_hidden_item_active_bg">#1AE65100</color>
|
<color name="sbt_hidden_item_active_bg">#1AE65100</color>
|
||||||
|
|||||||
@@ -14,7 +14,6 @@
|
|||||||
<string name="nav_layout_lockscreen">    Lockscreen</string>
|
<string name="nav_layout_lockscreen">    Lockscreen</string>
|
||||||
<string name="nav_layout_aod">    AOD</string>
|
<string name="nav_layout_aod">    AOD</string>
|
||||||
<string name="nav_battery_bar">Battery bar</string>
|
<string name="nav_battery_bar">Battery bar</string>
|
||||||
<string name="nav_block_app_notification_icons">Hide notification icons</string>
|
|
||||||
<string name="nav_status_chips">Status chips</string>
|
<string name="nav_status_chips">Status chips</string>
|
||||||
<string name="nav_misc">Misc</string>
|
<string name="nav_misc">Misc</string>
|
||||||
<string name="debug_title">Debugging</string>
|
<string name="debug_title">Debugging</string>
|
||||||
@@ -51,7 +50,6 @@
|
|||||||
<string name="debug_camera_action_undo">↶</string>
|
<string name="debug_camera_action_undo">↶</string>
|
||||||
<string name="debug_camera_other_item">%1$s • %2$s</string>
|
<string name="debug_camera_other_item">%1$s • %2$s</string>
|
||||||
<string name="debug_camera_unknown">unknown</string>
|
<string name="debug_camera_unknown">unknown</string>
|
||||||
<string name="notification_icons_title">Notification icons</string>
|
|
||||||
<string name="system_icons_title">Hide status icons</string>
|
<string name="system_icons_title">Hide status icons</string>
|
||||||
<string name="system_icons_hint">Status-icon rules for the custom layout engine.</string>
|
<string name="system_icons_hint">Status-icon rules for the custom layout engine.</string>
|
||||||
<string name="system_icons_hide_hint">Icons represent, in order:\nAOD, Lockscreen, Unlocked.</string>
|
<string name="system_icons_hide_hint">Icons represent, in order:\nAOD, Lockscreen, Unlocked.</string>
|
||||||
@@ -72,43 +70,27 @@
|
|||||||
<string name="system_icon_bluetooth">Bluetooth</string>
|
<string name="system_icon_bluetooth">Bluetooth</string>
|
||||||
<string name="system_icon_data_saver">Data saver</string>
|
<string name="system_icon_data_saver">Data saver</string>
|
||||||
<string name="system_icon_do_not_disturb">Do not disturb</string>
|
<string name="system_icon_do_not_disturb">Do not disturb</string>
|
||||||
<string name="system_icon_enhanced_processing">Enhanced processing</string>
|
|
||||||
<string name="system_icon_home_carrier">Homescreen carrier</string>
|
|
||||||
<string name="system_icon_hotspot">Mobile hotspot</string>
|
<string name="system_icon_hotspot">Mobile hotspot</string>
|
||||||
<string name="system_icon_ims">IMS network icons</string>
|
|
||||||
<string name="system_icon_location">Location</string>
|
<string name="system_icon_location">Location</string>
|
||||||
<string name="system_icon_lock_carrier">Lockscreen carrier</string>
|
|
||||||
<string name="system_icon_lockscreen_mum">Two phone user icon</string>
|
|
||||||
<string name="system_icon_managed_profile">Managed profile</string>
|
|
||||||
<string name="system_icon_mobile">Mobile data signal</string>
|
<string name="system_icon_mobile">Mobile data signal</string>
|
||||||
<string name="system_icon_modes">Modes</string>
|
|
||||||
<string name="system_icon_nfc">NFC</string>
|
<string name="system_icon_nfc">NFC</string>
|
||||||
<string name="system_icon_panel_carrier">Expanded panel carrier</string>
|
|
||||||
<string name="system_icon_power_saver">Power saver</string>
|
|
||||||
<string name="system_icon_rcs">RCS</string>
|
|
||||||
<string name="system_icon_two_phone_mode">Two phone mode icon</string>
|
|
||||||
<string name="system_icon_volume">Volume</string>
|
<string name="system_icon_volume">Volume</string>
|
||||||
<string name="system_icon_vpn">VPN</string>
|
<string name="system_icon_vpn">VPN</string>
|
||||||
<string name="system_icon_wifi">Wi-Fi</string>
|
<string name="system_icon_wifi">Wi-Fi</string>
|
||||||
<string name="section_unlocked">Unlocked</string>
|
<string name="section_unlocked">Unlocked</string>
|
||||||
<string name="section_icons_mode">Icons mode</string>
|
|
||||||
<string name="section_cards_mode">Cards mode</string>
|
|
||||||
<string name="section_aod">AOD</string>
|
<string name="section_aod">AOD</string>
|
||||||
<string name="section_lockscreen">Lockscreen</string>
|
<string name="section_lockscreen">Lockscreen</string>
|
||||||
<string name="label_max_icons_per_row">Max icons per row</string>
|
<string name="label_max_icons_per_row">Max icons per row</string>
|
||||||
<string name="label_max_rows">Max rows</string>
|
<string name="label_max_rows">Max rows</string>
|
||||||
<string name="label_even_distribution">Even distribution</string>
|
<string name="label_even_distribution">Even distribution</string>
|
||||||
<string name="label_limit_screen_width">Limit to screen width</string>
|
<string name="label_limit_screen_width">Limit to screen width</string>
|
||||||
<string name="label_cutout_aware">Cutout aware</string>
|
|
||||||
<string name="label_aod_keep_visible_during_call">Keep AOD visible during calls</string>
|
<string name="label_aod_keep_visible_during_call">Keep AOD visible during calls</string>
|
||||||
<string name="label_aod_keep_visible_during_call_hint">Prevents SystemUI from suppressing AOD while an active call is in progress.</string>
|
<string name="label_aod_keep_visible_during_call_hint">Prevents SystemUI from suppressing AOD while an active call is in progress.</string>
|
||||||
<string name="hidden_apps_dialog_title">Notification icon app blocks</string>
|
|
||||||
<string name="hidden_apps_page_title">Hide notification icons</string>
|
<string name="hidden_apps_page_title">Hide notification icons</string>
|
||||||
<string name="hidden_apps_dialog_subtitle">Pull down to refresh session apps. List contents are fixed until refresh.</string>
|
<string name="hidden_apps_dialog_subtitle">Pull down to refresh session apps. List contents are fixed until refresh.</string>
|
||||||
<string name="hidden_apps_page_hint">Icons represent, in order:\nAOD, Lockscreen, Unlocked</string>
|
<string name="hidden_apps_page_hint">Icons represent, in order:\nAOD, Lockscreen, Unlocked</string>
|
||||||
<string name="hidden_apps_clear_session">Clear session list</string>
|
<string name="hidden_apps_clear_session">Clear session list</string>
|
||||||
<string name="hidden_apps_empty">No apps yet. Generate a notification first.</string>
|
<string name="hidden_apps_empty">No apps yet. Generate a notification first.</string>
|
||||||
<string name="hidden_apps_close">Close</string>
|
|
||||||
<string name="hidden_apps_exception_regex_input_hint">Regex</string>
|
<string name="hidden_apps_exception_regex_input_hint">Regex</string>
|
||||||
<plurals name="hidden_apps_package_with_exceptions">
|
<plurals name="hidden_apps_package_with_exceptions">
|
||||||
<item quantity="one">%1$s \u2022 %2$d exception</item>
|
<item quantity="one">%1$s \u2022 %2$d exception</item>
|
||||||
@@ -126,7 +108,6 @@
|
|||||||
<string name="hidden_apps_mode_unlock">Unlocked</string>
|
<string name="hidden_apps_mode_unlock">Unlocked</string>
|
||||||
<string name="hidden_apps_package_unknown">(unknown package)</string>
|
<string name="hidden_apps_package_unknown">(unknown package)</string>
|
||||||
<string name="status_chips_title">Status chips</string>
|
<string name="status_chips_title">Status chips</string>
|
||||||
<string name="status_chips_hint">Hide Samsung/SystemUI status chips (music, maps/navigation, call) in the top status area.</string>
|
|
||||||
<string name="status_chips_hide_all_label">Hide other status chips (unlocked)</string>
|
<string name="status_chips_hide_all_label">Hide other status chips (unlocked)</string>
|
||||||
<string name="status_chips_hide_all_hint">Hides detected status chips that are not media, navigation or call. Privacy indicators are excluded.</string>
|
<string name="status_chips_hide_all_hint">Hides detected status chips that are not media, navigation or call. Privacy indicators are excluded.</string>
|
||||||
<string name="status_chips_hide_media_unlocked_label">Hide media chip (unlocked)</string>
|
<string name="status_chips_hide_media_unlocked_label">Hide media chip (unlocked)</string>
|
||||||
@@ -142,9 +123,6 @@
|
|||||||
<string name="battery_bar_position_top">Top edge of screen</string>
|
<string name="battery_bar_position_top">Top edge of screen</string>
|
||||||
<string name="battery_bar_position_bottom">Bottom of status bar</string>
|
<string name="battery_bar_position_bottom">Bottom of status bar</string>
|
||||||
<string name="battery_bar_alignment_title">Alignment</string>
|
<string name="battery_bar_alignment_title">Alignment</string>
|
||||||
<string name="battery_bar_alignment_ltr">→</string>
|
|
||||||
<string name="battery_bar_alignment_rtl">←</string>
|
|
||||||
<string name="battery_bar_alignment_center">↔</string>
|
|
||||||
<string name="battery_bar_thickness_title">Thickness (dp)</string>
|
<string name="battery_bar_thickness_title">Thickness (dp)</string>
|
||||||
<string name="battery_bar_edge_offset_title">Edge offset (dp)</string>
|
<string name="battery_bar_edge_offset_title">Edge offset (dp)</string>
|
||||||
<string name="battery_bar_curved_geometry_length">Follow screen edges</string>
|
<string name="battery_bar_curved_geometry_length">Follow screen edges</string>
|
||||||
@@ -163,15 +141,12 @@
|
|||||||
<string name="battery_bar_thresholds_title">Threshold colours</string>
|
<string name="battery_bar_thresholds_title">Threshold colours</string>
|
||||||
<string name="battery_bar_thresholds_hint">Below a threshold, the first matching colour overrides the default.</string>
|
<string name="battery_bar_thresholds_hint">Below a threshold, the first matching colour overrides the default.</string>
|
||||||
<string name="battery_bar_add_threshold">Add threshold</string>
|
<string name="battery_bar_add_threshold">Add threshold</string>
|
||||||
<string name="battery_bar_colour_dialog_title">Set colour</string>
|
|
||||||
<string name="battery_bar_colour_dialog_hint">Examples: #FA0, FA0, or #FA0 ; invRGB 0.5 *RGB</string>
|
<string name="battery_bar_colour_dialog_hint">Examples: #FA0, FA0, or #FA0 ; invRGB 0.5 *RGB</string>
|
||||||
<string name="battery_bar_threshold_percent_title">Threshold percent</string>
|
<string name="battery_bar_threshold_percent_title">Threshold percent</string>
|
||||||
<string name="battery_bar_threshold_percent_hint">Applies when battery is at or below this percent.</string>
|
<string name="battery_bar_threshold_percent_hint">Applies when battery is at or below this percent.</string>
|
||||||
<string name="battery_bar_threshold_change_percent">Change threshold %</string>
|
|
||||||
<string name="battery_bar_threshold_label">Below %1$d%%</string>
|
<string name="battery_bar_threshold_label">Below %1$d%%</string>
|
||||||
<string name="battery_bar_threshold_discharge_colour">Discharge colour</string>
|
<string name="battery_bar_threshold_discharge_colour">Discharge colour</string>
|
||||||
<string name="battery_bar_threshold_charge_colour">Charge colour</string>
|
<string name="battery_bar_threshold_charge_colour">Charge colour</string>
|
||||||
<string name="battery_bar_threshold_remove">Remove threshold</string>
|
|
||||||
<string name="battery_bar_colour_auto">Auto</string>
|
<string name="battery_bar_colour_auto">Auto</string>
|
||||||
<string name="battery_bar_colour_same_as_discharge">Same as discharge</string>
|
<string name="battery_bar_colour_same_as_discharge">Same as discharge</string>
|
||||||
<string name="battery_bar_colour_same_as_default">Default</string>
|
<string name="battery_bar_colour_same_as_default">Default</string>
|
||||||
@@ -185,9 +160,7 @@
|
|||||||
<string name="layout_home_title">Layout</string>
|
<string name="layout_home_title">Layout</string>
|
||||||
<string name="layout_title">Unlocked</string>
|
<string name="layout_title">Unlocked</string>
|
||||||
<string name="layout_master_toggle_title">Master toggle</string>
|
<string name="layout_master_toggle_title">Master toggle</string>
|
||||||
<string name="clock_enabled">Use custom clock</string>
|
|
||||||
<string name="layout_enabled">Use custom layout</string>
|
<string name="layout_enabled">Use custom layout</string>
|
||||||
<string name="clock_position_title">Clock position</string>
|
|
||||||
<string name="layout_clock_position_title">Clock</string>
|
<string name="layout_clock_position_title">Clock</string>
|
||||||
<string name="layout_carrier_position_title">Carrier</string>
|
<string name="layout_carrier_position_title">Carrier</string>
|
||||||
<string name="layout_chip_position_title">Status chip</string>
|
<string name="layout_chip_position_title">Status chip</string>
|
||||||
@@ -234,7 +207,6 @@
|
|||||||
<string name="clock_vertical_offset_label">Vertical position</string>
|
<string name="clock_vertical_offset_label">Vertical position</string>
|
||||||
<string name="clock_middle_side_left">Left side</string>
|
<string name="clock_middle_side_left">Left side</string>
|
||||||
<string name="clock_middle_side_right">Right side</string>
|
<string name="clock_middle_side_right">Right side</string>
|
||||||
<string name="clock_custom_format_title">Custom format</string>
|
|
||||||
<string name="clock_custom_format_statusbar_title">Statusbar clock</string>
|
<string name="clock_custom_format_statusbar_title">Statusbar clock</string>
|
||||||
<string name="clock_custom_format_drawer_clock_title">Drawer clock</string>
|
<string name="clock_custom_format_drawer_clock_title">Drawer clock</string>
|
||||||
<string name="clock_custom_format_drawer_date_title">Drawer date</string>
|
<string name="clock_custom_format_drawer_date_title">Drawer date</string>
|
||||||
@@ -257,7 +229,6 @@
|
|||||||
<string name="clock_font_picker_hint">Search font family</string>
|
<string name="clock_font_picker_hint">Search font family</string>
|
||||||
<string name="clock_font_picker_copied">Copied: %1$s</string>
|
<string name="clock_font_picker_copied">Copied: %1$s</string>
|
||||||
<string name="clock_custom_format_help_link">Date/time pattern reference only: https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html</string>
|
<string name="clock_custom_format_help_link">Date/time pattern reference only: https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html</string>
|
||||||
<string name="clock_custom_format_invalid">Invalid pattern</string>
|
|
||||||
<string name="label_battery_lockscreen_unplugged_percent">Unplugged battery % on lockscreen</string>
|
<string name="label_battery_lockscreen_unplugged_percent">Unplugged battery % on lockscreen</string>
|
||||||
<string name="label_battery_lockscreen_unplugged_percent_hint">Shows the plain battery percentage on the lockscreen when unplugged.</string>
|
<string name="label_battery_lockscreen_unplugged_percent_hint">Shows the plain battery percentage on the lockscreen when unplugged.</string>
|
||||||
<string name="label_battery_aod_unplugged_percent">Unplugged battery % on AOD</string>
|
<string name="label_battery_aod_unplugged_percent">Unplugged battery % on AOD</string>
|
||||||
|
|||||||
@@ -1,26 +1,4 @@
|
|||||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||||
<style name="Theme.StatusBarTweak" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
|
||||||
<item name="colorPrimary">@color/sbt_primary</item>
|
|
||||||
<item name="colorPrimaryVariant">@color/sbt_primary_dark</item>
|
|
||||||
<item name="colorOnPrimary">@color/sbt_on_primary</item>
|
|
||||||
<item name="colorSecondary">@color/sbt_accent</item>
|
|
||||||
<item name="colorSecondaryVariant">@color/sbt_accent_dark</item>
|
|
||||||
<item name="colorOnSecondary">@color/black</item>
|
|
||||||
<item name="colorSurface">@color/sbt_surface</item>
|
|
||||||
<item name="colorOnSurface">@color/sbt_on_surface</item>
|
|
||||||
<item name="android:colorAccent">@color/sbt_accent</item>
|
|
||||||
<item name="android:fontFamily">sans-serif</item>
|
|
||||||
<item name="android:windowBackground">@drawable/sbt_window_background</item>
|
|
||||||
<item name="android:navigationBarColor">@color/sbt_primary_dark</item>
|
|
||||||
<item name="android:statusBarColor">@color/sbt_primary_dark</item>
|
|
||||||
<item name="android:windowLightStatusBar">false</item>
|
|
||||||
<item name="materialCardViewStyle">@style/Widget.StatusBarTweak.Card</item>
|
|
||||||
<item name="materialButtonOutlinedStyle">@style/Widget.StatusBarTweak.OutlinedButton</item>
|
|
||||||
<item name="materialAlertDialogTheme">@style/ThemeOverlay.StatusBarTweak.MaterialAlertDialog</item>
|
|
||||||
<item name="sliderStyle">@style/Widget.StatusBarTweak.Slider</item>
|
|
||||||
<item name="switchStyle">@style/Widget.StatusBarTweak.Switch</item>
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<style name="Theme.StatusBarTweak.NoActionBar" parent="Theme.MaterialComponents.DayNight.NoActionBar">
|
<style name="Theme.StatusBarTweak.NoActionBar" parent="Theme.MaterialComponents.DayNight.NoActionBar">
|
||||||
<item name="colorPrimary">@color/sbt_primary</item>
|
<item name="colorPrimary">@color/sbt_primary</item>
|
||||||
<item name="colorPrimaryVariant">@color/sbt_primary_dark</item>
|
<item name="colorPrimaryVariant">@color/sbt_primary_dark</item>
|
||||||
|
|||||||
@@ -0,0 +1,115 @@
|
|||||||
|
package se.ajpanton.statusbartweak.shell.settings;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public final class SbtSettingsTest {
|
||||||
|
@Test
|
||||||
|
public void emptySourceMatchesRepresentativeDefaults() {
|
||||||
|
SbtSettings defaults = SbtSettings.defaults();
|
||||||
|
SbtSettings decoded = SbtSettings.fromSource(new MapSource());
|
||||||
|
|
||||||
|
assertEquals(SbtDefaults.CLOCK_ENABLED_DEFAULT, defaults.clockEnabled);
|
||||||
|
assertEquals(SbtDefaults.CLOCK_CUSTOM_FORMAT_DEFAULT, defaults.clockCustomFormat);
|
||||||
|
assertEquals(SbtDefaults.BATTERY_BAR_POSITION_DEFAULT, defaults.batteryBarPosition);
|
||||||
|
assertEquals(SbtDefaults.BATTERY_BAR_THICKNESS_DP_DEFAULT, defaults.batteryBarThicknessDp);
|
||||||
|
assertEquals(
|
||||||
|
SbtDefaults.LAYOUT_NOTIF_UNLOCKED_COUNT_DEFAULT,
|
||||||
|
defaults.layoutNotifUnlockedCount);
|
||||||
|
assertEquals(
|
||||||
|
SbtDefaults.LAYOUT_STATUS_UNLOCKED_COUNT_DEFAULT,
|
||||||
|
defaults.layoutStatusUnlockedCount);
|
||||||
|
assertEquals(defaults.clockEnabled, decoded.clockEnabled);
|
||||||
|
assertEquals(defaults.clockCustomFormat, decoded.clockCustomFormat);
|
||||||
|
assertEquals(defaults.batteryBarPosition, decoded.batteryBarPosition);
|
||||||
|
assertEquals(defaults.batteryBarThicknessDp, decoded.batteryBarThicknessDp);
|
||||||
|
assertEquals(defaults.layoutNotifUnlockedCount, decoded.layoutNotifUnlockedCount);
|
||||||
|
assertEquals(defaults.layoutStatusUnlockedCount, decoded.layoutStatusUnlockedCount);
|
||||||
|
assertEquals(defaults.systemIconBlockedModes, decoded.systemIconBlockedModes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void sourceDecodingPreservesSettingsNormalization() {
|
||||||
|
MapSource source = new MapSource();
|
||||||
|
source.put(SbtSettings.KEY_CLOCK_ENABLED, false);
|
||||||
|
source.put(SbtSettings.KEY_CLOCK_CUSTOM_FORMAT, "H:mm:ss");
|
||||||
|
source.put(SbtSettings.KEY_UNLOCKED_MAX_ICONS_PER_ROW, 0);
|
||||||
|
source.put(SbtSettings.KEY_CLOCK_VERTICAL_OFFSET_PX, 500);
|
||||||
|
source.put(SbtSettings.KEY_BATTERY_BAR_CURVED_GEOMETRY_MODE, "unsupported");
|
||||||
|
source.put(SbtSettings.KEY_LAYOUT_NOTIF_UNLOCKED_COUNT, 100);
|
||||||
|
source.put(SbtSettings.KEY_SYSTEM_ICON_DUAL_SIM_SIGNAL_MODE, "unsupported");
|
||||||
|
source.put(
|
||||||
|
SystemIconRules.PREF_KEY_BLOCKED_MODES,
|
||||||
|
setOf("wifi|5", "invalid", "wifi|not-a-number"));
|
||||||
|
source.put(
|
||||||
|
SbtSettings.KEY_APP_ICON_BLOCKED_MODES,
|
||||||
|
setOf("app.example|1|0|1", "bad-entry"));
|
||||||
|
|
||||||
|
SbtSettings decoded = SbtSettings.fromSource(source);
|
||||||
|
|
||||||
|
assertFalse(decoded.clockEnabled);
|
||||||
|
assertEquals("H:mm:ss", decoded.clockCustomFormat);
|
||||||
|
assertEquals(SbtDefaults.UNLOCKED_MAX_ICONS_PER_ROW_MIN, decoded.unlockedMaxIconsPerRow);
|
||||||
|
assertEquals(500, decoded.clockVerticalOffsetPx);
|
||||||
|
assertEquals(SbtSettings.BATTERY_BAR_CURVED_GEOMETRY_OFF, decoded.batteryBarCurvedGeometryMode);
|
||||||
|
assertEquals(SbtDefaults.LAYOUT_ICON_CONTAINER_COUNT_MAX, decoded.layoutNotifUnlockedCount);
|
||||||
|
assertEquals(
|
||||||
|
SbtDefaults.SYSTEM_ICON_DUAL_SIM_SIGNAL_MODE_DEFAULT,
|
||||||
|
decoded.systemIconDualSimSignalMode);
|
||||||
|
assertEquals(Integer.valueOf(5), decoded.systemIconBlockedModes.get("wifi"));
|
||||||
|
assertEquals(Integer.valueOf(AppIconRules.MODE_AOD | AppIconRules.MODE_UNLOCK),
|
||||||
|
decoded.appIconBlockedModes.get("app.example"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Set<String> setOf(String... values) {
|
||||||
|
HashSet<String> result = new HashSet<>();
|
||||||
|
Collections.addAll(result, values);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class MapSource implements SbtSettings.SettingsSource {
|
||||||
|
private final Map<String, Object> values = new HashMap<>();
|
||||||
|
|
||||||
|
void put(String key, Object value) {
|
||||||
|
values.put(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getBoolean(String key, boolean defaultValue) {
|
||||||
|
Object value = values.get(key);
|
||||||
|
return value instanceof Boolean ? (Boolean) value : defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getInt(String key, int defaultValue) {
|
||||||
|
Object value = values.get(key);
|
||||||
|
return value instanceof Integer ? (Integer) value : defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getString(String key, String defaultValue) {
|
||||||
|
Object value = values.get(key);
|
||||||
|
return value instanceof String ? (String) value : defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public Set<String> getStringSet(String key) {
|
||||||
|
Object value = values.get(key);
|
||||||
|
return value instanceof Set ? (Set<String>) value : Collections.emptySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean contains(String key) {
|
||||||
|
return values.containsKey(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
-3
@@ -125,9 +125,6 @@ public final class HarnessForegroundService extends Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void ensureChannel() {
|
private void ensureChannel() {
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
NotificationManager nm = getSystemService(NotificationManager.class);
|
NotificationManager nm = getSystemService(NotificationManager.class);
|
||||||
if (nm == null) {
|
if (nm == null) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -315,11 +315,7 @@ public final class MainActivity extends Activity {
|
|||||||
}
|
}
|
||||||
Intent intent = new Intent(this, HarnessForegroundService.class);
|
Intent intent = new Intent(this, HarnessForegroundService.class);
|
||||||
intent.setAction(action);
|
intent.setAction(action);
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
||||||
startForegroundService(intent);
|
startForegroundService(intent);
|
||||||
} else {
|
|
||||||
startService(intent);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void stopHarnessService() {
|
private void stopHarnessService() {
|
||||||
@@ -337,9 +333,6 @@ public final class MainActivity extends Activity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void ensureChannel(NotificationManager nm) {
|
private void ensureChannel(NotificationManager nm) {
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
NotificationChannel channel = new NotificationChannel(
|
NotificationChannel channel = new NotificationChannel(
|
||||||
CHANNEL_ID,
|
CHANNEL_ID,
|
||||||
"StatusBarTweak harness",
|
"StatusBarTweak harness",
|
||||||
|
|||||||
@@ -444,19 +444,15 @@ public final class ScenarioActivity extends Activity {
|
|||||||
| WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS;
|
| WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS;
|
||||||
controller.setSystemBarsAppearance(lightBars ? mask : 0, mask);
|
controller.setSystemBarsAppearance(lightBars ? mask : 0, mask);
|
||||||
}
|
}
|
||||||
} else if (Build.VERSION.SDK_INT >= 23) {
|
} else {
|
||||||
int flags = getWindow().getDecorView().getSystemUiVisibility();
|
int flags = getWindow().getDecorView().getSystemUiVisibility();
|
||||||
if (lightBars) {
|
if (lightBars) {
|
||||||
flags |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
|
flags |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
|
||||||
if (Build.VERSION.SDK_INT >= 26) {
|
|
||||||
flags |= View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
|
flags |= View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
flags &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
|
flags &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
|
||||||
if (Build.VERSION.SDK_INT >= 26) {
|
|
||||||
flags &= ~View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
|
flags &= ~View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
getWindow().getDecorView().setSystemUiVisibility(flags);
|
getWindow().getDecorView().setSystemUiVisibility(flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
version=0.6
|
version=0.7
|
||||||
|
|||||||
Reference in New Issue
Block a user