Clean up post-AOD layout pipeline
This commit is contained in:
@@ -1,26 +0,0 @@
|
||||
package se.ajpanton.statusbartweak;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ExampleInstrumentedTest {
|
||||
@Test
|
||||
public void useAppContext() {
|
||||
// Context of the app under test.
|
||||
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
|
||||
assertEquals("se.ajpanton.statusbartweak", appContext.getPackageName());
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,9 @@ public final class NotificationKeyReflection {
|
||||
"mNotificationKey",
|
||||
"notificationKey",
|
||||
"mKey",
|
||||
"key"
|
||||
"key",
|
||||
"mSlot",
|
||||
"slot"
|
||||
};
|
||||
|
||||
private NotificationKeyReflection() {
|
||||
@@ -53,6 +55,10 @@ public final class NotificationKeyReflection {
|
||||
if (key != null) {
|
||||
return key;
|
||||
}
|
||||
key = nonEmptyStringFromMethod(view, "getSlot");
|
||||
if (key != null) {
|
||||
return key;
|
||||
}
|
||||
return nonEmptyStringFromFields(view, ICON_VIEW_KEY_FIELD_NAMES);
|
||||
}
|
||||
|
||||
|
||||
@@ -37,10 +37,6 @@ public final class RuntimeContext {
|
||||
return modeStateRepository;
|
||||
}
|
||||
|
||||
public boolean isLogEnabled() {
|
||||
return RuntimeLogGate.isEnabled();
|
||||
}
|
||||
|
||||
public void logWarning(String message, Throwable throwable) {
|
||||
logSplit(Log.WARN, message, throwable);
|
||||
}
|
||||
@@ -50,7 +46,7 @@ public final class RuntimeContext {
|
||||
}
|
||||
|
||||
private void logSplit(int priority, String message, Throwable throwable) {
|
||||
if (!isLogEnabled()) {
|
||||
if (!RuntimeLogGate.isEnabled()) {
|
||||
return;
|
||||
}
|
||||
String safeMessage = message != null ? message : "";
|
||||
|
||||
+8
-540
@@ -3,21 +3,14 @@ package se.ajpanton.statusbartweak.runtime.features.chips;
|
||||
import android.app.KeyguardManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewParent;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Collections;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import se.ajpanton.statusbartweak.runtime.SystemContextProvider;
|
||||
import se.ajpanton.statusbartweak.runtime.ViewIdNames;
|
||||
import se.ajpanton.statusbartweak.runtime.features.RuntimeContext;
|
||||
import se.ajpanton.statusbartweak.runtime.hooks.InstanceStateStore;
|
||||
import se.ajpanton.statusbartweak.runtime.hooks.ReflectionSupport;
|
||||
import se.ajpanton.statusbartweak.runtime.hooks.XposedHookSupport;
|
||||
import se.ajpanton.statusbartweak.runtime.settings.BroadcastReceiverSupport;
|
||||
@@ -26,25 +19,12 @@ import se.ajpanton.statusbartweak.shell.settings.SbtSettings;
|
||||
|
||||
final class StatusChipHider {
|
||||
|
||||
private static final String FIELD_FORCED_HIDDEN = "sbtStatusChipForcedHidden";
|
||||
private static final String FIELD_PREV_VIS = "sbtStatusChipPrevVis";
|
||||
private static final int TOP_REGION_DP = 220;
|
||||
private static final int MAX_TEXT_SCAN_LEN = 160;
|
||||
private static final int MAX_CLASS_SCAN_LEN = 480;
|
||||
private static final int MAX_TEXT_NODES = 48;
|
||||
private static final int MAX_ASCENT = 8;
|
||||
private static final int ZONE_NONE = 0;
|
||||
private static final int ZONE_TOP = 1;
|
||||
private static final int KIND_UNKNOWN = 0;
|
||||
private static final int KIND_MEDIA = 1;
|
||||
private static final int KIND_NAV = 2;
|
||||
private static final int KIND_CALL = 3;
|
||||
|
||||
private final RuntimeContext runtimeContext;
|
||||
private final InstanceStateStore instanceStateStore = new InstanceStateStore();
|
||||
private final Set<View> trackedRoots = Collections.newSetFromMap(new WeakHashMap<>());
|
||||
private final Set<View> scannedRoots = Collections.newSetFromMap(new WeakHashMap<>());
|
||||
private final Set<View> forcedHiddenViews = Collections.newSetFromMap(new WeakHashMap<>());
|
||||
private final Set<Object> ongoingControllers = Collections.newSetFromMap(new WeakHashMap<>());
|
||||
|
||||
private boolean hooksInstalled;
|
||||
@@ -69,8 +49,6 @@ final class StatusChipHider {
|
||||
installBroadcastReceiver(SystemContextProvider.currentApplication());
|
||||
refreshSettings();
|
||||
installOngoingActivityHooks(classLoader);
|
||||
installTouchInterceptHooks(classLoader);
|
||||
installViewRootHooks();
|
||||
hooksInstalled = true;
|
||||
}
|
||||
|
||||
@@ -100,7 +78,6 @@ final class StatusChipHider {
|
||||
refreshSettings();
|
||||
if (isAnyChipHidingEnabled()) {
|
||||
refreshOngoingActivityController(controller);
|
||||
rescanTrackedRoots();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -130,87 +107,8 @@ final class StatusChipHider {
|
||||
return result;
|
||||
}
|
||||
Object data = chain.getArg(1);
|
||||
boolean suppress = shouldHide(classifyOngoingData(data), ZONE_TOP);
|
||||
return suppress ? true : result;
|
||||
});
|
||||
}
|
||||
|
||||
private void installViewRootHooks() {
|
||||
Class<?> viewRootClass = ReflectionSupport.requireClass("android.view.ViewRootImpl", null);
|
||||
XposedHookSupport.hookAllMethods(runtimeContext.getFramework(), viewRootClass, "performTraversals", chain -> {
|
||||
Object result = chain.proceed();
|
||||
Object rootObj = ReflectionSupport.requireFieldValue(chain.getThisObject(), "mView");
|
||||
if (!(rootObj instanceof View root)) {
|
||||
return result;
|
||||
}
|
||||
installBroadcastReceiver(root.getContext());
|
||||
trackedRoots.add(root);
|
||||
if (!isAnyChipHidingEnabled()) {
|
||||
restoreForcedHiddenViews();
|
||||
return result;
|
||||
}
|
||||
if (scannedRoots.add(root)) {
|
||||
applyToViewTree(root);
|
||||
} else {
|
||||
keepForcedHiddenViewsHidden();
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
private void installTouchInterceptHooks(ClassLoader classLoader) {
|
||||
Class<?> targetClass = ReflectionSupport.findClassIfExists(
|
||||
"com.android.systemui.statusbar.phone.TouchInterceptFrameLayout",
|
||||
classLoader
|
||||
);
|
||||
if (targetClass == null) {
|
||||
return;
|
||||
}
|
||||
XposedHookSupport.hookAllMethodsIfExists(runtimeContext.getFramework(), targetClass, "onLayout", chain -> {
|
||||
Object result = chain.proceed();
|
||||
if (!isAnyChipHidingEnabled()) {
|
||||
return result;
|
||||
}
|
||||
if (!(chain.getThisObject() instanceof View view)) {
|
||||
return result;
|
||||
}
|
||||
if (view.getWidth() > 0 && view.getHeight() > 0) {
|
||||
applySourceDecision(view);
|
||||
}
|
||||
return result;
|
||||
});
|
||||
XposedHookSupport.hookAllMethodsIfExists(runtimeContext.getFramework(), targetClass, "onAttachedToWindow", chain -> {
|
||||
Object result = chain.proceed();
|
||||
if (!isAnyChipHidingEnabled()) {
|
||||
return result;
|
||||
}
|
||||
if (chain.getThisObject() instanceof View view && shouldPreemptivelyHide(view)) {
|
||||
forceHide(view);
|
||||
}
|
||||
return result;
|
||||
});
|
||||
XposedHookSupport.hookAllMethodsIfExists(runtimeContext.getFramework(), targetClass, "setVisibility", chain -> {
|
||||
if (!(chain.getThisObject() instanceof View view)) {
|
||||
return chain.proceed();
|
||||
}
|
||||
if (isAnyChipHidingEnabled()
|
||||
&& !chain.getArgs().isEmpty()
|
||||
&& chain.getArg(0) instanceof Integer requestedVisibility
|
||||
&& requestedVisibility != View.GONE
|
||||
&& shouldPreemptivelyHide(view)) {
|
||||
markForcedHidden(view, requestedVisibility);
|
||||
Object[] args = chain.getArgs().toArray();
|
||||
args[0] = View.GONE;
|
||||
return chain.proceed(args);
|
||||
}
|
||||
Object result = chain.proceed();
|
||||
if (!isAnyChipHidingEnabled()) {
|
||||
return result;
|
||||
}
|
||||
if (view.getWidth() > 0 && view.getHeight() > 0) {
|
||||
applySourceDecision(view);
|
||||
}
|
||||
return result;
|
||||
int kind = classifyOngoingData(data);
|
||||
return shouldHideEnabledKind(kind) ? true : result;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -226,9 +124,7 @@ final class StatusChipHider {
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
RuntimeSettingsCache.invalidate();
|
||||
refreshSettings();
|
||||
scannedRoots.clear();
|
||||
refreshOngoingActivityLists();
|
||||
rescanTrackedRoots();
|
||||
}
|
||||
};
|
||||
BroadcastReceiverSupport.registerExportedOnApplicationContext(
|
||||
@@ -260,19 +156,6 @@ final class StatusChipHider {
|
||||
return hideAll || hideMediaUnlocked || hideNavUnlocked || hideCallUnlocked;
|
||||
}
|
||||
|
||||
private void rescanTrackedRoots() {
|
||||
if (!isAnyChipHidingEnabled()) {
|
||||
restoreForcedHiddenViews();
|
||||
return;
|
||||
}
|
||||
for (View root : trackedRoots) {
|
||||
if (root != null) {
|
||||
scannedRoots.add(root);
|
||||
applyToViewTree(root);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void refreshOngoingActivityLists() {
|
||||
if (ongoingActivityDataHelperClass == null || notificationLockscreenUserManagerClass == null) {
|
||||
return;
|
||||
@@ -315,200 +198,14 @@ final class StatusChipHider {
|
||||
boolean sawItem = false;
|
||||
for (Object data : iterable) {
|
||||
sawItem = true;
|
||||
if (!shouldHide(classifyOngoingData(data), ZONE_TOP)) {
|
||||
if (!shouldHideEnabledKind(classifyOngoingData(data))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return sawItem;
|
||||
}
|
||||
|
||||
private void applyToViewTree(View root) {
|
||||
ArrayDeque<View> stack = new ArrayDeque<>();
|
||||
stack.push(root);
|
||||
while (!stack.isEmpty()) {
|
||||
View source = stack.pop();
|
||||
if (source == null) {
|
||||
continue;
|
||||
}
|
||||
if (source instanceof ViewGroup group) {
|
||||
for (int index = group.getChildCount() - 1; index >= 0; index--) {
|
||||
stack.push(group.getChildAt(index));
|
||||
}
|
||||
}
|
||||
applySourceDecision(source);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean applySourceDecision(View source) {
|
||||
if (source == null) {
|
||||
return false;
|
||||
}
|
||||
int zone = detectZone(source);
|
||||
if (zone == ZONE_NONE || !isSourceCandidate(source)) {
|
||||
restoreIfForcedHidden(source);
|
||||
return false;
|
||||
}
|
||||
View target = resolveHideTarget(source, zone);
|
||||
if (target == null) {
|
||||
restoreIfForcedHidden(source);
|
||||
return false;
|
||||
}
|
||||
int targetZone = detectZone(target);
|
||||
if (targetZone == ZONE_NONE) {
|
||||
restoreIfForcedHidden(target);
|
||||
return false;
|
||||
}
|
||||
String sourceText = collectText(source);
|
||||
String targetText = target == source ? sourceText : collectText(target);
|
||||
String kindText = sourceText.isEmpty() ? targetText : sourceText;
|
||||
String classNames = target == source
|
||||
? collectClassNames(source)
|
||||
: collectClassNames(source) + " " + collectClassNames(target);
|
||||
String lowerText = kindText.toLowerCase(Locale.ROOT);
|
||||
if (looksLikePrivacy(target, kindText) || isDefinitelyNotChipText(lowerText)) {
|
||||
restoreIfForcedHidden(target);
|
||||
return false;
|
||||
}
|
||||
int kind = classifyKind(source, kindText, classNames);
|
||||
if (shouldHide(kind, targetZone)) {
|
||||
forceHide(target);
|
||||
return true;
|
||||
} else {
|
||||
restoreIfForcedHidden(target);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean shouldPreemptivelyHide(View source) {
|
||||
if (source == null) {
|
||||
return false;
|
||||
}
|
||||
if (isForcedHidden(source) && shouldHideTopUnlocked()) {
|
||||
return true;
|
||||
}
|
||||
if (!isTransitionSourceCandidate(source)) {
|
||||
return false;
|
||||
}
|
||||
return shouldHideSource(source, true);
|
||||
}
|
||||
|
||||
private boolean shouldHideSource(View source, boolean allowRelaxedGeometry) {
|
||||
int zone = detectZone(source);
|
||||
boolean relaxedGeometry = false;
|
||||
if (zone == ZONE_NONE) {
|
||||
if (!allowRelaxedGeometry || !isTransitionSourceCandidate(source)) {
|
||||
return false;
|
||||
}
|
||||
if (source.getWidth() > 0 && source.getHeight() > 0) {
|
||||
return false;
|
||||
}
|
||||
zone = ZONE_TOP;
|
||||
relaxedGeometry = true;
|
||||
} else if (!isSourceCandidate(source)) {
|
||||
return false;
|
||||
}
|
||||
String sourceText = collectText(source);
|
||||
String lowerText = sourceText.toLowerCase(Locale.ROOT);
|
||||
if (looksLikePrivacy(source, sourceText) || isDefinitelyNotChipText(lowerText)) {
|
||||
return false;
|
||||
}
|
||||
int kind = classifyKind(source, sourceText, collectClassNames(source));
|
||||
if (relaxedGeometry && kind == KIND_UNKNOWN && lowerText.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
return shouldHide(kind, zone);
|
||||
}
|
||||
|
||||
private boolean isSourceCandidate(View view) {
|
||||
return isTransitionSourceCandidate(view) && looksLikeChipGeometry(view);
|
||||
}
|
||||
|
||||
private boolean isTransitionSourceCandidate(View view) {
|
||||
if (isOngoingActivityCapsule(view)) {
|
||||
return false;
|
||||
}
|
||||
if (!isSystemUiView(view)) {
|
||||
return false;
|
||||
}
|
||||
String className = className(view).toLowerCase(Locale.ROOT);
|
||||
if (className.contains("privacy") || isDefinitelyNotChipClass(className)) {
|
||||
return false;
|
||||
}
|
||||
return isChipClassName(className);
|
||||
}
|
||||
|
||||
private View resolveHideTarget(View source, int sourceZone) {
|
||||
String sourceClass = className(source).toLowerCase(Locale.ROOT);
|
||||
if (sourceClass.contains("touchinterceptframelayout")) {
|
||||
return source;
|
||||
}
|
||||
View best = null;
|
||||
View current = source;
|
||||
int depth = 0;
|
||||
int screenWidth = source.getResources().getDisplayMetrics().widthPixels;
|
||||
while (current != null && depth < MAX_ASCENT) {
|
||||
if (!isSystemUiView(current)) {
|
||||
break;
|
||||
}
|
||||
if (detectZone(current) != sourceZone) {
|
||||
break;
|
||||
}
|
||||
if (looksLikeHideTarget(current, source, screenWidth)) {
|
||||
best = current;
|
||||
}
|
||||
ViewParent parent = current.getParent();
|
||||
current = parent instanceof View view ? view : null;
|
||||
depth++;
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
private boolean looksLikeHideTarget(View candidate, View source, int screenWidth) {
|
||||
if (!looksLikeChipGeometry(candidate)) {
|
||||
return false;
|
||||
}
|
||||
String className = className(candidate).toLowerCase(Locale.ROOT);
|
||||
if (className.contains("privacy") || isDefinitelyNotChipClass(className)) {
|
||||
return false;
|
||||
}
|
||||
if (!isChipClassName(className)) {
|
||||
return false;
|
||||
}
|
||||
int width = candidate.getWidth();
|
||||
int height = candidate.getHeight();
|
||||
if (width >= (int) (screenWidth * 0.98f) && height < dp(candidate, 90)) {
|
||||
return false;
|
||||
}
|
||||
if (candidate == source) {
|
||||
return true;
|
||||
}
|
||||
return candidate instanceof ViewGroup && width >= source.getWidth();
|
||||
}
|
||||
|
||||
private boolean isChipClassName(String lowerClass) {
|
||||
return lowerClass.contains("chip")
|
||||
|| lowerClass.contains("ongoing")
|
||||
|| lowerClass.contains("statusevent")
|
||||
|| lowerClass.contains("touchinterceptframelayout");
|
||||
}
|
||||
|
||||
private int detectZone(View view) {
|
||||
if (view == null || view.getWidth() <= 0 || view.getHeight() <= 0) {
|
||||
return ZONE_NONE;
|
||||
}
|
||||
int[] location = new int[2];
|
||||
try {
|
||||
view.getLocationOnScreen(location);
|
||||
} catch (Throwable ignored) {
|
||||
return ZONE_NONE;
|
||||
}
|
||||
return location[1] >= 0 && location[1] <= dp(view, TOP_REGION_DP) ? ZONE_TOP : ZONE_NONE;
|
||||
}
|
||||
|
||||
private boolean shouldHide(int kind, int zone) {
|
||||
if (zone != ZONE_TOP || !shouldHideTopUnlocked()) {
|
||||
return false;
|
||||
}
|
||||
private boolean shouldHideEnabledKind(int kind) {
|
||||
if (hideAll && kind == KIND_UNKNOWN) {
|
||||
return true;
|
||||
}
|
||||
@@ -528,13 +225,10 @@ final class StatusChipHider {
|
||||
return isAnyChipHidingEnabled() && !isKeyguardLocked();
|
||||
}
|
||||
|
||||
private int classifyKind(View view, String text, String classNames) {
|
||||
private int classifyKind(String text, String classNames) {
|
||||
String lowerText = text != null ? text.toLowerCase(Locale.ROOT) : "";
|
||||
String lowerClass = classNames != null && !classNames.isEmpty()
|
||||
? classNames.toLowerCase(Locale.ROOT)
|
||||
: (view != null ? className(view).toLowerCase(Locale.ROOT) : "");
|
||||
String lowerClass = classNames != null ? classNames.toLowerCase(Locale.ROOT) : "";
|
||||
if (containsToken(lowerText, "call")
|
||||
|| containsPhrase(lowerText, "ongoing call")
|
||||
|| lowerClass.contains("call")) {
|
||||
return KIND_CALL;
|
||||
}
|
||||
@@ -577,188 +271,7 @@ final class StatusChipHider {
|
||||
+ textField(data, "mSecondaryInfo") + " "
|
||||
+ textField(data, "mDescription") + " "
|
||||
+ textField(data, "mExpandedChipText")).trim();
|
||||
return classifyKind(null, text, data.getClass().getName());
|
||||
}
|
||||
|
||||
private boolean looksLikePrivacy(View view, String text) {
|
||||
String lowerClass = className(view).toLowerCase(Locale.ROOT);
|
||||
String lowerText = text != null ? text.toLowerCase(Locale.ROOT) : "";
|
||||
return lowerClass.contains("privacy")
|
||||
|| containsToken(lowerText, "camera")
|
||||
|| containsToken(lowerText, "microphone")
|
||||
|| containsPhrase(lowerText, "location in use")
|
||||
|| containsPhrase(lowerText, "mic in use");
|
||||
}
|
||||
|
||||
private String collectClassNames(View root) {
|
||||
StringBuilder out = new StringBuilder();
|
||||
appendClassName(out, root);
|
||||
if (!(root instanceof ViewGroup)) {
|
||||
return out.toString();
|
||||
}
|
||||
ArrayDeque<View> stack = new ArrayDeque<>();
|
||||
stack.push(root);
|
||||
int nodes = 0;
|
||||
while (!stack.isEmpty() && out.length() < MAX_CLASS_SCAN_LEN && nodes < MAX_TEXT_NODES) {
|
||||
View current = stack.pop();
|
||||
nodes++;
|
||||
if (current != root) {
|
||||
appendClassName(out, current);
|
||||
}
|
||||
if (current instanceof ViewGroup group) {
|
||||
for (int index = 0; index < group.getChildCount(); index++) {
|
||||
stack.push(group.getChildAt(index));
|
||||
}
|
||||
}
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
private String collectText(View root) {
|
||||
StringBuilder out = new StringBuilder();
|
||||
appendText(out, root.getContentDescription());
|
||||
if (root instanceof TextView textView) {
|
||||
appendText(out, textView.getText());
|
||||
}
|
||||
if (!(root instanceof ViewGroup)) {
|
||||
return out.toString();
|
||||
}
|
||||
ArrayDeque<View> stack = new ArrayDeque<>();
|
||||
stack.push(root);
|
||||
int nodes = 0;
|
||||
while (!stack.isEmpty() && out.length() < MAX_TEXT_SCAN_LEN && nodes < MAX_TEXT_NODES) {
|
||||
View current = stack.pop();
|
||||
nodes++;
|
||||
if (current != root) {
|
||||
appendText(out, current.getContentDescription());
|
||||
if (current instanceof TextView textView) {
|
||||
appendText(out, textView.getText());
|
||||
}
|
||||
}
|
||||
if (current instanceof ViewGroup group) {
|
||||
for (int index = 0; index < group.getChildCount(); index++) {
|
||||
stack.push(group.getChildAt(index));
|
||||
}
|
||||
}
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
private void forceHide(View view) {
|
||||
int restoreVisibility = view.getVisibility() != View.GONE ? view.getVisibility() : View.VISIBLE;
|
||||
markForcedHidden(view, restoreVisibility);
|
||||
if (view.getVisibility() != View.GONE) {
|
||||
view.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private void keepForcedHiddenViewsHidden() {
|
||||
if (forcedHiddenViews.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
ArrayDeque<View> staleViews = new ArrayDeque<>();
|
||||
for (View view : forcedHiddenViews) {
|
||||
if (view == null || !view.isAttachedToWindow()) {
|
||||
staleViews.add(view);
|
||||
continue;
|
||||
}
|
||||
if (view.getVisibility() != View.GONE) {
|
||||
view.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
while (!staleViews.isEmpty()) {
|
||||
forcedHiddenViews.remove(staleViews.removeFirst());
|
||||
}
|
||||
}
|
||||
|
||||
private void restoreForcedHiddenViews() {
|
||||
if (forcedHiddenViews.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
ArrayDeque<View> views = new ArrayDeque<>(forcedHiddenViews);
|
||||
while (!views.isEmpty()) {
|
||||
restoreIfForcedHidden(views.removeFirst());
|
||||
}
|
||||
}
|
||||
|
||||
private void markForcedHidden(View view, int restoreVisibility) {
|
||||
instanceStateStore.put(view, FIELD_PREV_VIS, restoreVisibility);
|
||||
instanceStateStore.put(view, FIELD_FORCED_HIDDEN, Boolean.TRUE);
|
||||
forcedHiddenViews.add(view);
|
||||
}
|
||||
|
||||
private void restoreIfForcedHidden(View view) {
|
||||
if (!isForcedHidden(view)) {
|
||||
return;
|
||||
}
|
||||
Object previous = instanceStateStore.get(view, FIELD_PREV_VIS);
|
||||
int restoreVisibility = previous instanceof Integer integer ? integer : View.VISIBLE;
|
||||
instanceStateStore.remove(view, FIELD_FORCED_HIDDEN);
|
||||
instanceStateStore.remove(view, FIELD_PREV_VIS);
|
||||
forcedHiddenViews.remove(view);
|
||||
if (view.getVisibility() != restoreVisibility) {
|
||||
view.setVisibility(restoreVisibility);
|
||||
}
|
||||
if (restoreVisibility == View.VISIBLE && view.getAlpha() == 0f) {
|
||||
view.setAlpha(1f);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isForcedHidden(View view) {
|
||||
Object marker = instanceStateStore.get(view, FIELD_FORCED_HIDDEN);
|
||||
return marker instanceof Boolean bool && bool;
|
||||
}
|
||||
|
||||
private boolean isSystemUiView(View view) {
|
||||
return className(view).contains("systemui");
|
||||
}
|
||||
|
||||
private boolean looksLikeChipGeometry(View view) {
|
||||
if (view == null || view.getWidth() <= 0 || view.getHeight() <= 0) {
|
||||
return false;
|
||||
}
|
||||
int width = view.getWidth();
|
||||
int height = view.getHeight();
|
||||
int screenWidth = view.getResources().getDisplayMetrics().widthPixels;
|
||||
if (height < dp(view, 18) || height > dp(view, 160)) {
|
||||
return false;
|
||||
}
|
||||
if (width < height * 2) {
|
||||
return false;
|
||||
}
|
||||
return !(width > (int) (screenWidth * 0.95f) && height < dp(view, 110));
|
||||
}
|
||||
|
||||
private boolean isDefinitelyNotChipClass(String lowerClass) {
|
||||
return lowerClass.contains("clock")
|
||||
|| lowerClass.contains("date")
|
||||
|| lowerClass.contains("brightness")
|
||||
|| lowerClass.contains("tile")
|
||||
|| lowerClass.contains("qsbuttonscontainer")
|
||||
|| lowerClass.contains("sectionheaderview")
|
||||
|| lowerClass.contains("expandablenotificationrow")
|
||||
|| lowerClass.contains("carrier")
|
||||
|| lowerClass.contains("statusicon")
|
||||
|| lowerClass.contains("indicator")
|
||||
|| lowerClass.contains("launchabletextview")
|
||||
|| lowerClass.contains("qsshortendate")
|
||||
|| lowerClass.contains("qsclock")
|
||||
|| lowerClass.contains("quickqs");
|
||||
}
|
||||
|
||||
private boolean isDefinitelyNotChipText(String lowerText) {
|
||||
if (lowerText == null || lowerText.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
return containsPhrase(lowerText, "notification settings")
|
||||
|| containsToken(lowerText, "brightness")
|
||||
|| containsToken(lowerText, "wifi")
|
||||
|| containsPhrase(lowerText, "smart view")
|
||||
|| containsToken(lowerText, "mirror");
|
||||
}
|
||||
|
||||
private String className(View view) {
|
||||
return view != null && view.getClass() != null ? view.getClass().getName() : "";
|
||||
return classifyKind(text, data.getClass().getName());
|
||||
}
|
||||
|
||||
private String textField(Object target, String fieldName) {
|
||||
@@ -766,44 +279,6 @@ final class StatusChipHider {
|
||||
return value != null ? String.valueOf(value) : "";
|
||||
}
|
||||
|
||||
private boolean isOngoingActivityCapsule(View view) {
|
||||
return ViewIdNames.hasIdName(view, "ongoing_activity_capsule");
|
||||
}
|
||||
|
||||
private void appendText(StringBuilder out, CharSequence value) {
|
||||
if (value == null || value.length() == 0 || out.length() >= MAX_TEXT_SCAN_LEN) {
|
||||
return;
|
||||
}
|
||||
if (out.length() > 0) {
|
||||
out.append(' ');
|
||||
}
|
||||
int remaining = MAX_TEXT_SCAN_LEN - out.length();
|
||||
if (value.length() > remaining) {
|
||||
out.append(value, 0, remaining);
|
||||
} else {
|
||||
out.append(value);
|
||||
}
|
||||
}
|
||||
|
||||
private void appendClassName(StringBuilder out, View view) {
|
||||
if (view == null || out.length() >= MAX_CLASS_SCAN_LEN) {
|
||||
return;
|
||||
}
|
||||
String value = className(view);
|
||||
if (value.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (out.length() > 0) {
|
||||
out.append(' ');
|
||||
}
|
||||
int remaining = MAX_CLASS_SCAN_LEN - out.length();
|
||||
if (value.length() > remaining) {
|
||||
out.append(value, 0, remaining);
|
||||
} else {
|
||||
out.append(value);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean containsAny(String value, String... needles) {
|
||||
if (value == null || value.isEmpty()) {
|
||||
return false;
|
||||
@@ -816,10 +291,6 @@ final class StatusChipHider {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean containsPhrase(String value, String phrase) {
|
||||
return value != null && phrase != null && value.contains(phrase);
|
||||
}
|
||||
|
||||
private boolean containsToken(String value, String token) {
|
||||
if (value == null || value.isEmpty() || token == null || token.isEmpty()) {
|
||||
return false;
|
||||
@@ -850,10 +321,6 @@ final class StatusChipHider {
|
||||
return value != null && !value.isEmpty() && value.matches(".*\\b\\d+\\s*(m|km|mi|ft)\\b.*");
|
||||
}
|
||||
|
||||
private int dp(View view, int dp) {
|
||||
return Math.round(dp * view.getResources().getDisplayMetrics().density);
|
||||
}
|
||||
|
||||
private boolean isKeyguardLocked() {
|
||||
try {
|
||||
Context context = SystemContextProvider.currentApplication();
|
||||
@@ -876,4 +343,5 @@ final class StatusChipHider {
|
||||
}
|
||||
return keyguardManager;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+4
@@ -63,6 +63,10 @@ final class LockscreenCardsNotificationRowFilter {
|
||||
}
|
||||
}
|
||||
|
||||
boolean hasHiddenRows() {
|
||||
return !hiddenRows.isEmpty();
|
||||
}
|
||||
|
||||
void suppressHiddenRows() {
|
||||
if (hiddenRows.isEmpty()) {
|
||||
return;
|
||||
|
||||
+540
-121
@@ -16,11 +16,13 @@ import android.widget.TextView;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
@@ -42,6 +44,8 @@ import se.ajpanton.statusbartweak.runtime.render.AodStatusbarSourceStore;
|
||||
import se.ajpanton.statusbartweak.runtime.render.DebugBoundsOverlayController;
|
||||
import se.ajpanton.statusbartweak.runtime.render.LockscreenCardsNotificationIconSourceStore;
|
||||
import se.ajpanton.statusbartweak.runtime.render.LockscreenCardsNotificationStripRenderer;
|
||||
import se.ajpanton.statusbartweak.runtime.notifications.NotificationActiveKeyStore;
|
||||
import se.ajpanton.statusbartweak.runtime.notifications.NotificationUnreadTracker;
|
||||
import se.ajpanton.statusbartweak.runtime.render.OwnedIconHostManager;
|
||||
import se.ajpanton.statusbartweak.runtime.render.UnlockedIconSnapshotRenderController;
|
||||
import se.ajpanton.statusbartweak.runtime.render.UnlockedIconSnapshotRenderController.RenderResult;
|
||||
@@ -94,19 +98,7 @@ final class StockLayoutCanvasController {
|
||||
"notification_icon_area_inner",
|
||||
"notificationIcons"
|
||||
);
|
||||
|
||||
private static final Set<String> LAYOUT_OFF_EXTRA_RECOVERABLE_IDS = Set.of(
|
||||
"system_icon_area",
|
||||
"statusIcons",
|
||||
"battery"
|
||||
);
|
||||
|
||||
private static final Set<String> LAYOUT_OFF_RECOVERABLE_CLASS_SUBSTRINGS = Set.of(
|
||||
"NotificationIconContainer",
|
||||
"StatusIconContainer",
|
||||
"BatteryMeterView",
|
||||
"QSClockIndicatorView"
|
||||
);
|
||||
private static final int STATUS_BAR_STATE_SHADE_LOCKED = 2;
|
||||
|
||||
private final RuntimeContext runtimeContext;
|
||||
private final Map<View, HiddenViewState> hiddenViewStates = new WeakHashMap<>();
|
||||
@@ -172,6 +164,7 @@ final class StockLayoutCanvasController {
|
||||
|
||||
private boolean hooksInstalled;
|
||||
private int ownHiddenViewAlphaWriteDepth;
|
||||
private boolean notificationDrawerWasOpen;
|
||||
|
||||
StockLayoutCanvasController(RuntimeContext runtimeContext) {
|
||||
this.runtimeContext = runtimeContext;
|
||||
@@ -184,6 +177,8 @@ final class StockLayoutCanvasController {
|
||||
new LockscreenCardsNotificationStripRenderer();
|
||||
unlockedIconRenderController = new UnlockedIconSnapshotRenderController();
|
||||
runtimeContext.getModeStateRepository().addSceneListener(this::scheduleSceneRefresh);
|
||||
runtimeContext.getModeStateRepository().addSystemUiStatusBarStateListener(
|
||||
this::handleSystemUiStatusBarStateChanged);
|
||||
}
|
||||
|
||||
void install(ClassLoader classLoader) {
|
||||
@@ -194,12 +189,147 @@ final class StockLayoutCanvasController {
|
||||
installCardsNotificationIconSourceHook(classLoader);
|
||||
installLockscreenCardsNotificationRowFilterHook(classLoader);
|
||||
installUnlockedAppearanceInvalidationHooks(classLoader);
|
||||
installNotificationCollectionHooks(classLoader);
|
||||
statusIconModelTracker.installHooks(classLoader);
|
||||
installShadeExpansionHooks(classLoader);
|
||||
installShadeHeaderAnimationGuardHook(classLoader);
|
||||
installViewRootHook(classLoader);
|
||||
hooksInstalled = true;
|
||||
}
|
||||
|
||||
private void installNotificationCollectionHooks(ClassLoader classLoader) {
|
||||
for (String className : List.of(
|
||||
"com.android.systemui.statusbar.notification.collection.NotifCollection",
|
||||
"com.android.systemui.statusbar.notification.NotificationEntryManager")) {
|
||||
Class<?> type = ReflectionSupport.findClassIfExists(className, classLoader);
|
||||
if (type == null) {
|
||||
continue;
|
||||
}
|
||||
for (Method method : type.getDeclaredMethods()) {
|
||||
String lowerName = method.getName().toLowerCase(Locale.ROOT);
|
||||
if (!isNotificationCollectionMutationMethod(lowerName)) {
|
||||
continue;
|
||||
}
|
||||
method.setAccessible(true);
|
||||
runtimeContext.getFramework().hook(method).intercept(chain -> {
|
||||
Object result = chain.proceed();
|
||||
refreshActiveNotificationKeysFromCollection(chain.getThisObject());
|
||||
return result;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isNotificationCollectionMutationMethod(String lowerName) {
|
||||
boolean subject = lowerName.contains("notification")
|
||||
|| lowerName.contains("notif")
|
||||
|| lowerName.contains("entry");
|
||||
boolean mutation = lowerName.contains("add")
|
||||
|| lowerName.contains("post")
|
||||
|| lowerName.contains("update")
|
||||
|| lowerName.contains("remove")
|
||||
|| lowerName.contains("dismiss")
|
||||
|| lowerName.contains("cancel")
|
||||
|| lowerName.contains("cleanup")
|
||||
|| lowerName.contains("clean")
|
||||
|| lowerName.contains("clear");
|
||||
return subject
|
||||
&& mutation
|
||||
&& !lowerName.contains("listener")
|
||||
&& !lowerName.contains("lifetime")
|
||||
&& !lowerName.contains("interceptor");
|
||||
}
|
||||
|
||||
private void installShadeExpansionHooks(ClassLoader classLoader) {
|
||||
for (String className : List.of(
|
||||
"com.android.systemui.shade.ShadeExpansionStateManager",
|
||||
"com.android.systemui.shade.NotificationPanelViewController",
|
||||
"com.android.systemui.statusbar.phone.NotificationPanelViewController")) {
|
||||
Class<?> type = ReflectionSupport.findClassIfExists(className, classLoader);
|
||||
if (type == null) {
|
||||
continue;
|
||||
}
|
||||
for (Method method : type.getDeclaredMethods()) {
|
||||
String lowerName = method.getName().toLowerCase(Locale.ROOT);
|
||||
if (!lowerName.contains("expansion") && !lowerName.contains("expandedheight")) {
|
||||
continue;
|
||||
}
|
||||
method.setAccessible(true);
|
||||
runtimeContext.getFramework().hook(method).intercept(chain -> {
|
||||
Object result = chain.proceed();
|
||||
handleShadeExpansionHookCall(chain.getThisObject(), chain.getArgs());
|
||||
return result;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleShadeExpansionHookCall(Object target, List<Object> args) {
|
||||
SceneKey activeScene = runtimeContext.getModeStateRepository().getActiveScene();
|
||||
if (activeScene == null || !activeScene.isUnlocked()) {
|
||||
return;
|
||||
}
|
||||
Float expansion = firstExpansionFraction(args);
|
||||
if (expansion == null) {
|
||||
expansion = reflectedExpansion(target);
|
||||
}
|
||||
if (expansion == null) {
|
||||
return;
|
||||
}
|
||||
if (expansion <= 0.01f) {
|
||||
notificationDrawerWasOpen = false;
|
||||
return;
|
||||
}
|
||||
if (expansion <= 0.05f) {
|
||||
return;
|
||||
}
|
||||
markNotificationDrawerSeen();
|
||||
}
|
||||
|
||||
private Float firstExpansionFraction(List<Object> args) {
|
||||
if (args == null || args.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
for (Object arg : args) {
|
||||
Float value = fractionValue(arg);
|
||||
if (value == null) {
|
||||
value = reflectedFraction(arg);
|
||||
}
|
||||
if (value != null) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void markNotificationDrawerSeen() {
|
||||
if (notificationDrawerWasOpen) {
|
||||
return;
|
||||
}
|
||||
notificationDrawerWasOpen = true;
|
||||
boolean changed = NotificationUnreadTracker.markSeen();
|
||||
if (changed) {
|
||||
scheduleUnlockedAppearanceRefreshForAllRoots();
|
||||
}
|
||||
}
|
||||
|
||||
private void handleSystemUiStatusBarStateChanged(
|
||||
int previousState,
|
||||
int currentState,
|
||||
boolean dozing
|
||||
) {
|
||||
if (dozing) {
|
||||
return;
|
||||
}
|
||||
if (currentState == STATUS_BAR_STATE_SHADE_LOCKED
|
||||
&& previousState != STATUS_BAR_STATE_SHADE_LOCKED) {
|
||||
markNotificationDrawerSeen();
|
||||
} else if (previousState == STATUS_BAR_STATE_SHADE_LOCKED
|
||||
&& currentState != STATUS_BAR_STATE_SHADE_LOCKED) {
|
||||
notificationDrawerWasOpen = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void installShadeHeaderAnimationGuardHook(ClassLoader classLoader) {
|
||||
Class<?> viewClass = ReflectionSupport.requireClass("android.view.View", classLoader);
|
||||
XposedHookSupport.hookAllMethodsIfExists(runtimeContext.getFramework(), viewClass, "setAlpha", chain -> {
|
||||
@@ -494,6 +624,9 @@ final class StockLayoutCanvasController {
|
||||
methodName,
|
||||
chain -> {
|
||||
ViewGroup parent = chain.getThisObject() instanceof ViewGroup group ? group : null;
|
||||
if (parent != null && !isLayoutEnabled(parent.getContext())) {
|
||||
return chain.proceed();
|
||||
}
|
||||
View child = firstArg(chain.getArgs()) instanceof View view ? view : null;
|
||||
View rootBefore = parent != null ? unlockedStatusBarRootFor(parent) : null;
|
||||
boolean affectedBefore = isStatusChipTreeMutation(parent, child);
|
||||
@@ -541,17 +674,21 @@ final class StockLayoutCanvasController {
|
||||
return chain.proceed();
|
||||
}
|
||||
if (!isLayoutEnabled(container.getContext())) {
|
||||
Object result = chain.proceed();
|
||||
LockscreenCardsNotificationIconSourceStore.put(container, new ArrayList<>());
|
||||
return result;
|
||||
}
|
||||
if (!isCardsNotificationIconSourceContainer(container)) {
|
||||
Object result = chain.proceed();
|
||||
markUnlockedLayoutDirty(container);
|
||||
return result;
|
||||
return chain.proceed();
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
Function<Object, Object> original = (Function<Object, Object>) args.get(functionIndex);
|
||||
if (!isCardsNotificationIconSourceContainer(container)) {
|
||||
Function<Object, Object> wrapped = entryObj -> {
|
||||
recordNotificationEntry(entryObj);
|
||||
return original.apply(entryObj);
|
||||
};
|
||||
Object[] newArgs = args.toArray(new Object[0]);
|
||||
newArgs[functionIndex] = wrapped;
|
||||
Object result = chain.proceed(newArgs);
|
||||
requestUnlockedLayoutRefreshFromSource(container);
|
||||
return result;
|
||||
}
|
||||
ArrayList<LockscreenCardsNotificationIconSourceStore.SourceEntry> captured =
|
||||
new ArrayList<>();
|
||||
Function<Object, Object> wrapped = entryObj -> {
|
||||
@@ -563,6 +700,7 @@ final class StockLayoutCanvasController {
|
||||
return null;
|
||||
}
|
||||
Object result = original.apply(entryObj);
|
||||
recordNotificationEntry(entryObj);
|
||||
if (result == null) {
|
||||
result = fallbackStatusBarIcon(entryObj);
|
||||
}
|
||||
@@ -578,6 +716,7 @@ final class StockLayoutCanvasController {
|
||||
newArgs[functionIndex] = wrapped;
|
||||
Object result = chain.proceed(newArgs);
|
||||
LockscreenCardsNotificationIconSourceStore.put(container, captured);
|
||||
requestUnlockedLayoutRefreshFromSource(container);
|
||||
return result;
|
||||
});
|
||||
}
|
||||
@@ -711,11 +850,39 @@ final class StockLayoutCanvasController {
|
||||
|
||||
private void captureAodPackagesFromNotifCollection(Object wrapper) {
|
||||
Object collection = ReflectionSupport.getFieldValue(wrapper, "mNotifCollection");
|
||||
ArrayList<StatusBarNotification> notifications = notificationsFromNotifCollection(collection);
|
||||
if (notifications.isEmpty()) {
|
||||
if (collection == null) {
|
||||
return;
|
||||
}
|
||||
ArrayList<StatusBarNotification> notifications = notificationsFromNotifCollection(collection);
|
||||
if (notifications.isEmpty()) {
|
||||
latestAodNotifications = new ArrayList<>();
|
||||
latestAodIconImageViews = new ArrayList<>();
|
||||
NotificationActiveKeyStore.replace(Collections.emptySet());
|
||||
NotificationUnreadTracker.retainActiveKeys(Collections.emptySet());
|
||||
LockscreenCardsNotificationIconSourceStore.clearAodSources();
|
||||
markKnownAodNotificationRootsDirty();
|
||||
updateKnownAodNotificationSources();
|
||||
return;
|
||||
}
|
||||
boolean changed = false;
|
||||
ArrayList<String> packages = new ArrayList<>();
|
||||
HashSet<String> activeKeys = new HashSet<>();
|
||||
for (StatusBarNotification sbn : notifications) {
|
||||
changed |= NotificationUnreadTracker.record(sbn);
|
||||
if (sbn != null && sbn.getKey() != null) {
|
||||
activeKeys.add(sbn.getKey());
|
||||
}
|
||||
if (sbn != null && AppIconRules.isValidPackageName(sbn.getPackageName())) {
|
||||
packages.add(sbn.getPackageName());
|
||||
}
|
||||
}
|
||||
updateActiveNotificationKeys(activeNotificationIconKeys(notifications));
|
||||
changed |= NotificationUnreadTracker.retainActiveKeys(activeKeys);
|
||||
LockscreenCardsNotificationIconSourceStore.putAodNotificationPackages(packages);
|
||||
latestAodNotifications = notifications;
|
||||
if (changed) {
|
||||
markKnownAodNotificationRootsDirty();
|
||||
}
|
||||
updateKnownAodNotificationSources();
|
||||
}
|
||||
|
||||
@@ -787,6 +954,52 @@ final class StockLayoutCanvasController {
|
||||
notifications.add(sbn);
|
||||
}
|
||||
|
||||
private boolean recordNotificationEntry(Object entry) {
|
||||
StatusBarNotification sbn = NotificationReflection.statusBarNotificationEntry(entry);
|
||||
return NotificationUnreadTracker.record(sbn);
|
||||
}
|
||||
|
||||
private void refreshActiveNotificationKeysFromCollection(Object collection) {
|
||||
ArrayList<StatusBarNotification> notifications = notificationsFromNotifCollection(collection);
|
||||
if (notifications.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (StatusBarNotification sbn : notifications) {
|
||||
if (sbn != null && sbn.getKey() != null && AppIconRules.isValidPackageName(sbn.getPackageName())) {
|
||||
NotificationUnreadTracker.record(sbn);
|
||||
}
|
||||
}
|
||||
updateActiveNotificationKeys(activeNotificationIconKeys(notifications));
|
||||
}
|
||||
|
||||
private void updateActiveNotificationKeys(ArrayList<String> keys) {
|
||||
if (!NotificationActiveKeyStore.replace(keys)) {
|
||||
return;
|
||||
}
|
||||
requestUnlockedLayoutRefreshForAllRoots();
|
||||
markKnownAodNotificationRootsDirty();
|
||||
}
|
||||
|
||||
private ArrayList<String> activeNotificationIconKeys(ArrayList<StatusBarNotification> notifications) {
|
||||
ArrayList<String> keys = new ArrayList<>();
|
||||
if (notifications == null) {
|
||||
return keys;
|
||||
}
|
||||
for (StatusBarNotification sbn : notifications) {
|
||||
if (sbn == null || !AppIconRules.isValidPackageName(sbn.getPackageName())) {
|
||||
continue;
|
||||
}
|
||||
if (sbn.getKey() != null) {
|
||||
keys.add(sbn.getKey());
|
||||
}
|
||||
String packageName = sbn.getPackageName();
|
||||
int id = sbn.getId();
|
||||
keys.add(packageName + "/" + id);
|
||||
keys.add(packageName + "/0x" + Integer.toHexString(id));
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
|
||||
private void installViewRootHook(ClassLoader classLoader) {
|
||||
Class<?> viewRootClass = ReflectionSupport.requireClass("android.view.ViewRootImpl", classLoader);
|
||||
XposedHookSupport.hookAllMethods(runtimeContext.getFramework(), viewRootClass, "performDraw", chain -> {
|
||||
@@ -838,6 +1051,9 @@ final class StockLayoutCanvasController {
|
||||
if (activeScene == null) {
|
||||
return;
|
||||
}
|
||||
if (!runtimeContext.getModeStateRepository().isSystemUiShadeLocked() && !activeScene.isAod()) {
|
||||
notificationDrawerWasOpen = false;
|
||||
}
|
||||
if (isNotificationShadeWindowRoot(root)) {
|
||||
if (shouldPrepareCarrierlessAodNotificationTransition(settings, activeScene)) {
|
||||
prepareCarrierlessAodNotificationTransition(root);
|
||||
@@ -848,12 +1064,14 @@ final class StockLayoutCanvasController {
|
||||
if (activeScene.isLockscreen()
|
||||
&& activeScene.notificationDisplayStyle() == NotificationDisplayStyle.CARDS
|
||||
&& isNotificationShadeWindowRoot(root)) {
|
||||
applyLockscreenCardsNotificationRowFilterInTreeIfNeeded(
|
||||
boolean applied = applyLockscreenCardsNotificationRowFilterInTreeIfNeeded(
|
||||
root,
|
||||
settings,
|
||||
activeScene,
|
||||
true);
|
||||
if (!applied && lockscreenCardsNotificationRowFilter.hasHiddenRows()) {
|
||||
lockscreenCardsNotificationRowFilter.suppressHiddenRows();
|
||||
}
|
||||
} else if (activeScene.isUnlocked() && isNotificationShadeWindowRoot(root)) {
|
||||
lockscreenCardsNotificationRowFilter.restoreAll();
|
||||
} else if (activeScene.isAod()
|
||||
@@ -862,6 +1080,98 @@ final class StockLayoutCanvasController {
|
||||
}
|
||||
}
|
||||
|
||||
private Float reflectedExpansion(Object target) {
|
||||
for (String method : List.of(
|
||||
"getExpandedFraction",
|
||||
"getExpansionFraction",
|
||||
"getPanelExpansion",
|
||||
"getShadeExpansion")) {
|
||||
Float value = floatValue(ReflectionSupport.invokeMethod(target, method));
|
||||
if (value != null) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
for (String field : List.of(
|
||||
"mExpandedFraction",
|
||||
"mExpansionFraction",
|
||||
"mPanelExpansionFraction",
|
||||
"mShadeExpansion")) {
|
||||
Float value = floatValue(ReflectionSupport.getFieldValue(target, field));
|
||||
if (value != null) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
Float height = heightValue(ReflectionSupport.invokeMethod(target, "getExpandedHeight"));
|
||||
if (height == null) {
|
||||
height = heightValue(ReflectionSupport.getFieldValue(target, "mExpandedHeight"));
|
||||
}
|
||||
if (height != null && target instanceof View view && view.getHeight() > 0) {
|
||||
return Math.min(1f, Math.max(0f, height / view.getHeight()));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Float reflectedFraction(Object target) {
|
||||
for (String method : List.of(
|
||||
"getFraction",
|
||||
"getExpandedFraction",
|
||||
"getExpansionFraction",
|
||||
"getPanelExpansion",
|
||||
"getShadeExpansion")) {
|
||||
Float value = fractionValue(ReflectionSupport.invokeMethod(target, method));
|
||||
if (value != null) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
for (String field : List.of(
|
||||
"fraction",
|
||||
"expandedFraction",
|
||||
"expansionFraction",
|
||||
"panelExpansionFraction",
|
||||
"shadeExpansion")) {
|
||||
Float value = fractionValue(ReflectionSupport.getFieldValue(target, field));
|
||||
if (value != null) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Float floatValue(Object value) {
|
||||
return fractionValue(value);
|
||||
}
|
||||
|
||||
private Float fractionValue(Object value) {
|
||||
if (value instanceof Float floatValue) {
|
||||
return fraction(floatValue);
|
||||
}
|
||||
if (value instanceof Double doubleValue) {
|
||||
return fraction(doubleValue.floatValue());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Float heightValue(Object value) {
|
||||
if (value instanceof Number number) {
|
||||
float floatValue = number.floatValue();
|
||||
if (Float.isNaN(floatValue) || Float.isInfinite(floatValue) || floatValue < 0f) {
|
||||
return null;
|
||||
}
|
||||
return floatValue;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Float fraction(float value) {
|
||||
if (Float.isNaN(value) || Float.isInfinite(value)) {
|
||||
return null;
|
||||
}
|
||||
if (value < 0f || value > 1f) {
|
||||
return null;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private void applyBeforeDrawInternal(View root) {
|
||||
if (root == null) {
|
||||
return;
|
||||
@@ -894,11 +1204,13 @@ final class StockLayoutCanvasController {
|
||||
&& activeScene.isLockscreen()
|
||||
&& activeScene.notificationDisplayStyle() == NotificationDisplayStyle.CARDS
|
||||
&& canContainLockedStatusBarIconSurfaces(root)) {
|
||||
if (isNotificationShadeWindowRoot(root)) {
|
||||
applyLockscreenCardsNotificationRowFilterInTreeIfNeeded(
|
||||
root,
|
||||
settings,
|
||||
activeScene,
|
||||
isNotificationShadeWindowRoot(root));
|
||||
true);
|
||||
}
|
||||
renderLockscreenCardsNotificationStripIfNeeded(root, settings, activeScene);
|
||||
} else if (activeScene != null
|
||||
&& activeScene.isAod()
|
||||
@@ -943,10 +1255,29 @@ final class StockLayoutCanvasController {
|
||||
if (root != null) {
|
||||
dirtyUnlockedLayoutRoots.add(root);
|
||||
}
|
||||
View current = sourceView;
|
||||
while (current != null) {
|
||||
if (isUnlockedStatusBarRoot(current)) {
|
||||
dirtyUnlockedLayoutRoots.add(current);
|
||||
}
|
||||
Object parent = current.getParent();
|
||||
current = parent instanceof View ? (View) parent : null;
|
||||
}
|
||||
}
|
||||
|
||||
private void markStatusChipLifecycleDirtyIfNeeded(View view) {
|
||||
markStatusChipLifecycleDirtyIfNeeded(view, null);
|
||||
private void requestUnlockedLayoutRefreshFromSource(View sourceView) {
|
||||
View root = unlockedStatusBarRootFor(sourceView);
|
||||
if (root != null) {
|
||||
requestUnlockedLayoutRefresh(root);
|
||||
}
|
||||
View current = sourceView;
|
||||
while (current != null) {
|
||||
if (current != root && isUnlockedStatusBarRoot(current)) {
|
||||
requestUnlockedLayoutRefresh(current);
|
||||
}
|
||||
Object parent = current.getParent();
|
||||
current = parent instanceof View ? (View) parent : null;
|
||||
}
|
||||
}
|
||||
|
||||
private void markStatusChipLifecycleDirtyIfNeeded(View view, View fallbackRoot) {
|
||||
@@ -1189,6 +1520,18 @@ final class StockLayoutCanvasController {
|
||||
}
|
||||
}
|
||||
|
||||
private void requestUnlockedLayoutRefreshForAllRoots() {
|
||||
ArrayList<View> roots = new ArrayList<>(rootGeometries.keySet());
|
||||
for (View root : new ArrayList<>(unlockedHostsByRoot.keySet())) {
|
||||
if (!roots.contains(root)) {
|
||||
roots.add(root);
|
||||
}
|
||||
}
|
||||
for (View root : roots) {
|
||||
requestUnlockedLayoutRefresh(root);
|
||||
}
|
||||
}
|
||||
|
||||
private void scheduleSceneRefresh(SceneKey previous, SceneKey current) {
|
||||
if (previous == null || current == null || previous.equals(current)) {
|
||||
return;
|
||||
@@ -1436,7 +1779,7 @@ final class StockLayoutCanvasController {
|
||||
return;
|
||||
}
|
||||
UnlockedHosts unlockedHosts = updateUnlockedOwnedHosts(root, activeScene);
|
||||
RenderResult renderResult = new RenderResult(false, false);
|
||||
RenderResult renderResult = new RenderResult(false, false, false);
|
||||
if (unlockedHosts != null
|
||||
&& (unlockedScene
|
||||
|| activeScene != null && activeScene.isLockscreen()
|
||||
@@ -1456,6 +1799,7 @@ final class StockLayoutCanvasController {
|
||||
unlockedHosts.statusHost,
|
||||
unlockedHosts.notificationHost,
|
||||
activeScene,
|
||||
rootDirty,
|
||||
lockedCarrierTextSource());
|
||||
boolean shouldShowUnlockedHosts = unlockedScene || aodScene || renderResult.shouldOwnLockscreen();
|
||||
ownedIconHostManager.setUnlockedHostsVisible(root, shouldShowUnlockedHosts);
|
||||
@@ -1532,9 +1876,35 @@ final class StockLayoutCanvasController {
|
||||
} else {
|
||||
removeDebugOverlay(root);
|
||||
}
|
||||
if (isLayoutOffCleanupNoOp(root)) {
|
||||
return;
|
||||
}
|
||||
cleanupLayoutOffRoot(root, activeScene);
|
||||
}
|
||||
|
||||
private boolean isLayoutOffCleanupNoOp(View root) {
|
||||
return hiddenViewStates.isEmpty()
|
||||
&& trackedStatusChipSources.isEmpty()
|
||||
&& trackedUnlockedStockSurfaces.isEmpty()
|
||||
&& trackedLockedStatusBarIconSurfaces.isEmpty()
|
||||
&& !lockscreenCardsNotificationRowFilter.hasHiddenRows()
|
||||
&& !unlockedHostsByRoot.containsKey(root)
|
||||
&& !hasDirectOwnedLayoutHost(root);
|
||||
}
|
||||
|
||||
private boolean hasDirectOwnedLayoutHost(View root) {
|
||||
if (!(root instanceof ViewGroup group)) {
|
||||
return false;
|
||||
}
|
||||
return findDirectOwnedHost(group, OwnedIconHostManager.TAG_UNLOCKED_STATUS_HOST) != null
|
||||
|| findDirectOwnedHost(group, OwnedIconHostManager.TAG_UNLOCKED_NOTIFICATION_HOST) != null
|
||||
|| findDirectOwnedHost(group, OwnedIconHostManager.TAG_UNLOCKED_CLOCK_HOST) != null
|
||||
|| findDirectOwnedHost(group, OwnedIconHostManager.TAG_UNLOCKED_CARRIER_HOST) != null
|
||||
|| findDirectOwnedHost(group, OwnedIconHostManager.TAG_UNLOCKED_CHIP_HOST) != null
|
||||
|| findDirectOwnedHost(group, OwnedIconHostManager.TAG_LOCKSCREEN_CARDS_NOTIFICATION_HOST) != null
|
||||
|| findDirectOwnedHost(group, OwnedIconHostManager.TAG_AOD_CARDS_NOTIFICATION_HOST) != null;
|
||||
}
|
||||
|
||||
private void applyDebugOverlay(
|
||||
View root,
|
||||
boolean layoutEnabled,
|
||||
@@ -2113,7 +2483,8 @@ final class StockLayoutCanvasController {
|
||||
private boolean shouldSuppressTrackedStatusChipVisibility(View view, int visibility) {
|
||||
return visibility != View.VISIBLE
|
||||
&& isTrackedStatusChipWriteTarget(view)
|
||||
&& hasVisibleStatusChipContent(view);
|
||||
&& hasVisibleStatusChipContent(view)
|
||||
&& !isCallStatusChip(view);
|
||||
}
|
||||
|
||||
private boolean isTrackedStatusChipWriteTarget(View view) {
|
||||
@@ -2528,6 +2899,43 @@ final class StockLayoutCanvasController {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isCallStatusChip(View source) {
|
||||
if (source == null) {
|
||||
return false;
|
||||
}
|
||||
ArrayDeque<View> queue = new ArrayDeque<>();
|
||||
queue.add(source);
|
||||
int scanned = 0;
|
||||
while (!queue.isEmpty() && scanned++ < 48) {
|
||||
View view = queue.removeFirst();
|
||||
String className = view.getClass().getName().toLowerCase(Locale.ROOT);
|
||||
String idName = ViewIdNames.idName(view).toLowerCase(Locale.ROOT);
|
||||
if (className.contains("call") || idName.contains("call")) {
|
||||
return true;
|
||||
}
|
||||
if (containsCallToken(view.getContentDescription())) {
|
||||
return true;
|
||||
}
|
||||
if (view instanceof TextView textView && containsCallToken(textView.getText())) {
|
||||
return true;
|
||||
}
|
||||
if (view instanceof ViewGroup childGroup) {
|
||||
for (int i = 0; i < childGroup.getChildCount(); i++) {
|
||||
queue.addLast(childGroup.getChildAt(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean containsCallToken(CharSequence value) {
|
||||
if (value == null || value.length() == 0) {
|
||||
return false;
|
||||
}
|
||||
String text = value.toString().toLowerCase(Locale.ROOT);
|
||||
return text.contains("call") || text.contains("phone");
|
||||
}
|
||||
|
||||
private boolean isStatusChipCandidate(View view) {
|
||||
String className = view.getClass().getName().toLowerCase(Locale.ROOT);
|
||||
String idName = ViewIdNames.idName(view).toLowerCase(Locale.ROOT);
|
||||
@@ -2798,16 +3206,7 @@ final class StockLayoutCanvasController {
|
||||
LockscreenCardsNotificationIconSourceStore.clearAodSources(container);
|
||||
return;
|
||||
}
|
||||
boolean changed = false;
|
||||
ArrayList<String> packages = alignedAodIconPackages(container.getContext());
|
||||
if (!packages.isEmpty()) {
|
||||
changed |= LockscreenCardsNotificationIconSourceStore.putPackages(container, packages);
|
||||
}
|
||||
boolean prepared = prepareAodNotificationIconSources(container);
|
||||
changed |= prepared;
|
||||
changed |= LockscreenCardsNotificationIconSourceStore.putAodDrawables(
|
||||
container,
|
||||
latestAodIconImageViews);
|
||||
boolean changed = refreshAodNotificationSources(container);
|
||||
knownAodNotificationContainers.add(container);
|
||||
if (changed) {
|
||||
View root = container.getRootView();
|
||||
@@ -2827,16 +3226,7 @@ final class StockLayoutCanvasController {
|
||||
LockscreenCardsNotificationIconSourceStore.clearAodSources(container);
|
||||
continue;
|
||||
}
|
||||
ArrayList<String> packages = alignedAodIconPackages(container.getContext());
|
||||
boolean changed = false;
|
||||
if (!packages.isEmpty()) {
|
||||
changed |= LockscreenCardsNotificationIconSourceStore.putPackages(container, packages);
|
||||
}
|
||||
boolean prepared = prepareAodNotificationIconSources(container);
|
||||
changed |= prepared;
|
||||
changed |= LockscreenCardsNotificationIconSourceStore.putAodDrawables(
|
||||
container,
|
||||
latestAodIconImageViews);
|
||||
boolean changed = refreshAodNotificationSources(container);
|
||||
if (changed) {
|
||||
View root = container.getRootView();
|
||||
invalidateAodNotificationRoot(root);
|
||||
@@ -2844,10 +3234,24 @@ final class StockLayoutCanvasController {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean refreshAodNotificationSources(ViewGroup container) {
|
||||
ArrayList<String> packages = alignedAodIconPackages(container.getContext());
|
||||
if (packages.isEmpty() && isAodDotScene()) {
|
||||
packages = aodNotificationPackages();
|
||||
}
|
||||
boolean changed = false;
|
||||
if (!packages.isEmpty()) {
|
||||
changed |= LockscreenCardsNotificationIconSourceStore.putPackages(container, packages);
|
||||
}
|
||||
changed |= prepareAodNotificationIconSources(container);
|
||||
changed |= LockscreenCardsNotificationIconSourceStore.putAodDrawables(
|
||||
container,
|
||||
latestAodIconImageViews);
|
||||
return changed;
|
||||
}
|
||||
|
||||
private boolean prepareAodNotificationIconSources(ViewGroup container) {
|
||||
if (container == null
|
||||
|| latestAodIconImageViews == null
|
||||
|| latestAodIconImageViews.isEmpty()) {
|
||||
if (container == null || latestAodIconImageViews.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
boolean invoked = false;
|
||||
@@ -2867,9 +3271,25 @@ final class StockLayoutCanvasController {
|
||||
return invoked;
|
||||
}
|
||||
|
||||
private boolean isAodDotScene() {
|
||||
SceneKey scene = runtimeContext.getModeStateRepository().getActiveScene();
|
||||
return scene != null
|
||||
&& scene.isAod()
|
||||
&& scene.notificationDisplayStyle() == NotificationDisplayStyle.DOT;
|
||||
}
|
||||
|
||||
private ArrayList<String> aodNotificationPackages() {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
for (StatusBarNotification sbn : latestAodNotifications) {
|
||||
if (sbn != null && AppIconRules.isValidPackageName(sbn.getPackageName())) {
|
||||
result.add(sbn.getPackageName());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private ArrayList<String> alignedAodIconPackages(Context context) {
|
||||
int imageCount = latestAodIconImageViews != null ? latestAodIconImageViews.size() : 0;
|
||||
if (imageCount <= 0) {
|
||||
if (latestAodIconImageViews.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
ArrayList<String> aligned = alignAodPackagesByDrawable(context);
|
||||
@@ -2882,9 +3302,7 @@ final class StockLayoutCanvasController {
|
||||
private ArrayList<String> alignAodPackagesByDrawable(Context context) {
|
||||
ArrayList<String> aligned = new ArrayList<>();
|
||||
if (context == null
|
||||
|| latestAodIconImageViews == null
|
||||
|| latestAodIconImageViews.isEmpty()
|
||||
|| latestAodNotifications == null
|
||||
|| latestAodNotifications.isEmpty()) {
|
||||
return aligned;
|
||||
}
|
||||
@@ -2989,6 +3407,20 @@ final class StockLayoutCanvasController {
|
||||
dirtyUnlockedLayoutRoots.add(root);
|
||||
}
|
||||
|
||||
private void markKnownAodNotificationRootsDirty() {
|
||||
for (ViewGroup container : knownAodNotificationContainers) {
|
||||
if (container == null || !container.isAttachedToWindow()) {
|
||||
continue;
|
||||
}
|
||||
View root = container.getRootView();
|
||||
if (root != null) {
|
||||
dirtyUnlockedLayoutRoots.add(root);
|
||||
root.requestLayout();
|
||||
root.invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void markAodLayoutDirty(View view) {
|
||||
if (view == null || !view.isAttachedToWindow()) {
|
||||
return;
|
||||
@@ -3151,19 +3583,19 @@ final class StockLayoutCanvasController {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void restoreAllHiddenViews() {
|
||||
private void restoreAllHiddenViews(View root, SceneKey activeScene) {
|
||||
ArrayDeque<View> views = new ArrayDeque<>(hiddenViewStates.keySet());
|
||||
while (!views.isEmpty()) {
|
||||
View view = views.removeFirst();
|
||||
if (forgetInactiveTrackedStatusChip(view)) {
|
||||
continue;
|
||||
}
|
||||
if (shouldDeferLayoutOffRestore(root, activeScene, view)) {
|
||||
keepViewHidden(view);
|
||||
continue;
|
||||
}
|
||||
restoreView(view);
|
||||
}
|
||||
trackedStatusChipSources.clear();
|
||||
trackedLockedStatusBarIconSurfaces.clear();
|
||||
trackedUnlockedStockSurfaces.clear();
|
||||
aodPluginVisualAlphaByView.clear();
|
||||
}
|
||||
|
||||
private boolean forgetInactiveTrackedStatusChip(View view) {
|
||||
@@ -3176,16 +3608,16 @@ final class StockLayoutCanvasController {
|
||||
hiddenViewStates.remove(view);
|
||||
trackedStatusChipSources.remove(view);
|
||||
trackedUnlockedStockSurfaces.remove(view);
|
||||
statusChipLifecycleLayoutSignatureByView.remove(view);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void cleanupLayoutOffRoot(View root, SceneKey activeScene) {
|
||||
lockscreenCardsNotificationRowFilter.restoreAll();
|
||||
if (!hiddenViewStates.isEmpty()) {
|
||||
restoreAllHiddenViews();
|
||||
restoreAllHiddenViews(root, activeScene);
|
||||
}
|
||||
restoreLayoutOffStockSurfaces(root, activeScene);
|
||||
trackedStatusChipSources.clear();
|
||||
clearTrackedStatusChipState();
|
||||
trackedLockedStatusBarIconSurfaces.clear();
|
||||
trackedUnlockedStockSurfaces.clear();
|
||||
confirmedAodPluginViews.clear();
|
||||
@@ -3219,63 +3651,38 @@ final class StockLayoutCanvasController {
|
||||
ownedIconHostManager.removeOwnedHosts(root);
|
||||
}
|
||||
|
||||
private void restoreLayoutOffStockSurfaces(View root, SceneKey activeScene) {
|
||||
if (root == null || !isViewThread(root)) {
|
||||
return;
|
||||
}
|
||||
boolean unlockedScene = activeScene == null || activeScene.isUnlocked();
|
||||
walkTree(root, view -> {
|
||||
if (!isLayoutOffRecoverableStockSurface(view)) {
|
||||
return;
|
||||
}
|
||||
String idName = ViewIdNames.idName(view);
|
||||
int beforeVisibility = view.getVisibility();
|
||||
float beforeAlpha = view.getAlpha();
|
||||
restoreView(view);
|
||||
if (!unlockedScene && LAYOUT_OFF_UNLOCKED_ONLY_IDS.contains(idName)) {
|
||||
if (view.getAlpha() != 0f) {
|
||||
view.setAlpha(0f);
|
||||
}
|
||||
if (view.getVisibility() != View.INVISIBLE) {
|
||||
view.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (unlockedScene && view.getVisibility() != View.VISIBLE) {
|
||||
view.setVisibility(View.VISIBLE);
|
||||
}
|
||||
if (shouldPreserveUnlockedStockAlpha(idName, beforeVisibility, beforeAlpha)) {
|
||||
if (view.getAlpha() != beforeAlpha) {
|
||||
view.setAlpha(beforeAlpha);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (unlockedScene && view.getAlpha() <= 0f) {
|
||||
view.setAlpha(1f);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private boolean shouldPreserveUnlockedStockAlpha(
|
||||
String idName,
|
||||
int beforeVisibility,
|
||||
float beforeAlpha
|
||||
private boolean shouldDeferLayoutOffRestore(
|
||||
View root,
|
||||
SceneKey activeScene,
|
||||
View view
|
||||
) {
|
||||
if (!"notification_icon_area_inner".equals(idName)) {
|
||||
return false;
|
||||
}
|
||||
return beforeVisibility == View.VISIBLE && beforeAlpha < 1f;
|
||||
return shouldKeepUnlockedShadeShelfOwnedByCustomLayout(root, activeScene, view);
|
||||
}
|
||||
|
||||
private boolean isLayoutOffRecoverableStockSurface(View view) {
|
||||
if (view == null || ownedIconHostManager.isOwnedHost(view)) {
|
||||
private void keepViewHidden(View view) {
|
||||
hideView(view, false);
|
||||
}
|
||||
|
||||
private boolean shouldKeepUnlockedShadeShelfOwnedByCustomLayout(
|
||||
View root,
|
||||
SceneKey activeScene,
|
||||
View view
|
||||
) {
|
||||
if (root == null
|
||||
|| activeScene == null
|
||||
|| !activeScene.isUnlocked()
|
||||
|| !isDescendantOfNotificationShadeWindow(view)) {
|
||||
return false;
|
||||
}
|
||||
String idName = ViewIdNames.idName(view);
|
||||
String className = view.getClass().getName();
|
||||
return LAYOUT_OFF_UNLOCKED_ONLY_IDS.contains(idName)
|
||||
|| LAYOUT_OFF_EXTRA_RECOVERABLE_IDS.contains(idName)
|
||||
|| containsAny(className, LAYOUT_OFF_RECOVERABLE_CLASS_SUBSTRINGS);
|
||||
return (isCardsNotificationIconSurface(view) || isCardsNotificationShelfBackgroundSurface(view))
|
||||
&& hasAncestorClass(view, "NotificationShelf");
|
||||
}
|
||||
|
||||
private void clearTrackedStatusChipState() {
|
||||
trackedStatusChipSources.clear();
|
||||
statusChipContentSignatureByRoot.clear();
|
||||
statusChipLayoutSignatureByRoot.clear();
|
||||
statusChipLifecycleLayoutSignatureByView.clear();
|
||||
}
|
||||
|
||||
private static boolean containsAny(String value, Set<String> tokens) {
|
||||
@@ -3395,11 +3802,20 @@ final class StockLayoutCanvasController {
|
||||
generation = 31 * generation + latestAodNotifications.size();
|
||||
Bounds sourceBounds = LockscreenCardsNotificationIconSourceStore
|
||||
.sourceContainerBoundsForRoot(root);
|
||||
boolean hiddenSource = LockscreenCardsNotificationIconSourceStore
|
||||
.sourceContainerHasHiddenAncestorForRoot(root);
|
||||
if (hiddenSource) {
|
||||
// Samsung hides the cards icon source during the clock/date handoff.
|
||||
// Keep our mirror hidden too instead of following its transient translation.
|
||||
setHostAlpha(host, 0f);
|
||||
return;
|
||||
}
|
||||
generation = 31 * generation + (sourceBounds != null ? sourceBounds.signature() : 0);
|
||||
Integer previous = aodCardsNotificationRenderGenerationByRoot.get(root);
|
||||
boolean dirty = dirtyUnlockedLayoutRoots.contains(root);
|
||||
boolean shouldRender = previous == null
|
||||
|| previous != generation
|
||||
|| dirtyUnlockedLayoutRoots.contains(root)
|
||||
|| dirty
|
||||
|| hostGroup.getChildCount() <= 0;
|
||||
if (shouldRender) {
|
||||
aodCardsNotificationRenderGenerationByRoot.put(root, generation);
|
||||
@@ -3421,7 +3837,7 @@ final class StockLayoutCanvasController {
|
||||
lockscreenCardsNotificationRowFilter.apply(stack, allowAfterKeyguardUnlock);
|
||||
}
|
||||
|
||||
private void applyLockscreenCardsNotificationRowFilterInTreeIfNeeded(
|
||||
private boolean applyLockscreenCardsNotificationRowFilterInTreeIfNeeded(
|
||||
View root,
|
||||
SbtSettings settings,
|
||||
SceneKey activeScene,
|
||||
@@ -3429,9 +3845,10 @@ final class StockLayoutCanvasController {
|
||||
int signature = lockscreenCardsRowFilterSignature(root, settings, activeScene);
|
||||
Integer previous = lockscreenCardsRowFilterSignatures.put(root, signature);
|
||||
if (previous != null && previous == signature) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
applyLockscreenCardsNotificationRowFilterInTree(root, allowAfterKeyguardUnlock);
|
||||
return true;
|
||||
}
|
||||
|
||||
private int lockscreenCardsRowFilterSignature(
|
||||
@@ -3620,11 +4037,13 @@ final class StockLayoutCanvasController {
|
||||
}
|
||||
NotificationDisplayStyle notificationStyle =
|
||||
SystemNotificationDisplayStyleDetector.read(context);
|
||||
if (isAodRoot(root) || (isKeyguardLocked(context) && !isInteractive(context))) {
|
||||
boolean keyguardLocked = isKeyguardLocked(context);
|
||||
boolean interactive = isInteractive(context);
|
||||
if (isAodRoot(root) || (keyguardLocked && !interactive)) {
|
||||
runtimeContext.getModeStateRepository().setAod(notificationStyle);
|
||||
return;
|
||||
}
|
||||
if (isKeyguardLocked(context)) {
|
||||
if (keyguardLocked) {
|
||||
runtimeContext.getModeStateRepository().setLockscreen(notificationStyle);
|
||||
return;
|
||||
}
|
||||
|
||||
+1
-6
@@ -798,7 +798,7 @@ public final class PackedStatusBarLayoutSolver {
|
||||
}
|
||||
}
|
||||
|
||||
public static void collisionTree(ArrayList<LayoutItem> items) {
|
||||
private static void collisionTree(ArrayList<LayoutItem> items) {
|
||||
for (LayoutItem item : items) {
|
||||
for (Box box : item.boxes) {
|
||||
box.collisionLeft.clear();
|
||||
@@ -1165,11 +1165,6 @@ public final class PackedStatusBarLayoutSolver {
|
||||
return oldWidth - width();
|
||||
}
|
||||
|
||||
public void setPoolRemaining(int remaining) {
|
||||
poolRemaining = Math.max(0, remaining);
|
||||
recomputeIconState();
|
||||
}
|
||||
|
||||
public void setPoolIcons(ArrayList<Integer> widths, int startIndex) {
|
||||
widthLimit = Math.min(currentWidthLimit(), width());
|
||||
poolIconWidths = widths != null ? new ArrayList<>(widths) : new ArrayList<>();
|
||||
|
||||
+16
-696
@@ -1,668 +1,9 @@
|
||||
package se.ajpanton.statusbartweak.runtime.layoutsolver;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
||||
public final class StatusBarLayoutSolver {
|
||||
private static final int MIDDLE_COLLISION_MARGIN_PX = 2;
|
||||
|
||||
private StatusBarLayoutSolver() {
|
||||
}
|
||||
|
||||
public static <T extends LayoutBand> ArrayList<T> bandsForPosition(
|
||||
ArrayList<T> bands,
|
||||
LayoutPosition position,
|
||||
ArrayList<LayoutItemKind> itemOrder
|
||||
) {
|
||||
ArrayList<T> result = new ArrayList<>();
|
||||
for (LayoutItemKind kind : itemOrder) {
|
||||
for (T band : bands) {
|
||||
if (band.kind == kind
|
||||
&& band.position == position
|
||||
&& band.splitRegion == SplitRegion.NONE) {
|
||||
result.add(band);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <T extends LayoutBand> ArrayList<T> middleBandsForPlacement(
|
||||
ArrayList<T> bands,
|
||||
ArrayList<LayoutItemKind> itemOrder,
|
||||
AnchorSide side
|
||||
) {
|
||||
ArrayList<T> result = new ArrayList<>();
|
||||
SplitRegion sideRegion = side == AnchorSide.LEFT ? SplitRegion.LEFT : SplitRegion.RIGHT;
|
||||
for (T band : bands) {
|
||||
if (band.splitRegion == sideRegion) {
|
||||
result.add(band);
|
||||
}
|
||||
}
|
||||
result.addAll(bandsForPosition(bands, LayoutPosition.MIDDLE, itemOrder));
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <T extends LayoutBand> RegionPlan<T> planRegions(
|
||||
int rootWidth,
|
||||
LayoutEdges edges,
|
||||
ArrayList<T> bands,
|
||||
ArrayList<LayoutItemKind> itemOrder,
|
||||
Bounds cutoutBounds,
|
||||
int itemPadding
|
||||
) {
|
||||
int leftEdge = Math.max(0, Math.min(rootWidth, edges.left));
|
||||
int rightEdge = Math.max(leftEdge, Math.min(rootWidth, edges.right));
|
||||
Region<T> leftRegion;
|
||||
Region<T> rightRegion = null;
|
||||
if (cutoutBounds == null) {
|
||||
leftRegion = new Region<>(leftEdge, rightEdge);
|
||||
} else {
|
||||
leftRegion = new Region<>(leftEdge, Math.min(cutoutBounds.left, rightEdge));
|
||||
rightRegion = new Region<>(
|
||||
Math.max(cutoutBounds.left + cutoutBounds.width, leftEdge),
|
||||
rightEdge);
|
||||
}
|
||||
|
||||
ArrayList<T> leftBands = bandsForPosition(bands, LayoutPosition.LEFT, itemOrder);
|
||||
ArrayList<T> middleBands = bandsForPosition(bands, LayoutPosition.MIDDLE, itemOrder);
|
||||
ArrayList<T> rightBands = bandsForPosition(bands, LayoutPosition.RIGHT, itemOrder);
|
||||
AnchorSide middleSide = sideForMiddleRegion(rootWidth, middleBands, cutoutBounds, itemPadding);
|
||||
if (rightRegion == null) {
|
||||
addSplitRegionBands(bands, leftRegion, SplitRegion.LEFT);
|
||||
addSplitRegionBands(bands, leftRegion, SplitRegion.RIGHT);
|
||||
leftRegion.bands.addAll(leftBands);
|
||||
leftRegion.bands.addAll(middleBands);
|
||||
Collections.reverse(rightBands);
|
||||
leftRegion.bands.addAll(rightBands);
|
||||
} else {
|
||||
leftRegion.bands.addAll(leftBands);
|
||||
ArrayList<T> middleRegionBands = new ArrayList<>(middleBands);
|
||||
Collections.reverse(middleRegionBands);
|
||||
if (middleSide == AnchorSide.LEFT) {
|
||||
leftRegion.bands.addAll(middleRegionBands);
|
||||
}
|
||||
addSplitRegionBands(bands, leftRegion, SplitRegion.LEFT);
|
||||
|
||||
addSplitRegionBands(bands, rightRegion, SplitRegion.RIGHT);
|
||||
if (middleSide == AnchorSide.RIGHT) {
|
||||
rightRegion.bands.addAll(middleRegionBands);
|
||||
}
|
||||
Collections.reverse(rightBands);
|
||||
rightRegion.bands.addAll(rightBands);
|
||||
}
|
||||
|
||||
ArrayList<Region<T>> regions = new ArrayList<>();
|
||||
regions.add(leftRegion);
|
||||
if (rightRegion != null) {
|
||||
regions.add(rightRegion);
|
||||
}
|
||||
return new RegionPlan<>(regions, middleSide);
|
||||
}
|
||||
|
||||
private static <T extends LayoutBand> void addSplitRegionBands(
|
||||
ArrayList<T> source,
|
||||
Region<T> target,
|
||||
SplitRegion region
|
||||
) {
|
||||
if (source == null || target == null || region == SplitRegion.NONE) {
|
||||
return;
|
||||
}
|
||||
for (T band : source) {
|
||||
if (band.splitRegion == region) {
|
||||
target.bands.add(band);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static <T extends LayoutBand> AnchorSide sideForMiddleRegion(
|
||||
int rootWidth,
|
||||
ArrayList<T> middleBands,
|
||||
Bounds cutoutBounds,
|
||||
int itemPadding
|
||||
) {
|
||||
int middle = rootWidth / 2;
|
||||
if (middleBands == null || middleBands.isEmpty()) {
|
||||
return cutoutBounds == null || cutoutBounds.left + cutoutBounds.width / 2 < middle
|
||||
? AnchorSide.RIGHT
|
||||
: AnchorSide.LEFT;
|
||||
}
|
||||
T firstBand = middleBands.get(0);
|
||||
int width = packedWidth(middleBands, itemPadding);
|
||||
int cameraDistance = distanceFromMiddle(cutoutBounds, middle);
|
||||
boolean centered = cutoutBounds != null
|
||||
&& cutoutBounds.left <= middle + MIDDLE_COLLISION_MARGIN_PX
|
||||
&& cutoutBounds.left + cutoutBounds.width >= middle - MIDDLE_COLLISION_MARGIN_PX;
|
||||
if (cameraDistance < width / 2 && (centered || !firstBand.middleAutoNearestSide)) {
|
||||
return firstBand.middleSide;
|
||||
}
|
||||
if (cutoutBounds == null || cutoutBounds.left + cutoutBounds.width / 2 < middle) {
|
||||
return AnchorSide.RIGHT;
|
||||
}
|
||||
return AnchorSide.LEFT;
|
||||
}
|
||||
|
||||
public static <T extends LayoutBand> Anchor anchorForMiddle(
|
||||
int rootWidth,
|
||||
ArrayList<T> bands,
|
||||
ArrayList<PlacedBand> placedBands,
|
||||
Bounds cutoutBounds,
|
||||
AnchorSide side,
|
||||
int itemPadding
|
||||
) {
|
||||
int middle = rootWidth / 2;
|
||||
int width = packedWidth(bands, itemPadding);
|
||||
if (coversMiddle(cutoutBounds, middle)) {
|
||||
return obstacleAnchor(cutoutBounds, side, AnchorKind.WALL);
|
||||
}
|
||||
Bounds nearestItem = nearestPlacedBand(placedBands, middle);
|
||||
int cameraDistance = distanceFromMiddle(cutoutBounds, middle);
|
||||
int itemDistance = distanceFromMiddle(nearestItem, middle);
|
||||
if (Math.min(cameraDistance, itemDistance) < width / 2) {
|
||||
if (cameraDistance < itemDistance) {
|
||||
return obstacleAnchor(cutoutBounds, side, AnchorKind.WALL);
|
||||
}
|
||||
return obstacleAnchor(nearestItem, side, AnchorKind.ITEM);
|
||||
}
|
||||
return middleAnchor(rootWidth, width, side);
|
||||
}
|
||||
|
||||
private static Anchor obstacleAnchor(Bounds obstacle, AnchorSide side, AnchorKind kind) {
|
||||
if (obstacle == null) {
|
||||
return new Anchor(0, side, kind);
|
||||
}
|
||||
int anchorPoint = side == AnchorSide.RIGHT ? obstacle.left + obstacle.width : obstacle.left;
|
||||
return new Anchor(anchorPoint, side, kind);
|
||||
}
|
||||
|
||||
private static Anchor middleAnchor(int rootWidth, int width, AnchorSide side) {
|
||||
int middle = rootWidth / 2;
|
||||
if (side == AnchorSide.RIGHT) {
|
||||
return new Anchor(middle - width / 2, AnchorSide.RIGHT, AnchorKind.CENTER);
|
||||
}
|
||||
return new Anchor(middle + width / 2, AnchorSide.LEFT, AnchorKind.CENTER);
|
||||
}
|
||||
|
||||
public static <T extends LayoutBand> void placeStackedBands(
|
||||
ArrayList<T> bands,
|
||||
Anchor anchor,
|
||||
ArrayList<PlacedBand> placedBands,
|
||||
String sortOrder,
|
||||
boolean avoidPlacedBands,
|
||||
int itemPadding
|
||||
) {
|
||||
if (bands == null || bands.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (T band : bands) {
|
||||
band.prepareForSide(anchor.side, sortOrder);
|
||||
}
|
||||
ArrayList<StackedBand<T>> stackedBands = stackBands(bands, itemPadding);
|
||||
int shift = avoidPlacedBands ? middleShift(stackedBands, anchor, placedBands, itemPadding) : 0;
|
||||
for (StackedBand<T> stackedBand : stackedBands) {
|
||||
T band = stackedBand.band;
|
||||
int wallDotSlack = anchor.kind == AnchorKind.WALL
|
||||
&& stackedBand.left == 0
|
||||
&& shift == 0
|
||||
? band.wallDotSlack(anchor.side)
|
||||
: 0;
|
||||
int left = stackedLeft(stackedBand, anchor, shift, wallDotSlack, itemPadding);
|
||||
band.place(left);
|
||||
ArrayList<Bounds> bounds = band.placedCollisionBounds();
|
||||
if (!bounds.isEmpty()) {
|
||||
placedBands.add(new PlacedBand(band.kind, band.position, bounds));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static <T extends LayoutBand> int middleShift(
|
||||
ArrayList<StackedBand<T>> stackedBands,
|
||||
Anchor anchor,
|
||||
ArrayList<PlacedBand> placedBands,
|
||||
int itemPadding
|
||||
) {
|
||||
int shift = 0;
|
||||
for (StackedBand<T> stackedBand : stackedBands) {
|
||||
ArrayList<Bounds> bounds = boundsForStackedBand(stackedBand, anchor, shift, itemPadding);
|
||||
int leftOverstep = overstepFromPlacedBands(bounds, placedBands, LayoutPosition.LEFT, itemPadding);
|
||||
if (leftOverstep > 0) {
|
||||
shift += leftOverstep;
|
||||
continue;
|
||||
}
|
||||
int rightOverstep = overstepFromPlacedBands(bounds, placedBands, LayoutPosition.RIGHT, itemPadding);
|
||||
if (rightOverstep > 0) {
|
||||
shift -= rightOverstep;
|
||||
}
|
||||
}
|
||||
return shift;
|
||||
}
|
||||
|
||||
private static <T extends LayoutBand> ArrayList<Bounds> boundsForStackedBand(
|
||||
StackedBand<T> stackedBand,
|
||||
Anchor anchor,
|
||||
int shift,
|
||||
int itemPadding
|
||||
) {
|
||||
ArrayList<Bounds> result = new ArrayList<>();
|
||||
int left = stackedLeft(stackedBand, anchor, shift, 0, itemPadding);
|
||||
for (Bounds box : stackedBand.boxes) {
|
||||
result.add(new Bounds(left + box.left, box.top, box.width, box.height));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static <T extends LayoutBand> int stackedLeft(
|
||||
StackedBand<T> stackedBand,
|
||||
Anchor anchor,
|
||||
int shift,
|
||||
int wallDotSlack,
|
||||
int itemPadding
|
||||
) {
|
||||
T band = stackedBand.band;
|
||||
int anchorGap = anchor.kind == AnchorKind.ITEM ? Math.max(0, itemPadding) : 0;
|
||||
if (anchor.side == AnchorSide.RIGHT) {
|
||||
return anchor.point + anchorGap + stackedBand.left + shift - wallDotSlack;
|
||||
}
|
||||
return anchor.point - anchorGap - stackedBand.left - band.width() + shift + wallDotSlack;
|
||||
}
|
||||
|
||||
private static int overstepFromPlacedBands(
|
||||
ArrayList<Bounds> bounds,
|
||||
ArrayList<PlacedBand> placedBands,
|
||||
LayoutPosition position,
|
||||
int itemPadding
|
||||
) {
|
||||
int overstep = 0;
|
||||
if (bounds == null || placedBands == null) {
|
||||
return overstep;
|
||||
}
|
||||
for (Bounds boundsItem : bounds) {
|
||||
if (boundsItem == null) {
|
||||
continue;
|
||||
}
|
||||
for (PlacedBand placedBand : placedBands) {
|
||||
if (placedBand.position != position) {
|
||||
continue;
|
||||
}
|
||||
for (Bounds obstacle : placedBand.bounds) {
|
||||
if (obstacle == null
|
||||
|| !verticalRangesOverlap(
|
||||
boundsItem.top,
|
||||
boundsItem.height,
|
||||
obstacle.top,
|
||||
obstacle.height)) {
|
||||
continue;
|
||||
}
|
||||
overstep = Math.max(overstep, horizontalOverstep(boundsItem, obstacle, position, itemPadding));
|
||||
}
|
||||
}
|
||||
}
|
||||
return overstep;
|
||||
}
|
||||
|
||||
private static int horizontalOverstep(
|
||||
Bounds item,
|
||||
Bounds obstacle,
|
||||
LayoutPosition obstaclePosition,
|
||||
int itemPadding
|
||||
) {
|
||||
int gap = Math.max(0, itemPadding);
|
||||
if (obstaclePosition == LayoutPosition.LEFT) {
|
||||
return Math.max(0, obstacle.left + blockingWidth(obstacle) + gap - item.left);
|
||||
}
|
||||
if (obstaclePosition == LayoutPosition.RIGHT) {
|
||||
return Math.max(0, item.left + blockingWidth(item) + gap - obstacle.left);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static <T extends LayoutBand> void truncateToFit(
|
||||
ArrayList<T> bands,
|
||||
int freeSpace,
|
||||
AnchorSide middleSide,
|
||||
String sortOrder,
|
||||
int itemPadding
|
||||
) {
|
||||
int target = Math.max(0, freeSpace);
|
||||
for (T band : bands) {
|
||||
band.prepareForSide(truncationAnchorSide(band, middleSide), sortOrder);
|
||||
}
|
||||
int guard = 64;
|
||||
while (packedWidthForTruncation(bands, middleSide, itemPadding) > target && guard-- > 0) {
|
||||
if (shrinkToReducePackedWidth(bands, LayoutItemKind.NOTIFICATIONS, middleSide, itemPadding)) {
|
||||
continue;
|
||||
}
|
||||
if (shrinkToReducePackedWidth(bands, LayoutItemKind.STATUS, middleSide, itemPadding)) {
|
||||
continue;
|
||||
}
|
||||
if (clipToReducePackedWidth(bands, LayoutItemKind.CHIP, middleSide, target, itemPadding)) {
|
||||
continue;
|
||||
}
|
||||
if (removeDotToReducePackedWidth(bands, LayoutItemKind.NOTIFICATIONS, middleSide, itemPadding)) {
|
||||
continue;
|
||||
}
|
||||
if (removeDotToReducePackedWidth(bands, LayoutItemKind.STATUS, middleSide, itemPadding)) {
|
||||
continue;
|
||||
}
|
||||
if (clipToReducePackedWidth(bands, LayoutItemKind.CLOCK, middleSide, target, itemPadding)) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static <T extends LayoutBand> boolean shrinkToReducePackedWidth(
|
||||
ArrayList<T> bands,
|
||||
LayoutItemKind kind,
|
||||
AnchorSide middleSide,
|
||||
int itemPadding
|
||||
) {
|
||||
return mutateBandToReducePackedWidth(
|
||||
bands,
|
||||
kind,
|
||||
middleSide,
|
||||
itemPadding,
|
||||
LayoutBand::shrinkOneIcon,
|
||||
false,
|
||||
true);
|
||||
}
|
||||
|
||||
private static <T extends LayoutBand> boolean removeDotToReducePackedWidth(
|
||||
ArrayList<T> bands,
|
||||
LayoutItemKind kind,
|
||||
AnchorSide middleSide,
|
||||
int itemPadding
|
||||
) {
|
||||
return mutateBandToReducePackedWidth(
|
||||
bands,
|
||||
kind,
|
||||
middleSide,
|
||||
itemPadding,
|
||||
LayoutBand::removeOverflowDot,
|
||||
true,
|
||||
false);
|
||||
}
|
||||
|
||||
private static <T extends LayoutBand> boolean mutateBandToReducePackedWidth(
|
||||
ArrayList<T> bands,
|
||||
LayoutItemKind kind,
|
||||
AnchorSide middleSide,
|
||||
int itemPadding,
|
||||
BandMutation mutation,
|
||||
boolean acceptEqualWidth,
|
||||
boolean acceptCreatedDot
|
||||
) {
|
||||
T band = findBand(bands, kind);
|
||||
if (band == null) {
|
||||
return false;
|
||||
}
|
||||
int before = packedWidthForTruncation(bands, middleSide, itemPadding);
|
||||
Object state = band.captureState();
|
||||
if (!mutation.apply(band)) {
|
||||
return false;
|
||||
}
|
||||
int after = packedWidthForTruncation(bands, middleSide, itemPadding);
|
||||
if (after < before
|
||||
|| (acceptEqualWidth && after == before)
|
||||
|| (acceptCreatedDot && band.createdOverflowDotSince(state))) {
|
||||
return true;
|
||||
}
|
||||
band.restoreState(state);
|
||||
return false;
|
||||
}
|
||||
|
||||
private static <T extends LayoutBand> boolean clipToReducePackedWidth(
|
||||
ArrayList<T> bands,
|
||||
LayoutItemKind kind,
|
||||
AnchorSide middleSide,
|
||||
int target,
|
||||
int itemPadding
|
||||
) {
|
||||
T band = findBand(bands, kind);
|
||||
if (band == null || !band.canClipContinuously()) {
|
||||
return false;
|
||||
}
|
||||
int before = packedWidthForTruncation(bands, middleSide, itemPadding);
|
||||
int amount = Math.max(1, before - target);
|
||||
if (!band.clipContinuous(truncationAnchorSide(band, middleSide), amount)) {
|
||||
return false;
|
||||
}
|
||||
return packedWidthForTruncation(bands, middleSide, itemPadding) <= before;
|
||||
}
|
||||
|
||||
public static <T extends LayoutBand> int packedWidth(ArrayList<T> bands) {
|
||||
return packedWidth(bands, 0);
|
||||
}
|
||||
|
||||
public static <T extends LayoutBand> int packedWidth(ArrayList<T> bands, int itemPadding) {
|
||||
return stackBounds(stackBands(bands, itemPadding)).width;
|
||||
}
|
||||
|
||||
private static <T extends LayoutBand> int packedWidthForTruncation(
|
||||
ArrayList<T> bands,
|
||||
AnchorSide middleSide,
|
||||
int itemPadding
|
||||
) {
|
||||
ArrayList<StackedBand<T>> stackedBands = stackBands(bands, itemPadding);
|
||||
Bounds bounds = stackBounds(stackedBands);
|
||||
int width = bounds.width;
|
||||
if (width <= 0 || stackedBands.isEmpty()) {
|
||||
return width;
|
||||
}
|
||||
int leftEdge = bounds.left;
|
||||
int rightEdge = bounds.left + bounds.width;
|
||||
Integer leftSlack = null;
|
||||
Integer rightSlack = null;
|
||||
for (StackedBand<T> stackedBand : stackedBands) {
|
||||
T band = stackedBand.band;
|
||||
Bounds bandBounds = shiftedBounds(stackedBand.boxes, stackedBand.left);
|
||||
int bandLeft = bandBounds != null ? bandBounds.left : stackedBand.left;
|
||||
int bandRight = bandBounds != null ? bandBounds.left + bandBounds.width : bandLeft;
|
||||
if (bandLeft == leftEdge) {
|
||||
int slack = band.wallDotSlack(AnchorSide.RIGHT);
|
||||
leftSlack = leftSlack == null ? slack : Math.min(leftSlack, slack);
|
||||
}
|
||||
if (bandRight == rightEdge) {
|
||||
int slack = band.wallDotSlack(AnchorSide.LEFT);
|
||||
rightSlack = rightSlack == null ? slack : Math.min(rightSlack, slack);
|
||||
}
|
||||
}
|
||||
return Math.max(0, width - (leftSlack != null ? leftSlack : 0) - (rightSlack != null ? rightSlack : 0));
|
||||
}
|
||||
|
||||
private static AnchorSide truncationAnchorSide(LayoutBand band, AnchorSide middleSide) {
|
||||
if (band.splitRegion == SplitRegion.LEFT) {
|
||||
return AnchorSide.LEFT;
|
||||
}
|
||||
if (band.splitRegion == SplitRegion.RIGHT) {
|
||||
return AnchorSide.RIGHT;
|
||||
}
|
||||
if (band.position == LayoutPosition.LEFT) {
|
||||
return AnchorSide.RIGHT;
|
||||
}
|
||||
if (band.position == LayoutPosition.RIGHT) {
|
||||
return AnchorSide.LEFT;
|
||||
}
|
||||
return middleSide;
|
||||
}
|
||||
|
||||
private static <T extends LayoutBand> ArrayList<StackedBand<T>> stackBands(
|
||||
ArrayList<T> bands,
|
||||
int itemPadding
|
||||
) {
|
||||
ArrayList<StackedBand<T>> stackedBands = new ArrayList<>();
|
||||
if (bands == null) {
|
||||
return stackedBands;
|
||||
}
|
||||
int gap = Math.max(0, itemPadding);
|
||||
for (T band : bands) {
|
||||
int left = 0;
|
||||
ArrayList<Bounds> boxes = band.collisionBoxes();
|
||||
for (StackedBand<T> stackedBand : stackedBands) {
|
||||
for (Bounds box : boxes) {
|
||||
for (Bounds placedBox : stackedBand.boxes) {
|
||||
if (verticalRangesOverlap(box.top, box.height, placedBox.top, placedBox.height)) {
|
||||
left = Math.max(
|
||||
left,
|
||||
stackedBand.left + placedBox.left + blockingWidth(placedBox) + gap - box.left);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stackedBands.add(new StackedBand<>(band, left, boxes));
|
||||
}
|
||||
return stackedBands;
|
||||
}
|
||||
|
||||
private static <T extends LayoutBand> Bounds stackBounds(ArrayList<StackedBand<T>> stackedBands) {
|
||||
Bounds bounds = new Bounds(0, 0, 0, 0);
|
||||
if (stackedBands == null || stackedBands.isEmpty()) {
|
||||
return bounds;
|
||||
}
|
||||
Bounds union = null;
|
||||
for (StackedBand<T> stackedBand : stackedBands) {
|
||||
Bounds bandBounds = shiftedBounds(stackedBand.boxes, stackedBand.left);
|
||||
if (bandBounds != null) {
|
||||
union = union == null ? bandBounds : union.union(bandBounds);
|
||||
}
|
||||
}
|
||||
return union != null ? union : bounds;
|
||||
}
|
||||
|
||||
private static Bounds shiftedBounds(ArrayList<Bounds> boxes, int left) {
|
||||
Bounds union = null;
|
||||
if (boxes == null) {
|
||||
return null;
|
||||
}
|
||||
for (Bounds box : boxes) {
|
||||
Bounds shifted = new Bounds(left + box.left, box.top, blockingWidth(box), box.height);
|
||||
union = union == null ? shifted : union.union(shifted);
|
||||
}
|
||||
return union;
|
||||
}
|
||||
|
||||
private static boolean verticalRangesOverlap(int topA, int heightA, int topB, int heightB) {
|
||||
return topA < topB + heightB && topB < topA + heightA;
|
||||
}
|
||||
|
||||
private static int blockingWidth(Bounds bounds) {
|
||||
return bounds != null && bounds.height > 0 ? Math.max(1, bounds.width) : 0;
|
||||
}
|
||||
|
||||
private static <T extends LayoutBand> T findBand(ArrayList<T> bands, LayoutItemKind kind) {
|
||||
for (T band : bands) {
|
||||
if (band.kind == kind) {
|
||||
return band;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Bounds nearestPlacedBand(ArrayList<PlacedBand> placedBands, int middle) {
|
||||
Bounds nearest = null;
|
||||
int nearestDistance = Integer.MAX_VALUE;
|
||||
for (PlacedBand placedBand : placedBands) {
|
||||
for (Bounds bounds : placedBand.bounds) {
|
||||
int distance = distanceFromMiddle(bounds, middle);
|
||||
if (distance < nearestDistance) {
|
||||
nearest = bounds;
|
||||
nearestDistance = distance;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nearest;
|
||||
}
|
||||
|
||||
public static int distanceFromMiddle(Bounds bounds, int middle) {
|
||||
if (bounds == null) {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
if (bounds.left <= middle && bounds.left + bounds.width >= middle) {
|
||||
return 0;
|
||||
}
|
||||
return Math.min(Math.abs(middle - bounds.left), Math.abs(middle - (bounds.left + bounds.width)));
|
||||
}
|
||||
|
||||
public static boolean coversMiddle(Bounds bounds, int middle) {
|
||||
return bounds != null
|
||||
&& bounds.left <= middle + MIDDLE_COLLISION_MARGIN_PX
|
||||
&& bounds.left + bounds.width >= middle - MIDDLE_COLLISION_MARGIN_PX;
|
||||
}
|
||||
|
||||
public abstract static class LayoutBand {
|
||||
public final LayoutItemKind kind;
|
||||
public final LayoutPosition position;
|
||||
public final boolean middleAutoNearestSide;
|
||||
public final AnchorSide middleSide;
|
||||
public final SplitRegion splitRegion;
|
||||
|
||||
protected LayoutBand(
|
||||
LayoutItemKind kind,
|
||||
LayoutPosition position,
|
||||
boolean middleAutoNearestSide,
|
||||
AnchorSide middleSide,
|
||||
SplitRegion splitRegion
|
||||
) {
|
||||
this.kind = kind;
|
||||
this.position = position;
|
||||
this.middleAutoNearestSide = middleAutoNearestSide;
|
||||
this.middleSide = middleSide;
|
||||
this.splitRegion = splitRegion != null ? splitRegion : SplitRegion.NONE;
|
||||
}
|
||||
|
||||
protected abstract void prepareForSide(AnchorSide side, String sortOrder);
|
||||
|
||||
protected abstract int width();
|
||||
|
||||
protected abstract ArrayList<Bounds> collisionBoxes();
|
||||
|
||||
protected abstract void place(int left);
|
||||
|
||||
protected abstract ArrayList<Bounds> placedCollisionBounds();
|
||||
|
||||
protected int wallDotSlack(AnchorSide side) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected boolean shrinkOneIcon() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean removeOverflowDot() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected Object captureState() {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void restoreState(Object state) {
|
||||
}
|
||||
|
||||
protected boolean createdOverflowDotSince(Object state) {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean canClipContinuously() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean clipContinuous(AnchorSide wallSide, int amountPx) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private interface BandMutation {
|
||||
boolean apply(LayoutBand band);
|
||||
}
|
||||
|
||||
private record StackedBand<T extends LayoutBand>(
|
||||
T band,
|
||||
int left,
|
||||
ArrayList<Bounds> boxes
|
||||
) {
|
||||
}
|
||||
|
||||
public enum LayoutItemKind {
|
||||
CARRIER,
|
||||
CLOCK,
|
||||
@@ -682,21 +23,12 @@ public final class StatusBarLayoutSolver {
|
||||
RIGHT
|
||||
}
|
||||
|
||||
public enum AnchorKind {
|
||||
WALL,
|
||||
ITEM,
|
||||
CENTER
|
||||
}
|
||||
|
||||
public enum SplitRegion {
|
||||
NONE,
|
||||
LEFT,
|
||||
RIGHT
|
||||
}
|
||||
|
||||
public record Anchor(int point, AnchorSide side, AnchorKind kind) {
|
||||
}
|
||||
|
||||
public static final class Bounds {
|
||||
public final int left;
|
||||
public final int top;
|
||||
@@ -726,36 +58,24 @@ public final class StatusBarLayoutSolver {
|
||||
result = 31 * result + height;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof Bounds other)) {
|
||||
return false;
|
||||
}
|
||||
return left == other.left
|
||||
&& top == other.top
|
||||
&& width == other.width
|
||||
&& height == other.height;
|
||||
}
|
||||
|
||||
public record PlacedBand(
|
||||
LayoutItemKind kind,
|
||||
LayoutPosition position,
|
||||
ArrayList<Bounds> bounds
|
||||
) {
|
||||
}
|
||||
|
||||
public record RegionPlan<T extends LayoutBand>(
|
||||
ArrayList<Region<T>> regions,
|
||||
AnchorSide middleSide
|
||||
) {
|
||||
}
|
||||
|
||||
public record LayoutEdges(int left, int right) {
|
||||
}
|
||||
|
||||
public static final class Region<T extends LayoutBand> {
|
||||
public final int left;
|
||||
public final int right;
|
||||
public final ArrayList<T> bands = new ArrayList<>();
|
||||
|
||||
Region(int left, int right) {
|
||||
this.left = left;
|
||||
this.right = Math.max(left, right);
|
||||
}
|
||||
|
||||
public int width() {
|
||||
return Math.max(0, right - left);
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return signature();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+37
-19
@@ -2,15 +2,9 @@ package se.ajpanton.statusbartweak.runtime.mode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Central source of truth for the current scene.
|
||||
*
|
||||
* This is intentionally small at the reset stage: it only tracks the active
|
||||
* scene and whether the custom layout runtime should currently output anything.
|
||||
* Hook-driven updates can be wired in later without changing the rest of the
|
||||
* runtime API.
|
||||
*/
|
||||
public final class ModeStateRepository {
|
||||
private SceneKey activeScene = SceneKey.unlocked();
|
||||
@@ -19,6 +13,7 @@ public final class ModeStateRepository {
|
||||
private boolean layoutEnabled;
|
||||
private final List<LayoutEnabledListener> layoutEnabledListeners = new ArrayList<>();
|
||||
private final List<SceneListener> sceneListeners = new ArrayList<>();
|
||||
private final List<SystemUiStatusBarStateListener> systemUiStatusBarStateListeners = new ArrayList<>();
|
||||
|
||||
public synchronized SceneKey getActiveScene() {
|
||||
return activeScene;
|
||||
@@ -68,10 +63,6 @@ public final class ModeStateRepository {
|
||||
setActiveScene(SceneKey.aod(requireDisplayStyle(style)));
|
||||
}
|
||||
|
||||
public void setScene(SceneKey sceneKey) {
|
||||
setActiveScene(Objects.requireNonNull(sceneKey, "sceneKey"));
|
||||
}
|
||||
|
||||
public void setSystemUiStatusBarState(
|
||||
int state,
|
||||
boolean dozing,
|
||||
@@ -84,11 +75,23 @@ public final class ModeStateRepository {
|
||||
SceneKey scene = dozing
|
||||
? SceneKey.aod(style)
|
||||
: state == 0 ? SceneKey.unlocked() : SceneKey.lockscreen(style);
|
||||
boolean changed;
|
||||
int previousState;
|
||||
boolean previousKnown;
|
||||
synchronized (this) {
|
||||
previousKnown = systemUiStatusBarStateKnown;
|
||||
previousState = systemUiStatusBarState;
|
||||
changed = !systemUiStatusBarStateKnown || systemUiStatusBarState != state;
|
||||
systemUiStatusBarStateKnown = true;
|
||||
systemUiStatusBarState = state;
|
||||
}
|
||||
setActiveScene(scene);
|
||||
if (changed) {
|
||||
notifySystemUiStatusBarStateListeners(
|
||||
previousKnown ? previousState : -1,
|
||||
state,
|
||||
dozing);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void addSceneListener(SceneListener listener) {
|
||||
@@ -97,6 +100,14 @@ public final class ModeStateRepository {
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void addSystemUiStatusBarStateListener(
|
||||
SystemUiStatusBarStateListener listener
|
||||
) {
|
||||
if (listener != null && !systemUiStatusBarStateListeners.contains(listener)) {
|
||||
systemUiStatusBarStateListeners.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
private void setActiveScene(SceneKey scene) {
|
||||
SceneKey previous;
|
||||
List<SceneListener> listeners;
|
||||
@@ -108,19 +119,22 @@ public final class ModeStateRepository {
|
||||
activeScene = scene;
|
||||
listeners = new ArrayList<>(sceneListeners);
|
||||
}
|
||||
notifySceneChanged(previous, scene, listeners);
|
||||
for (SceneListener listener : listeners) {
|
||||
listener.onSceneChanged(previous, scene);
|
||||
}
|
||||
}
|
||||
|
||||
private void notifySceneChanged(
|
||||
SceneKey previous,
|
||||
SceneKey current,
|
||||
List<SceneListener> listeners
|
||||
private void notifySystemUiStatusBarStateListeners(
|
||||
int previousState,
|
||||
int currentState,
|
||||
boolean dozing
|
||||
) {
|
||||
if (listeners == null || listeners.isEmpty()) {
|
||||
return;
|
||||
List<SystemUiStatusBarStateListener> listeners;
|
||||
synchronized (this) {
|
||||
listeners = new ArrayList<>(systemUiStatusBarStateListeners);
|
||||
}
|
||||
for (SceneListener listener : listeners) {
|
||||
listener.onSceneChanged(previous, current);
|
||||
for (SystemUiStatusBarStateListener listener : listeners) {
|
||||
listener.onSystemUiStatusBarStateChanged(previousState, currentState, dozing);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,4 +152,8 @@ public final class ModeStateRepository {
|
||||
public interface SceneListener {
|
||||
void onSceneChanged(SceneKey previous, SceneKey current);
|
||||
}
|
||||
|
||||
public interface SystemUiStatusBarStateListener {
|
||||
void onSystemUiStatusBarStateChanged(int previousState, int currentState, boolean dozing);
|
||||
}
|
||||
}
|
||||
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
package se.ajpanton.statusbartweak.runtime.notifications;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public final class NotificationActiveKeyStore {
|
||||
private static final HashSet<String> ACTIVE_KEYS = new HashSet<>();
|
||||
private static int generation;
|
||||
|
||||
private NotificationActiveKeyStore() {
|
||||
}
|
||||
|
||||
public static synchronized boolean replace(Collection<String> keys) {
|
||||
HashSet<String> normalized = new HashSet<>();
|
||||
if (keys != null) {
|
||||
for (String key : keys) {
|
||||
addKey(normalized, key);
|
||||
}
|
||||
}
|
||||
if (ACTIVE_KEYS.equals(normalized)) {
|
||||
return false;
|
||||
}
|
||||
ACTIVE_KEYS.clear();
|
||||
ACTIVE_KEYS.addAll(normalized);
|
||||
generation++;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static synchronized boolean hasSnapshot() {
|
||||
return !ACTIVE_KEYS.isEmpty();
|
||||
}
|
||||
|
||||
public static synchronized boolean isActive(String key) {
|
||||
String normalized = normalizeKey(key);
|
||||
return normalized != null && ACTIVE_KEYS.contains(normalized);
|
||||
}
|
||||
|
||||
public static synchronized int generation() {
|
||||
return generation;
|
||||
}
|
||||
|
||||
public static synchronized Set<String> snapshot() {
|
||||
return new HashSet<>(ACTIVE_KEYS);
|
||||
}
|
||||
|
||||
private static void addKey(HashSet<String> out, String key) {
|
||||
String normalized = normalizeKey(key);
|
||||
if (normalized != null) {
|
||||
out.add(normalized);
|
||||
}
|
||||
}
|
||||
|
||||
private static String normalizeKey(String key) {
|
||||
if (key == null) {
|
||||
return null;
|
||||
}
|
||||
String normalized = key.trim();
|
||||
if (normalized.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
int identitySuffix = normalized.indexOf('@');
|
||||
if (identitySuffix >= 0) {
|
||||
normalized = normalized.substring(0, identitySuffix);
|
||||
}
|
||||
return normalized.isEmpty() ? null : normalized;
|
||||
}
|
||||
}
|
||||
+137
@@ -0,0 +1,137 @@
|
||||
package se.ajpanton.statusbartweak.runtime.notifications;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.os.Bundle;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import se.ajpanton.statusbartweak.runtime.NotificationKeyReflection;
|
||||
import se.ajpanton.statusbartweak.shell.settings.AppIconRules;
|
||||
|
||||
public final class NotificationUnreadTracker {
|
||||
private static final HashMap<String, State> STATE_BY_KEY = new HashMap<>();
|
||||
private static final HashMap<String, Long> UPDATED_BY_PACKAGE = new HashMap<>();
|
||||
private static long lastSeenMs;
|
||||
private static int generation;
|
||||
|
||||
private NotificationUnreadTracker() {
|
||||
}
|
||||
|
||||
public static synchronized boolean markSeen() {
|
||||
long now = System.currentTimeMillis();
|
||||
if (now <= lastSeenMs) {
|
||||
return false;
|
||||
}
|
||||
lastSeenMs = now;
|
||||
generation++;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static synchronized boolean record(StatusBarNotification sbn) {
|
||||
if (sbn == null || !AppIconRules.isValidPackageName(sbn.getPackageName())) {
|
||||
return false;
|
||||
}
|
||||
String key = sbn.getKey();
|
||||
if (key == null || key.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
int signature = signature(sbn);
|
||||
State previous = STATE_BY_KEY.get(key);
|
||||
if (previous != null && previous.signature == signature) {
|
||||
return false;
|
||||
}
|
||||
long updateTime = previous == null ? notificationTime(sbn) : System.currentTimeMillis();
|
||||
State state = new State(sbn.getPackageName(), signature, updateTime);
|
||||
STATE_BY_KEY.put(key, state);
|
||||
Long packageTime = UPDATED_BY_PACKAGE.get(state.packageName);
|
||||
if (packageTime == null || updateTime > packageTime) {
|
||||
UPDATED_BY_PACKAGE.put(state.packageName, updateTime);
|
||||
}
|
||||
generation++;
|
||||
return updateTime > lastSeenMs;
|
||||
}
|
||||
|
||||
public static synchronized boolean retainActiveKeys(Set<String> activeKeys) {
|
||||
if (activeKeys == null) {
|
||||
return false;
|
||||
}
|
||||
boolean changed = STATE_BY_KEY.keySet().removeIf(key -> !activeKeys.contains(key));
|
||||
if (changed) {
|
||||
rebuildPackageTimes();
|
||||
generation++;
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
public static synchronized int generation() {
|
||||
return generation;
|
||||
}
|
||||
|
||||
public static synchronized boolean isUnread(String key) {
|
||||
if (key == null || key.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
State state = STATE_BY_KEY.get(key);
|
||||
if (state != null) {
|
||||
return state.updatedMs > lastSeenMs;
|
||||
}
|
||||
String packageName = NotificationKeyReflection.packageFromNotificationKey(key);
|
||||
Long packageTime = packageName != null ? UPDATED_BY_PACKAGE.get(packageName) : null;
|
||||
return packageTime != null && packageTime > lastSeenMs;
|
||||
}
|
||||
|
||||
private static long notificationTime(StatusBarNotification sbn) {
|
||||
long result = sbn.getPostTime();
|
||||
Notification notification = sbn.getNotification();
|
||||
if (notification != null && notification.when > result) {
|
||||
result = notification.when;
|
||||
}
|
||||
return result > 0L ? result : System.currentTimeMillis();
|
||||
}
|
||||
|
||||
private static int signature(StatusBarNotification sbn) {
|
||||
Notification notification = sbn.getNotification();
|
||||
Bundle extras = notification != null ? notification.extras : null;
|
||||
return Objects.hash(
|
||||
sbn.getKey(),
|
||||
sbn.getPostTime(),
|
||||
notification != null ? notification.when : 0L,
|
||||
notification != null ? notification.number : 0,
|
||||
notification != null ? notification.flags : 0,
|
||||
notification != null ? notification.category : null,
|
||||
textExtra(extras, Notification.EXTRA_TITLE),
|
||||
textExtra(extras, Notification.EXTRA_TEXT),
|
||||
textExtra(extras, Notification.EXTRA_BIG_TEXT),
|
||||
textExtra(extras, Notification.EXTRA_SUB_TEXT));
|
||||
}
|
||||
|
||||
private static String textExtra(Bundle extras, String key) {
|
||||
CharSequence value = extras != null ? extras.getCharSequence(key) : null;
|
||||
return value != null ? value.toString() : null;
|
||||
}
|
||||
|
||||
private static void rebuildPackageTimes() {
|
||||
UPDATED_BY_PACKAGE.clear();
|
||||
for (State state : STATE_BY_KEY.values()) {
|
||||
Long previous = UPDATED_BY_PACKAGE.get(state.packageName);
|
||||
if (previous == null || state.updatedMs > previous) {
|
||||
UPDATED_BY_PACKAGE.put(state.packageName, state.updatedMs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final class State {
|
||||
final String packageName;
|
||||
final int signature;
|
||||
final long updatedMs;
|
||||
|
||||
State(String packageName, int signature, long updatedMs) {
|
||||
this.packageName = packageName;
|
||||
this.signature = signature;
|
||||
this.updatedMs = updatedMs;
|
||||
}
|
||||
}
|
||||
}
|
||||
+7
-35
@@ -18,7 +18,7 @@ import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import se.ajpanton.statusbartweak.R;
|
||||
import se.ajpanton.statusbartweak.runtime.layoutsolver.StatusBarLayoutSolver;
|
||||
import se.ajpanton.statusbartweak.runtime.layoutsolver.StatusBarLayoutSolver.Bounds;
|
||||
import se.ajpanton.statusbartweak.runtime.mode.NotificationDisplayStyle;
|
||||
import se.ajpanton.statusbartweak.runtime.mode.SceneKey;
|
||||
import se.ajpanton.statusbartweak.shell.settings.SbtSettings;
|
||||
@@ -209,9 +209,9 @@ public final class DebugBoundsOverlayController {
|
||||
Bounds notificationBounds = aodNotificationBounds(root, scene);
|
||||
Bounds statusBounds = liveAodStatusIconsBounds(root);
|
||||
if (!isUsableAodAnchor(root, statusBounds)) {
|
||||
statusBounds = overlayBounds(AodStatusbarSourceStore.statusBoundsForRoot(
|
||||
statusBounds = AodStatusbarSourceStore.statusBoundsForRoot(
|
||||
root,
|
||||
notificationContainer));
|
||||
notificationContainer);
|
||||
}
|
||||
boolean hasNotification = isUsableAodAnchor(root, notificationBounds);
|
||||
boolean hasStatus = isUsableAodAnchor(root, statusBounds);
|
||||
@@ -238,8 +238,7 @@ public final class DebugBoundsOverlayController {
|
||||
&& scene.notificationDisplayStyle() == NotificationDisplayStyle.CARDS) {
|
||||
return null;
|
||||
}
|
||||
return overlayBounds(
|
||||
LockscreenCardsNotificationIconSourceStore.sourceContainerBoundsForAodIconsRoot(root));
|
||||
return LockscreenCardsNotificationIconSourceStore.sourceContainerBoundsForAodIconsRoot(root);
|
||||
}
|
||||
|
||||
private ViewGroup aodNotificationContainer(View root, SceneKey scene) {
|
||||
@@ -266,16 +265,8 @@ public final class DebugBoundsOverlayController {
|
||||
return bounds != null ? bounds.signature() : 0;
|
||||
}
|
||||
|
||||
private Bounds overlayBounds(StatusBarLayoutSolver.Bounds bounds) {
|
||||
if (bounds == null) {
|
||||
return null;
|
||||
}
|
||||
return new Bounds(bounds.left, bounds.top, bounds.width, bounds.height);
|
||||
}
|
||||
|
||||
private Bounds liveAodStatusIconsBounds(View root) {
|
||||
StatusBarLayoutSolver.Bounds bounds = AodLiveStatusbarSource.boundsForRoot(root);
|
||||
return bounds != null ? new Bounds(bounds.left, bounds.top, bounds.width, bounds.height) : null;
|
||||
return AodLiveStatusbarSource.boundsForRoot(root);
|
||||
}
|
||||
|
||||
private void addCutoutSpecs(View root, ArrayList<OverlaySpec> specs) {
|
||||
@@ -352,8 +343,8 @@ public final class DebugBoundsOverlayController {
|
||||
}
|
||||
ArrayList<Bounds> out = new ArrayList<>();
|
||||
for (Object value : values) {
|
||||
if (value instanceof StatusBarLayoutSolver.Bounds bounds) {
|
||||
out.add(new Bounds(bounds.left, bounds.top, bounds.width, bounds.height));
|
||||
if (value instanceof Bounds bounds) {
|
||||
out.add(bounds);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
@@ -606,25 +597,6 @@ public final class DebugBoundsOverlayController {
|
||||
}
|
||||
}
|
||||
|
||||
private record Bounds(int left, int top, int width, int height) {
|
||||
Bounds union(Bounds other) {
|
||||
int right = Math.max(left + width, other.left + other.width);
|
||||
int bottom = Math.max(top + height, other.top + other.height);
|
||||
int newLeft = Math.min(left, other.left);
|
||||
int newTop = Math.min(top, other.top);
|
||||
return new Bounds(newLeft, newTop, right - newLeft, bottom - newTop);
|
||||
}
|
||||
|
||||
int signature() {
|
||||
int result = 17;
|
||||
result = 31 * result + left;
|
||||
result = 31 * result + top;
|
||||
result = 31 * result + width;
|
||||
result = 31 * result + height;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class OverlayView extends View {
|
||||
private final Paint paint = new Paint();
|
||||
private ArrayList<OverlaySpec> specs = new ArrayList<>();
|
||||
|
||||
+58
-1
@@ -25,6 +25,7 @@ public final class LockscreenCardsNotificationIconSourceStore {
|
||||
new WeakHashMap<>();
|
||||
private static final WeakHashMap<ViewGroup, ArrayList<View>> AOD_DRAWABLES_BY_CONTAINER =
|
||||
new WeakHashMap<>();
|
||||
private static final ArrayList<String> AOD_NOTIFICATION_PACKAGES = new ArrayList<>();
|
||||
private static final int VIRTUAL_ICON_SIZE_PX = 39;
|
||||
|
||||
private LockscreenCardsNotificationIconSourceStore() {
|
||||
@@ -113,6 +114,7 @@ public final class LockscreenCardsNotificationIconSourceStore {
|
||||
public static void clearAodSources() {
|
||||
PACKAGES_BY_CONTAINER.clear();
|
||||
AOD_DRAWABLES_BY_CONTAINER.clear();
|
||||
AOD_NOTIFICATION_PACKAGES.clear();
|
||||
}
|
||||
|
||||
public static void clearAodSources(ViewGroup container) {
|
||||
@@ -123,6 +125,18 @@ public final class LockscreenCardsNotificationIconSourceStore {
|
||||
AOD_DRAWABLES_BY_CONTAINER.remove(container);
|
||||
}
|
||||
|
||||
public static void putAodNotificationPackages(ArrayList<String> packages) {
|
||||
AOD_NOTIFICATION_PACKAGES.clear();
|
||||
if (packages == null || packages.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (String pkg : packages) {
|
||||
if (AppIconRules.isValidPackageName(pkg) && !AOD_NOTIFICATION_PACKAGES.contains(pkg)) {
|
||||
AOD_NOTIFICATION_PACKAGES.add(pkg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean sameViews(ArrayList<View> previous, ArrayList<View> current) {
|
||||
if (previous == current) {
|
||||
return true;
|
||||
@@ -252,6 +266,25 @@ public final class LockscreenCardsNotificationIconSourceStore {
|
||||
return result;
|
||||
}
|
||||
|
||||
static ArrayList<SnapshotSource> snapshotAodNotificationPackageSources(View root) {
|
||||
ArrayList<SnapshotSource> result = new ArrayList<>();
|
||||
if (AOD_NOTIFICATION_PACKAGES.isEmpty()) {
|
||||
return result;
|
||||
}
|
||||
Bounds bounds = sourceContainerBoundsForAodIconsRoot(root);
|
||||
int top = bounds != null ? bounds.top : 0;
|
||||
int size = VIRTUAL_ICON_SIZE_PX;
|
||||
for (int i = 0; i < AOD_NOTIFICATION_PACKAGES.size(); i++) {
|
||||
String pkg = AOD_NOTIFICATION_PACKAGES.get(i);
|
||||
result.add(new SnapshotSource(
|
||||
null,
|
||||
SnapshotMode.APP_ICON,
|
||||
pkg + "@aodUnread" + i,
|
||||
new Bounds(0, top, size, size)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static ViewGroup sourceContainerForRoot(View root) {
|
||||
ViewGroup container = sourceContainerForRoot(root, AOD_DRAWABLES_BY_CONTAINER.keySet());
|
||||
if (container != null) {
|
||||
@@ -284,6 +317,22 @@ public final class LockscreenCardsNotificationIconSourceStore {
|
||||
return bounds;
|
||||
}
|
||||
|
||||
public static boolean sourceContainerHasHiddenAncestorForRoot(View root) {
|
||||
ViewGroup container = sourceContainerForRoot(root);
|
||||
if (container == null) {
|
||||
return false;
|
||||
}
|
||||
View current = container;
|
||||
while (current != null && current != root) {
|
||||
if (current.getVisibility() != View.VISIBLE) {
|
||||
return true;
|
||||
}
|
||||
Object parent = current.getParent();
|
||||
current = parent instanceof View ? (View) parent : null;
|
||||
}
|
||||
return current != root;
|
||||
}
|
||||
|
||||
public static Bounds sourceContainerBoundsForAodIconsRoot(View root) {
|
||||
ViewGroup container = sourceContainerForAodIconsRoot(root);
|
||||
Bounds bounds = sourceBoundsRelativeTo(root, container);
|
||||
@@ -294,7 +343,11 @@ public final class LockscreenCardsNotificationIconSourceStore {
|
||||
}
|
||||
|
||||
private static Bounds sourceBoundsRelativeTo(View root, ViewGroup container) {
|
||||
Bounds bounds = container != null ? ViewGeometry.boundsRelativeTo(root, container) : null;
|
||||
Bounds bounds = rawSourceBoundsRelativeTo(root, container);
|
||||
return normalizeSourceBounds(container, bounds);
|
||||
}
|
||||
|
||||
private static Bounds normalizeSourceBounds(ViewGroup container, Bounds bounds) {
|
||||
if (bounds == null || isZeroSizeDotContainer(container, bounds)) {
|
||||
return bounds;
|
||||
}
|
||||
@@ -308,6 +361,10 @@ public final class LockscreenCardsNotificationIconSourceStore {
|
||||
return new Bounds(bounds.left, top, bounds.width, VIRTUAL_ICON_SIZE_PX);
|
||||
}
|
||||
|
||||
private static Bounds rawSourceBoundsRelativeTo(View root, ViewGroup container) {
|
||||
return container != null ? ViewGeometry.boundsRelativeTo(root, container) : null;
|
||||
}
|
||||
|
||||
private static boolean hasAodSources(ViewGroup container) {
|
||||
return container != null
|
||||
&& (AOD_DRAWABLES_BY_CONTAINER.containsKey(container)
|
||||
|
||||
@@ -460,15 +460,6 @@ final class LayoutPlan {
|
||||
final ArrayList<SnapshotPlacement> notificationPlacements;
|
||||
final ClockPlacement carrierPlacement;
|
||||
|
||||
LayoutPlan(
|
||||
ClockPlacement clockPlacement,
|
||||
ArrayList<SnapshotPlacement> chipPlacements,
|
||||
ArrayList<SnapshotPlacement> statusPlacements,
|
||||
ArrayList<SnapshotPlacement> notificationPlacements
|
||||
) {
|
||||
this(clockPlacement, chipPlacements, statusPlacements, notificationPlacements, null);
|
||||
}
|
||||
|
||||
LayoutPlan(
|
||||
ClockPlacement clockPlacement,
|
||||
ArrayList<SnapshotPlacement> chipPlacements,
|
||||
|
||||
+8
-11
@@ -65,13 +65,14 @@ public final class UnlockedIconSnapshotRenderController {
|
||||
ViewGroup statusHost,
|
||||
ViewGroup notificationHost,
|
||||
SceneKey scene,
|
||||
boolean forceStockRefresh,
|
||||
TextView externalCarrierView
|
||||
) {
|
||||
if (scene == null
|
||||
|| (!scene.isUnlocked() && !scene.isLockscreen() && !scene.isAod())
|
||||
|| !root.isAttachedToWindow()) {
|
||||
clearAll();
|
||||
return new RenderResult(true, true);
|
||||
return new RenderResult(true, true, true);
|
||||
}
|
||||
SbtSettings settings = RuntimeSettingsCache.get(root.getContext());
|
||||
layoutHostToRoot(root, clockHost);
|
||||
@@ -139,7 +140,7 @@ public final class UnlockedIconSnapshotRenderController {
|
||||
lastLayoutPlanByRoot.put(root, updatedPlan);
|
||||
lastClockSourceGeometryByRoot.put(root, currentClockSourceGeometry);
|
||||
clockRenderer.render(clockHost, updatedClock);
|
||||
return new RenderResult(false, false);
|
||||
return new RenderResult(false, false, false);
|
||||
}
|
||||
}
|
||||
currentClockLayout = buildClockLayout(root, anchors, settings);
|
||||
@@ -166,16 +167,16 @@ public final class UnlockedIconSnapshotRenderController {
|
||||
LayoutPlan updatedPlan = previousPlan.withClockPlacement(updatedClock);
|
||||
lastLayoutPlanByRoot.put(root, updatedPlan);
|
||||
clockRenderer.render(clockHost, updatedClock);
|
||||
return new RenderResult(false, false);
|
||||
return new RenderResult(false, false, false);
|
||||
}
|
||||
}
|
||||
CollectedIcons collectedIcons = previousIcons;
|
||||
if (forceChipRefresh && collectedIcons != null) {
|
||||
collectedIcons = sourceCollector.collectChips(root, anchors, collectedIcons);
|
||||
lastCollectedIconsByRoot.put(root, collectedIcons);
|
||||
} else if (sceneChanged || stockSourcesChanged || collectedIcons == null) {
|
||||
if (forceStockRefresh || sceneChanged || stockSourcesChanged || collectedIcons == null) {
|
||||
collectedIcons = sourceCollector.collect(root, anchors, scene);
|
||||
lastCollectedIconsByRoot.put(root, collectedIcons);
|
||||
} else if (forceChipRefresh && collectedIcons != null) {
|
||||
collectedIcons = sourceCollector.collectChips(root, anchors, collectedIcons);
|
||||
lastCollectedIconsByRoot.put(root, collectedIcons);
|
||||
} else if (chipSourcesChanged) {
|
||||
collectedIcons = sourceCollector.collectChips(root, anchors, collectedIcons);
|
||||
lastCollectedIconsByRoot.put(root, collectedIcons);
|
||||
@@ -993,10 +994,6 @@ public final class UnlockedIconSnapshotRenderController {
|
||||
boolean chipSourcesChanged,
|
||||
boolean shouldOwnLockscreen
|
||||
) {
|
||||
public RenderResult(boolean layoutChanged, boolean stockSourcesChanged) {
|
||||
this(layoutChanged, stockSourcesChanged, stockSourcesChanged, true);
|
||||
}
|
||||
|
||||
public RenderResult(boolean layoutChanged, boolean stockSourcesChanged, boolean chipSourcesChanged) {
|
||||
this(layoutChanged, stockSourcesChanged, chipSourcesChanged, true);
|
||||
}
|
||||
|
||||
+24
-208
@@ -6,21 +6,21 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Locale;
|
||||
|
||||
import se.ajpanton.statusbartweak.runtime.layoutsolver.StatusBarLayoutSolver;
|
||||
import se.ajpanton.statusbartweak.runtime.layoutsolver.StatusBarLayoutSolver.AnchorSide;
|
||||
import se.ajpanton.statusbartweak.runtime.layoutsolver.StatusBarLayoutSolver.Bounds;
|
||||
import se.ajpanton.statusbartweak.runtime.layoutsolver.StatusBarLayoutSolver.LayoutItemKind;
|
||||
import se.ajpanton.statusbartweak.runtime.layoutsolver.StatusBarLayoutSolver.LayoutPosition;
|
||||
import se.ajpanton.statusbartweak.runtime.layoutsolver.StatusBarLayoutSolver.SplitRegion;
|
||||
import se.ajpanton.statusbartweak.shell.settings.SbtSettings;
|
||||
|
||||
final class UnlockedLayoutBand extends StatusBarLayoutSolver.LayoutBand {
|
||||
final class UnlockedLayoutBand {
|
||||
final LayoutItemKind kind;
|
||||
final LayoutPosition position;
|
||||
final AnchorSide middleSide;
|
||||
final SplitRegion splitRegion;
|
||||
final ViewGroup host;
|
||||
final SnapshotRenderer renderer;
|
||||
final ArrayList<SnapshotPlacement> rawPlacements;
|
||||
final boolean showDotIfTruncated;
|
||||
final boolean forceOverflowDotOnly;
|
||||
final Bounds reservedBounds;
|
||||
final ClockLayout clockLayout;
|
||||
|
||||
ArrayList<SnapshotPlacement> placements;
|
||||
@@ -37,21 +37,19 @@ final class UnlockedLayoutBand extends StatusBarLayoutSolver.LayoutBand {
|
||||
SnapshotRenderer renderer,
|
||||
ArrayList<SnapshotPlacement> rawPlacements,
|
||||
LayoutPosition position,
|
||||
boolean middleAutoNearestSide,
|
||||
AnchorSide middleSide,
|
||||
boolean showDotIfTruncated,
|
||||
boolean forceOverflowDotOnly,
|
||||
Bounds reservedBounds,
|
||||
ClockLayout clockLayout,
|
||||
SplitRegion splitRegion
|
||||
) {
|
||||
super(kind, position, middleAutoNearestSide, middleSide, splitRegion);
|
||||
this.kind = kind;
|
||||
this.position = position;
|
||||
this.middleSide = middleSide;
|
||||
this.splitRegion = splitRegion != null ? splitRegion : SplitRegion.NONE;
|
||||
this.host = host;
|
||||
this.renderer = renderer;
|
||||
this.rawPlacements = rawPlacements;
|
||||
this.showDotIfTruncated = showDotIfTruncated;
|
||||
this.forceOverflowDotOnly = forceOverflowDotOnly;
|
||||
this.reservedBounds = reservedBounds;
|
||||
this.clockLayout = clockLayout;
|
||||
}
|
||||
|
||||
@@ -59,7 +57,7 @@ final class UnlockedLayoutBand extends StatusBarLayoutSolver.LayoutBand {
|
||||
ViewGroup host,
|
||||
ClockLayout clockLayout,
|
||||
LayoutPosition position,
|
||||
SbtSettings settings
|
||||
AnchorSide middleSide
|
||||
) {
|
||||
return new UnlockedLayoutBand(
|
||||
LayoutItemKind.CLOCK,
|
||||
@@ -67,11 +65,8 @@ final class UnlockedLayoutBand extends StatusBarLayoutSolver.LayoutBand {
|
||||
null,
|
||||
null,
|
||||
position,
|
||||
settings.clockMiddleAutoNearestSide,
|
||||
sideFor(settings.clockMiddleCutoutSide),
|
||||
middleSide,
|
||||
false,
|
||||
false,
|
||||
null,
|
||||
clockLayout,
|
||||
SplitRegion.NONE);
|
||||
}
|
||||
@@ -80,7 +75,7 @@ final class UnlockedLayoutBand extends StatusBarLayoutSolver.LayoutBand {
|
||||
ViewGroup host,
|
||||
ClockLayout clockLayout,
|
||||
SplitRegion splitRegion,
|
||||
SbtSettings settings
|
||||
AnchorSide middleSide
|
||||
) {
|
||||
return new UnlockedLayoutBand(
|
||||
LayoutItemKind.CLOCK,
|
||||
@@ -88,11 +83,8 @@ final class UnlockedLayoutBand extends StatusBarLayoutSolver.LayoutBand {
|
||||
null,
|
||||
null,
|
||||
LayoutPosition.MIDDLE,
|
||||
settings.clockMiddleAutoNearestSide,
|
||||
sideFor(settings.clockMiddleCutoutSide),
|
||||
middleSide,
|
||||
false,
|
||||
false,
|
||||
null,
|
||||
clockLayout,
|
||||
splitRegion);
|
||||
}
|
||||
@@ -101,7 +93,6 @@ final class UnlockedLayoutBand extends StatusBarLayoutSolver.LayoutBand {
|
||||
ViewGroup host,
|
||||
ClockLayout carrierLayout,
|
||||
LayoutPosition position,
|
||||
boolean middleAutoNearestSide,
|
||||
AnchorSide middleSide
|
||||
) {
|
||||
return new UnlockedLayoutBand(
|
||||
@@ -110,11 +101,8 @@ final class UnlockedLayoutBand extends StatusBarLayoutSolver.LayoutBand {
|
||||
null,
|
||||
null,
|
||||
position,
|
||||
middleAutoNearestSide,
|
||||
middleSide,
|
||||
false,
|
||||
false,
|
||||
null,
|
||||
carrierLayout,
|
||||
SplitRegion.NONE);
|
||||
}
|
||||
@@ -125,9 +113,7 @@ final class UnlockedLayoutBand extends StatusBarLayoutSolver.LayoutBand {
|
||||
SnapshotRenderer renderer,
|
||||
ArrayList<SnapshotPlacement> rawPlacements,
|
||||
LayoutPosition position,
|
||||
boolean middleAutoNearestSide,
|
||||
AnchorSide middleSide,
|
||||
boolean showDotIfTruncated
|
||||
AnchorSide middleSide
|
||||
) {
|
||||
return new UnlockedLayoutBand(
|
||||
kind,
|
||||
@@ -135,12 +121,9 @@ final class UnlockedLayoutBand extends StatusBarLayoutSolver.LayoutBand {
|
||||
renderer,
|
||||
rawPlacements,
|
||||
position,
|
||||
middleAutoNearestSide,
|
||||
middleSide,
|
||||
showDotIfTruncated,
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
SplitRegion.NONE);
|
||||
}
|
||||
|
||||
@@ -156,7 +139,6 @@ final class UnlockedLayoutBand extends StatusBarLayoutSolver.LayoutBand {
|
||||
SnapshotRenderer renderer,
|
||||
ArrayList<SnapshotPlacement> rawPlacements,
|
||||
LayoutPosition position,
|
||||
boolean middleAutoNearestSide,
|
||||
AnchorSide middleSide
|
||||
) {
|
||||
return new UnlockedLayoutBand(
|
||||
@@ -165,20 +147,16 @@ final class UnlockedLayoutBand extends StatusBarLayoutSolver.LayoutBand {
|
||||
renderer,
|
||||
rawPlacements,
|
||||
position,
|
||||
middleAutoNearestSide,
|
||||
middleSide,
|
||||
true,
|
||||
true,
|
||||
null,
|
||||
null,
|
||||
SplitRegion.NONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void prepareForSide(AnchorSide side, String sortOrder) {
|
||||
void prepareForSide(AnchorSide side, String sortOrder) {
|
||||
if (isTextKind()) {
|
||||
placements = null;
|
||||
placedBounds = clockLayout != null ? clockLayout.bounds() : reservedBounds;
|
||||
placedBounds = clockLayout != null ? clockLayout.bounds() : null;
|
||||
return;
|
||||
}
|
||||
placements = new ArrayList<>(activePlacements());
|
||||
@@ -189,8 +167,7 @@ final class UnlockedLayoutBand extends StatusBarLayoutSolver.LayoutBand {
|
||||
placedBounds = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int width() {
|
||||
int width() {
|
||||
return Math.max(0, naturalWidth() - clipStartPx - clipEndPx);
|
||||
}
|
||||
|
||||
@@ -199,19 +176,17 @@ final class UnlockedLayoutBand extends StatusBarLayoutSolver.LayoutBand {
|
||||
if (clockLayout != null) {
|
||||
return clockLayout.width();
|
||||
}
|
||||
return reservedBounds != null ? reservedBounds.width : 0;
|
||||
return 0;
|
||||
}
|
||||
return sumWidths(activePlacements());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canClipContinuously() {
|
||||
boolean canClipContinuously() {
|
||||
return (kind == LayoutItemKind.CHIP || isTextKind())
|
||||
&& naturalWidth() > clipStartPx + clipEndPx;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean clipContinuous(AnchorSide wallSide, int amountPx) {
|
||||
boolean clipContinuous(AnchorSide wallSide, int amountPx) {
|
||||
int remaining = naturalWidth() - clipStartPx - clipEndPx;
|
||||
if (amountPx <= 0 || remaining <= 0 || !canClipContinuously()) {
|
||||
return false;
|
||||
@@ -261,23 +236,12 @@ final class UnlockedLayoutBand extends StatusBarLayoutSolver.LayoutBand {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int wallDotSlack(AnchorSide side) {
|
||||
SnapshotPlacement placement = wallPlacement(side);
|
||||
if (placement == null || !placement.overflowDot) {
|
||||
return 0;
|
||||
}
|
||||
int collisionWidth = relativeCollisionBounds(placement).width;
|
||||
int dotWidth = overflowDotVisualWidth(placement);
|
||||
return Math.max(0, (collisionWidth - dotWidth) / 2);
|
||||
}
|
||||
|
||||
int height() {
|
||||
if (isTextKind()) {
|
||||
if (clockLayout != null) {
|
||||
return clockLayout.height();
|
||||
}
|
||||
return reservedBounds != null ? reservedBounds.height : 0;
|
||||
return 0;
|
||||
}
|
||||
int height = 0;
|
||||
for (SnapshotPlacement placement : activePlacements()) {
|
||||
@@ -291,7 +255,7 @@ final class UnlockedLayoutBand extends StatusBarLayoutSolver.LayoutBand {
|
||||
if (clockLayout != null) {
|
||||
return clockLayout.top();
|
||||
}
|
||||
return reservedBounds != null ? reservedBounds.top : 0;
|
||||
return 0;
|
||||
}
|
||||
int top = Integer.MAX_VALUE;
|
||||
for (SnapshotPlacement placement : activePlacements()) {
|
||||
@@ -300,41 +264,6 @@ final class UnlockedLayoutBand extends StatusBarLayoutSolver.LayoutBand {
|
||||
return top == Integer.MAX_VALUE ? 0 : top;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shrinkOneIcon() {
|
||||
if (kind == LayoutItemKind.NOTIFICATIONS) {
|
||||
return shrinkIcon(false);
|
||||
}
|
||||
if (kind == LayoutItemKind.STATUS) {
|
||||
return shrinkIcon(true);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean removeOverflowDot() {
|
||||
if (placements == null || placements.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
ArrayList<SnapshotPlacement> withoutDot = new ArrayList<>();
|
||||
boolean removed = false;
|
||||
for (SnapshotPlacement placement : placements) {
|
||||
if (placement.overflowDot) {
|
||||
removed = true;
|
||||
} else {
|
||||
withoutDot.add(placement);
|
||||
}
|
||||
}
|
||||
if (!removed) {
|
||||
return false;
|
||||
}
|
||||
if (withoutDot.isEmpty()) {
|
||||
withoutDot.add(emptyIconContainerPlacement());
|
||||
}
|
||||
placements = withoutDot;
|
||||
return true;
|
||||
}
|
||||
|
||||
private void replaceOverflowDot(int width, int height) {
|
||||
if (placements == null) {
|
||||
placements = new ArrayList<>();
|
||||
@@ -354,29 +283,7 @@ final class UnlockedLayoutBand extends StatusBarLayoutSolver.LayoutBand {
|
||||
placements = withoutDot;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object captureState() {
|
||||
return new LayoutBandState(placements == null, new ArrayList<>(activePlacements()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void restoreState(Object state) {
|
||||
if (!(state instanceof LayoutBandState bandState)) {
|
||||
return;
|
||||
}
|
||||
placements = bandState.placementsWereNull ? null : new ArrayList<>(bandState.placements);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean createdOverflowDotSince(Object state) {
|
||||
if (!(state instanceof LayoutBandState bandState)) {
|
||||
return hasOverflowDot(activePlacements());
|
||||
}
|
||||
return !hasOverflowDot(bandState.placements) && hasOverflowDot(activePlacements());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void place(int left) {
|
||||
void place(int left) {
|
||||
if (isTextKind()) {
|
||||
placedBounds = clockLayout != null
|
||||
? clockLayout.place(left)
|
||||
@@ -441,8 +348,7 @@ final class UnlockedLayoutBand extends StatusBarLayoutSolver.LayoutBand {
|
||||
return union;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ArrayList<Bounds> collisionBoxes() {
|
||||
ArrayList<Bounds> collisionBoxes() {
|
||||
ArrayList<Bounds> boxes = new ArrayList<>();
|
||||
if (isTextKind()) {
|
||||
if (clockLayout != null) {
|
||||
@@ -455,8 +361,6 @@ final class UnlockedLayoutBand extends StatusBarLayoutSolver.LayoutBand {
|
||||
boxes.add(new Bounds(left - clipStartPx, box.top, right - left, box.height));
|
||||
}
|
||||
}
|
||||
} else if (reservedBounds != null) {
|
||||
boxes.add(new Bounds(0, reservedBounds.top, width(), reservedBounds.height));
|
||||
}
|
||||
return boxes;
|
||||
}
|
||||
@@ -486,47 +390,6 @@ final class UnlockedLayoutBand extends StatusBarLayoutSolver.LayoutBand {
|
||||
return solverBoxes;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ArrayList<Bounds> placedCollisionBounds() {
|
||||
ArrayList<Bounds> boxes = new ArrayList<>();
|
||||
int left = isTextKind() && placedBounds != null
|
||||
? placedBounds.left
|
||||
: 0;
|
||||
for (Bounds box : collisionBoxes()) {
|
||||
boxes.add(new Bounds(left + box.left, box.top, box.width, box.height));
|
||||
}
|
||||
if (kind != LayoutItemKind.CLOCK && placedBounds != null) {
|
||||
boxes.clear();
|
||||
boxes.add(placedBounds);
|
||||
}
|
||||
return boxes;
|
||||
}
|
||||
|
||||
private SnapshotPlacement wallPlacement(AnchorSide side) {
|
||||
if (isTextKind()) {
|
||||
return null;
|
||||
}
|
||||
ArrayList<SnapshotPlacement> icons = activePlacements();
|
||||
if (icons.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
boolean wallAtStart = side == AnchorSide.RIGHT;
|
||||
int index;
|
||||
if (wallAtStart) {
|
||||
index = reverseForPlacement ? icons.size() - 1 : 0;
|
||||
} else {
|
||||
index = reverseForPlacement ? 0 : icons.size() - 1;
|
||||
}
|
||||
return icons.get(index);
|
||||
}
|
||||
|
||||
private int overflowDotVisualWidth(SnapshotPlacement placement) {
|
||||
Bounds bounds = placement.bounds;
|
||||
int base = Math.max(1, Math.min(bounds.width, bounds.height));
|
||||
int radius = Math.max(1, Math.round(base * 0.125f));
|
||||
return Math.min(bounds.width, radius * 2);
|
||||
}
|
||||
|
||||
private Bounds collisionBounds(SnapshotPlacement placement) {
|
||||
Bounds relative = relativeCollisionBounds(placement);
|
||||
Bounds bounds = placement.bounds;
|
||||
@@ -547,38 +410,6 @@ final class UnlockedLayoutBand extends StatusBarLayoutSolver.LayoutBand {
|
||||
return new Bounds(0, 0, bounds.width, bounds.height);
|
||||
}
|
||||
|
||||
private boolean shrinkIcon(boolean fromStart) {
|
||||
ArrayList<SnapshotPlacement> icons = new ArrayList<>(activePlacements());
|
||||
int removeIndex = nonDotIndex(icons, fromStart);
|
||||
if (removeIndex < 0) {
|
||||
return false;
|
||||
}
|
||||
boolean hadDot = hasOverflowDot(icons);
|
||||
icons.remove(removeIndex);
|
||||
if (showDotIfTruncated && !hadDot) {
|
||||
SnapshotPlacement dot = dotPlacement(dotWidth(icons), dotHeight(icons), rowTop(icons));
|
||||
if (fromStart) {
|
||||
icons.add(0, dot);
|
||||
} else {
|
||||
icons.add(dot);
|
||||
}
|
||||
}
|
||||
placements = icons;
|
||||
return true;
|
||||
}
|
||||
|
||||
private int nonDotIndex(ArrayList<SnapshotPlacement> icons, boolean fromStart) {
|
||||
int start = fromStart ? 0 : icons.size() - 1;
|
||||
int end = fromStart ? icons.size() : -1;
|
||||
int step = fromStart ? 1 : -1;
|
||||
for (int i = start; i != end; i += step) {
|
||||
if (isShrinkableIcon(icons.get(i))) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private boolean isShrinkableIcon(SnapshotPlacement placement) {
|
||||
return placement != null
|
||||
&& !placement.overflowDot
|
||||
@@ -612,15 +443,6 @@ final class UnlockedLayoutBand extends StatusBarLayoutSolver.LayoutBand {
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean hasOverflowDot(ArrayList<SnapshotPlacement> icons) {
|
||||
for (SnapshotPlacement icon : icons) {
|
||||
if (icon.overflowDot) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private ArrayList<SnapshotPlacement> activePlacements() {
|
||||
if (placements != null) {
|
||||
return placements;
|
||||
@@ -884,10 +706,4 @@ final class UnlockedLayoutBand extends StatusBarLayoutSolver.LayoutBand {
|
||||
return kind == LayoutItemKind.CLOCK || kind == LayoutItemKind.CARRIER;
|
||||
}
|
||||
|
||||
private static AnchorSide sideFor(String value) {
|
||||
return "right".equals(value) ? AnchorSide.RIGHT : AnchorSide.LEFT;
|
||||
}
|
||||
|
||||
private record LayoutBandState(boolean placementsWereNull, ArrayList<SnapshotPlacement> placements) {
|
||||
}
|
||||
}
|
||||
|
||||
+65
-70
@@ -12,16 +12,15 @@ import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import se.ajpanton.statusbartweak.R;
|
||||
import se.ajpanton.statusbartweak.runtime.layoutsolver.StatusBarLayoutSolver;
|
||||
import se.ajpanton.statusbartweak.runtime.layoutsolver.StatusBarLayoutSolver.AnchorSide;
|
||||
import se.ajpanton.statusbartweak.runtime.layoutsolver.StatusBarLayoutSolver.Bounds;
|
||||
import se.ajpanton.statusbartweak.runtime.layoutsolver.StatusBarLayoutSolver.LayoutEdges;
|
||||
import se.ajpanton.statusbartweak.runtime.layoutsolver.StatusBarLayoutSolver.LayoutItemKind;
|
||||
import se.ajpanton.statusbartweak.runtime.layoutsolver.StatusBarLayoutSolver.LayoutPosition;
|
||||
import se.ajpanton.statusbartweak.runtime.layoutsolver.StatusBarLayoutSolver.SplitRegion;
|
||||
import se.ajpanton.statusbartweak.runtime.layoutsolver.PackedStatusBarLayoutSolver;
|
||||
import se.ajpanton.statusbartweak.runtime.mode.NotificationDisplayStyle;
|
||||
import se.ajpanton.statusbartweak.runtime.mode.SceneKey;
|
||||
import se.ajpanton.statusbartweak.runtime.notifications.NotificationUnreadTracker;
|
||||
import se.ajpanton.statusbartweak.shell.settings.SbtSettings;
|
||||
|
||||
final class UnlockedLayoutPlanner {
|
||||
@@ -83,7 +82,7 @@ final class UnlockedLayoutPlanner {
|
||||
? aodStatusContentBounds(root, aodStatusAnchorBounds)
|
||||
: null;
|
||||
Bounds aodNotificationBounds = scene != null && scene.isAod()
|
||||
? aodNotificationBounds(root, anchors, scene)
|
||||
? aodNotificationBounds(root, scene)
|
||||
: null;
|
||||
Bounds aodStatusbarBounds = scene != null && scene.isAod()
|
||||
? aodStatusbarBounds(root, settings, aodNotificationBounds, aodStatusAnchorBounds)
|
||||
@@ -94,7 +93,7 @@ final class UnlockedLayoutPlanner {
|
||||
clockHost,
|
||||
clockLayout,
|
||||
positionFor(settings.clockPosition),
|
||||
settings));
|
||||
sideFor(settings.clockMiddleCutoutSide)));
|
||||
}
|
||||
ClockLayout carrierLayout = carrierLayout(root, collectedIcons, settings, scene);
|
||||
if (carrierLayout != null && carrierLayout.width() > 0) {
|
||||
@@ -102,7 +101,6 @@ final class UnlockedLayoutPlanner {
|
||||
carrierHost,
|
||||
carrierLayout,
|
||||
positionFor(settings.layoutCarrierPosition),
|
||||
settings.layoutCarrierMiddleAutoNearestSide,
|
||||
sideFor(settings.layoutCarrierMiddleSide)));
|
||||
}
|
||||
int statusCount = statusCountForScene(settings, scene);
|
||||
@@ -123,7 +121,6 @@ final class UnlockedLayoutPlanner {
|
||||
iconHeightPx(statusbarHeight, statusIconHeightSteps(settings, scene)));
|
||||
String[] positions = statusPositionsForScene(settings, scene);
|
||||
String[] middleSides = statusMiddleSidesForScene(settings, scene);
|
||||
boolean[] autoNearest = statusAutoNearestForScene(settings, scene);
|
||||
int[] verticalOffsets = statusVerticalOffsetsForScene(settings, scene);
|
||||
int statusHeightSteps = statusIconHeightSteps(settings, scene);
|
||||
for (int i = 0; i < statusCount; i++) {
|
||||
@@ -148,12 +145,7 @@ final class UnlockedLayoutPlanner {
|
||||
statusRenderer,
|
||||
placements,
|
||||
positionFor(stringAt(positions, i, settings.layoutStatusPosition)),
|
||||
booleanAt(
|
||||
autoNearest,
|
||||
i,
|
||||
settings.layoutStatusMiddleAutoNearestSide),
|
||||
sideFor(stringAt(middleSides, i, settings.layoutStatusMiddleSide)),
|
||||
true)
|
||||
sideFor(stringAt(middleSides, i, settings.layoutStatusMiddleSide)))
|
||||
.withSolverCollision(
|
||||
logicalRowTop(statusHeightSteps, verticalOffsetSteps),
|
||||
statusHeightSteps));
|
||||
@@ -168,15 +160,19 @@ final class UnlockedLayoutPlanner {
|
||||
notificationSeenAppReporter.report(
|
||||
root != null ? root.getContext() : null,
|
||||
unfilteredPlacements);
|
||||
ArrayList<SnapshotPlacement> filteredPlacements =
|
||||
SnapshotIconFilter.notificationPlacements(unfilteredPlacements, settings, scene);
|
||||
if (isDotNotificationScene(scene)) {
|
||||
filteredPlacements = unreadNotificationPlacements(filteredPlacements);
|
||||
}
|
||||
ArrayList<SnapshotPlacement> rawPlacements = resizePlacementsToHeight(
|
||||
SnapshotIconFilter.notificationPlacements(unfilteredPlacements, settings, scene),
|
||||
filteredPlacements,
|
||||
iconHeightPx(statusbarHeight, notificationIconHeightSteps(settings, scene)));
|
||||
notificationRowBounds = placementBounds(rawPlacements);
|
||||
boolean dotNotificationScene = isDotNotificationScene(scene);
|
||||
notificationCount = dotNotificationScene && !rawPlacements.isEmpty() ? 1 : notificationCount;
|
||||
String[] positions = notificationPositionsForScene(settings, scene);
|
||||
String[] middleSides = notificationMiddleSidesForScene(settings, scene);
|
||||
boolean[] autoNearest = notificationAutoNearestForScene(settings, scene);
|
||||
int[] verticalOffsets = notificationVerticalOffsetsForScene(settings, scene);
|
||||
int notificationHeightSteps = notificationIconHeightSteps(settings, scene);
|
||||
for (int i = 0; i < notificationCount; i++) {
|
||||
@@ -195,10 +191,6 @@ final class UnlockedLayoutPlanner {
|
||||
stepsToPx(verticalOffsetSteps, statusbarHeight));
|
||||
if (!placements.isEmpty()) {
|
||||
LayoutPosition position = positionFor(stringAt(positions, i, settings.layoutNotifPosition));
|
||||
boolean middleAutoNearest = booleanAt(
|
||||
autoNearest,
|
||||
i,
|
||||
settings.layoutNotifMiddleAutoNearestSide);
|
||||
AnchorSide middleSide = sideFor(stringAt(middleSides, i, settings.layoutNotifMiddleSide));
|
||||
bands.add(dotNotificationScene
|
||||
? UnlockedLayoutBand.dotIcons(
|
||||
@@ -207,7 +199,6 @@ final class UnlockedLayoutPlanner {
|
||||
notificationRenderer,
|
||||
placements,
|
||||
position,
|
||||
middleAutoNearest,
|
||||
middleSide)
|
||||
.withSolverCollision(
|
||||
logicalRowTop(notificationHeightSteps, verticalOffsetSteps),
|
||||
@@ -218,9 +209,7 @@ final class UnlockedLayoutPlanner {
|
||||
notificationRenderer,
|
||||
placements,
|
||||
position,
|
||||
middleAutoNearest,
|
||||
middleSide,
|
||||
true)
|
||||
middleSide)
|
||||
.withSolverCollision(
|
||||
logicalRowTop(notificationHeightSteps, verticalOffsetSteps),
|
||||
notificationHeightSteps));
|
||||
@@ -254,9 +243,7 @@ final class UnlockedLayoutPlanner {
|
||||
chipRenderer,
|
||||
placements,
|
||||
positionFor(settings.layoutChipPosition),
|
||||
settings.layoutChipMiddleAutoNearestSide,
|
||||
sideFor(settings.layoutChipMiddleSide),
|
||||
false)
|
||||
sideFor(settings.layoutChipMiddleSide))
|
||||
.withSolverCollision(
|
||||
logicalRowTop(
|
||||
settings.layoutChipHeightSteps,
|
||||
@@ -265,7 +252,7 @@ final class UnlockedLayoutPlanner {
|
||||
}
|
||||
}
|
||||
if (bands.isEmpty()) {
|
||||
return new LayoutPlan(null, new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
|
||||
return new LayoutPlan(null, new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), null);
|
||||
}
|
||||
ArrayList<LayoutItemKind> itemOrder = orderedKinds(settings.layoutItemOrder);
|
||||
splitClockIfNeeded(root, bands, itemOrder, clockCutoutBounds, settings);
|
||||
@@ -540,10 +527,6 @@ final class UnlockedLayoutPlanner {
|
||||
: fallback;
|
||||
}
|
||||
|
||||
private boolean booleanAt(boolean[] values, int index, boolean fallback) {
|
||||
return values != null && index >= 0 && index < values.length ? values[index] : fallback;
|
||||
}
|
||||
|
||||
private int intAt(int[] values, int index, int fallback) {
|
||||
return values != null && index >= 0 && index < values.length ? values[index] : fallback;
|
||||
}
|
||||
@@ -726,6 +709,21 @@ final class UnlockedLayoutPlanner {
|
||||
&& scene.notificationDisplayStyle() == NotificationDisplayStyle.DOT;
|
||||
}
|
||||
|
||||
private ArrayList<SnapshotPlacement> unreadNotificationPlacements(
|
||||
ArrayList<SnapshotPlacement> placements
|
||||
) {
|
||||
if (placements == null || placements.isEmpty()) {
|
||||
return placements != null ? placements : new ArrayList<>();
|
||||
}
|
||||
ArrayList<SnapshotPlacement> unread = new ArrayList<>(placements.size());
|
||||
for (SnapshotPlacement placement : placements) {
|
||||
if (placement != null && NotificationUnreadTracker.isUnread(placement.key)) {
|
||||
unread.add(placement);
|
||||
}
|
||||
}
|
||||
return unread;
|
||||
}
|
||||
|
||||
private String[] statusPositionsForScene(SbtSettings settings, SceneKey scene) {
|
||||
if (scene != null && scene.isLockscreen()) {
|
||||
return settings.layoutStatusLockPositions;
|
||||
@@ -746,16 +744,6 @@ final class UnlockedLayoutPlanner {
|
||||
return settings.layoutStatusMiddleSides;
|
||||
}
|
||||
|
||||
private boolean[] statusAutoNearestForScene(SbtSettings settings, SceneKey scene) {
|
||||
if (scene != null && scene.isLockscreen()) {
|
||||
return settings.layoutStatusLockMiddleAutoNearestSides;
|
||||
}
|
||||
if (scene != null && scene.isAod()) {
|
||||
return settings.layoutStatusAodMiddleAutoNearestSides;
|
||||
}
|
||||
return settings.layoutStatusMiddleAutoNearestSides;
|
||||
}
|
||||
|
||||
private int[] statusVerticalOffsetsForScene(SbtSettings settings, SceneKey scene) {
|
||||
if (scene != null && scene.isLockscreen()) {
|
||||
return settings.layoutStatusLockVerticalOffsetsPx;
|
||||
@@ -786,16 +774,6 @@ final class UnlockedLayoutPlanner {
|
||||
return settings.layoutNotifMiddleSides;
|
||||
}
|
||||
|
||||
private boolean[] notificationAutoNearestForScene(SbtSettings settings, SceneKey scene) {
|
||||
if (scene != null && scene.isLockscreen()) {
|
||||
return settings.layoutNotifLockMiddleAutoNearestSides;
|
||||
}
|
||||
if (scene != null && scene.isAod()) {
|
||||
return settings.layoutNotifAodMiddleAutoNearestSides;
|
||||
}
|
||||
return settings.layoutNotifMiddleAutoNearestSides;
|
||||
}
|
||||
|
||||
private int[] notificationVerticalOffsetsForScene(SbtSettings settings, SceneKey scene) {
|
||||
if (scene != null && scene.isLockscreen()) {
|
||||
return settings.layoutNotifLockVerticalOffsetsPx;
|
||||
@@ -1119,21 +1097,11 @@ final class UnlockedLayoutPlanner {
|
||||
private ArrayList<SnapshotPlacement> bottomAlignAodPlacements(
|
||||
ArrayList<SnapshotPlacement> placements,
|
||||
Bounds aodStatusbarBounds
|
||||
) {
|
||||
return bottomAlignAodPlacements(placements, aodStatusbarBounds, 0);
|
||||
}
|
||||
|
||||
private ArrayList<SnapshotPlacement> bottomAlignAodPlacements(
|
||||
ArrayList<SnapshotPlacement> placements,
|
||||
Bounds aodStatusbarBounds,
|
||||
int bottomInsetPx
|
||||
) {
|
||||
if (placements == null || placements.isEmpty() || aodStatusbarBounds == null) {
|
||||
return placements;
|
||||
}
|
||||
int bottom = aodStatusbarBounds.top
|
||||
+ aodStatusbarBounds.height
|
||||
- Math.max(0, bottomInsetPx);
|
||||
int bottom = aodStatusbarBounds.top + aodStatusbarBounds.height;
|
||||
ArrayList<SnapshotPlacement> result = new ArrayList<>();
|
||||
for (SnapshotPlacement placement : placements) {
|
||||
Bounds bounds = placement.bounds;
|
||||
@@ -1198,7 +1166,7 @@ final class UnlockedLayoutPlanner {
|
||||
if (root == null || cutoutBounds == null || bands == null || settings == null) {
|
||||
return;
|
||||
}
|
||||
ArrayList<UnlockedLayoutBand> middleBands = StatusBarLayoutSolver.bandsForPosition(
|
||||
ArrayList<UnlockedLayoutBand> middleBands = bandsForPosition(
|
||||
bands,
|
||||
LayoutPosition.MIDDLE,
|
||||
itemOrder);
|
||||
@@ -1215,7 +1183,7 @@ final class UnlockedLayoutPlanner {
|
||||
root.getWidth(),
|
||||
cutoutBounds,
|
||||
settings.clockMiddleAutoNearestSide,
|
||||
sideFor(settings.clockMiddleCutoutSide));
|
||||
clockBand.middleSide);
|
||||
if (splitLayouts.size() < 2) {
|
||||
return;
|
||||
}
|
||||
@@ -1224,8 +1192,34 @@ final class UnlockedLayoutPlanner {
|
||||
return;
|
||||
}
|
||||
bands.remove(index);
|
||||
bands.add(index, UnlockedLayoutBand.fixedClock(clockBand.host, splitLayouts.get(1), SplitRegion.RIGHT, settings));
|
||||
bands.add(index, UnlockedLayoutBand.fixedClock(clockBand.host, splitLayouts.get(0), SplitRegion.LEFT, settings));
|
||||
bands.add(index, UnlockedLayoutBand.fixedClock(
|
||||
clockBand.host,
|
||||
splitLayouts.get(1),
|
||||
SplitRegion.RIGHT,
|
||||
clockBand.middleSide));
|
||||
bands.add(index, UnlockedLayoutBand.fixedClock(
|
||||
clockBand.host,
|
||||
splitLayouts.get(0),
|
||||
SplitRegion.LEFT,
|
||||
clockBand.middleSide));
|
||||
}
|
||||
|
||||
private ArrayList<UnlockedLayoutBand> bandsForPosition(
|
||||
ArrayList<UnlockedLayoutBand> bands,
|
||||
LayoutPosition position,
|
||||
ArrayList<LayoutItemKind> itemOrder
|
||||
) {
|
||||
ArrayList<UnlockedLayoutBand> result = new ArrayList<>();
|
||||
for (LayoutItemKind kind : itemOrder) {
|
||||
for (UnlockedLayoutBand band : bands) {
|
||||
if (band.kind == kind
|
||||
&& band.position == position
|
||||
&& band.splitRegion == SplitRegion.NONE) {
|
||||
result.add(band);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private LayoutEdges layoutEdges(
|
||||
@@ -1240,7 +1234,6 @@ final class UnlockedLayoutPlanner {
|
||||
LayoutEdges aodEdges = aodBurnInEdges(
|
||||
root,
|
||||
settings,
|
||||
anchors,
|
||||
scene,
|
||||
rootWidth,
|
||||
aodStatusAnchorBounds);
|
||||
@@ -1295,7 +1288,6 @@ final class UnlockedLayoutPlanner {
|
||||
private LayoutEdges aodBurnInEdges(
|
||||
View root,
|
||||
SbtSettings settings,
|
||||
RootAnchors anchors,
|
||||
SceneKey scene,
|
||||
int rootWidth,
|
||||
Bounds statusBounds
|
||||
@@ -1303,7 +1295,7 @@ final class UnlockedLayoutPlanner {
|
||||
if (root == null || settings == null || rootWidth <= 0) {
|
||||
return null;
|
||||
}
|
||||
Bounds notificationBounds = aodNotificationBounds(root, anchors, scene);
|
||||
Bounds notificationBounds = aodNotificationBounds(root, scene);
|
||||
Bounds bounds = aodStatusbarBounds(root, settings, notificationBounds, statusBounds);
|
||||
if (bounds == null) {
|
||||
return null;
|
||||
@@ -1350,7 +1342,7 @@ final class UnlockedLayoutPlanner {
|
||||
if (root == null || root.getWidth() <= 0) {
|
||||
return null;
|
||||
}
|
||||
Bounds notificationBounds = aodNotificationBounds(root, anchors, scene);
|
||||
Bounds notificationBounds = aodNotificationBounds(root, scene);
|
||||
Bounds liveMovingStatusBounds = AodLiveStatusbarSource.movingBoundsForRoot(root);
|
||||
Bounds storedStatusBounds = AodStatusbarSourceStore.statusBoundsForRoot(
|
||||
root,
|
||||
@@ -1404,7 +1396,7 @@ final class UnlockedLayoutPlanner {
|
||||
liveMovingStatusBounds.height);
|
||||
}
|
||||
|
||||
private Bounds aodNotificationBounds(View root, RootAnchors anchors, SceneKey scene) {
|
||||
private Bounds aodNotificationBounds(View root, SceneKey scene) {
|
||||
if (scene != null
|
||||
&& scene.notificationDisplayStyle() == NotificationDisplayStyle.CARDS) {
|
||||
return null;
|
||||
@@ -1626,6 +1618,9 @@ final class UnlockedLayoutPlanner {
|
||||
return null;
|
||||
}
|
||||
|
||||
private record LayoutEdges(int left, int right) {
|
||||
}
|
||||
|
||||
private record StockInsets(int left, int right) {
|
||||
}
|
||||
}
|
||||
|
||||
+30
-36
@@ -15,11 +15,14 @@ import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import se.ajpanton.statusbartweak.runtime.NotificationKeyReflection;
|
||||
import se.ajpanton.statusbartweak.runtime.ViewIdNames;
|
||||
import se.ajpanton.statusbartweak.runtime.hooks.ReflectionSupport;
|
||||
import se.ajpanton.statusbartweak.runtime.layoutsolver.StatusBarLayoutSolver.Bounds;
|
||||
import se.ajpanton.statusbartweak.runtime.mode.NotificationDisplayStyle;
|
||||
import se.ajpanton.statusbartweak.runtime.mode.SceneKey;
|
||||
import se.ajpanton.statusbartweak.runtime.notifications.NotificationActiveKeyStore;
|
||||
import se.ajpanton.statusbartweak.runtime.notifications.NotificationUnreadTracker;
|
||||
import se.ajpanton.statusbartweak.shell.settings.SbtSettings;
|
||||
|
||||
final class UnlockedStockSourceCollector {
|
||||
@@ -76,6 +79,12 @@ final class UnlockedStockSourceCollector {
|
||||
|| scene.notificationDisplayStyle() == NotificationDisplayStyle.DOT) {
|
||||
notificationIcons.addAll(
|
||||
LockscreenCardsNotificationIconSourceStore.snapshotSourcesForAodIconsRoot(root));
|
||||
if (notificationIcons.isEmpty()
|
||||
&& scene.notificationDisplayStyle() == NotificationDisplayStyle.DOT) {
|
||||
notificationIcons.addAll(
|
||||
LockscreenCardsNotificationIconSourceStore
|
||||
.snapshotAodNotificationPackageSources(root));
|
||||
}
|
||||
}
|
||||
} else if (anchors.notificationRoot != null) {
|
||||
collectNotificationSnapshotViews(anchors.notificationRoot, notificationIcons);
|
||||
@@ -178,6 +187,16 @@ final class UnlockedStockSourceCollector {
|
||||
statusSourceSignature = 31 * statusSourceSignature
|
||||
+ aodLayoutAnchorSignature(root, anchors, scene);
|
||||
}
|
||||
int notificationSourceSignature = sourceLayoutListSignature(
|
||||
previousIcons != null ? previousIcons.notificationIcons : null);
|
||||
notificationSourceSignature = 31 * notificationSourceSignature
|
||||
+ NotificationActiveKeyStore.generation();
|
||||
if (scene != null
|
||||
&& (scene.isAod() || scene.isLockscreen())
|
||||
&& scene.notificationDisplayStyle() == NotificationDisplayStyle.DOT) {
|
||||
notificationSourceSignature = 31 * notificationSourceSignature
|
||||
+ NotificationUnreadTracker.generation();
|
||||
}
|
||||
return new LayoutInputSignature(
|
||||
scene != null ? scene.toString() : "",
|
||||
root.getWidth(),
|
||||
@@ -188,7 +207,7 @@ final class UnlockedStockSourceCollector {
|
||||
cutout != null ? cutout.top : Integer.MIN_VALUE,
|
||||
cutout != null ? cutout.right : Integer.MIN_VALUE,
|
||||
cutout != null ? cutout.bottom : Integer.MIN_VALUE,
|
||||
loggingAwareSettingsSignature(root, settings),
|
||||
layoutSettingsSignature(settings),
|
||||
clockTimeSignature(settings),
|
||||
viewSignatureOrZero(anchors != null ? anchors.clockView : null),
|
||||
shallowTreeSignatureExcluding(anchors != null ? anchors.clockContainer : null, null),
|
||||
@@ -207,7 +226,7 @@ final class UnlockedStockSourceCollector {
|
||||
notificationRootSignature(anchors != null ? anchors.notificationRoot : null),
|
||||
viewSignatureOrZero(anchors != null ? anchors.carrierView : null),
|
||||
statusSourceSignature,
|
||||
sourceLayoutListSignature(previousIcons != null ? previousIcons.notificationIcons : null),
|
||||
notificationSourceSignature,
|
||||
chipSourceSignature);
|
||||
}
|
||||
|
||||
@@ -682,7 +701,13 @@ final class UnlockedStockSourceCollector {
|
||||
|
||||
private void collectNotificationSnapshotViews(View source, ArrayList<SnapshotSource> out) {
|
||||
if (isNotificationSnapshotCandidate(source)) {
|
||||
out.add(new SnapshotSource(source, SnapshotMode.NOTIFICATION_DRAWABLE));
|
||||
String key = NotificationKeyReflection.keyForIconView(source);
|
||||
if (key != null
|
||||
&& NotificationActiveKeyStore.hasSnapshot()
|
||||
&& !NotificationActiveKeyStore.isActive(key)) {
|
||||
return;
|
||||
}
|
||||
out.add(new SnapshotSource(source, SnapshotMode.NOTIFICATION_DRAWABLE, key));
|
||||
return;
|
||||
}
|
||||
if (source instanceof ViewGroup group) {
|
||||
@@ -967,22 +992,7 @@ final class UnlockedStockSourceCollector {
|
||||
if (view == null) {
|
||||
return 0;
|
||||
}
|
||||
int result = 17;
|
||||
result = 31 * result + System.identityHashCode(view);
|
||||
result = 31 * result + view.getClass().getName().hashCode();
|
||||
result = 31 * result + view.getId();
|
||||
result = 31 * result + view.getVisibility();
|
||||
if (view instanceof ViewGroup group) {
|
||||
result = 31 * result + group.getChildCount();
|
||||
for (int i = 0; i < group.getChildCount(); i++) {
|
||||
View child = group.getChildAt(i);
|
||||
result = 31 * result + System.identityHashCode(child);
|
||||
result = 31 * result + child.getClass().getName().hashCode();
|
||||
result = 31 * result + child.getId();
|
||||
result = 31 * result + child.getVisibility();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
return sourceLayoutSignature(view);
|
||||
}
|
||||
|
||||
private static int sourceLayoutListSignature(ArrayList<SnapshotSource> sources) {
|
||||
@@ -1007,6 +1017,7 @@ final class UnlockedStockSourceCollector {
|
||||
int result = 17;
|
||||
result = 31 * result + System.identityHashCode(view);
|
||||
result = 31 * result + view.getClass().getName().hashCode();
|
||||
result = 31 * result + (view.isAttachedToWindow() ? 1 : 0);
|
||||
result = 31 * result + view.getId();
|
||||
result = 31 * result + view.getVisibility();
|
||||
result = 31 * result + width;
|
||||
@@ -1207,12 +1218,10 @@ final class UnlockedStockSourceCollector {
|
||||
settings.layoutCarrierPosition,
|
||||
settings.layoutCarrierEnabledLockscreen,
|
||||
settings.layoutCarrierMiddleSide,
|
||||
settings.layoutCarrierMiddleAutoNearestSide,
|
||||
settings.layoutCarrierVerticalOffsetPx,
|
||||
settings.layoutChipPosition,
|
||||
settings.layoutChipEnabledUnlocked,
|
||||
settings.layoutChipMiddleSide,
|
||||
settings.layoutChipMiddleAutoNearestSide,
|
||||
settings.layoutChipVerticalOffsetPx,
|
||||
settings.layoutChipHeightSteps,
|
||||
settings.layoutNotifPosition,
|
||||
@@ -1221,44 +1230,36 @@ final class UnlockedStockSourceCollector {
|
||||
settings.layoutNotifUnlockedCount,
|
||||
Arrays.hashCode(settings.layoutNotifPositions),
|
||||
Arrays.hashCode(settings.layoutNotifMiddleSides),
|
||||
Arrays.hashCode(settings.layoutNotifMiddleAutoNearestSides),
|
||||
Arrays.hashCode(settings.layoutNotifVerticalOffsetsPx),
|
||||
settings.layoutNotifEnabledLockscreen,
|
||||
settings.layoutNotifLockCount,
|
||||
Arrays.hashCode(settings.layoutNotifLockPositions),
|
||||
Arrays.hashCode(settings.layoutNotifLockMiddleSides),
|
||||
Arrays.hashCode(settings.layoutNotifLockMiddleAutoNearestSides),
|
||||
Arrays.hashCode(settings.layoutNotifLockVerticalOffsetsPx),
|
||||
settings.layoutNotifEnabledAod,
|
||||
settings.layoutNotifAodCount,
|
||||
Arrays.hashCode(settings.layoutNotifAodPositions),
|
||||
Arrays.hashCode(settings.layoutNotifAodMiddleSides),
|
||||
Arrays.hashCode(settings.layoutNotifAodMiddleAutoNearestSides),
|
||||
Arrays.hashCode(settings.layoutNotifAodVerticalOffsetsPx),
|
||||
settings.layoutNotifMiddleSide,
|
||||
settings.layoutNotifMiddleAutoNearestSide,
|
||||
settings.layoutNotifVerticalOffsetPx,
|
||||
settings.layoutStatusPosition,
|
||||
settings.layoutStatusEnabledUnlocked,
|
||||
settings.layoutStatusUnlockedCount,
|
||||
Arrays.hashCode(settings.layoutStatusPositions),
|
||||
Arrays.hashCode(settings.layoutStatusMiddleSides),
|
||||
Arrays.hashCode(settings.layoutStatusMiddleAutoNearestSides),
|
||||
Arrays.hashCode(settings.layoutStatusVerticalOffsetsPx),
|
||||
settings.layoutStatusEnabledLockscreen,
|
||||
settings.layoutStatusLockCount,
|
||||
Arrays.hashCode(settings.layoutStatusLockPositions),
|
||||
Arrays.hashCode(settings.layoutStatusLockMiddleSides),
|
||||
Arrays.hashCode(settings.layoutStatusLockMiddleAutoNearestSides),
|
||||
Arrays.hashCode(settings.layoutStatusLockVerticalOffsetsPx),
|
||||
settings.layoutStatusEnabledAod,
|
||||
settings.layoutStatusAodCount,
|
||||
Arrays.hashCode(settings.layoutStatusAodPositions),
|
||||
Arrays.hashCode(settings.layoutStatusAodMiddleSides),
|
||||
Arrays.hashCode(settings.layoutStatusAodMiddleAutoNearestSides),
|
||||
Arrays.hashCode(settings.layoutStatusAodVerticalOffsetsPx),
|
||||
settings.layoutStatusMiddleSide,
|
||||
settings.layoutStatusMiddleAutoNearestSide,
|
||||
settings.layoutStatusVerticalOffsetPx,
|
||||
settings.systemIconBlockedModes,
|
||||
settings.appIconBlockedModes,
|
||||
@@ -1269,11 +1270,4 @@ final class UnlockedStockSourceCollector {
|
||||
settings.statusChipsHideCallUnlocked);
|
||||
}
|
||||
|
||||
private int loggingAwareSettingsSignature(View root, SbtSettings settings) {
|
||||
int result = layoutSettingsSignature(settings);
|
||||
boolean logsEnabled = root != null
|
||||
&& root.getContext() != null
|
||||
&& SbtSettings.isDebugLogWritingEnabled(root.getContext());
|
||||
return 31 * result + (logsEnabled ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,24 +107,19 @@ public final class SbtDefaults {
|
||||
public static final String LAYOUT_CARRIER_POSITION_DEFAULT = "left";
|
||||
public static final boolean LAYOUT_CARRIER_ENABLED_LOCKSCREEN_DEFAULT = true;
|
||||
public static final String LAYOUT_CARRIER_MIDDLE_SIDE_DEFAULT = "left";
|
||||
public static final boolean LAYOUT_CARRIER_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT = true;
|
||||
public static final int LAYOUT_CARRIER_VERTICAL_OFFSET_PX_DEFAULT = 0;
|
||||
public static final String LAYOUT_CHIP_POSITION_DEFAULT = "left";
|
||||
public static final boolean LAYOUT_CHIP_ENABLED_LOCKSCREEN_DEFAULT = true;
|
||||
public static final boolean LAYOUT_CHIP_ENABLED_UNLOCKED_DEFAULT = true;
|
||||
public static final String LAYOUT_CHIP_MIDDLE_SIDE_DEFAULT = "left";
|
||||
public static final boolean LAYOUT_CHIP_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT = true;
|
||||
public static final int LAYOUT_CHIP_VERTICAL_OFFSET_PX_DEFAULT = 0;
|
||||
public static final int LAYOUT_CHIP_HEIGHT_STEPS_DEFAULT = 52;
|
||||
public static final String LAYOUT_NOTIF_POSITION_DEFAULT = "left";
|
||||
public static final String LAYOUT_NOTIF_SORT_ORDER_DEFAULT = "automatic";
|
||||
public static final boolean LAYOUT_NOTIF_SHOW_DOT_IF_TRUNCATED_DEFAULT = true;
|
||||
public static final boolean LAYOUT_NOTIF_ENABLED_AOD_DEFAULT = true;
|
||||
public static final boolean LAYOUT_NOTIF_ENABLED_LOCKSCREEN_DEFAULT = true;
|
||||
public static final boolean LAYOUT_NOTIF_ENABLED_UNLOCKED_DEFAULT = true;
|
||||
public static final int LAYOUT_NOTIF_UNLOCKED_COUNT_DEFAULT = 1;
|
||||
public static final String LAYOUT_NOTIF_MIDDLE_SIDE_DEFAULT = "left";
|
||||
public static final boolean LAYOUT_NOTIF_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT = true;
|
||||
public static final int LAYOUT_NOTIF_VERTICAL_OFFSET_PX_DEFAULT = 0;
|
||||
public static final int LAYOUT_NOTIF_ICON_HEIGHT_STEPS_DEFAULT = 46;
|
||||
public static final int LAYOUT_NOTIF_LOCK_ICON_HEIGHT_STEPS_DEFAULT = 46;
|
||||
@@ -136,9 +131,7 @@ public final class SbtDefaults {
|
||||
public static final boolean LAYOUT_STATUS_ENABLED_LOCKSCREEN_DEFAULT = true;
|
||||
public static final boolean LAYOUT_STATUS_ENABLED_UNLOCKED_DEFAULT = true;
|
||||
public static final int LAYOUT_STATUS_UNLOCKED_COUNT_DEFAULT = 1;
|
||||
public static final boolean LAYOUT_STATUS_SHOW_DOT_IF_TRUNCATED_DEFAULT = true;
|
||||
public static final String LAYOUT_STATUS_MIDDLE_SIDE_DEFAULT = "left";
|
||||
public static final boolean LAYOUT_STATUS_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT = true;
|
||||
public static final int LAYOUT_STATUS_VERTICAL_OFFSET_PX_DEFAULT = 0;
|
||||
public static final int LAYOUT_STATUS_ICON_HEIGHT_STEPS_DEFAULT = 38;
|
||||
public static final int LAYOUT_ICON_HEIGHT_STEPS_MIN = 10;
|
||||
|
||||
@@ -103,18 +103,14 @@ public final class SbtSettings {
|
||||
public static final String KEY_LAYOUT_CARRIER_POSITION = "layout_carrier_position";
|
||||
public static final String KEY_LAYOUT_CARRIER_ENABLED_LOCKSCREEN = "layout_carrier_enabled_lockscreen";
|
||||
public static final String KEY_LAYOUT_CARRIER_MIDDLE_SIDE = "layout_carrier_middle_side";
|
||||
public static final String KEY_LAYOUT_CARRIER_MIDDLE_AUTO_NEAREST_SIDE = "layout_carrier_middle_auto_nearest_side";
|
||||
public static final String KEY_LAYOUT_CARRIER_VERTICAL_OFFSET_PX = "layout_carrier_vertical_offset_px";
|
||||
public static final String KEY_LAYOUT_CHIP_POSITION = "layout_chip_position";
|
||||
public static final String KEY_LAYOUT_CHIP_ENABLED_LOCKSCREEN = "layout_chip_enabled_lockscreen";
|
||||
public static final String KEY_LAYOUT_CHIP_ENABLED_UNLOCKED = "layout_chip_enabled_unlocked";
|
||||
public static final String KEY_LAYOUT_CHIP_MIDDLE_SIDE = "layout_chip_middle_side";
|
||||
public static final String KEY_LAYOUT_CHIP_MIDDLE_AUTO_NEAREST_SIDE = "layout_chip_middle_auto_nearest_side";
|
||||
public static final String KEY_LAYOUT_CHIP_VERTICAL_OFFSET_PX = "layout_chip_vertical_offset_px";
|
||||
public static final String KEY_LAYOUT_CHIP_HEIGHT_STEPS = "layout_chip_height_steps";
|
||||
public static final String KEY_LAYOUT_NOTIF_POSITION = "layout_notif_position";
|
||||
public static final String KEY_LAYOUT_NOTIF_SORT_ORDER = "layout_notif_sort_order";
|
||||
public static final String KEY_LAYOUT_NOTIF_SHOW_DOT_IF_TRUNCATED = "layout_notif_show_dot_if_truncated";
|
||||
public static final String KEY_LAYOUT_NOTIF_ENABLED_AOD = "layout_notif_enabled_aod";
|
||||
public static final String KEY_LAYOUT_NOTIF_ENABLED_LOCKSCREEN = "layout_notif_enabled_lockscreen";
|
||||
public static final String KEY_LAYOUT_NOTIF_ENABLED_UNLOCKED = "layout_notif_enabled_unlocked";
|
||||
@@ -123,22 +119,17 @@ public final class SbtSettings {
|
||||
public static final String KEY_LAYOUT_NOTIF_AOD_COUNT = "layout_aod_notifications_count";
|
||||
public static final String KEY_LAYOUT_NOTIF_LOCK_POSITION = "layout_lock_notifications_position";
|
||||
public static final String KEY_LAYOUT_NOTIF_LOCK_MIDDLE_SIDE = "layout_lock_notifications_middle_side";
|
||||
public static final String KEY_LAYOUT_NOTIF_LOCK_MIDDLE_AUTO_NEAREST_SIDE =
|
||||
"layout_lock_notifications_middle_auto_nearest_side";
|
||||
public static final String KEY_LAYOUT_NOTIF_LOCK_VERTICAL_OFFSET_PX =
|
||||
"layout_lock_notifications_vertical_offset_px";
|
||||
public static final String KEY_LAYOUT_NOTIF_LOCK_ICON_HEIGHT_STEPS =
|
||||
"layout_lock_notifications_icon_height_steps";
|
||||
public static final String KEY_LAYOUT_NOTIF_AOD_POSITION = "layout_aod_notifications_position";
|
||||
public static final String KEY_LAYOUT_NOTIF_AOD_MIDDLE_SIDE = "layout_aod_notifications_middle_side";
|
||||
public static final String KEY_LAYOUT_NOTIF_AOD_MIDDLE_AUTO_NEAREST_SIDE =
|
||||
"layout_aod_notifications_middle_auto_nearest_side";
|
||||
public static final String KEY_LAYOUT_NOTIF_AOD_VERTICAL_OFFSET_PX =
|
||||
"layout_aod_notifications_vertical_offset_px";
|
||||
public static final String KEY_LAYOUT_NOTIF_AOD_ICON_HEIGHT_STEPS =
|
||||
"layout_aod_notifications_icon_height_steps";
|
||||
public static final String KEY_LAYOUT_NOTIF_MIDDLE_SIDE = "layout_notif_middle_side";
|
||||
public static final String KEY_LAYOUT_NOTIF_MIDDLE_AUTO_NEAREST_SIDE = "layout_notif_middle_auto_nearest_side";
|
||||
public static final String KEY_LAYOUT_NOTIF_VERTICAL_OFFSET_PX = "layout_notif_vertical_offset_px";
|
||||
public static final String KEY_LAYOUT_NOTIF_ICON_HEIGHT_STEPS = "layout_notif_icon_height_steps";
|
||||
public static final String KEY_LAYOUT_STATUS_POSITION = "layout_status_position";
|
||||
@@ -150,23 +141,17 @@ public final class SbtSettings {
|
||||
public static final String KEY_LAYOUT_STATUS_AOD_COUNT = "layout_aod_status_count";
|
||||
public static final String KEY_LAYOUT_STATUS_LOCK_POSITION = "layout_lock_status_position";
|
||||
public static final String KEY_LAYOUT_STATUS_LOCK_MIDDLE_SIDE = "layout_lock_status_middle_side";
|
||||
public static final String KEY_LAYOUT_STATUS_LOCK_MIDDLE_AUTO_NEAREST_SIDE =
|
||||
"layout_lock_status_middle_auto_nearest_side";
|
||||
public static final String KEY_LAYOUT_STATUS_LOCK_VERTICAL_OFFSET_PX =
|
||||
"layout_lock_status_vertical_offset_px";
|
||||
public static final String KEY_LAYOUT_STATUS_LOCK_ICON_HEIGHT_STEPS =
|
||||
"layout_lock_status_icon_height_steps";
|
||||
public static final String KEY_LAYOUT_STATUS_AOD_POSITION = "layout_aod_status_position";
|
||||
public static final String KEY_LAYOUT_STATUS_AOD_MIDDLE_SIDE = "layout_aod_status_middle_side";
|
||||
public static final String KEY_LAYOUT_STATUS_AOD_MIDDLE_AUTO_NEAREST_SIDE =
|
||||
"layout_aod_status_middle_auto_nearest_side";
|
||||
public static final String KEY_LAYOUT_STATUS_AOD_VERTICAL_OFFSET_PX =
|
||||
"layout_aod_status_vertical_offset_px";
|
||||
public static final String KEY_LAYOUT_STATUS_AOD_ICON_HEIGHT_STEPS =
|
||||
"layout_aod_status_icon_height_steps";
|
||||
public static final String KEY_LAYOUT_STATUS_SHOW_DOT_IF_TRUNCATED = "layout_status_show_dot_if_truncated";
|
||||
public static final String KEY_LAYOUT_STATUS_MIDDLE_SIDE = "layout_status_middle_side";
|
||||
public static final String KEY_LAYOUT_STATUS_MIDDLE_AUTO_NEAREST_SIDE = "layout_status_middle_auto_nearest_side";
|
||||
public static final String KEY_LAYOUT_STATUS_VERTICAL_OFFSET_PX = "layout_status_vertical_offset_px";
|
||||
public static final String KEY_LAYOUT_STATUS_ICON_HEIGHT_STEPS = "layout_status_icon_height_steps";
|
||||
public static final String KEY_SYSTEM_ICON_BLOCKED_MODES = SystemIconRules.PREF_KEY_BLOCKED_MODES;
|
||||
@@ -182,10 +167,6 @@ public final class SbtSettings {
|
||||
return suffixedKey(KEY_LAYOUT_NOTIF_MIDDLE_SIDE, index);
|
||||
}
|
||||
|
||||
public static String layoutNotifMiddleAutoNearestSideKey(int index) {
|
||||
return suffixedKey(KEY_LAYOUT_NOTIF_MIDDLE_AUTO_NEAREST_SIDE, index);
|
||||
}
|
||||
|
||||
public static String layoutNotifVerticalOffsetKey(int index) {
|
||||
return suffixedKey(KEY_LAYOUT_NOTIF_VERTICAL_OFFSET_PX, index);
|
||||
}
|
||||
@@ -198,10 +179,6 @@ public final class SbtSettings {
|
||||
return suffixedKey(KEY_LAYOUT_STATUS_MIDDLE_SIDE, index);
|
||||
}
|
||||
|
||||
public static String layoutStatusMiddleAutoNearestSideKey(int index) {
|
||||
return suffixedKey(KEY_LAYOUT_STATUS_MIDDLE_AUTO_NEAREST_SIDE, index);
|
||||
}
|
||||
|
||||
public static String layoutStatusVerticalOffsetKey(int index) {
|
||||
return suffixedKey(KEY_LAYOUT_STATUS_VERTICAL_OFFSET_PX, index);
|
||||
}
|
||||
@@ -214,10 +191,6 @@ public final class SbtSettings {
|
||||
return suffixedKey(KEY_LAYOUT_NOTIF_LOCK_MIDDLE_SIDE, index);
|
||||
}
|
||||
|
||||
public static String layoutLockNotifMiddleAutoNearestSideKey(int index) {
|
||||
return suffixedKey(KEY_LAYOUT_NOTIF_LOCK_MIDDLE_AUTO_NEAREST_SIDE, index);
|
||||
}
|
||||
|
||||
public static String layoutLockNotifVerticalOffsetKey(int index) {
|
||||
return suffixedKey(KEY_LAYOUT_NOTIF_LOCK_VERTICAL_OFFSET_PX, index);
|
||||
}
|
||||
@@ -234,10 +207,6 @@ public final class SbtSettings {
|
||||
return suffixedKey(KEY_LAYOUT_NOTIF_AOD_MIDDLE_SIDE, index);
|
||||
}
|
||||
|
||||
public static String layoutAodNotifMiddleAutoNearestSideKey(int index) {
|
||||
return suffixedKey(KEY_LAYOUT_NOTIF_AOD_MIDDLE_AUTO_NEAREST_SIDE, index);
|
||||
}
|
||||
|
||||
public static String layoutAodNotifVerticalOffsetKey(int index) {
|
||||
return suffixedKey(KEY_LAYOUT_NOTIF_AOD_VERTICAL_OFFSET_PX, index);
|
||||
}
|
||||
@@ -254,10 +223,6 @@ public final class SbtSettings {
|
||||
return suffixedKey(KEY_LAYOUT_STATUS_LOCK_MIDDLE_SIDE, index);
|
||||
}
|
||||
|
||||
public static String layoutLockStatusMiddleAutoNearestSideKey(int index) {
|
||||
return suffixedKey(KEY_LAYOUT_STATUS_LOCK_MIDDLE_AUTO_NEAREST_SIDE, index);
|
||||
}
|
||||
|
||||
public static String layoutLockStatusVerticalOffsetKey(int index) {
|
||||
return suffixedKey(KEY_LAYOUT_STATUS_LOCK_VERTICAL_OFFSET_PX, index);
|
||||
}
|
||||
@@ -274,10 +239,6 @@ public final class SbtSettings {
|
||||
return suffixedKey(KEY_LAYOUT_STATUS_AOD_MIDDLE_SIDE, index);
|
||||
}
|
||||
|
||||
public static String layoutAodStatusMiddleAutoNearestSideKey(int index) {
|
||||
return suffixedKey(KEY_LAYOUT_STATUS_AOD_MIDDLE_AUTO_NEAREST_SIDE, index);
|
||||
}
|
||||
|
||||
public static String layoutAodStatusVerticalOffsetKey(int index) {
|
||||
return suffixedKey(KEY_LAYOUT_STATUS_AOD_VERTICAL_OFFSET_PX, index);
|
||||
}
|
||||
@@ -350,38 +311,30 @@ public final class SbtSettings {
|
||||
public final String layoutCarrierPosition;
|
||||
public final boolean layoutCarrierEnabledLockscreen;
|
||||
public final String layoutCarrierMiddleSide;
|
||||
public final boolean layoutCarrierMiddleAutoNearestSide;
|
||||
public final int layoutCarrierVerticalOffsetPx;
|
||||
public final String layoutChipPosition;
|
||||
public final boolean layoutChipEnabledLockscreen;
|
||||
public final boolean layoutChipEnabledUnlocked;
|
||||
public final String layoutChipMiddleSide;
|
||||
public final boolean layoutChipMiddleAutoNearestSide;
|
||||
public final int layoutChipVerticalOffsetPx;
|
||||
public final int layoutChipHeightSteps;
|
||||
public final String layoutNotifPosition;
|
||||
public final String layoutNotifSortOrder;
|
||||
public final boolean layoutNotifShowDotIfTruncated;
|
||||
public final boolean layoutNotifEnabledAod;
|
||||
public final boolean layoutNotifEnabledLockscreen;
|
||||
public final boolean layoutNotifEnabledUnlocked;
|
||||
public final int layoutNotifUnlockedCount;
|
||||
public final String[] layoutNotifPositions;
|
||||
public final String[] layoutNotifMiddleSides;
|
||||
public final boolean[] layoutNotifMiddleAutoNearestSides;
|
||||
public final int[] layoutNotifVerticalOffsetsPx;
|
||||
public final int layoutNotifLockCount;
|
||||
public final String[] layoutNotifLockPositions;
|
||||
public final String[] layoutNotifLockMiddleSides;
|
||||
public final boolean[] layoutNotifLockMiddleAutoNearestSides;
|
||||
public final int[] layoutNotifLockVerticalOffsetsPx;
|
||||
public final int layoutNotifAodCount;
|
||||
public final String[] layoutNotifAodPositions;
|
||||
public final String[] layoutNotifAodMiddleSides;
|
||||
public final boolean[] layoutNotifAodMiddleAutoNearestSides;
|
||||
public final int[] layoutNotifAodVerticalOffsetsPx;
|
||||
public final String layoutNotifMiddleSide;
|
||||
public final boolean layoutNotifMiddleAutoNearestSide;
|
||||
public final int layoutNotifVerticalOffsetPx;
|
||||
public final int layoutNotifIconHeightSteps;
|
||||
public final int layoutNotifLockIconHeightSteps;
|
||||
@@ -393,21 +346,16 @@ public final class SbtSettings {
|
||||
public final int layoutStatusUnlockedCount;
|
||||
public final String[] layoutStatusPositions;
|
||||
public final String[] layoutStatusMiddleSides;
|
||||
public final boolean[] layoutStatusMiddleAutoNearestSides;
|
||||
public final int[] layoutStatusVerticalOffsetsPx;
|
||||
public final int layoutStatusLockCount;
|
||||
public final String[] layoutStatusLockPositions;
|
||||
public final String[] layoutStatusLockMiddleSides;
|
||||
public final boolean[] layoutStatusLockMiddleAutoNearestSides;
|
||||
public final int[] layoutStatusLockVerticalOffsetsPx;
|
||||
public final int layoutStatusAodCount;
|
||||
public final String[] layoutStatusAodPositions;
|
||||
public final String[] layoutStatusAodMiddleSides;
|
||||
public final boolean[] layoutStatusAodMiddleAutoNearestSides;
|
||||
public final int[] layoutStatusAodVerticalOffsetsPx;
|
||||
public final boolean layoutStatusShowDotIfTruncated;
|
||||
public final String layoutStatusMiddleSide;
|
||||
public final boolean layoutStatusMiddleAutoNearestSide;
|
||||
public final int layoutStatusVerticalOffsetPx;
|
||||
public final int layoutStatusIconHeightSteps;
|
||||
public final int layoutStatusLockIconHeightSteps;
|
||||
@@ -485,23 +433,18 @@ public final class SbtSettings {
|
||||
String layoutCarrierPosition,
|
||||
boolean layoutCarrierEnabledLockscreen,
|
||||
String layoutCarrierMiddleSide,
|
||||
boolean layoutCarrierMiddleAutoNearestSide,
|
||||
int layoutCarrierVerticalOffsetPx,
|
||||
String layoutChipPosition,
|
||||
boolean layoutChipEnabledLockscreen,
|
||||
boolean layoutChipEnabledUnlocked,
|
||||
String layoutChipMiddleSide,
|
||||
boolean layoutChipMiddleAutoNearestSide,
|
||||
int layoutChipVerticalOffsetPx,
|
||||
int layoutChipHeightSteps,
|
||||
String layoutNotifPosition,
|
||||
String layoutNotifSortOrder,
|
||||
boolean layoutNotifShowDotIfTruncated,
|
||||
boolean layoutNotifEnabledAod,
|
||||
boolean layoutNotifEnabledLockscreen,
|
||||
boolean layoutNotifEnabledUnlocked,
|
||||
String layoutNotifMiddleSide,
|
||||
boolean layoutNotifMiddleAutoNearestSide,
|
||||
int layoutNotifVerticalOffsetPx,
|
||||
int layoutNotifIconHeightSteps,
|
||||
int layoutNotifLockIconHeightSteps,
|
||||
@@ -509,25 +452,20 @@ public final class SbtSettings {
|
||||
int layoutNotifUnlockedCount,
|
||||
String[] layoutNotifPositions,
|
||||
String[] layoutNotifMiddleSides,
|
||||
boolean[] layoutNotifMiddleAutoNearestSides,
|
||||
int[] layoutNotifVerticalOffsetsPx,
|
||||
int layoutNotifLockCount,
|
||||
String[] layoutNotifLockPositions,
|
||||
String[] layoutNotifLockMiddleSides,
|
||||
boolean[] layoutNotifLockMiddleAutoNearestSides,
|
||||
int[] layoutNotifLockVerticalOffsetsPx,
|
||||
int layoutNotifAodCount,
|
||||
String[] layoutNotifAodPositions,
|
||||
String[] layoutNotifAodMiddleSides,
|
||||
boolean[] layoutNotifAodMiddleAutoNearestSides,
|
||||
int[] layoutNotifAodVerticalOffsetsPx,
|
||||
String layoutStatusPosition,
|
||||
boolean layoutStatusEnabledAod,
|
||||
boolean layoutStatusEnabledLockscreen,
|
||||
boolean layoutStatusEnabledUnlocked,
|
||||
boolean layoutStatusShowDotIfTruncated,
|
||||
String layoutStatusMiddleSide,
|
||||
boolean layoutStatusMiddleAutoNearestSide,
|
||||
int layoutStatusVerticalOffsetPx,
|
||||
int layoutStatusIconHeightSteps,
|
||||
int layoutStatusLockIconHeightSteps,
|
||||
@@ -535,17 +473,14 @@ public final class SbtSettings {
|
||||
int layoutStatusUnlockedCount,
|
||||
String[] layoutStatusPositions,
|
||||
String[] layoutStatusMiddleSides,
|
||||
boolean[] layoutStatusMiddleAutoNearestSides,
|
||||
int[] layoutStatusVerticalOffsetsPx,
|
||||
int layoutStatusLockCount,
|
||||
String[] layoutStatusLockPositions,
|
||||
String[] layoutStatusLockMiddleSides,
|
||||
boolean[] layoutStatusLockMiddleAutoNearestSides,
|
||||
int[] layoutStatusLockVerticalOffsetsPx,
|
||||
int layoutStatusAodCount,
|
||||
String[] layoutStatusAodPositions,
|
||||
String[] layoutStatusAodMiddleSides,
|
||||
boolean[] layoutStatusAodMiddleAutoNearestSides,
|
||||
int[] layoutStatusAodVerticalOffsetsPx,
|
||||
Map<String, String> clockCameraTypeOverrides,
|
||||
Map<String, Integer> systemIconBlockedModes,
|
||||
@@ -671,7 +606,6 @@ public final class SbtSettings {
|
||||
this.layoutCarrierMiddleSide = layoutCarrierMiddleSide != null
|
||||
? layoutCarrierMiddleSide
|
||||
: SbtDefaults.LAYOUT_CARRIER_MIDDLE_SIDE_DEFAULT;
|
||||
this.layoutCarrierMiddleAutoNearestSide = layoutCarrierMiddleAutoNearestSide;
|
||||
this.layoutCarrierVerticalOffsetPx = clampInt(
|
||||
layoutCarrierVerticalOffsetPx,
|
||||
SbtDefaults.CLOCK_VERTICAL_OFFSET_PX_MIN,
|
||||
@@ -679,12 +613,10 @@ public final class SbtSettings {
|
||||
this.layoutChipPosition = layoutChipPosition != null
|
||||
? layoutChipPosition
|
||||
: SbtDefaults.LAYOUT_CHIP_POSITION_DEFAULT;
|
||||
this.layoutChipEnabledLockscreen = layoutChipEnabledLockscreen;
|
||||
this.layoutChipEnabledUnlocked = layoutChipEnabledUnlocked;
|
||||
this.layoutChipMiddleSide = layoutChipMiddleSide != null
|
||||
? layoutChipMiddleSide
|
||||
: SbtDefaults.LAYOUT_CHIP_MIDDLE_SIDE_DEFAULT;
|
||||
this.layoutChipMiddleAutoNearestSide = layoutChipMiddleAutoNearestSide;
|
||||
this.layoutChipVerticalOffsetPx = clampInt(
|
||||
layoutChipVerticalOffsetPx,
|
||||
SbtDefaults.CLOCK_VERTICAL_OFFSET_PX_MIN,
|
||||
@@ -696,14 +628,12 @@ public final class SbtSettings {
|
||||
this.layoutNotifSortOrder = layoutNotifSortOrder != null
|
||||
? layoutNotifSortOrder
|
||||
: SbtDefaults.LAYOUT_NOTIF_SORT_ORDER_DEFAULT;
|
||||
this.layoutNotifShowDotIfTruncated = layoutNotifShowDotIfTruncated;
|
||||
this.layoutNotifEnabledAod = layoutNotifEnabledAod;
|
||||
this.layoutNotifEnabledLockscreen = layoutNotifEnabledLockscreen;
|
||||
this.layoutNotifEnabledUnlocked = layoutNotifEnabledUnlocked;
|
||||
this.layoutNotifMiddleSide = layoutNotifMiddleSide != null
|
||||
? layoutNotifMiddleSide
|
||||
: SbtDefaults.LAYOUT_NOTIF_MIDDLE_SIDE_DEFAULT;
|
||||
this.layoutNotifMiddleAutoNearestSide = layoutNotifMiddleAutoNearestSide;
|
||||
this.layoutNotifVerticalOffsetPx = clampInt(
|
||||
layoutNotifVerticalOffsetPx,
|
||||
SbtDefaults.CLOCK_VERTICAL_OFFSET_PX_MIN,
|
||||
@@ -720,10 +650,6 @@ public final class SbtSettings {
|
||||
layoutNotifMiddleSides,
|
||||
this.layoutNotifMiddleSide,
|
||||
SbtDefaults.LAYOUT_ICON_CONTAINER_COUNT_MAX);
|
||||
this.layoutNotifMiddleAutoNearestSides = sanitizeBooleanArray(
|
||||
layoutNotifMiddleAutoNearestSides,
|
||||
this.layoutNotifMiddleAutoNearestSide,
|
||||
SbtDefaults.LAYOUT_ICON_CONTAINER_COUNT_MAX);
|
||||
this.layoutNotifVerticalOffsetsPx = sanitizeIntArray(
|
||||
layoutNotifVerticalOffsetsPx,
|
||||
this.layoutNotifVerticalOffsetPx,
|
||||
@@ -739,10 +665,6 @@ public final class SbtSettings {
|
||||
layoutNotifLockMiddleSides,
|
||||
this.layoutNotifMiddleSide,
|
||||
SbtDefaults.LAYOUT_ICON_CONTAINER_COUNT_MAX);
|
||||
this.layoutNotifLockMiddleAutoNearestSides = sanitizeBooleanArray(
|
||||
layoutNotifLockMiddleAutoNearestSides,
|
||||
this.layoutNotifMiddleAutoNearestSide,
|
||||
SbtDefaults.LAYOUT_ICON_CONTAINER_COUNT_MAX);
|
||||
this.layoutNotifLockVerticalOffsetsPx = sanitizeIntArray(
|
||||
layoutNotifLockVerticalOffsetsPx,
|
||||
this.layoutNotifVerticalOffsetPx,
|
||||
@@ -758,10 +680,6 @@ public final class SbtSettings {
|
||||
layoutNotifAodMiddleSides,
|
||||
this.layoutNotifMiddleSide,
|
||||
SbtDefaults.LAYOUT_ICON_CONTAINER_COUNT_MAX);
|
||||
this.layoutNotifAodMiddleAutoNearestSides = sanitizeBooleanArray(
|
||||
layoutNotifAodMiddleAutoNearestSides,
|
||||
this.layoutNotifMiddleAutoNearestSide,
|
||||
SbtDefaults.LAYOUT_ICON_CONTAINER_COUNT_MAX);
|
||||
this.layoutNotifAodVerticalOffsetsPx = sanitizeIntArray(
|
||||
layoutNotifAodVerticalOffsetsPx,
|
||||
this.layoutNotifVerticalOffsetPx,
|
||||
@@ -774,11 +692,9 @@ public final class SbtSettings {
|
||||
this.layoutStatusEnabledAod = layoutStatusEnabledAod;
|
||||
this.layoutStatusEnabledLockscreen = layoutStatusEnabledLockscreen;
|
||||
this.layoutStatusEnabledUnlocked = layoutStatusEnabledUnlocked;
|
||||
this.layoutStatusShowDotIfTruncated = layoutStatusShowDotIfTruncated;
|
||||
this.layoutStatusMiddleSide = layoutStatusMiddleSide != null
|
||||
? layoutStatusMiddleSide
|
||||
: SbtDefaults.LAYOUT_STATUS_MIDDLE_SIDE_DEFAULT;
|
||||
this.layoutStatusMiddleAutoNearestSide = layoutStatusMiddleAutoNearestSide;
|
||||
this.layoutStatusVerticalOffsetPx = clampInt(
|
||||
layoutStatusVerticalOffsetPx,
|
||||
SbtDefaults.CLOCK_VERTICAL_OFFSET_PX_MIN,
|
||||
@@ -795,10 +711,6 @@ public final class SbtSettings {
|
||||
layoutStatusMiddleSides,
|
||||
this.layoutStatusMiddleSide,
|
||||
SbtDefaults.LAYOUT_ICON_CONTAINER_COUNT_MAX);
|
||||
this.layoutStatusMiddleAutoNearestSides = sanitizeBooleanArray(
|
||||
layoutStatusMiddleAutoNearestSides,
|
||||
this.layoutStatusMiddleAutoNearestSide,
|
||||
SbtDefaults.LAYOUT_ICON_CONTAINER_COUNT_MAX);
|
||||
this.layoutStatusVerticalOffsetsPx = sanitizeIntArray(
|
||||
layoutStatusVerticalOffsetsPx,
|
||||
this.layoutStatusVerticalOffsetPx,
|
||||
@@ -814,10 +726,6 @@ public final class SbtSettings {
|
||||
layoutStatusLockMiddleSides,
|
||||
this.layoutStatusMiddleSide,
|
||||
SbtDefaults.LAYOUT_ICON_CONTAINER_COUNT_MAX);
|
||||
this.layoutStatusLockMiddleAutoNearestSides = sanitizeBooleanArray(
|
||||
layoutStatusLockMiddleAutoNearestSides,
|
||||
this.layoutStatusMiddleAutoNearestSide,
|
||||
SbtDefaults.LAYOUT_ICON_CONTAINER_COUNT_MAX);
|
||||
this.layoutStatusLockVerticalOffsetsPx = sanitizeIntArray(
|
||||
layoutStatusLockVerticalOffsetsPx,
|
||||
this.layoutStatusVerticalOffsetPx,
|
||||
@@ -833,10 +741,6 @@ public final class SbtSettings {
|
||||
layoutStatusAodMiddleSides,
|
||||
this.layoutStatusMiddleSide,
|
||||
SbtDefaults.LAYOUT_ICON_CONTAINER_COUNT_MAX);
|
||||
this.layoutStatusAodMiddleAutoNearestSides = sanitizeBooleanArray(
|
||||
layoutStatusAodMiddleAutoNearestSides,
|
||||
this.layoutStatusMiddleAutoNearestSide,
|
||||
SbtDefaults.LAYOUT_ICON_CONTAINER_COUNT_MAX);
|
||||
this.layoutStatusAodVerticalOffsetsPx = sanitizeIntArray(
|
||||
layoutStatusAodVerticalOffsetsPx,
|
||||
this.layoutStatusVerticalOffsetPx,
|
||||
@@ -936,23 +840,18 @@ public final class SbtSettings {
|
||||
SbtDefaults.LAYOUT_CARRIER_POSITION_DEFAULT,
|
||||
SbtDefaults.LAYOUT_CARRIER_ENABLED_LOCKSCREEN_DEFAULT,
|
||||
SbtDefaults.LAYOUT_CARRIER_MIDDLE_SIDE_DEFAULT,
|
||||
SbtDefaults.LAYOUT_CARRIER_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT,
|
||||
SbtDefaults.LAYOUT_CARRIER_VERTICAL_OFFSET_PX_DEFAULT,
|
||||
SbtDefaults.LAYOUT_CHIP_POSITION_DEFAULT,
|
||||
SbtDefaults.LAYOUT_CHIP_ENABLED_LOCKSCREEN_DEFAULT,
|
||||
SbtDefaults.LAYOUT_CHIP_ENABLED_UNLOCKED_DEFAULT,
|
||||
SbtDefaults.LAYOUT_CHIP_MIDDLE_SIDE_DEFAULT,
|
||||
SbtDefaults.LAYOUT_CHIP_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT,
|
||||
SbtDefaults.LAYOUT_CHIP_VERTICAL_OFFSET_PX_DEFAULT,
|
||||
SbtDefaults.LAYOUT_CHIP_HEIGHT_STEPS_DEFAULT,
|
||||
SbtDefaults.LAYOUT_NOTIF_POSITION_DEFAULT,
|
||||
SbtDefaults.LAYOUT_NOTIF_SORT_ORDER_DEFAULT,
|
||||
SbtDefaults.LAYOUT_NOTIF_SHOW_DOT_IF_TRUNCATED_DEFAULT,
|
||||
SbtDefaults.LAYOUT_NOTIF_ENABLED_AOD_DEFAULT,
|
||||
SbtDefaults.LAYOUT_NOTIF_ENABLED_LOCKSCREEN_DEFAULT,
|
||||
SbtDefaults.LAYOUT_NOTIF_ENABLED_UNLOCKED_DEFAULT,
|
||||
SbtDefaults.LAYOUT_NOTIF_MIDDLE_SIDE_DEFAULT,
|
||||
SbtDefaults.LAYOUT_NOTIF_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT,
|
||||
SbtDefaults.LAYOUT_NOTIF_VERTICAL_OFFSET_PX_DEFAULT,
|
||||
SbtDefaults.LAYOUT_NOTIF_ICON_HEIGHT_STEPS_DEFAULT,
|
||||
SbtDefaults.LAYOUT_NOTIF_LOCK_ICON_HEIGHT_STEPS_DEFAULT,
|
||||
@@ -961,24 +860,19 @@ public final class SbtSettings {
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
SbtDefaults.LAYOUT_NOTIF_UNLOCKED_COUNT_DEFAULT,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
SbtDefaults.LAYOUT_NOTIF_UNLOCKED_COUNT_DEFAULT,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
SbtDefaults.LAYOUT_STATUS_POSITION_DEFAULT,
|
||||
SbtDefaults.LAYOUT_STATUS_ENABLED_AOD_DEFAULT,
|
||||
SbtDefaults.LAYOUT_STATUS_ENABLED_LOCKSCREEN_DEFAULT,
|
||||
SbtDefaults.LAYOUT_STATUS_ENABLED_UNLOCKED_DEFAULT,
|
||||
SbtDefaults.LAYOUT_STATUS_SHOW_DOT_IF_TRUNCATED_DEFAULT,
|
||||
SbtDefaults.LAYOUT_STATUS_MIDDLE_SIDE_DEFAULT,
|
||||
SbtDefaults.LAYOUT_STATUS_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT,
|
||||
SbtDefaults.LAYOUT_STATUS_VERTICAL_OFFSET_PX_DEFAULT,
|
||||
SbtDefaults.LAYOUT_STATUS_ICON_HEIGHT_STEPS_DEFAULT,
|
||||
SbtDefaults.LAYOUT_STATUS_ICON_HEIGHT_STEPS_DEFAULT,
|
||||
@@ -987,17 +881,14 @@ public final class SbtSettings {
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
SbtDefaults.LAYOUT_STATUS_UNLOCKED_COUNT_DEFAULT,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
SbtDefaults.LAYOUT_STATUS_UNLOCKED_COUNT_DEFAULT,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
Collections.emptyMap(),
|
||||
Collections.emptyMap(),
|
||||
false,
|
||||
@@ -1208,13 +1099,10 @@ public final class SbtSettings {
|
||||
prefs.getString(KEY_LAYOUT_CARRIER_POSITION, SbtDefaults.LAYOUT_CARRIER_POSITION_DEFAULT),
|
||||
prefs.getBoolean(KEY_LAYOUT_CARRIER_ENABLED_LOCKSCREEN, SbtDefaults.LAYOUT_CARRIER_ENABLED_LOCKSCREEN_DEFAULT),
|
||||
prefs.getString(KEY_LAYOUT_CARRIER_MIDDLE_SIDE, SbtDefaults.LAYOUT_CARRIER_MIDDLE_SIDE_DEFAULT),
|
||||
prefs.getBoolean(KEY_LAYOUT_CARRIER_MIDDLE_AUTO_NEAREST_SIDE, SbtDefaults.LAYOUT_CARRIER_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT),
|
||||
prefs.getInt(KEY_LAYOUT_CARRIER_VERTICAL_OFFSET_PX, SbtDefaults.LAYOUT_CARRIER_VERTICAL_OFFSET_PX_DEFAULT),
|
||||
prefs.getString(KEY_LAYOUT_CHIP_POSITION, SbtDefaults.LAYOUT_CHIP_POSITION_DEFAULT),
|
||||
prefs.getBoolean(KEY_LAYOUT_CHIP_ENABLED_LOCKSCREEN, SbtDefaults.LAYOUT_CHIP_ENABLED_LOCKSCREEN_DEFAULT),
|
||||
prefs.getBoolean(KEY_LAYOUT_CHIP_ENABLED_UNLOCKED, SbtDefaults.LAYOUT_CHIP_ENABLED_UNLOCKED_DEFAULT),
|
||||
prefs.getString(KEY_LAYOUT_CHIP_MIDDLE_SIDE, SbtDefaults.LAYOUT_CHIP_MIDDLE_SIDE_DEFAULT),
|
||||
prefs.getBoolean(KEY_LAYOUT_CHIP_MIDDLE_AUTO_NEAREST_SIDE, SbtDefaults.LAYOUT_CHIP_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT),
|
||||
clampInt(prefs.getInt(KEY_LAYOUT_CHIP_VERTICAL_OFFSET_PX,
|
||||
SbtDefaults.LAYOUT_CHIP_VERTICAL_OFFSET_PX_DEFAULT),
|
||||
SbtDefaults.CLOCK_VERTICAL_OFFSET_PX_MIN,
|
||||
@@ -1223,12 +1111,10 @@ public final class SbtSettings {
|
||||
SbtDefaults.LAYOUT_CHIP_HEIGHT_STEPS_DEFAULT)),
|
||||
prefs.getString(KEY_LAYOUT_NOTIF_POSITION, SbtDefaults.LAYOUT_NOTIF_POSITION_DEFAULT),
|
||||
prefs.getString(KEY_LAYOUT_NOTIF_SORT_ORDER, SbtDefaults.LAYOUT_NOTIF_SORT_ORDER_DEFAULT),
|
||||
prefs.getBoolean(KEY_LAYOUT_NOTIF_SHOW_DOT_IF_TRUNCATED, SbtDefaults.LAYOUT_NOTIF_SHOW_DOT_IF_TRUNCATED_DEFAULT),
|
||||
prefs.getBoolean(KEY_LAYOUT_NOTIF_ENABLED_AOD, SbtDefaults.LAYOUT_NOTIF_ENABLED_AOD_DEFAULT),
|
||||
prefs.getBoolean(KEY_LAYOUT_NOTIF_ENABLED_LOCKSCREEN, SbtDefaults.LAYOUT_NOTIF_ENABLED_LOCKSCREEN_DEFAULT),
|
||||
prefs.getBoolean(KEY_LAYOUT_NOTIF_ENABLED_UNLOCKED, SbtDefaults.LAYOUT_NOTIF_ENABLED_UNLOCKED_DEFAULT),
|
||||
prefs.getString(KEY_LAYOUT_NOTIF_MIDDLE_SIDE, SbtDefaults.LAYOUT_NOTIF_MIDDLE_SIDE_DEFAULT),
|
||||
prefs.getBoolean(KEY_LAYOUT_NOTIF_MIDDLE_AUTO_NEAREST_SIDE, SbtDefaults.LAYOUT_NOTIF_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT),
|
||||
clampInt(prefs.getInt(KEY_LAYOUT_NOTIF_VERTICAL_OFFSET_PX,
|
||||
SbtDefaults.LAYOUT_NOTIF_VERTICAL_OFFSET_PX_DEFAULT),
|
||||
SbtDefaults.CLOCK_VERTICAL_OFFSET_PX_MIN,
|
||||
@@ -1259,10 +1145,6 @@ public final class SbtSettings {
|
||||
prefs,
|
||||
SbtSettings::layoutNotifMiddleSideKey,
|
||||
SbtDefaults.LAYOUT_NOTIF_MIDDLE_SIDE_DEFAULT),
|
||||
readBooleanArrayFromPrefs(
|
||||
prefs,
|
||||
SbtSettings::layoutNotifMiddleAutoNearestSideKey,
|
||||
SbtDefaults.LAYOUT_NOTIF_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT),
|
||||
readIntArrayFromPrefs(
|
||||
prefs,
|
||||
SbtSettings::layoutNotifVerticalOffsetKey,
|
||||
@@ -1281,10 +1163,6 @@ public final class SbtSettings {
|
||||
prefs,
|
||||
SbtSettings::layoutLockNotifMiddleSideKey,
|
||||
SbtDefaults.LAYOUT_NOTIF_MIDDLE_SIDE_DEFAULT),
|
||||
readBooleanArrayFromPrefs(
|
||||
prefs,
|
||||
SbtSettings::layoutLockNotifMiddleAutoNearestSideKey,
|
||||
SbtDefaults.LAYOUT_NOTIF_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT),
|
||||
readIntArrayFromPrefs(
|
||||
prefs,
|
||||
SbtSettings::layoutLockNotifVerticalOffsetKey,
|
||||
@@ -1303,10 +1181,6 @@ public final class SbtSettings {
|
||||
prefs,
|
||||
SbtSettings::layoutAodNotifMiddleSideKey,
|
||||
SbtDefaults.LAYOUT_NOTIF_MIDDLE_SIDE_DEFAULT),
|
||||
readBooleanArrayFromPrefs(
|
||||
prefs,
|
||||
SbtSettings::layoutAodNotifMiddleAutoNearestSideKey,
|
||||
SbtDefaults.LAYOUT_NOTIF_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT),
|
||||
readIntArrayFromPrefs(
|
||||
prefs,
|
||||
SbtSettings::layoutAodNotifVerticalOffsetKey,
|
||||
@@ -1315,9 +1189,7 @@ public final class SbtSettings {
|
||||
prefs.getBoolean(KEY_LAYOUT_STATUS_ENABLED_AOD, SbtDefaults.LAYOUT_STATUS_ENABLED_AOD_DEFAULT),
|
||||
prefs.getBoolean(KEY_LAYOUT_STATUS_ENABLED_LOCKSCREEN, SbtDefaults.LAYOUT_STATUS_ENABLED_LOCKSCREEN_DEFAULT),
|
||||
prefs.getBoolean(KEY_LAYOUT_STATUS_ENABLED_UNLOCKED, SbtDefaults.LAYOUT_STATUS_ENABLED_UNLOCKED_DEFAULT),
|
||||
prefs.getBoolean(KEY_LAYOUT_STATUS_SHOW_DOT_IF_TRUNCATED, SbtDefaults.LAYOUT_STATUS_SHOW_DOT_IF_TRUNCATED_DEFAULT),
|
||||
prefs.getString(KEY_LAYOUT_STATUS_MIDDLE_SIDE, SbtDefaults.LAYOUT_STATUS_MIDDLE_SIDE_DEFAULT),
|
||||
prefs.getBoolean(KEY_LAYOUT_STATUS_MIDDLE_AUTO_NEAREST_SIDE, SbtDefaults.LAYOUT_STATUS_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT),
|
||||
clampInt(prefs.getInt(KEY_LAYOUT_STATUS_VERTICAL_OFFSET_PX,
|
||||
SbtDefaults.LAYOUT_STATUS_VERTICAL_OFFSET_PX_DEFAULT),
|
||||
SbtDefaults.CLOCK_VERTICAL_OFFSET_PX_MIN,
|
||||
@@ -1348,10 +1220,6 @@ public final class SbtSettings {
|
||||
prefs,
|
||||
SbtSettings::layoutStatusMiddleSideKey,
|
||||
SbtDefaults.LAYOUT_STATUS_MIDDLE_SIDE_DEFAULT),
|
||||
readBooleanArrayFromPrefs(
|
||||
prefs,
|
||||
SbtSettings::layoutStatusMiddleAutoNearestSideKey,
|
||||
SbtDefaults.LAYOUT_STATUS_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT),
|
||||
readIntArrayFromPrefs(
|
||||
prefs,
|
||||
SbtSettings::layoutStatusVerticalOffsetKey,
|
||||
@@ -1370,10 +1238,6 @@ public final class SbtSettings {
|
||||
prefs,
|
||||
SbtSettings::layoutLockStatusMiddleSideKey,
|
||||
SbtDefaults.LAYOUT_STATUS_MIDDLE_SIDE_DEFAULT),
|
||||
readBooleanArrayFromPrefs(
|
||||
prefs,
|
||||
SbtSettings::layoutLockStatusMiddleAutoNearestSideKey,
|
||||
SbtDefaults.LAYOUT_STATUS_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT),
|
||||
readIntArrayFromPrefs(
|
||||
prefs,
|
||||
SbtSettings::layoutLockStatusVerticalOffsetKey,
|
||||
@@ -1392,10 +1256,6 @@ public final class SbtSettings {
|
||||
prefs,
|
||||
SbtSettings::layoutAodStatusMiddleSideKey,
|
||||
SbtDefaults.LAYOUT_STATUS_MIDDLE_SIDE_DEFAULT),
|
||||
readBooleanArrayFromPrefs(
|
||||
prefs,
|
||||
SbtSettings::layoutAodStatusMiddleAutoNearestSideKey,
|
||||
SbtDefaults.LAYOUT_STATUS_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT),
|
||||
readIntArrayFromPrefs(
|
||||
prefs,
|
||||
SbtSettings::layoutAodStatusVerticalOffsetKey,
|
||||
@@ -1537,13 +1397,10 @@ public final class SbtSettings {
|
||||
bundle.getString(KEY_LAYOUT_CARRIER_POSITION, SbtDefaults.LAYOUT_CARRIER_POSITION_DEFAULT),
|
||||
bundle.getBoolean(KEY_LAYOUT_CARRIER_ENABLED_LOCKSCREEN, SbtDefaults.LAYOUT_CARRIER_ENABLED_LOCKSCREEN_DEFAULT),
|
||||
bundle.getString(KEY_LAYOUT_CARRIER_MIDDLE_SIDE, SbtDefaults.LAYOUT_CARRIER_MIDDLE_SIDE_DEFAULT),
|
||||
bundle.getBoolean(KEY_LAYOUT_CARRIER_MIDDLE_AUTO_NEAREST_SIDE, SbtDefaults.LAYOUT_CARRIER_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT),
|
||||
bundle.getInt(KEY_LAYOUT_CARRIER_VERTICAL_OFFSET_PX, SbtDefaults.LAYOUT_CARRIER_VERTICAL_OFFSET_PX_DEFAULT),
|
||||
bundle.getString(KEY_LAYOUT_CHIP_POSITION, SbtDefaults.LAYOUT_CHIP_POSITION_DEFAULT),
|
||||
bundle.getBoolean(KEY_LAYOUT_CHIP_ENABLED_LOCKSCREEN, SbtDefaults.LAYOUT_CHIP_ENABLED_LOCKSCREEN_DEFAULT),
|
||||
bundle.getBoolean(KEY_LAYOUT_CHIP_ENABLED_UNLOCKED, SbtDefaults.LAYOUT_CHIP_ENABLED_UNLOCKED_DEFAULT),
|
||||
bundle.getString(KEY_LAYOUT_CHIP_MIDDLE_SIDE, SbtDefaults.LAYOUT_CHIP_MIDDLE_SIDE_DEFAULT),
|
||||
bundle.getBoolean(KEY_LAYOUT_CHIP_MIDDLE_AUTO_NEAREST_SIDE, SbtDefaults.LAYOUT_CHIP_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT),
|
||||
clampInt(bundle.getInt(KEY_LAYOUT_CHIP_VERTICAL_OFFSET_PX,
|
||||
SbtDefaults.LAYOUT_CHIP_VERTICAL_OFFSET_PX_DEFAULT),
|
||||
SbtDefaults.CLOCK_VERTICAL_OFFSET_PX_MIN,
|
||||
@@ -1552,12 +1409,10 @@ public final class SbtSettings {
|
||||
SbtDefaults.LAYOUT_CHIP_HEIGHT_STEPS_DEFAULT)),
|
||||
bundle.getString(KEY_LAYOUT_NOTIF_POSITION, SbtDefaults.LAYOUT_NOTIF_POSITION_DEFAULT),
|
||||
bundle.getString(KEY_LAYOUT_NOTIF_SORT_ORDER, SbtDefaults.LAYOUT_NOTIF_SORT_ORDER_DEFAULT),
|
||||
bundle.getBoolean(KEY_LAYOUT_NOTIF_SHOW_DOT_IF_TRUNCATED, SbtDefaults.LAYOUT_NOTIF_SHOW_DOT_IF_TRUNCATED_DEFAULT),
|
||||
bundle.getBoolean(KEY_LAYOUT_NOTIF_ENABLED_AOD, SbtDefaults.LAYOUT_NOTIF_ENABLED_AOD_DEFAULT),
|
||||
bundle.getBoolean(KEY_LAYOUT_NOTIF_ENABLED_LOCKSCREEN, SbtDefaults.LAYOUT_NOTIF_ENABLED_LOCKSCREEN_DEFAULT),
|
||||
bundle.getBoolean(KEY_LAYOUT_NOTIF_ENABLED_UNLOCKED, SbtDefaults.LAYOUT_NOTIF_ENABLED_UNLOCKED_DEFAULT),
|
||||
bundle.getString(KEY_LAYOUT_NOTIF_MIDDLE_SIDE, SbtDefaults.LAYOUT_NOTIF_MIDDLE_SIDE_DEFAULT),
|
||||
bundle.getBoolean(KEY_LAYOUT_NOTIF_MIDDLE_AUTO_NEAREST_SIDE, SbtDefaults.LAYOUT_NOTIF_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT),
|
||||
clampInt(bundle.getInt(KEY_LAYOUT_NOTIF_VERTICAL_OFFSET_PX,
|
||||
SbtDefaults.LAYOUT_NOTIF_VERTICAL_OFFSET_PX_DEFAULT),
|
||||
SbtDefaults.CLOCK_VERTICAL_OFFSET_PX_MIN,
|
||||
@@ -1588,10 +1443,6 @@ public final class SbtSettings {
|
||||
bundle,
|
||||
SbtSettings::layoutNotifMiddleSideKey,
|
||||
SbtDefaults.LAYOUT_NOTIF_MIDDLE_SIDE_DEFAULT),
|
||||
readBooleanArrayFromBundle(
|
||||
bundle,
|
||||
SbtSettings::layoutNotifMiddleAutoNearestSideKey,
|
||||
SbtDefaults.LAYOUT_NOTIF_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT),
|
||||
readIntArrayFromBundle(
|
||||
bundle,
|
||||
SbtSettings::layoutNotifVerticalOffsetKey,
|
||||
@@ -1610,10 +1461,6 @@ public final class SbtSettings {
|
||||
bundle,
|
||||
SbtSettings::layoutLockNotifMiddleSideKey,
|
||||
SbtDefaults.LAYOUT_NOTIF_MIDDLE_SIDE_DEFAULT),
|
||||
readBooleanArrayFromBundle(
|
||||
bundle,
|
||||
SbtSettings::layoutLockNotifMiddleAutoNearestSideKey,
|
||||
SbtDefaults.LAYOUT_NOTIF_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT),
|
||||
readIntArrayFromBundle(
|
||||
bundle,
|
||||
SbtSettings::layoutLockNotifVerticalOffsetKey,
|
||||
@@ -1632,10 +1479,6 @@ public final class SbtSettings {
|
||||
bundle,
|
||||
SbtSettings::layoutAodNotifMiddleSideKey,
|
||||
SbtDefaults.LAYOUT_NOTIF_MIDDLE_SIDE_DEFAULT),
|
||||
readBooleanArrayFromBundle(
|
||||
bundle,
|
||||
SbtSettings::layoutAodNotifMiddleAutoNearestSideKey,
|
||||
SbtDefaults.LAYOUT_NOTIF_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT),
|
||||
readIntArrayFromBundle(
|
||||
bundle,
|
||||
SbtSettings::layoutAodNotifVerticalOffsetKey,
|
||||
@@ -1644,9 +1487,7 @@ public final class SbtSettings {
|
||||
bundle.getBoolean(KEY_LAYOUT_STATUS_ENABLED_AOD, SbtDefaults.LAYOUT_STATUS_ENABLED_AOD_DEFAULT),
|
||||
bundle.getBoolean(KEY_LAYOUT_STATUS_ENABLED_LOCKSCREEN, SbtDefaults.LAYOUT_STATUS_ENABLED_LOCKSCREEN_DEFAULT),
|
||||
bundle.getBoolean(KEY_LAYOUT_STATUS_ENABLED_UNLOCKED, SbtDefaults.LAYOUT_STATUS_ENABLED_UNLOCKED_DEFAULT),
|
||||
bundle.getBoolean(KEY_LAYOUT_STATUS_SHOW_DOT_IF_TRUNCATED, SbtDefaults.LAYOUT_STATUS_SHOW_DOT_IF_TRUNCATED_DEFAULT),
|
||||
bundle.getString(KEY_LAYOUT_STATUS_MIDDLE_SIDE, SbtDefaults.LAYOUT_STATUS_MIDDLE_SIDE_DEFAULT),
|
||||
bundle.getBoolean(KEY_LAYOUT_STATUS_MIDDLE_AUTO_NEAREST_SIDE, SbtDefaults.LAYOUT_STATUS_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT),
|
||||
clampInt(bundle.getInt(KEY_LAYOUT_STATUS_VERTICAL_OFFSET_PX,
|
||||
SbtDefaults.LAYOUT_STATUS_VERTICAL_OFFSET_PX_DEFAULT),
|
||||
SbtDefaults.CLOCK_VERTICAL_OFFSET_PX_MIN,
|
||||
@@ -1677,10 +1518,6 @@ public final class SbtSettings {
|
||||
bundle,
|
||||
SbtSettings::layoutStatusMiddleSideKey,
|
||||
SbtDefaults.LAYOUT_STATUS_MIDDLE_SIDE_DEFAULT),
|
||||
readBooleanArrayFromBundle(
|
||||
bundle,
|
||||
SbtSettings::layoutStatusMiddleAutoNearestSideKey,
|
||||
SbtDefaults.LAYOUT_STATUS_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT),
|
||||
readIntArrayFromBundle(
|
||||
bundle,
|
||||
SbtSettings::layoutStatusVerticalOffsetKey,
|
||||
@@ -1699,10 +1536,6 @@ public final class SbtSettings {
|
||||
bundle,
|
||||
SbtSettings::layoutLockStatusMiddleSideKey,
|
||||
SbtDefaults.LAYOUT_STATUS_MIDDLE_SIDE_DEFAULT),
|
||||
readBooleanArrayFromBundle(
|
||||
bundle,
|
||||
SbtSettings::layoutLockStatusMiddleAutoNearestSideKey,
|
||||
SbtDefaults.LAYOUT_STATUS_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT),
|
||||
readIntArrayFromBundle(
|
||||
bundle,
|
||||
SbtSettings::layoutLockStatusVerticalOffsetKey,
|
||||
@@ -1721,10 +1554,6 @@ public final class SbtSettings {
|
||||
bundle,
|
||||
SbtSettings::layoutAodStatusMiddleSideKey,
|
||||
SbtDefaults.LAYOUT_STATUS_MIDDLE_SIDE_DEFAULT),
|
||||
readBooleanArrayFromBundle(
|
||||
bundle,
|
||||
SbtSettings::layoutAodStatusMiddleAutoNearestSideKey,
|
||||
SbtDefaults.LAYOUT_STATUS_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT),
|
||||
readIntArrayFromBundle(
|
||||
bundle,
|
||||
SbtSettings::layoutAodStatusVerticalOffsetKey,
|
||||
@@ -1829,20 +1658,6 @@ public final class SbtSettings {
|
||||
return result;
|
||||
}
|
||||
|
||||
private static boolean[] readBooleanArrayFromPrefs(
|
||||
SharedPreferences prefs,
|
||||
IndexedKey key,
|
||||
boolean fallback
|
||||
) {
|
||||
boolean[] result = new boolean[SbtDefaults.LAYOUT_ICON_CONTAINER_COUNT_MAX];
|
||||
boolean previous = fallback;
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
previous = prefs.contains(key.key(i)) ? prefs.getBoolean(key.key(i), previous) : previous;
|
||||
result[i] = previous;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static int[] readIntArrayFromPrefs(SharedPreferences prefs, IndexedKey key, int fallback) {
|
||||
int[] result = new int[SbtDefaults.LAYOUT_ICON_CONTAINER_COUNT_MAX];
|
||||
int previous = fallback;
|
||||
@@ -1863,16 +1678,6 @@ public final class SbtSettings {
|
||||
return result;
|
||||
}
|
||||
|
||||
private static boolean[] readBooleanArrayFromBundle(Bundle bundle, IndexedKey key, boolean fallback) {
|
||||
boolean[] result = new boolean[SbtDefaults.LAYOUT_ICON_CONTAINER_COUNT_MAX];
|
||||
boolean previous = fallback;
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
previous = bundle.containsKey(key.key(i)) ? bundle.getBoolean(key.key(i), previous) : previous;
|
||||
result[i] = previous;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static int[] readIntArrayFromBundle(Bundle bundle, IndexedKey key, int fallback) {
|
||||
int[] result = new int[SbtDefaults.LAYOUT_ICON_CONTAINER_COUNT_MAX];
|
||||
int previous = fallback;
|
||||
@@ -1892,14 +1697,6 @@ public final class SbtSettings {
|
||||
return result;
|
||||
}
|
||||
|
||||
private static boolean[] sanitizeBooleanArray(boolean[] source, boolean fallback, int length) {
|
||||
boolean[] result = new boolean[Math.max(0, length)];
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
result[i] = source != null && i < source.length ? source[i] : fallback;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static int[] sanitizeIntArray(int[] source, int fallback, int length, int min, int max) {
|
||||
int[] result = new int[Math.max(0, length)];
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
|
||||
@@ -195,27 +195,18 @@ public class SbtSettingsProvider extends ContentProvider {
|
||||
out.putString(SbtSettings.KEY_LAYOUT_CARRIER_MIDDLE_SIDE,
|
||||
prefs.getString(SbtSettings.KEY_LAYOUT_CARRIER_MIDDLE_SIDE,
|
||||
SbtDefaults.LAYOUT_CARRIER_MIDDLE_SIDE_DEFAULT));
|
||||
out.putBoolean(SbtSettings.KEY_LAYOUT_CARRIER_MIDDLE_AUTO_NEAREST_SIDE,
|
||||
prefs.getBoolean(SbtSettings.KEY_LAYOUT_CARRIER_MIDDLE_AUTO_NEAREST_SIDE,
|
||||
SbtDefaults.LAYOUT_CARRIER_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT));
|
||||
out.putInt(SbtSettings.KEY_LAYOUT_CARRIER_VERTICAL_OFFSET_PX,
|
||||
prefs.getInt(SbtSettings.KEY_LAYOUT_CARRIER_VERTICAL_OFFSET_PX,
|
||||
SbtDefaults.LAYOUT_CARRIER_VERTICAL_OFFSET_PX_DEFAULT));
|
||||
out.putString(SbtSettings.KEY_LAYOUT_CHIP_POSITION,
|
||||
prefs.getString(SbtSettings.KEY_LAYOUT_CHIP_POSITION,
|
||||
SbtDefaults.LAYOUT_CHIP_POSITION_DEFAULT));
|
||||
out.putBoolean(SbtSettings.KEY_LAYOUT_CHIP_ENABLED_LOCKSCREEN,
|
||||
prefs.getBoolean(SbtSettings.KEY_LAYOUT_CHIP_ENABLED_LOCKSCREEN,
|
||||
SbtDefaults.LAYOUT_CHIP_ENABLED_LOCKSCREEN_DEFAULT));
|
||||
out.putBoolean(SbtSettings.KEY_LAYOUT_CHIP_ENABLED_UNLOCKED,
|
||||
prefs.getBoolean(SbtSettings.KEY_LAYOUT_CHIP_ENABLED_UNLOCKED,
|
||||
SbtDefaults.LAYOUT_CHIP_ENABLED_UNLOCKED_DEFAULT));
|
||||
out.putString(SbtSettings.KEY_LAYOUT_CHIP_MIDDLE_SIDE,
|
||||
prefs.getString(SbtSettings.KEY_LAYOUT_CHIP_MIDDLE_SIDE,
|
||||
SbtDefaults.LAYOUT_CHIP_MIDDLE_SIDE_DEFAULT));
|
||||
out.putBoolean(SbtSettings.KEY_LAYOUT_CHIP_MIDDLE_AUTO_NEAREST_SIDE,
|
||||
prefs.getBoolean(SbtSettings.KEY_LAYOUT_CHIP_MIDDLE_AUTO_NEAREST_SIDE,
|
||||
SbtDefaults.LAYOUT_CHIP_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT));
|
||||
out.putInt(SbtSettings.KEY_LAYOUT_CHIP_VERTICAL_OFFSET_PX,
|
||||
prefs.getInt(SbtSettings.KEY_LAYOUT_CHIP_VERTICAL_OFFSET_PX,
|
||||
SbtDefaults.LAYOUT_CHIP_VERTICAL_OFFSET_PX_DEFAULT));
|
||||
@@ -228,9 +219,6 @@ public class SbtSettingsProvider extends ContentProvider {
|
||||
out.putString(SbtSettings.KEY_LAYOUT_NOTIF_SORT_ORDER,
|
||||
prefs.getString(SbtSettings.KEY_LAYOUT_NOTIF_SORT_ORDER,
|
||||
SbtDefaults.LAYOUT_NOTIF_SORT_ORDER_DEFAULT));
|
||||
out.putBoolean(SbtSettings.KEY_LAYOUT_NOTIF_SHOW_DOT_IF_TRUNCATED,
|
||||
prefs.getBoolean(SbtSettings.KEY_LAYOUT_NOTIF_SHOW_DOT_IF_TRUNCATED,
|
||||
SbtDefaults.LAYOUT_NOTIF_SHOW_DOT_IF_TRUNCATED_DEFAULT));
|
||||
out.putBoolean(SbtSettings.KEY_LAYOUT_NOTIF_ENABLED_AOD,
|
||||
prefs.getBoolean(SbtSettings.KEY_LAYOUT_NOTIF_ENABLED_AOD,
|
||||
SbtDefaults.LAYOUT_NOTIF_ENABLED_AOD_DEFAULT));
|
||||
@@ -250,9 +238,6 @@ public class SbtSettingsProvider extends ContentProvider {
|
||||
out.putString(SbtSettings.KEY_LAYOUT_NOTIF_MIDDLE_SIDE,
|
||||
prefs.getString(SbtSettings.KEY_LAYOUT_NOTIF_MIDDLE_SIDE,
|
||||
SbtDefaults.LAYOUT_NOTIF_MIDDLE_SIDE_DEFAULT));
|
||||
out.putBoolean(SbtSettings.KEY_LAYOUT_NOTIF_MIDDLE_AUTO_NEAREST_SIDE,
|
||||
prefs.getBoolean(SbtSettings.KEY_LAYOUT_NOTIF_MIDDLE_AUTO_NEAREST_SIDE,
|
||||
SbtDefaults.LAYOUT_NOTIF_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT));
|
||||
out.putInt(SbtSettings.KEY_LAYOUT_NOTIF_VERTICAL_OFFSET_PX,
|
||||
prefs.getInt(SbtSettings.KEY_LAYOUT_NOTIF_VERTICAL_OFFSET_PX,
|
||||
SbtDefaults.LAYOUT_NOTIF_VERTICAL_OFFSET_PX_DEFAULT));
|
||||
@@ -266,8 +251,6 @@ public class SbtSettingsProvider extends ContentProvider {
|
||||
SbtDefaults.LAYOUT_NOTIF_POSITION_DEFAULT,
|
||||
SbtSettings::layoutNotifMiddleSideKey,
|
||||
SbtDefaults.LAYOUT_NOTIF_MIDDLE_SIDE_DEFAULT,
|
||||
SbtSettings::layoutNotifMiddleAutoNearestSideKey,
|
||||
SbtDefaults.LAYOUT_NOTIF_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT,
|
||||
SbtSettings::layoutNotifVerticalOffsetKey,
|
||||
SbtDefaults.LAYOUT_NOTIF_VERTICAL_OFFSET_PX_DEFAULT);
|
||||
out.putInt(SbtSettings.KEY_LAYOUT_NOTIF_LOCK_COUNT,
|
||||
@@ -287,8 +270,6 @@ public class SbtSettingsProvider extends ContentProvider {
|
||||
SbtDefaults.LAYOUT_NOTIF_POSITION_DEFAULT,
|
||||
SbtSettings::layoutLockNotifMiddleSideKey,
|
||||
SbtDefaults.LAYOUT_NOTIF_MIDDLE_SIDE_DEFAULT,
|
||||
SbtSettings::layoutLockNotifMiddleAutoNearestSideKey,
|
||||
SbtDefaults.LAYOUT_NOTIF_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT,
|
||||
SbtSettings::layoutLockNotifVerticalOffsetKey,
|
||||
SbtDefaults.LAYOUT_NOTIF_VERTICAL_OFFSET_PX_DEFAULT);
|
||||
out.putInt(SbtSettings.KEY_LAYOUT_NOTIF_AOD_COUNT,
|
||||
@@ -308,8 +289,6 @@ public class SbtSettingsProvider extends ContentProvider {
|
||||
SbtDefaults.LAYOUT_NOTIF_POSITION_DEFAULT,
|
||||
SbtSettings::layoutAodNotifMiddleSideKey,
|
||||
SbtDefaults.LAYOUT_NOTIF_MIDDLE_SIDE_DEFAULT,
|
||||
SbtSettings::layoutAodNotifMiddleAutoNearestSideKey,
|
||||
SbtDefaults.LAYOUT_NOTIF_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT,
|
||||
SbtSettings::layoutAodNotifVerticalOffsetKey,
|
||||
SbtDefaults.LAYOUT_NOTIF_VERTICAL_OFFSET_PX_DEFAULT);
|
||||
out.putString(SbtSettings.KEY_LAYOUT_STATUS_POSITION,
|
||||
@@ -331,15 +310,9 @@ public class SbtSettingsProvider extends ContentProvider {
|
||||
SbtDefaults.LAYOUT_STATUS_ENABLED_UNLOCKED_DEFAULT)
|
||||
? SbtDefaults.LAYOUT_STATUS_UNLOCKED_COUNT_DEFAULT
|
||||
: 0));
|
||||
out.putBoolean(SbtSettings.KEY_LAYOUT_STATUS_SHOW_DOT_IF_TRUNCATED,
|
||||
prefs.getBoolean(SbtSettings.KEY_LAYOUT_STATUS_SHOW_DOT_IF_TRUNCATED,
|
||||
SbtDefaults.LAYOUT_STATUS_SHOW_DOT_IF_TRUNCATED_DEFAULT));
|
||||
out.putString(SbtSettings.KEY_LAYOUT_STATUS_MIDDLE_SIDE,
|
||||
prefs.getString(SbtSettings.KEY_LAYOUT_STATUS_MIDDLE_SIDE,
|
||||
SbtDefaults.LAYOUT_STATUS_MIDDLE_SIDE_DEFAULT));
|
||||
out.putBoolean(SbtSettings.KEY_LAYOUT_STATUS_MIDDLE_AUTO_NEAREST_SIDE,
|
||||
prefs.getBoolean(SbtSettings.KEY_LAYOUT_STATUS_MIDDLE_AUTO_NEAREST_SIDE,
|
||||
SbtDefaults.LAYOUT_STATUS_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT));
|
||||
out.putInt(SbtSettings.KEY_LAYOUT_STATUS_VERTICAL_OFFSET_PX,
|
||||
prefs.getInt(SbtSettings.KEY_LAYOUT_STATUS_VERTICAL_OFFSET_PX,
|
||||
SbtDefaults.LAYOUT_STATUS_VERTICAL_OFFSET_PX_DEFAULT));
|
||||
@@ -353,8 +326,6 @@ public class SbtSettingsProvider extends ContentProvider {
|
||||
SbtDefaults.LAYOUT_STATUS_POSITION_DEFAULT,
|
||||
SbtSettings::layoutStatusMiddleSideKey,
|
||||
SbtDefaults.LAYOUT_STATUS_MIDDLE_SIDE_DEFAULT,
|
||||
SbtSettings::layoutStatusMiddleAutoNearestSideKey,
|
||||
SbtDefaults.LAYOUT_STATUS_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT,
|
||||
SbtSettings::layoutStatusVerticalOffsetKey,
|
||||
SbtDefaults.LAYOUT_STATUS_VERTICAL_OFFSET_PX_DEFAULT);
|
||||
out.putInt(SbtSettings.KEY_LAYOUT_STATUS_LOCK_COUNT,
|
||||
@@ -374,8 +345,6 @@ public class SbtSettingsProvider extends ContentProvider {
|
||||
SbtDefaults.LAYOUT_STATUS_POSITION_DEFAULT,
|
||||
SbtSettings::layoutLockStatusMiddleSideKey,
|
||||
SbtDefaults.LAYOUT_STATUS_MIDDLE_SIDE_DEFAULT,
|
||||
SbtSettings::layoutLockStatusMiddleAutoNearestSideKey,
|
||||
SbtDefaults.LAYOUT_STATUS_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT,
|
||||
SbtSettings::layoutLockStatusVerticalOffsetKey,
|
||||
SbtDefaults.LAYOUT_STATUS_VERTICAL_OFFSET_PX_DEFAULT);
|
||||
out.putInt(SbtSettings.KEY_LAYOUT_STATUS_AOD_COUNT,
|
||||
@@ -395,8 +364,6 @@ public class SbtSettingsProvider extends ContentProvider {
|
||||
SbtDefaults.LAYOUT_STATUS_POSITION_DEFAULT,
|
||||
SbtSettings::layoutAodStatusMiddleSideKey,
|
||||
SbtDefaults.LAYOUT_STATUS_MIDDLE_SIDE_DEFAULT,
|
||||
SbtSettings::layoutAodStatusMiddleAutoNearestSideKey,
|
||||
SbtDefaults.LAYOUT_STATUS_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT,
|
||||
SbtSettings::layoutAodStatusVerticalOffsetKey,
|
||||
SbtDefaults.LAYOUT_STATUS_VERTICAL_OFFSET_PX_DEFAULT);
|
||||
putStringSetArrayList(out, prefs, SbtSettings.KEY_CLOCK_CAMERA_TYPE_OVERRIDES);
|
||||
@@ -465,14 +432,11 @@ public class SbtSettingsProvider extends ContentProvider {
|
||||
String positionDefault,
|
||||
SbtSettings.IndexedKey middleSideKey,
|
||||
String middleSideDefault,
|
||||
SbtSettings.IndexedKey autoNearestKey,
|
||||
boolean autoNearestDefault,
|
||||
SbtSettings.IndexedKey verticalOffsetKey,
|
||||
int verticalOffsetDefault
|
||||
) {
|
||||
String position = positionDefault;
|
||||
String middleSide = middleSideDefault;
|
||||
boolean autoNearest = autoNearestDefault;
|
||||
int verticalOffset = verticalOffsetDefault;
|
||||
for (int i = 0; i < SbtDefaults.LAYOUT_ICON_CONTAINER_COUNT_MAX; i++) {
|
||||
position = prefs.contains(positionKey.key(i))
|
||||
@@ -481,15 +445,11 @@ public class SbtSettingsProvider extends ContentProvider {
|
||||
middleSide = prefs.contains(middleSideKey.key(i))
|
||||
? prefs.getString(middleSideKey.key(i), middleSide)
|
||||
: middleSide;
|
||||
autoNearest = prefs.contains(autoNearestKey.key(i))
|
||||
? prefs.getBoolean(autoNearestKey.key(i), autoNearest)
|
||||
: autoNearest;
|
||||
verticalOffset = prefs.contains(verticalOffsetKey.key(i))
|
||||
? prefs.getInt(verticalOffsetKey.key(i), verticalOffset)
|
||||
: verticalOffset;
|
||||
out.putString(positionKey.key(i), position);
|
||||
out.putString(middleSideKey.key(i), middleSide);
|
||||
out.putBoolean(autoNearestKey.key(i), autoNearest);
|
||||
out.putInt(verticalOffsetKey.key(i), verticalOffset);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,31 +56,31 @@ public final class LayoutFragment extends Fragment {
|
||||
prefs,
|
||||
R.id.notif_position_group,
|
||||
R.id.notif_position_middle_options_container,
|
||||
R.id.notif_middle_auto_nearest,
|
||||
View.NO_ID,
|
||||
R.id.notif_middle_side_prompt,
|
||||
SbtSettings.KEY_LAYOUT_NOTIF_POSITION,
|
||||
SbtDefaults.LAYOUT_NOTIF_POSITION_DEFAULT,
|
||||
SbtSettings.KEY_LAYOUT_NOTIF_MIDDLE_AUTO_NEAREST_SIDE,
|
||||
null,
|
||||
SbtSettings.KEY_LAYOUT_NOTIF_MIDDLE_SIDE);
|
||||
setupPositionSection(root,
|
||||
prefs,
|
||||
R.id.chip_position_group,
|
||||
R.id.chip_position_middle_options_container,
|
||||
R.id.chip_middle_auto_nearest,
|
||||
View.NO_ID,
|
||||
R.id.chip_middle_side_prompt,
|
||||
SbtSettings.KEY_LAYOUT_CHIP_POSITION,
|
||||
SbtDefaults.LAYOUT_CHIP_POSITION_DEFAULT,
|
||||
SbtSettings.KEY_LAYOUT_CHIP_MIDDLE_AUTO_NEAREST_SIDE,
|
||||
null,
|
||||
SbtSettings.KEY_LAYOUT_CHIP_MIDDLE_SIDE);
|
||||
setupPositionSection(root,
|
||||
prefs,
|
||||
R.id.status_position_group,
|
||||
R.id.status_position_middle_options_container,
|
||||
R.id.status_middle_auto_nearest,
|
||||
View.NO_ID,
|
||||
R.id.status_middle_side_prompt,
|
||||
SbtSettings.KEY_LAYOUT_STATUS_POSITION,
|
||||
SbtDefaults.LAYOUT_STATUS_POSITION_DEFAULT,
|
||||
SbtSettings.KEY_LAYOUT_STATUS_MIDDLE_AUTO_NEAREST_SIDE,
|
||||
null,
|
||||
SbtSettings.KEY_LAYOUT_STATUS_MIDDLE_SIDE);
|
||||
|
||||
bindStepper(prefs,
|
||||
@@ -150,12 +150,10 @@ public final class LayoutFragment extends Fragment {
|
||||
SbtSettings.KEY_LAYOUT_NOTIF_ENABLED_UNLOCKED,
|
||||
SbtDefaults.LAYOUT_NOTIF_ENABLED_UNLOCKED_DEFAULT,
|
||||
SbtSettings::layoutNotifPositionKey,
|
||||
SbtSettings::layoutNotifMiddleAutoNearestSideKey,
|
||||
SbtSettings::layoutNotifMiddleSideKey,
|
||||
SbtSettings::layoutNotifVerticalOffsetKey,
|
||||
SbtSettings.KEY_LAYOUT_NOTIF_ICON_HEIGHT_STEPS,
|
||||
SbtDefaults.LAYOUT_NOTIF_POSITION_DEFAULT,
|
||||
SbtDefaults.LAYOUT_NOTIF_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT,
|
||||
SbtDefaults.LAYOUT_NOTIF_MIDDLE_SIDE_DEFAULT,
|
||||
SbtDefaults.LAYOUT_NOTIF_VERTICAL_OFFSET_PX_DEFAULT,
|
||||
SbtDefaults.LAYOUT_NOTIF_ICON_HEIGHT_STEPS_DEFAULT,
|
||||
@@ -170,12 +168,10 @@ public final class LayoutFragment extends Fragment {
|
||||
SbtSettings.KEY_LAYOUT_STATUS_ENABLED_UNLOCKED,
|
||||
SbtDefaults.LAYOUT_STATUS_ENABLED_UNLOCKED_DEFAULT,
|
||||
SbtSettings::layoutStatusPositionKey,
|
||||
SbtSettings::layoutStatusMiddleAutoNearestSideKey,
|
||||
SbtSettings::layoutStatusMiddleSideKey,
|
||||
SbtSettings::layoutStatusVerticalOffsetKey,
|
||||
SbtSettings.KEY_LAYOUT_STATUS_ICON_HEIGHT_STEPS,
|
||||
SbtDefaults.LAYOUT_STATUS_POSITION_DEFAULT,
|
||||
SbtDefaults.LAYOUT_STATUS_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT,
|
||||
SbtDefaults.LAYOUT_STATUS_MIDDLE_SIDE_DEFAULT,
|
||||
SbtDefaults.LAYOUT_STATUS_VERTICAL_OFFSET_PX_DEFAULT,
|
||||
SbtDefaults.LAYOUT_STATUS_ICON_HEIGHT_STEPS_DEFAULT,
|
||||
@@ -193,12 +189,10 @@ public final class LayoutFragment extends Fragment {
|
||||
String legacyEnabledKey,
|
||||
boolean legacyEnabledDefault,
|
||||
SbtSettings.IndexedKey positionKey,
|
||||
SbtSettings.IndexedKey autoNearestKey,
|
||||
SbtSettings.IndexedKey middleSideKey,
|
||||
SbtSettings.IndexedKey verticalOffsetKey,
|
||||
String iconHeightKey,
|
||||
String positionDefault,
|
||||
boolean autoNearestDefault,
|
||||
String middleSideDefault,
|
||||
int verticalOffsetDefault,
|
||||
int iconHeightDefault,
|
||||
@@ -225,7 +219,12 @@ public final class LayoutFragment extends Fragment {
|
||||
rebuild[0] = () -> {
|
||||
countContainer.removeAllViews();
|
||||
removeGeneratedCopyCards(cardsParent, copyTag);
|
||||
int count = iconContainerCount(prefs, countKey, countDefault, legacyEnabledKey, legacyEnabledDefault);
|
||||
int count = ViewTreeSupport.iconContainerCount(
|
||||
prefs,
|
||||
countKey,
|
||||
legacyEnabledKey,
|
||||
countDefault,
|
||||
legacyEnabledDefault);
|
||||
LayoutXmlCardSupport.setIndexedCardTitle(requireContext(), sourceCard, sectionTitleId, 0, count);
|
||||
boolean cardsMode = LockedNotificationModeUi.MODE_CARDS.equals(
|
||||
LockedNotificationModeUi.currentMode(requireContext()));
|
||||
@@ -238,11 +237,15 @@ public final class LayoutFragment extends Fragment {
|
||||
cardsMode,
|
||||
0,
|
||||
this::refreshSelf);
|
||||
countContainer.addView(iconContainerCountControl(
|
||||
countContainer.addView(ViewTreeSupport.iconContainerCountControl(
|
||||
requireContext(),
|
||||
count,
|
||||
value -> ViewTreeSupport.persistIconContainerCount(
|
||||
requireContext(),
|
||||
prefs,
|
||||
countKey,
|
||||
count,
|
||||
legacyEnabledKey,
|
||||
value),
|
||||
() -> {
|
||||
if (rebuild[0] != null) {
|
||||
rebuild[0].run();
|
||||
@@ -264,11 +267,9 @@ public final class LayoutFragment extends Fragment {
|
||||
sectionTitleId,
|
||||
i,
|
||||
positionKey,
|
||||
autoNearestKey,
|
||||
middleSideKey,
|
||||
verticalOffsetKey,
|
||||
positionDefault,
|
||||
autoNearestDefault,
|
||||
middleSideDefault,
|
||||
verticalOffsetDefault,
|
||||
copyTag);
|
||||
@@ -294,105 +295,28 @@ public final class LayoutFragment extends Fragment {
|
||||
});
|
||||
}
|
||||
|
||||
private View iconContainerCountControl(
|
||||
SharedPreferences prefs,
|
||||
String countKey,
|
||||
int current,
|
||||
String legacyEnabledKey,
|
||||
Runnable onChanged
|
||||
) {
|
||||
Context context = requireContext();
|
||||
LinearLayout outer = ViewTreeSupport.verticalLayout(context);
|
||||
TextView label = ViewTreeSupport.bodyText(context, R.string.layout_icon_container_count, 0);
|
||||
outer.addView(label);
|
||||
|
||||
LinearLayout row = new LinearLayout(context);
|
||||
row.setOrientation(LinearLayout.HORIZONTAL);
|
||||
row.setGravity(android.view.Gravity.CENTER_VERTICAL);
|
||||
MaterialButton minus = ViewTreeSupport.outlinedStepperButton(context, "-");
|
||||
MaterialButton plus = ViewTreeSupport.outlinedStepperButton(context, "+");
|
||||
EditText input = ViewTreeSupport.numericInput(context, false, 1);
|
||||
input.setText(String.valueOf(current));
|
||||
row.addView(minus, ViewTreeSupport.stepperButtonParams(context));
|
||||
row.addView(input, ViewTreeSupport.stepperInputParams(context));
|
||||
row.addView(plus, ViewTreeSupport.stepperButtonParams(context));
|
||||
outer.addView(row);
|
||||
|
||||
View.OnClickListener listener = view -> {
|
||||
int next = SbtSettings.clampIconContainerCount(
|
||||
ViewTreeSupport.parseInt(input, current) + (view == minus ? -1 : 1));
|
||||
persistIconContainerCount(prefs, countKey, legacyEnabledKey, next);
|
||||
onChanged.run();
|
||||
};
|
||||
minus.setOnClickListener(listener);
|
||||
plus.setOnClickListener(listener);
|
||||
input.setOnFocusChangeListener((v, hasFocus) -> {
|
||||
if (!hasFocus) {
|
||||
int next = SbtSettings.clampIconContainerCount(ViewTreeSupport.parseInt(input, current));
|
||||
persistIconContainerCount(prefs, countKey, legacyEnabledKey, next);
|
||||
onChanged.run();
|
||||
}
|
||||
});
|
||||
return outer;
|
||||
}
|
||||
|
||||
private View iconHeightControl(
|
||||
SharedPreferences prefs,
|
||||
String key,
|
||||
int defaultValue,
|
||||
int labelRes
|
||||
) {
|
||||
Context context = requireContext();
|
||||
LinearLayout outer = ViewTreeSupport.verticalLayout(context);
|
||||
TextView label = ViewTreeSupport.bodyText(context, labelRes, 0);
|
||||
outer.addView(label);
|
||||
|
||||
LinearLayout row = new LinearLayout(context);
|
||||
row.setOrientation(LinearLayout.HORIZONTAL);
|
||||
row.setGravity(android.view.Gravity.CENTER_VERTICAL);
|
||||
MaterialButton minus = ViewTreeSupport.outlinedStepperButton(context, "-");
|
||||
MaterialButton plus = ViewTreeSupport.outlinedStepperButton(context, "+");
|
||||
MaterialButton reset = ViewTreeSupport.outlinedStepperButton(context, "D");
|
||||
EditText input = ViewTreeSupport.numericInput(context, false, 3);
|
||||
int current = SbtSettings.clampIconHeightSteps(prefs.getInt(key, defaultValue));
|
||||
input.setText(String.valueOf(current));
|
||||
row.addView(minus, ViewTreeSupport.stepperButtonParams(context));
|
||||
row.addView(input, ViewTreeSupport.stepperInputParams(context));
|
||||
row.addView(plus, ViewTreeSupport.stepperButtonParams(context));
|
||||
LinearLayout.LayoutParams resetParams = ViewTreeSupport.stepperButtonParams(context);
|
||||
resetParams.leftMargin = ViewTreeSupport.dp(context, 8);
|
||||
row.addView(reset, resetParams);
|
||||
outer.addView(row);
|
||||
|
||||
View.OnClickListener listener = view -> {
|
||||
int next = SbtSettings.clampIconHeightSteps(
|
||||
ViewTreeSupport.parseInt(input, current) + (view == minus ? -1 : 1));
|
||||
persistIconHeight(prefs, key, input, next);
|
||||
};
|
||||
minus.setOnClickListener(listener);
|
||||
plus.setOnClickListener(listener);
|
||||
reset.setOnClickListener(v -> {
|
||||
int next = SbtSettings.clampIconHeightSteps(defaultValue);
|
||||
persistIconHeight(prefs, key, input, next);
|
||||
});
|
||||
input.setOnFocusChangeListener((v, hasFocus) -> {
|
||||
if (!hasFocus) {
|
||||
int next = SbtSettings.clampIconHeightSteps(ViewTreeSupport.parseInt(input, current));
|
||||
persistIconHeight(prefs, key, input, next);
|
||||
}
|
||||
});
|
||||
return outer;
|
||||
}
|
||||
|
||||
private void persistIconHeight(
|
||||
SharedPreferences prefs,
|
||||
String key,
|
||||
EditText input,
|
||||
int value
|
||||
) {
|
||||
prefs.edit().putInt(key, value).apply();
|
||||
SbtSettings.ensureReadable(requireContext());
|
||||
input.setText(String.valueOf(value));
|
||||
return ViewTreeSupport.intPreferenceStepper(
|
||||
requireContext(),
|
||||
prefs,
|
||||
labelRes,
|
||||
key,
|
||||
defaultValue,
|
||||
SbtDefaults.LAYOUT_ICON_HEIGHT_STEPS_MIN,
|
||||
SbtDefaults.LAYOUT_ICON_HEIGHT_STEPS_MAX,
|
||||
false,
|
||||
3,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
true,
|
||||
true,
|
||||
null);
|
||||
}
|
||||
|
||||
private void addChipHeightControl(View root, SharedPreferences prefs) {
|
||||
@@ -424,11 +348,9 @@ public final class LayoutFragment extends Fragment {
|
||||
int titleId,
|
||||
int index,
|
||||
SbtSettings.IndexedKey positionKey,
|
||||
SbtSettings.IndexedKey autoNearestKey,
|
||||
SbtSettings.IndexedKey middleSideKey,
|
||||
SbtSettings.IndexedKey verticalOffsetKey,
|
||||
String positionDefault,
|
||||
boolean autoNearestDefault,
|
||||
String middleSideDefault,
|
||||
int verticalOffsetDefault,
|
||||
String copyTag
|
||||
@@ -447,11 +369,11 @@ public final class LayoutFragment extends Fragment {
|
||||
prefs,
|
||||
R.id.notif_position_group,
|
||||
R.id.notif_position_middle_options_container,
|
||||
R.id.notif_middle_auto_nearest,
|
||||
View.NO_ID,
|
||||
R.id.notif_middle_side_prompt,
|
||||
positionKey.key(index),
|
||||
positionDefault,
|
||||
autoNearestKey.key(index),
|
||||
null,
|
||||
middleSideKey.key(index));
|
||||
bindStepper(prefs,
|
||||
verticalOffsetKey.key(index),
|
||||
@@ -467,11 +389,11 @@ public final class LayoutFragment extends Fragment {
|
||||
prefs,
|
||||
R.id.status_position_group,
|
||||
R.id.status_position_middle_options_container,
|
||||
R.id.status_middle_auto_nearest,
|
||||
View.NO_ID,
|
||||
R.id.status_middle_side_prompt,
|
||||
positionKey.key(index),
|
||||
positionDefault,
|
||||
autoNearestKey.key(index),
|
||||
null,
|
||||
middleSideKey.key(index));
|
||||
bindStepper(prefs,
|
||||
verticalOffsetKey.key(index),
|
||||
@@ -563,30 +485,6 @@ public final class LayoutFragment extends Fragment {
|
||||
}
|
||||
}
|
||||
|
||||
private int iconContainerCount(
|
||||
SharedPreferences prefs,
|
||||
String countKey,
|
||||
int countDefault,
|
||||
String legacyEnabledKey,
|
||||
boolean legacyEnabledDefault
|
||||
) {
|
||||
int fallback = prefs.getBoolean(legacyEnabledKey, legacyEnabledDefault) ? countDefault : 0;
|
||||
return SbtSettings.clampIconContainerCount(prefs.getInt(countKey, fallback));
|
||||
}
|
||||
|
||||
private void persistIconContainerCount(
|
||||
SharedPreferences prefs,
|
||||
String countKey,
|
||||
String legacyEnabledKey,
|
||||
int count
|
||||
) {
|
||||
prefs.edit()
|
||||
.putInt(countKey, SbtSettings.clampIconContainerCount(count))
|
||||
.putBoolean(legacyEnabledKey, count > 0)
|
||||
.apply();
|
||||
SbtSettings.ensureReadable(requireContext());
|
||||
}
|
||||
|
||||
private void hideUnlockedSubpageObsoleteControls(View root) {
|
||||
hide(root, R.id.clock_position_mode_lockscreen);
|
||||
hide(root, R.id.notif_position_mode_aod);
|
||||
@@ -620,43 +518,42 @@ public final class LayoutFragment extends Fragment {
|
||||
int middleOptionsId,
|
||||
int autoNearestId,
|
||||
int promptId,
|
||||
@Nullable String positionKey,
|
||||
@Nullable String positionDefault,
|
||||
String positionKey,
|
||||
String positionDefault,
|
||||
@Nullable String autoNearestKey,
|
||||
@Nullable String middleSideKey) {
|
||||
String middleSideKey) {
|
||||
RadioGroup group = root.findViewById(groupId);
|
||||
View middleOptions = root.findViewById(middleOptionsId);
|
||||
CheckBox autoNearest = root.findViewById(autoNearestId);
|
||||
TextView prompt = root.findViewById(promptId);
|
||||
if (group == null || middleOptions == null || autoNearest == null || prompt == null) {
|
||||
if (group == null || middleOptions == null || prompt == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (positionKey != null && positionDefault != null) {
|
||||
group.check(positionIdForValue(groupId, prefs.getString(positionKey, positionDefault)));
|
||||
}
|
||||
if (autoNearestKey != null) {
|
||||
boolean autoNearestAvailable = autoNearestKey != null && autoNearest != null;
|
||||
if (autoNearestAvailable) {
|
||||
autoNearest.setChecked(prefs.getBoolean(autoNearestKey, true));
|
||||
} else if (autoNearest != null) {
|
||||
autoNearest.setChecked(false);
|
||||
autoNearest.setVisibility(View.GONE);
|
||||
}
|
||||
updateMiddleOptions(middleOptions, autoNearest, prompt, group.getCheckedRadioButtonId());
|
||||
|
||||
group.setOnCheckedChangeListener((radioGroup, id) -> {
|
||||
updateMiddleOptions(middleOptions, autoNearest, prompt, id);
|
||||
if (positionKey != null) {
|
||||
prefs.edit().putString(positionKey, positionValueForId(id)).apply();
|
||||
SbtSettings.ensureReadable(requireContext());
|
||||
}
|
||||
});
|
||||
|
||||
if (autoNearestAvailable) {
|
||||
autoNearest.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
updateMiddlePrompt(prompt, isChecked);
|
||||
if (autoNearestKey != null) {
|
||||
prefs.edit().putBoolean(autoNearestKey, isChecked).apply();
|
||||
SbtSettings.ensureReadable(requireContext());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (middleSideKey != null) {
|
||||
RadioGroup sideGroup = resolveMiddleSideGroup(root, groupId);
|
||||
if (sideGroup != null) {
|
||||
sideGroup.check(sideIdForValue(sideGroup, prefs.getString(middleSideKey, "left")));
|
||||
@@ -666,13 +563,12 @@ public final class LayoutFragment extends Fragment {
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateMiddleOptions(View middleOptions,
|
||||
CheckBox autoNearest,
|
||||
@Nullable CheckBox autoNearest,
|
||||
TextView prompt,
|
||||
int checkedId) {
|
||||
if (middleOptions == null || autoNearest == null || prompt == null) {
|
||||
if (middleOptions == null || prompt == null) {
|
||||
return;
|
||||
}
|
||||
if (middleOptions.getVisibility() != View.VISIBLE) {
|
||||
@@ -681,7 +577,7 @@ public final class LayoutFragment extends Fragment {
|
||||
boolean enabled = isMiddleSelection(checkedId);
|
||||
ViewTreeSupport.setEnabledRecursive(middleOptions, enabled);
|
||||
middleOptions.setAlpha(enabled ? 1f : 0.45f);
|
||||
updateMiddlePrompt(prompt, autoNearest.isChecked());
|
||||
updateMiddlePrompt(prompt, autoNearest != null && autoNearest.isChecked());
|
||||
}
|
||||
|
||||
private boolean isMiddleSelection(int checkedId) {
|
||||
@@ -700,37 +596,6 @@ public final class LayoutFragment extends Fragment {
|
||||
: R.string.layout_middle_side_prompt_attach_only);
|
||||
}
|
||||
|
||||
private void bindStepper(SharedPreferences prefs,
|
||||
@Nullable String key,
|
||||
@Nullable EditText input,
|
||||
@Nullable MaterialButton minusButton,
|
||||
@Nullable MaterialButton plusButton,
|
||||
int initialValue) {
|
||||
bindStepper(prefs, key, input, null, minusButton, plusButton, null, null, initialValue);
|
||||
}
|
||||
|
||||
private void bindStepper(SharedPreferences prefs,
|
||||
@Nullable String key,
|
||||
@Nullable EditText input,
|
||||
@Nullable MaterialButton minusButton,
|
||||
@Nullable MaterialButton plusButton,
|
||||
int initialValue,
|
||||
int minValue,
|
||||
int maxValue) {
|
||||
bindStepper(
|
||||
prefs,
|
||||
key,
|
||||
input,
|
||||
null,
|
||||
minusButton,
|
||||
plusButton,
|
||||
null,
|
||||
null,
|
||||
initialValue,
|
||||
minValue,
|
||||
maxValue);
|
||||
}
|
||||
|
||||
private void bindStepper(SharedPreferences prefs,
|
||||
@Nullable String key,
|
||||
@Nullable EditText input,
|
||||
@@ -880,8 +745,7 @@ public final class LayoutFragment extends Fragment {
|
||||
if (key == null) {
|
||||
return;
|
||||
}
|
||||
prefs.edit().putInt(key, value).apply();
|
||||
SbtSettings.ensureReadable(requireContext());
|
||||
ViewTreeSupport.persistIntPreference(requireContext(), prefs, key, value);
|
||||
}
|
||||
|
||||
private int positionIdForValue(int groupId, @Nullable String value) {
|
||||
|
||||
@@ -6,7 +6,6 @@ import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RadioGroup;
|
||||
import android.widget.ScrollView;
|
||||
@@ -16,7 +15,6 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.google.android.material.button.MaterialButton;
|
||||
import com.google.android.material.switchmaterial.SwitchMaterial;
|
||||
|
||||
import se.ajpanton.statusbartweak.R;
|
||||
@@ -38,7 +36,7 @@ public final class LayoutHomeFragment extends Fragment {
|
||||
Context context = requireContext();
|
||||
SharedPreferences prefs = context.getSharedPreferences(SbtSettings.PREFS_NAME, Context.MODE_PRIVATE);
|
||||
ScrollView scroll = new ScrollView(context);
|
||||
LinearLayout root = vertical(context);
|
||||
LinearLayout root = ViewTreeSupport.verticalLayout(context);
|
||||
root.setPadding(
|
||||
ViewTreeSupport.dp(context, 20),
|
||||
ViewTreeSupport.dp(context, 20),
|
||||
@@ -46,23 +44,23 @@ public final class LayoutHomeFragment extends Fragment {
|
||||
ViewTreeSupport.dp(context, 20));
|
||||
scroll.addView(root);
|
||||
|
||||
TextView title = title(context, R.string.layout_home_title);
|
||||
TextView title = ViewTreeSupport.titleText(context, R.string.layout_home_title);
|
||||
root.addView(title);
|
||||
|
||||
SwitchMaterial master = new SwitchMaterial(context);
|
||||
master.setText(R.string.layout_enabled);
|
||||
master.setChecked(prefs.getBoolean(SbtSettings.KEY_CLOCK_ENABLED, SbtDefaults.CLOCK_ENABLED_DEFAULT));
|
||||
root.addView(card(context, R.string.layout_master_toggle_title, master));
|
||||
root.addView(outlinedCard(context, R.string.layout_master_toggle_title, master));
|
||||
|
||||
lockedModeGroup = new RadioGroup(context);
|
||||
lockedModeGroup.setOrientation(RadioGroup.VERTICAL);
|
||||
lockedModeHint = body(context, R.string.layout_locked_notifications_hint);
|
||||
LinearLayout lockedContent = vertical(context);
|
||||
lockedModeHint = ViewTreeSupport.bodyText(context, R.string.layout_locked_notifications_hint, 0);
|
||||
LinearLayout lockedContent = ViewTreeSupport.verticalLayout(context);
|
||||
lockedContent.addView(lockedModeHint);
|
||||
lockedContent.addView(lockedModeGroup);
|
||||
root.addView(card(context, R.string.layout_locked_notifications_title, lockedContent));
|
||||
root.addView(outlinedCard(context, R.string.layout_locked_notifications_title, lockedContent));
|
||||
|
||||
layoutOnContainer = vertical(context);
|
||||
layoutOnContainer = ViewTreeSupport.verticalLayout(context);
|
||||
layoutOnContainer.addView(paddingCard(context, prefs));
|
||||
layoutOnContainer.addView(LayoutOrderingUi.createCard(context, prefs));
|
||||
root.addView(layoutOnContainer);
|
||||
@@ -94,7 +92,7 @@ public final class LayoutHomeFragment extends Fragment {
|
||||
}
|
||||
|
||||
private View paddingCard(Context context, SharedPreferences prefs) {
|
||||
LinearLayout content = vertical(context);
|
||||
LinearLayout content = ViewTreeSupport.verticalLayout(context);
|
||||
content.addView(stepper(
|
||||
context,
|
||||
prefs,
|
||||
@@ -141,12 +139,12 @@ public final class LayoutHomeFragment extends Fragment {
|
||||
SbtDefaults.LAYOUT_ITEM_PADDING_PX_DEFAULT,
|
||||
SbtDefaults.LAYOUT_ITEM_PADDING_PX_MIN,
|
||||
SbtDefaults.LAYOUT_ITEM_PADDING_PX_MAX));
|
||||
return card(context, R.string.layout_padding_title, content);
|
||||
return outlinedCard(context, R.string.layout_padding_title, content);
|
||||
}
|
||||
|
||||
private View miscCard(Context context, SharedPreferences prefs) {
|
||||
LinearLayout content = vertical(context);
|
||||
miscLayoutOnContainer = vertical(context);
|
||||
LinearLayout content = ViewTreeSupport.verticalLayout(context);
|
||||
miscLayoutOnContainer = ViewTreeSupport.verticalLayout(context);
|
||||
miscLayoutOnContainer.addView(ViewTreeSupport.boundCheckBox(
|
||||
context,
|
||||
prefs,
|
||||
@@ -155,7 +153,7 @@ public final class LayoutHomeFragment extends Fragment {
|
||||
SbtDefaults.LAYOUT_IGNORE_UNDER_DISPLAY_CAMERAS_DEFAULT,
|
||||
false));
|
||||
content.addView(miscLayoutOnContainer);
|
||||
miscUnlockedOffOnlyContainer = vertical(context);
|
||||
miscUnlockedOffOnlyContainer = ViewTreeSupport.verticalLayout(context);
|
||||
miscUnlockedOffOnlyContainer.addView(stepper(
|
||||
context,
|
||||
prefs,
|
||||
@@ -165,7 +163,7 @@ public final class LayoutHomeFragment extends Fragment {
|
||||
SbtDefaults.UNLOCKED_MAX_ICONS_PER_ROW_MIN,
|
||||
SbtDefaults.UNLOCKED_MAX_ICONS_PER_ROW_MAX));
|
||||
content.addView(miscUnlockedOffOnlyContainer);
|
||||
return card(context, R.string.layout_misc_title, content);
|
||||
return outlinedCard(context, R.string.layout_misc_title, content);
|
||||
}
|
||||
|
||||
private View stepper(
|
||||
@@ -190,65 +188,28 @@ public final class LayoutHomeFragment extends Fragment {
|
||||
int max,
|
||||
@Nullable View trailingView
|
||||
) {
|
||||
LinearLayout outer = vertical(context);
|
||||
TextView label = body(context, labelId);
|
||||
outer.addView(label);
|
||||
LinearLayout row = new LinearLayout(context);
|
||||
row.setOrientation(LinearLayout.HORIZONTAL);
|
||||
row.setGravity(android.view.Gravity.CENTER_VERTICAL);
|
||||
row.setPadding(0, ViewTreeSupport.dp(context, 6), 0, ViewTreeSupport.dp(context, 8));
|
||||
MaterialButton minus = ViewTreeSupport.outlinedStepperButton(context, "-");
|
||||
MaterialButton plus = ViewTreeSupport.outlinedStepperButton(context, "+");
|
||||
EditText input = ViewTreeSupport.numericInput(context, true, 5);
|
||||
input.setText(String.valueOf(ViewTreeSupport.clamp(prefs.getInt(key, defaultValue), min, max)));
|
||||
row.addView(minus, ViewTreeSupport.stepperButtonParams(context));
|
||||
row.addView(input, ViewTreeSupport.stepperInputParams(context));
|
||||
row.addView(plus, ViewTreeSupport.stepperButtonParams(context));
|
||||
if (trailingView != null) {
|
||||
LinearLayout.LayoutParams trailingParams = new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
trailingParams.leftMargin = ViewTreeSupport.dp(context, 8);
|
||||
row.addView(trailingView, trailingParams);
|
||||
}
|
||||
outer.addView(row);
|
||||
View.OnClickListener listener = v -> {
|
||||
int delta = v == minus ? -1 : 1;
|
||||
int next = ViewTreeSupport.clamp(ViewTreeSupport.parseInt(input, defaultValue) + delta, min, max);
|
||||
input.setText(String.valueOf(next));
|
||||
prefs.edit().putInt(key, next).apply();
|
||||
SbtSettings.ensureReadable(context);
|
||||
};
|
||||
minus.setOnClickListener(listener);
|
||||
plus.setOnClickListener(listener);
|
||||
input.setOnFocusChangeListener((v, hasFocus) -> {
|
||||
if (!hasFocus) {
|
||||
int next = ViewTreeSupport.clamp(ViewTreeSupport.parseInt(input, defaultValue), min, max);
|
||||
input.setText(String.valueOf(next));
|
||||
prefs.edit().putInt(key, next).apply();
|
||||
SbtSettings.ensureReadable(context);
|
||||
}
|
||||
});
|
||||
return outer;
|
||||
return ViewTreeSupport.intPreferenceStepper(
|
||||
context,
|
||||
prefs,
|
||||
labelId,
|
||||
key,
|
||||
defaultValue,
|
||||
min,
|
||||
max,
|
||||
true,
|
||||
5,
|
||||
0,
|
||||
6,
|
||||
8,
|
||||
false,
|
||||
false,
|
||||
trailingView);
|
||||
}
|
||||
|
||||
private View card(Context context, int titleId, View content) {
|
||||
return ViewTreeSupport.outlinedCard(context, sectionTitle(context, titleId), content);
|
||||
}
|
||||
|
||||
private LinearLayout vertical(Context context) {
|
||||
return ViewTreeSupport.verticalLayout(context);
|
||||
}
|
||||
|
||||
private TextView title(Context context, int stringId) {
|
||||
return ViewTreeSupport.titleText(context, stringId);
|
||||
}
|
||||
|
||||
private TextView sectionTitle(Context context, int stringId) {
|
||||
return ViewTreeSupport.sectionTitleText(context, stringId, true);
|
||||
}
|
||||
|
||||
private TextView body(Context context, int stringId) {
|
||||
return ViewTreeSupport.bodyText(context, stringId, 0);
|
||||
private View outlinedCard(Context context, int titleId, View content) {
|
||||
return ViewTreeSupport.outlinedCard(
|
||||
context,
|
||||
ViewTreeSupport.sectionTitleText(context, titleId, true),
|
||||
content);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,8 +30,8 @@ final class LayoutOrderingUi {
|
||||
}
|
||||
|
||||
static View createCard(Context context, SharedPreferences prefs) {
|
||||
LinearLayout content = vertical(context);
|
||||
TextView hint = body(context, R.string.layout_ordering_hint);
|
||||
LinearLayout content = ViewTreeSupport.verticalLayout(context);
|
||||
TextView hint = bodyText(context, R.string.layout_ordering_hint);
|
||||
content.addView(hint);
|
||||
|
||||
RecyclerView list = new RecyclerView(context);
|
||||
@@ -43,7 +43,7 @@ final class LayoutOrderingUi {
|
||||
content.addView(list, listParams);
|
||||
bindOrderingList(context, prefs, list);
|
||||
|
||||
TextView sortTitle = body(context, R.string.layout_sort_icons_title);
|
||||
TextView sortTitle = bodyText(context, R.string.layout_sort_icons_title);
|
||||
sortTitle.setTypeface(sortTitle.getTypeface(), android.graphics.Typeface.BOLD);
|
||||
LinearLayout.LayoutParams sortTitleParams = new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
@@ -71,7 +71,10 @@ final class LayoutOrderingUi {
|
||||
sortParams.topMargin = ViewTreeSupport.dp(context, 8);
|
||||
content.addView(sortGroup, sortParams);
|
||||
|
||||
return card(context, R.string.layout_ordering_title, content);
|
||||
return ViewTreeSupport.outlinedCard(
|
||||
context,
|
||||
ViewTreeSupport.sectionTitleText(context, R.string.layout_ordering_title, true),
|
||||
content);
|
||||
}
|
||||
|
||||
static ArrayList<String> orderedKeys(SharedPreferences prefs) {
|
||||
@@ -225,18 +228,7 @@ final class LayoutOrderingUi {
|
||||
return tag instanceof String value ? value : "automatic";
|
||||
}
|
||||
|
||||
private static View card(Context context, int titleId, View content) {
|
||||
return ViewTreeSupport.outlinedCard(
|
||||
context,
|
||||
ViewTreeSupport.sectionTitleText(context, titleId, true),
|
||||
content);
|
||||
}
|
||||
|
||||
private static LinearLayout vertical(Context context) {
|
||||
return ViewTreeSupport.verticalLayout(context);
|
||||
}
|
||||
|
||||
private static TextView body(Context context, int stringId) {
|
||||
private static TextView bodyText(Context context, int stringId) {
|
||||
TextView view = new TextView(context);
|
||||
view.setText(stringId);
|
||||
view.setTextAppearance(com.google.android.material.R.style.TextAppearance_MaterialComponents_Body2);
|
||||
|
||||
+2
-21
@@ -197,7 +197,6 @@ final class LayoutSectionCopySupport {
|
||||
copyInt(editor, prefs, src.iconHeight, dst.iconHeight, src.iconHeightDefault);
|
||||
for (int i = 0; i < MAX_COPIES; i++) {
|
||||
copyString(editor, prefs, src.positionAt(i), dst.positionAt(i), src.positionDefault);
|
||||
copyBoolean(editor, prefs, src.autoNearestAt(i), dst.autoNearestAt(i), src.autoNearestDefault);
|
||||
copyString(editor, prefs, src.middleSideAt(i), dst.middleSideAt(i), src.middleSideDefault);
|
||||
copyInt(editor, prefs, src.verticalOffsetAt(i), dst.verticalOffsetAt(i), src.verticalOffsetDefault);
|
||||
}
|
||||
@@ -276,14 +275,12 @@ final class LayoutSectionCopySupport {
|
||||
SbtSettings.KEY_LAYOUT_NOTIF_ENABLED_LOCKSCREEN,
|
||||
SbtSettings.KEY_LAYOUT_NOTIF_LOCK_COUNT,
|
||||
SbtSettings.KEY_LAYOUT_NOTIF_LOCK_POSITION,
|
||||
SbtSettings.KEY_LAYOUT_NOTIF_LOCK_MIDDLE_AUTO_NEAREST_SIDE,
|
||||
SbtSettings.KEY_LAYOUT_NOTIF_LOCK_MIDDLE_SIDE,
|
||||
SbtSettings.KEY_LAYOUT_NOTIF_LOCK_VERTICAL_OFFSET_PX,
|
||||
SbtSettings.layoutLockNotifIconHeightKey(),
|
||||
SbtDefaults.LAYOUT_NOTIF_ENABLED_LOCKSCREEN_DEFAULT,
|
||||
SbtDefaults.LAYOUT_NOTIF_UNLOCKED_COUNT_DEFAULT,
|
||||
SbtDefaults.LAYOUT_NOTIF_POSITION_DEFAULT,
|
||||
SbtDefaults.LAYOUT_NOTIF_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT,
|
||||
SbtDefaults.LAYOUT_NOTIF_MIDDLE_SIDE_DEFAULT,
|
||||
SbtDefaults.LAYOUT_NOTIF_VERTICAL_OFFSET_PX_DEFAULT,
|
||||
SbtDefaults.LAYOUT_NOTIF_LOCK_ICON_HEIGHT_STEPS_DEFAULT);
|
||||
@@ -293,14 +290,12 @@ final class LayoutSectionCopySupport {
|
||||
SbtSettings.KEY_LAYOUT_NOTIF_ENABLED_AOD,
|
||||
SbtSettings.KEY_LAYOUT_NOTIF_AOD_COUNT,
|
||||
SbtSettings.KEY_LAYOUT_NOTIF_AOD_POSITION,
|
||||
SbtSettings.KEY_LAYOUT_NOTIF_AOD_MIDDLE_AUTO_NEAREST_SIDE,
|
||||
SbtSettings.KEY_LAYOUT_NOTIF_AOD_MIDDLE_SIDE,
|
||||
SbtSettings.KEY_LAYOUT_NOTIF_AOD_VERTICAL_OFFSET_PX,
|
||||
SbtSettings.layoutAodNotifIconHeightKey(),
|
||||
SbtDefaults.LAYOUT_NOTIF_ENABLED_AOD_DEFAULT,
|
||||
SbtDefaults.LAYOUT_NOTIF_UNLOCKED_COUNT_DEFAULT,
|
||||
SbtDefaults.LAYOUT_NOTIF_POSITION_DEFAULT,
|
||||
SbtDefaults.LAYOUT_NOTIF_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT,
|
||||
SbtDefaults.LAYOUT_NOTIF_MIDDLE_SIDE_DEFAULT,
|
||||
SbtDefaults.LAYOUT_NOTIF_VERTICAL_OFFSET_PX_DEFAULT,
|
||||
SbtDefaults.LAYOUT_NOTIF_AOD_ICON_HEIGHT_STEPS_DEFAULT);
|
||||
@@ -309,14 +304,12 @@ final class LayoutSectionCopySupport {
|
||||
SbtSettings.KEY_LAYOUT_NOTIF_ENABLED_UNLOCKED,
|
||||
SbtSettings.KEY_LAYOUT_NOTIF_UNLOCKED_COUNT,
|
||||
SbtSettings.KEY_LAYOUT_NOTIF_POSITION,
|
||||
SbtSettings.KEY_LAYOUT_NOTIF_MIDDLE_AUTO_NEAREST_SIDE,
|
||||
SbtSettings.KEY_LAYOUT_NOTIF_MIDDLE_SIDE,
|
||||
SbtSettings.KEY_LAYOUT_NOTIF_VERTICAL_OFFSET_PX,
|
||||
SbtSettings.KEY_LAYOUT_NOTIF_ICON_HEIGHT_STEPS,
|
||||
SbtDefaults.LAYOUT_NOTIF_ENABLED_UNLOCKED_DEFAULT,
|
||||
SbtDefaults.LAYOUT_NOTIF_UNLOCKED_COUNT_DEFAULT,
|
||||
SbtDefaults.LAYOUT_NOTIF_POSITION_DEFAULT,
|
||||
SbtDefaults.LAYOUT_NOTIF_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT,
|
||||
SbtDefaults.LAYOUT_NOTIF_MIDDLE_SIDE_DEFAULT,
|
||||
SbtDefaults.LAYOUT_NOTIF_VERTICAL_OFFSET_PX_DEFAULT,
|
||||
SbtDefaults.LAYOUT_NOTIF_ICON_HEIGHT_STEPS_DEFAULT);
|
||||
@@ -328,14 +321,12 @@ final class LayoutSectionCopySupport {
|
||||
SbtSettings.KEY_LAYOUT_STATUS_ENABLED_LOCKSCREEN,
|
||||
SbtSettings.KEY_LAYOUT_STATUS_LOCK_COUNT,
|
||||
SbtSettings.KEY_LAYOUT_STATUS_LOCK_POSITION,
|
||||
SbtSettings.KEY_LAYOUT_STATUS_LOCK_MIDDLE_AUTO_NEAREST_SIDE,
|
||||
SbtSettings.KEY_LAYOUT_STATUS_LOCK_MIDDLE_SIDE,
|
||||
SbtSettings.KEY_LAYOUT_STATUS_LOCK_VERTICAL_OFFSET_PX,
|
||||
SbtSettings.layoutLockStatusIconHeightKey(),
|
||||
SbtDefaults.LAYOUT_STATUS_ENABLED_LOCKSCREEN_DEFAULT,
|
||||
SbtDefaults.LAYOUT_STATUS_UNLOCKED_COUNT_DEFAULT,
|
||||
SbtDefaults.LAYOUT_STATUS_POSITION_DEFAULT,
|
||||
SbtDefaults.LAYOUT_STATUS_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT,
|
||||
SbtDefaults.LAYOUT_STATUS_MIDDLE_SIDE_DEFAULT,
|
||||
SbtDefaults.LAYOUT_STATUS_VERTICAL_OFFSET_PX_DEFAULT,
|
||||
SbtDefaults.LAYOUT_STATUS_ICON_HEIGHT_STEPS_DEFAULT);
|
||||
@@ -345,14 +336,12 @@ final class LayoutSectionCopySupport {
|
||||
SbtSettings.KEY_LAYOUT_STATUS_ENABLED_AOD,
|
||||
SbtSettings.KEY_LAYOUT_STATUS_AOD_COUNT,
|
||||
SbtSettings.KEY_LAYOUT_STATUS_AOD_POSITION,
|
||||
SbtSettings.KEY_LAYOUT_STATUS_AOD_MIDDLE_AUTO_NEAREST_SIDE,
|
||||
SbtSettings.KEY_LAYOUT_STATUS_AOD_MIDDLE_SIDE,
|
||||
SbtSettings.KEY_LAYOUT_STATUS_AOD_VERTICAL_OFFSET_PX,
|
||||
SbtSettings.layoutAodStatusIconHeightKey(),
|
||||
SbtDefaults.LAYOUT_STATUS_ENABLED_AOD_DEFAULT,
|
||||
SbtDefaults.LAYOUT_STATUS_UNLOCKED_COUNT_DEFAULT,
|
||||
SbtDefaults.LAYOUT_STATUS_POSITION_DEFAULT,
|
||||
SbtDefaults.LAYOUT_STATUS_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT,
|
||||
SbtDefaults.LAYOUT_STATUS_MIDDLE_SIDE_DEFAULT,
|
||||
SbtDefaults.LAYOUT_STATUS_VERTICAL_OFFSET_PX_DEFAULT,
|
||||
SbtDefaults.LAYOUT_STATUS_ICON_HEIGHT_STEPS_DEFAULT);
|
||||
@@ -361,14 +350,12 @@ final class LayoutSectionCopySupport {
|
||||
SbtSettings.KEY_LAYOUT_STATUS_ENABLED_UNLOCKED,
|
||||
SbtSettings.KEY_LAYOUT_STATUS_UNLOCKED_COUNT,
|
||||
SbtSettings.KEY_LAYOUT_STATUS_POSITION,
|
||||
SbtSettings.KEY_LAYOUT_STATUS_MIDDLE_AUTO_NEAREST_SIDE,
|
||||
SbtSettings.KEY_LAYOUT_STATUS_MIDDLE_SIDE,
|
||||
SbtSettings.KEY_LAYOUT_STATUS_VERTICAL_OFFSET_PX,
|
||||
SbtSettings.KEY_LAYOUT_STATUS_ICON_HEIGHT_STEPS,
|
||||
SbtDefaults.LAYOUT_STATUS_ENABLED_UNLOCKED_DEFAULT,
|
||||
SbtDefaults.LAYOUT_STATUS_UNLOCKED_COUNT_DEFAULT,
|
||||
SbtDefaults.LAYOUT_STATUS_POSITION_DEFAULT,
|
||||
SbtDefaults.LAYOUT_STATUS_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT,
|
||||
SbtDefaults.LAYOUT_STATUS_MIDDLE_SIDE_DEFAULT,
|
||||
SbtDefaults.LAYOUT_STATUS_VERTICAL_OFFSET_PX_DEFAULT,
|
||||
SbtDefaults.LAYOUT_STATUS_ICON_HEIGHT_STEPS_DEFAULT);
|
||||
@@ -405,14 +392,12 @@ final class LayoutSectionCopySupport {
|
||||
String enabled,
|
||||
String count,
|
||||
String position,
|
||||
String autoNearest,
|
||||
String middleSide,
|
||||
String verticalOffset,
|
||||
String iconHeight,
|
||||
boolean enabledDefault,
|
||||
int countDefault,
|
||||
String positionDefault,
|
||||
boolean autoNearestDefault,
|
||||
String middleSideDefault,
|
||||
int verticalOffsetDefault,
|
||||
int iconHeightDefault
|
||||
@@ -420,14 +405,14 @@ final class LayoutSectionCopySupport {
|
||||
return new KeySet(
|
||||
enabled,
|
||||
position,
|
||||
autoNearest,
|
||||
null,
|
||||
middleSide,
|
||||
verticalOffset,
|
||||
iconHeight,
|
||||
count,
|
||||
enabledDefault,
|
||||
positionDefault,
|
||||
autoNearestDefault,
|
||||
false,
|
||||
middleSideDefault,
|
||||
verticalOffsetDefault,
|
||||
iconHeightDefault,
|
||||
@@ -701,10 +686,6 @@ final class LayoutSectionCopySupport {
|
||||
return suffixed(position, index);
|
||||
}
|
||||
|
||||
String autoNearestAt(int index) {
|
||||
return suffixed(autoNearest, index);
|
||||
}
|
||||
|
||||
String middleSideAt(int index) {
|
||||
return suffixed(middleSide, index);
|
||||
}
|
||||
|
||||
+69
-165
@@ -4,7 +4,6 @@ import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.text.InputFilter;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@@ -20,6 +19,7 @@ import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.google.android.material.button.MaterialButton;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
import se.ajpanton.statusbartweak.R;
|
||||
@@ -44,7 +44,7 @@ abstract class LockedSceneLayoutFragment extends Fragment {
|
||||
Context context = requireContext();
|
||||
SharedPreferences prefs = context.getSharedPreferences(SbtSettings.PREFS_NAME, Context.MODE_PRIVATE);
|
||||
ScrollView scroll = new ScrollView(context);
|
||||
LinearLayout root = vertical(context);
|
||||
LinearLayout root = ViewTreeSupport.verticalLayout(context);
|
||||
root.setPadding(
|
||||
ViewTreeSupport.dp(context, 20),
|
||||
ViewTreeSupport.dp(context, 20),
|
||||
@@ -52,16 +52,18 @@ abstract class LockedSceneLayoutFragment extends Fragment {
|
||||
ViewTreeSupport.dp(context, 20));
|
||||
scroll.addView(root);
|
||||
|
||||
root.addView(title(context, aod ? R.string.section_aod : R.string.section_lockscreen));
|
||||
root.addView(ViewTreeSupport.titleText(
|
||||
context,
|
||||
aod ? R.string.section_aod : R.string.section_lockscreen));
|
||||
modeGroup = new RadioGroup(context);
|
||||
modeGroup.setOrientation(RadioGroup.VERTICAL);
|
||||
modeHint = body(context, R.string.layout_locked_notifications_hint);
|
||||
LinearLayout modeContent = vertical(context);
|
||||
modeHint = ViewTreeSupport.bodyText(context, R.string.layout_locked_notifications_hint, 6);
|
||||
LinearLayout modeContent = ViewTreeSupport.verticalLayout(context);
|
||||
modeContent.addView(modeHint);
|
||||
modeContent.addView(modeGroup);
|
||||
root.addView(card(context, R.string.layout_locked_notifications_title, modeContent));
|
||||
root.addView(outlinedCard(context, R.string.layout_locked_notifications_title, modeContent));
|
||||
|
||||
dynamicContent = vertical(context);
|
||||
dynamicContent = ViewTreeSupport.verticalLayout(context);
|
||||
root.addView(dynamicContent);
|
||||
bindMode(context, prefs);
|
||||
return scroll;
|
||||
@@ -142,8 +144,8 @@ abstract class LockedSceneLayoutFragment extends Fragment {
|
||||
R.id.clock_vertical_offset_reset,
|
||||
SbtSettings.KEY_LAYOUT_CARRIER_POSITION,
|
||||
SbtDefaults.LAYOUT_CARRIER_POSITION_DEFAULT,
|
||||
SbtSettings.KEY_LAYOUT_CARRIER_MIDDLE_AUTO_NEAREST_SIDE,
|
||||
SbtDefaults.LAYOUT_CARRIER_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT,
|
||||
null,
|
||||
false,
|
||||
SbtSettings.KEY_LAYOUT_CARRIER_MIDDLE_SIDE,
|
||||
SbtDefaults.LAYOUT_CARRIER_MIDDLE_SIDE_DEFAULT,
|
||||
SbtSettings.KEY_LAYOUT_CARRIER_VERTICAL_OFFSET_PX,
|
||||
@@ -159,7 +161,7 @@ abstract class LockedSceneLayoutFragment extends Fragment {
|
||||
aod ? R.id.status_position_mode_aod : R.id.status_position_mode_lockscreen,
|
||||
R.id.status_position_group,
|
||||
R.id.status_position_middle_options_container,
|
||||
R.id.status_middle_auto_nearest,
|
||||
View.NO_ID,
|
||||
R.id.status_middle_side_prompt,
|
||||
R.id.status_middle_side_group,
|
||||
R.id.status_middle_side_right,
|
||||
@@ -173,7 +175,6 @@ abstract class LockedSceneLayoutFragment extends Fragment {
|
||||
aod ? SbtSettings.KEY_LAYOUT_STATUS_ENABLED_AOD : SbtSettings.KEY_LAYOUT_STATUS_ENABLED_LOCKSCREEN,
|
||||
aod ? SbtDefaults.LAYOUT_STATUS_ENABLED_AOD_DEFAULT : SbtDefaults.LAYOUT_STATUS_ENABLED_LOCKSCREEN_DEFAULT,
|
||||
SbtDefaults.LAYOUT_STATUS_POSITION_DEFAULT,
|
||||
SbtDefaults.LAYOUT_STATUS_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT,
|
||||
SbtDefaults.LAYOUT_STATUS_MIDDLE_SIDE_DEFAULT,
|
||||
SbtDefaults.LAYOUT_STATUS_VERTICAL_OFFSET_PX_DEFAULT,
|
||||
aod ? SbtSettings.layoutAodStatusIconHeightKey() : SbtSettings.layoutLockStatusIconHeightKey(),
|
||||
@@ -192,7 +193,7 @@ abstract class LockedSceneLayoutFragment extends Fragment {
|
||||
aod ? R.id.notif_position_mode_aod : R.id.notif_position_mode_lockscreen,
|
||||
R.id.notif_position_group,
|
||||
R.id.notif_position_middle_options_container,
|
||||
R.id.notif_middle_auto_nearest,
|
||||
View.NO_ID,
|
||||
R.id.notif_middle_side_prompt,
|
||||
R.id.notif_middle_side_group,
|
||||
R.id.notif_middle_side_right,
|
||||
@@ -206,7 +207,6 @@ abstract class LockedSceneLayoutFragment extends Fragment {
|
||||
aod ? SbtSettings.KEY_LAYOUT_NOTIF_ENABLED_AOD : SbtSettings.KEY_LAYOUT_NOTIF_ENABLED_LOCKSCREEN,
|
||||
aod ? SbtDefaults.LAYOUT_NOTIF_ENABLED_AOD_DEFAULT : SbtDefaults.LAYOUT_NOTIF_ENABLED_LOCKSCREEN_DEFAULT,
|
||||
SbtDefaults.LAYOUT_NOTIF_POSITION_DEFAULT,
|
||||
SbtDefaults.LAYOUT_NOTIF_MIDDLE_AUTO_NEAREST_SIDE_DEFAULT,
|
||||
SbtDefaults.LAYOUT_NOTIF_MIDDLE_SIDE_DEFAULT,
|
||||
SbtDefaults.LAYOUT_NOTIF_VERTICAL_OFFSET_PX_DEFAULT,
|
||||
aod ? SbtSettings.layoutAodNotifIconHeightKey() : SbtSettings.layoutLockNotifIconHeightKey(),
|
||||
@@ -307,7 +307,6 @@ abstract class LockedSceneLayoutFragment extends Fragment {
|
||||
String legacyEnabledKey,
|
||||
boolean legacyEnabledDefault,
|
||||
String positionDefault,
|
||||
boolean autoNearestDefault,
|
||||
String middleSideDefault,
|
||||
int verticalOffsetDefault,
|
||||
String iconHeightKey,
|
||||
@@ -316,12 +315,17 @@ abstract class LockedSceneLayoutFragment extends Fragment {
|
||||
boolean cardsMode,
|
||||
@Nullable Runnable refresh
|
||||
) {
|
||||
LinearLayout wrapper = vertical(context);
|
||||
LinearLayout wrapper = ViewTreeSupport.verticalLayout(context);
|
||||
String countKey = sceneKey(base + "_count");
|
||||
Runnable[] rebuild = new Runnable[1];
|
||||
rebuild[0] = () -> {
|
||||
wrapper.removeAllViews();
|
||||
int count = iconContainerCount(prefs, countKey, legacyEnabledKey, legacyEnabledDefault);
|
||||
int count = ViewTreeSupport.iconContainerCount(
|
||||
prefs,
|
||||
countKey,
|
||||
legacyEnabledKey,
|
||||
1,
|
||||
legacyEnabledDefault);
|
||||
View primary = configuredIconContainerCard(
|
||||
context,
|
||||
prefs,
|
||||
@@ -343,8 +347,6 @@ abstract class LockedSceneLayoutFragment extends Fragment {
|
||||
0,
|
||||
indexedSceneKey(base + "_position", 0),
|
||||
positionDefault,
|
||||
indexedSceneKey(base + "_middle_auto_nearest_side", 0),
|
||||
autoNearestDefault,
|
||||
indexedSceneKey(base + "_middle_side", 0),
|
||||
middleSideDefault,
|
||||
indexedSceneKey(base + "_vertical_offset_px", 0),
|
||||
@@ -379,8 +381,6 @@ abstract class LockedSceneLayoutFragment extends Fragment {
|
||||
i,
|
||||
indexedSceneKey(base + "_position", i),
|
||||
positionDefault,
|
||||
indexedSceneKey(base + "_middle_auto_nearest_side", i),
|
||||
autoNearestDefault,
|
||||
indexedSceneKey(base + "_middle_side", i),
|
||||
middleSideDefault,
|
||||
indexedSceneKey(base + "_vertical_offset_px", i),
|
||||
@@ -441,8 +441,6 @@ abstract class LockedSceneLayoutFragment extends Fragment {
|
||||
int index,
|
||||
String positionKey,
|
||||
String positionDefault,
|
||||
String autoNearestKey,
|
||||
boolean autoNearestDefault,
|
||||
String middleSideKey,
|
||||
String middleSideDefault,
|
||||
String verticalOffsetKey,
|
||||
@@ -460,7 +458,16 @@ abstract class LockedSceneLayoutFragment extends Fragment {
|
||||
if (sectionContent != null && countKey != null && onCountChanged != null) {
|
||||
int insertIndex = Math.min(1, sectionContent.getChildCount());
|
||||
sectionContent.addView(
|
||||
iconContainerCountControl(context, prefs, countKey, legacyEnabledKey, count, onCountChanged),
|
||||
ViewTreeSupport.iconContainerCountControl(
|
||||
context,
|
||||
count,
|
||||
value -> ViewTreeSupport.persistIconContainerCount(
|
||||
context,
|
||||
prefs,
|
||||
countKey,
|
||||
legacyEnabledKey,
|
||||
value),
|
||||
onCountChanged),
|
||||
insertIndex);
|
||||
if (iconHeightKey != null) {
|
||||
sectionContent.addView(
|
||||
@@ -487,8 +494,8 @@ abstract class LockedSceneLayoutFragment extends Fragment {
|
||||
middleSideRightId,
|
||||
positionKey,
|
||||
positionDefault,
|
||||
autoNearestKey,
|
||||
autoNearestDefault,
|
||||
null,
|
||||
false,
|
||||
middleSideKey,
|
||||
middleSideDefault);
|
||||
bindXmlStepper(
|
||||
@@ -544,7 +551,7 @@ abstract class LockedSceneLayoutFragment extends Fragment {
|
||||
}
|
||||
|
||||
private View cardsNotificationCard(Context context, SharedPreferences prefs, @Nullable Runnable refresh) {
|
||||
LinearLayout content = vertical(context);
|
||||
LinearLayout content = ViewTreeSupport.verticalLayout(context);
|
||||
LayoutSectionCopySupport.addCardsDropdown(context, prefs, content, copyMode(), refresh);
|
||||
content.addView(stepper(
|
||||
context,
|
||||
@@ -586,48 +593,7 @@ abstract class LockedSceneLayoutFragment extends Fragment {
|
||||
: SbtDefaults.LAYOUT_CARDS_NOTIF_LOCK_ICON_HEIGHT_STEPS_DEFAULT,
|
||||
SbtDefaults.LAYOUT_ICON_HEIGHT_STEPS_MIN,
|
||||
SbtDefaults.LAYOUT_ICON_HEIGHT_STEPS_MAX));
|
||||
return card(context, R.string.layout_notification_position_title, content);
|
||||
}
|
||||
|
||||
private View iconContainerCountControl(
|
||||
Context context,
|
||||
SharedPreferences prefs,
|
||||
String countKey,
|
||||
String legacyEnabledKey,
|
||||
int current,
|
||||
Runnable onChanged
|
||||
) {
|
||||
LinearLayout outer = vertical(context);
|
||||
outer.addView(body(context, R.string.layout_icon_container_count));
|
||||
LinearLayout row = new LinearLayout(context);
|
||||
row.setOrientation(LinearLayout.HORIZONTAL);
|
||||
row.setGravity(Gravity.CENTER_VERTICAL);
|
||||
MaterialButton minus = ViewTreeSupport.outlinedStepperButton(context, "-");
|
||||
MaterialButton plus = ViewTreeSupport.outlinedStepperButton(context, "+");
|
||||
EditText input = ViewTreeSupport.numericInput(context, false, 4);
|
||||
input.setFilters(new InputFilter[]{new InputFilter.LengthFilter(1)});
|
||||
input.setText(String.valueOf(current));
|
||||
row.addView(minus, ViewTreeSupport.stepperButtonParams(context));
|
||||
row.addView(input, ViewTreeSupport.stepperInputParams(context));
|
||||
row.addView(plus, ViewTreeSupport.stepperButtonParams(context));
|
||||
outer.addView(row);
|
||||
|
||||
View.OnClickListener listener = view -> {
|
||||
int next = SbtSettings.clampIconContainerCount(
|
||||
ViewTreeSupport.parseInt(input, current) + (view == minus ? -1 : 1));
|
||||
persistIconContainerCount(prefs, countKey, legacyEnabledKey, next);
|
||||
onChanged.run();
|
||||
};
|
||||
minus.setOnClickListener(listener);
|
||||
plus.setOnClickListener(listener);
|
||||
input.setOnFocusChangeListener((v, hasFocus) -> {
|
||||
if (!hasFocus) {
|
||||
int next = SbtSettings.clampIconContainerCount(ViewTreeSupport.parseInt(input, current));
|
||||
persistIconContainerCount(prefs, countKey, legacyEnabledKey, next);
|
||||
onChanged.run();
|
||||
}
|
||||
});
|
||||
return outer;
|
||||
return outlinedCard(context, R.string.layout_notification_position_title, content);
|
||||
}
|
||||
|
||||
private void bindXmlPositionSection(
|
||||
@@ -641,7 +607,7 @@ abstract class LockedSceneLayoutFragment extends Fragment {
|
||||
int middleSideRightId,
|
||||
String positionKey,
|
||||
String positionDefault,
|
||||
String autoNearestKey,
|
||||
@Nullable String autoNearestKey,
|
||||
boolean autoNearestDefault,
|
||||
String middleSideKey,
|
||||
String middleSideDefault
|
||||
@@ -651,17 +617,23 @@ abstract class LockedSceneLayoutFragment extends Fragment {
|
||||
CheckBox autoNearest = root.findViewById(autoNearestId);
|
||||
TextView prompt = root.findViewById(promptId);
|
||||
RadioGroup side = root.findViewById(middleSideGroupId);
|
||||
if (position == null || middleOptions == null || autoNearest == null || prompt == null || side == null) {
|
||||
if (position == null || middleOptions == null || prompt == null || side == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
position.check(positionIdForValue(groupId, prefs.getString(positionKey, positionDefault)));
|
||||
boolean autoNearestAvailable = autoNearestKey != null && autoNearest != null;
|
||||
if (autoNearestAvailable) {
|
||||
autoNearest.setChecked(prefs.getBoolean(autoNearestKey, autoNearestDefault));
|
||||
} else if (autoNearest != null) {
|
||||
autoNearest.setChecked(false);
|
||||
autoNearest.setVisibility(View.GONE);
|
||||
}
|
||||
side.check("right".equals(prefs.getString(middleSideKey, middleSideDefault))
|
||||
? middleSideRightId
|
||||
: firstSideId(side, middleSideRightId));
|
||||
updateMiddleOptions(middleOptions, "middle".equals(positionValueForId(position.getCheckedRadioButtonId())));
|
||||
prompt.setText(autoNearest.isChecked()
|
||||
prompt.setText(autoNearest != null && autoNearest.isChecked()
|
||||
? R.string.layout_middle_side_prompt_centred
|
||||
: R.string.layout_middle_side_prompt_attach_only);
|
||||
|
||||
@@ -670,6 +642,7 @@ abstract class LockedSceneLayoutFragment extends Fragment {
|
||||
updateMiddleOptions(middleOptions, "middle".equals(positionValueForId(checkedId)));
|
||||
SbtSettings.ensureReadable(requireContext());
|
||||
});
|
||||
if (autoNearestAvailable) {
|
||||
autoNearest.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
prefs.edit().putBoolean(autoNearestKey, isChecked).apply();
|
||||
prompt.setText(isChecked
|
||||
@@ -677,6 +650,7 @@ abstract class LockedSceneLayoutFragment extends Fragment {
|
||||
: R.string.layout_middle_side_prompt_attach_only);
|
||||
SbtSettings.ensureReadable(requireContext());
|
||||
});
|
||||
}
|
||||
side.setOnCheckedChangeListener((group, checkedId) -> {
|
||||
prefs.edit().putString(middleSideKey, checkedId == middleSideRightId ? "right" : "left").apply();
|
||||
SbtSettings.ensureReadable(requireContext());
|
||||
@@ -709,14 +683,14 @@ abstract class LockedSceneLayoutFragment extends Fragment {
|
||||
if (reset != null) {
|
||||
reset.setOnClickListener(v -> {
|
||||
input.setText(String.valueOf(defaultValue));
|
||||
persistIntPref(prefs, key, defaultValue);
|
||||
ViewTreeSupport.persistIntPreference(requireContext(), prefs, key, defaultValue);
|
||||
});
|
||||
}
|
||||
input.setOnFocusChangeListener((v, hasFocus) -> {
|
||||
if (!hasFocus) {
|
||||
int next = ViewTreeSupport.clamp(ViewTreeSupport.parseInt(input, defaultValue), min, max);
|
||||
input.setText(String.valueOf(next));
|
||||
persistIntPref(prefs, key, next);
|
||||
ViewTreeSupport.persistIntPreference(requireContext(), prefs, key, next);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -736,7 +710,7 @@ abstract class LockedSceneLayoutFragment extends Fragment {
|
||||
button.setOnClickListener(v -> {
|
||||
int next = ViewTreeSupport.clamp(ViewTreeSupport.parseInt(input, 0) + delta, min, max);
|
||||
input.setText(String.valueOf(next));
|
||||
persistIntPref(prefs, key, next);
|
||||
ViewTreeSupport.persistIntPreference(requireContext(), prefs, key, next);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -822,79 +796,22 @@ abstract class LockedSceneLayoutFragment extends Fragment {
|
||||
int max,
|
||||
boolean showDefaultButton
|
||||
) {
|
||||
LinearLayout outer = vertical(context);
|
||||
outer.addView(body(context, label));
|
||||
LinearLayout row = new LinearLayout(context);
|
||||
row.setOrientation(LinearLayout.HORIZONTAL);
|
||||
row.setGravity(Gravity.CENTER_VERTICAL);
|
||||
MaterialButton minus = ViewTreeSupport.outlinedStepperButton(context, "-");
|
||||
MaterialButton plus = ViewTreeSupport.outlinedStepperButton(context, "+");
|
||||
MaterialButton reset = showDefaultButton
|
||||
? ViewTreeSupport.outlinedStepperButton(context, "D")
|
||||
: null;
|
||||
EditText input = ViewTreeSupport.numericInput(context, true, 4);
|
||||
input.setText(String.valueOf(ViewTreeSupport.clamp(prefs.getInt(key, def), min, max)));
|
||||
row.addView(minus, ViewTreeSupport.stepperButtonParams(context));
|
||||
row.addView(input, ViewTreeSupport.stepperInputParams(context));
|
||||
row.addView(plus, ViewTreeSupport.stepperButtonParams(context));
|
||||
if (reset != null) {
|
||||
LinearLayout.LayoutParams resetParams = ViewTreeSupport.stepperButtonParams(context);
|
||||
resetParams.leftMargin = ViewTreeSupport.dp(context, 8);
|
||||
row.addView(reset, resetParams);
|
||||
}
|
||||
outer.addView(row);
|
||||
View.OnClickListener listener = view -> {
|
||||
int delta = view == minus ? -1 : 1;
|
||||
int next = ViewTreeSupport.clamp(ViewTreeSupport.parseInt(input, def) + delta, min, max);
|
||||
input.setText(String.valueOf(next));
|
||||
persistIntPref(prefs, key, next);
|
||||
};
|
||||
minus.setOnClickListener(listener);
|
||||
plus.setOnClickListener(listener);
|
||||
if (reset != null) {
|
||||
reset.setOnClickListener(v -> {
|
||||
int next = ViewTreeSupport.clamp(def, min, max);
|
||||
input.setText(String.valueOf(next));
|
||||
persistIntPref(prefs, key, next);
|
||||
});
|
||||
}
|
||||
input.setOnFocusChangeListener((v, hasFocus) -> {
|
||||
if (!hasFocus) {
|
||||
int next = ViewTreeSupport.clamp(ViewTreeSupport.parseInt(input, def), min, max);
|
||||
input.setText(String.valueOf(next));
|
||||
persistIntPref(prefs, key, next);
|
||||
}
|
||||
});
|
||||
return outer;
|
||||
}
|
||||
|
||||
private void persistIntPref(SharedPreferences prefs, String key, int value) {
|
||||
prefs.edit().putInt(key, value).apply();
|
||||
SbtSettings.ensureReadable(requireContext());
|
||||
}
|
||||
|
||||
private int iconContainerCount(
|
||||
SharedPreferences prefs,
|
||||
String countKey,
|
||||
String legacyEnabledKey,
|
||||
boolean legacyEnabledDefault
|
||||
) {
|
||||
int fallback = prefs.getBoolean(legacyEnabledKey, legacyEnabledDefault) ? 1 : 0;
|
||||
return SbtSettings.clampIconContainerCount(prefs.getInt(countKey, fallback));
|
||||
}
|
||||
|
||||
private void persistIconContainerCount(
|
||||
SharedPreferences prefs,
|
||||
String countKey,
|
||||
String legacyEnabledKey,
|
||||
int count
|
||||
) {
|
||||
int clamped = SbtSettings.clampIconContainerCount(count);
|
||||
prefs.edit()
|
||||
.putInt(countKey, clamped)
|
||||
.putBoolean(legacyEnabledKey, clamped > 0)
|
||||
.apply();
|
||||
SbtSettings.ensureReadable(requireContext());
|
||||
return ViewTreeSupport.intPreferenceStepper(
|
||||
context,
|
||||
prefs,
|
||||
label,
|
||||
key,
|
||||
def,
|
||||
min,
|
||||
max,
|
||||
true,
|
||||
4,
|
||||
6,
|
||||
0,
|
||||
0,
|
||||
showDefaultButton,
|
||||
false,
|
||||
null);
|
||||
}
|
||||
|
||||
private String sceneKey(String suffix) {
|
||||
@@ -922,23 +839,10 @@ abstract class LockedSceneLayoutFragment extends Fragment {
|
||||
return content instanceof LinearLayout layout ? layout : null;
|
||||
}
|
||||
|
||||
private View card(Context context, int titleId, View content) {
|
||||
return ViewTreeSupport.outlinedCard(context, sectionTitle(context, titleId), content);
|
||||
}
|
||||
|
||||
private LinearLayout vertical(Context context) {
|
||||
return ViewTreeSupport.verticalLayout(context);
|
||||
}
|
||||
|
||||
private TextView title(Context context, int text) {
|
||||
return ViewTreeSupport.titleText(context, text);
|
||||
}
|
||||
|
||||
private TextView sectionTitle(Context context, int text) {
|
||||
return ViewTreeSupport.sectionTitleText(context, text, false);
|
||||
}
|
||||
|
||||
private TextView body(Context context, int text) {
|
||||
return ViewTreeSupport.bodyText(context, text, 6);
|
||||
private View outlinedCard(Context context, int titleId, View content) {
|
||||
return ViewTreeSupport.outlinedCard(
|
||||
context,
|
||||
ViewTreeSupport.sectionTitleText(context, titleId, false),
|
||||
content);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,8 +14,9 @@ import android.widget.TextView;
|
||||
import com.google.android.material.button.MaterialButton;
|
||||
import com.google.android.material.card.MaterialCardView;
|
||||
|
||||
import se.ajpanton.statusbartweak.R;
|
||||
import java.util.function.IntConsumer;
|
||||
|
||||
import se.ajpanton.statusbartweak.R;
|
||||
import se.ajpanton.statusbartweak.shell.settings.SbtSettings;
|
||||
|
||||
final class ViewTreeSupport {
|
||||
@@ -149,6 +150,160 @@ final class ViewTreeSupport {
|
||||
return input;
|
||||
}
|
||||
|
||||
static int iconContainerCount(
|
||||
SharedPreferences prefs,
|
||||
String countKey,
|
||||
String legacyEnabledKey,
|
||||
int defaultCount,
|
||||
boolean legacyEnabledDefault
|
||||
) {
|
||||
int fallback = prefs.getBoolean(legacyEnabledKey, legacyEnabledDefault) ? defaultCount : 0;
|
||||
return SbtSettings.clampIconContainerCount(prefs.getInt(countKey, fallback));
|
||||
}
|
||||
|
||||
static void persistIconContainerCount(
|
||||
Context context,
|
||||
SharedPreferences prefs,
|
||||
String countKey,
|
||||
String legacyEnabledKey,
|
||||
int count
|
||||
) {
|
||||
int clamped = SbtSettings.clampIconContainerCount(count);
|
||||
prefs.edit()
|
||||
.putInt(countKey, clamped)
|
||||
.putBoolean(legacyEnabledKey, clamped > 0)
|
||||
.apply();
|
||||
SbtSettings.ensureReadable(context);
|
||||
}
|
||||
|
||||
static View iconContainerCountControl(
|
||||
Context context,
|
||||
int current,
|
||||
IntConsumer countPersister,
|
||||
Runnable onChanged
|
||||
) {
|
||||
LinearLayout outer = verticalLayout(context);
|
||||
outer.addView(bodyText(context, R.string.layout_icon_container_count, 0));
|
||||
LinearLayout row = new LinearLayout(context);
|
||||
row.setOrientation(LinearLayout.HORIZONTAL);
|
||||
row.setGravity(android.view.Gravity.CENTER_VERTICAL);
|
||||
MaterialButton minus = outlinedStepperButton(context, "-");
|
||||
MaterialButton plus = outlinedStepperButton(context, "+");
|
||||
EditText input = numericInput(context, false, 1);
|
||||
input.setText(String.valueOf(current));
|
||||
row.addView(minus, stepperButtonParams(context));
|
||||
row.addView(input, stepperInputParams(context));
|
||||
row.addView(plus, stepperButtonParams(context));
|
||||
outer.addView(row);
|
||||
|
||||
View.OnClickListener listener = view -> {
|
||||
int next = SbtSettings.clampIconContainerCount(
|
||||
parseInt(input, current) + (view == minus ? -1 : 1));
|
||||
countPersister.accept(next);
|
||||
onChanged.run();
|
||||
};
|
||||
minus.setOnClickListener(listener);
|
||||
plus.setOnClickListener(listener);
|
||||
input.setOnFocusChangeListener((v, hasFocus) -> {
|
||||
if (!hasFocus) {
|
||||
int next = SbtSettings.clampIconContainerCount(parseInt(input, current));
|
||||
countPersister.accept(next);
|
||||
onChanged.run();
|
||||
}
|
||||
});
|
||||
return outer;
|
||||
}
|
||||
|
||||
static View intPreferenceStepper(
|
||||
Context context,
|
||||
SharedPreferences prefs,
|
||||
int labelRes,
|
||||
String key,
|
||||
int defaultValue,
|
||||
int min,
|
||||
int max,
|
||||
boolean signed,
|
||||
int inputMaxLength,
|
||||
int labelBottomPaddingDp,
|
||||
int rowTopPaddingDp,
|
||||
int rowBottomPaddingDp,
|
||||
boolean showDefaultButton,
|
||||
boolean useCurrentAsParseFallback,
|
||||
View trailingView
|
||||
) {
|
||||
LinearLayout outer = verticalLayout(context);
|
||||
outer.addView(bodyText(context, labelRes, labelBottomPaddingDp));
|
||||
|
||||
LinearLayout row = new LinearLayout(context);
|
||||
row.setOrientation(LinearLayout.HORIZONTAL);
|
||||
row.setGravity(android.view.Gravity.CENTER_VERTICAL);
|
||||
row.setPadding(0, dp(context, rowTopPaddingDp), 0, dp(context, rowBottomPaddingDp));
|
||||
|
||||
MaterialButton minus = outlinedStepperButton(context, "-");
|
||||
MaterialButton plus = outlinedStepperButton(context, "+");
|
||||
MaterialButton reset = showDefaultButton ? outlinedStepperButton(context, "D") : null;
|
||||
EditText input = numericInput(context, signed, inputMaxLength);
|
||||
int current = clamp(prefs.getInt(key, defaultValue), min, max);
|
||||
int parseFallback = useCurrentAsParseFallback ? current : defaultValue;
|
||||
input.setText(String.valueOf(current));
|
||||
|
||||
row.addView(minus, stepperButtonParams(context));
|
||||
row.addView(input, stepperInputParams(context));
|
||||
row.addView(plus, stepperButtonParams(context));
|
||||
if (reset != null) {
|
||||
LinearLayout.LayoutParams resetParams = stepperButtonParams(context);
|
||||
resetParams.leftMargin = dp(context, 8);
|
||||
row.addView(reset, resetParams);
|
||||
}
|
||||
if (trailingView != null) {
|
||||
LinearLayout.LayoutParams trailingParams = new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
trailingParams.leftMargin = dp(context, 8);
|
||||
row.addView(trailingView, trailingParams);
|
||||
}
|
||||
outer.addView(row);
|
||||
|
||||
View.OnClickListener listener = view -> {
|
||||
int delta = view == minus ? -1 : 1;
|
||||
int next = clamp(parseInt(input, parseFallback) + delta, min, max);
|
||||
persistIntPreference(context, prefs, key, input, next);
|
||||
};
|
||||
minus.setOnClickListener(listener);
|
||||
plus.setOnClickListener(listener);
|
||||
if (reset != null) {
|
||||
reset.setOnClickListener(v -> persistIntPreference(
|
||||
context,
|
||||
prefs,
|
||||
key,
|
||||
input,
|
||||
clamp(defaultValue, min, max)));
|
||||
}
|
||||
input.setOnFocusChangeListener((v, hasFocus) -> {
|
||||
if (!hasFocus) {
|
||||
int next = clamp(parseInt(input, parseFallback), min, max);
|
||||
persistIntPreference(context, prefs, key, input, next);
|
||||
}
|
||||
});
|
||||
return outer;
|
||||
}
|
||||
|
||||
static void persistIntPreference(
|
||||
Context context,
|
||||
SharedPreferences prefs,
|
||||
String key,
|
||||
EditText input,
|
||||
int value
|
||||
) {
|
||||
input.setText(String.valueOf(value));
|
||||
persistIntPreference(context, prefs, key, value);
|
||||
}
|
||||
|
||||
static void persistIntPreference(Context context, SharedPreferences prefs, String key, int value) {
|
||||
prefs.edit().putInt(key, value).apply();
|
||||
SbtSettings.ensureReadable(context);
|
||||
}
|
||||
|
||||
static LinearLayout verticalLayout(Context context) {
|
||||
LinearLayout layout = new LinearLayout(context);
|
||||
layout.setOrientation(LinearLayout.VERTICAL);
|
||||
|
||||
@@ -317,18 +317,10 @@
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone">
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/chip_middle_auto_nearest"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="true"
|
||||
android:text="@string/layout_middle_auto_nearest" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/chip_middle_side_prompt"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/layout_middle_side_prompt"
|
||||
android:textAppearance="?attr/textAppearanceBody2" />
|
||||
|
||||
@@ -546,18 +538,10 @@
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone">
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/notif_middle_auto_nearest"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="true"
|
||||
android:text="@string/layout_middle_auto_nearest" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/notif_middle_side_prompt"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/layout_middle_side_prompt"
|
||||
android:textAppearance="?attr/textAppearanceBody2" />
|
||||
|
||||
@@ -775,18 +759,10 @@
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone">
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/status_middle_auto_nearest"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="true"
|
||||
android:text="@string/layout_middle_auto_nearest" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/status_middle_side_prompt"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/layout_middle_side_prompt"
|
||||
android:textAppearance="?attr/textAppearanceBody2" />
|
||||
|
||||
|
||||
@@ -209,8 +209,6 @@
|
||||
<string name="clock_position_right">Right</string>
|
||||
<string name="clock_position_middle">Middle</string>
|
||||
<string name="clock_vertical_offset_label">Vertical position</string>
|
||||
<string name="clock_middle_auto_nearest">If Middle overlaps the cutout, move it to the nearest side.</string>
|
||||
<string name="clock_middle_cutout_prompt">Else, or if the overlap is centred, move clock to:</string>
|
||||
<string name="clock_middle_side_left">Left side</string>
|
||||
<string name="clock_middle_side_right">Right side</string>
|
||||
<string name="clock_custom_format_title">Custom format</string>
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
package se.ajpanton.statusbartweak;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
public class ExampleUnitTest {
|
||||
@Test
|
||||
public void addition_isCorrect() {
|
||||
assertEquals(4, 2 + 2);
|
||||
}
|
||||
}
|
||||
+3
-9
@@ -21,9 +21,7 @@ public final class UnlockedLayoutBandTest {
|
||||
null,
|
||||
placements(6, 39, 39),
|
||||
LayoutPosition.LEFT,
|
||||
false,
|
||||
AnchorSide.LEFT,
|
||||
true);
|
||||
AnchorSide.LEFT);
|
||||
|
||||
band.applyPackedIconState(0, 0, true, 14);
|
||||
band.place(388);
|
||||
@@ -54,9 +52,7 @@ public final class UnlockedLayoutBandTest {
|
||||
null,
|
||||
placements,
|
||||
LayoutPosition.LEFT,
|
||||
false,
|
||||
AnchorSide.LEFT,
|
||||
true);
|
||||
AnchorSide.LEFT);
|
||||
|
||||
band.applyPackedIconState(2, 3, false, 117);
|
||||
|
||||
@@ -86,9 +82,7 @@ public final class UnlockedLayoutBandTest {
|
||||
null,
|
||||
placements,
|
||||
LayoutPosition.LEFT,
|
||||
false,
|
||||
AnchorSide.LEFT,
|
||||
false);
|
||||
AnchorSide.LEFT);
|
||||
|
||||
band.prepareForSide(AnchorSide.RIGHT, "normal");
|
||||
band.applyPackedContinuousWidth(211, AnchorSide.RIGHT);
|
||||
|
||||
Reference in New Issue
Block a user