Refine runtime layout transitions
This commit is contained in:
+24
@@ -57,6 +57,7 @@ final class BatteryBarController {
|
|||||||
private final Set<View> pendingOverlayRetries = Collections.newSetFromMap(new WeakHashMap<>());
|
private final Set<View> pendingOverlayRetries = Collections.newSetFromMap(new WeakHashMap<>());
|
||||||
private final Map<View, String> lastSignatures = new WeakHashMap<>();
|
private final Map<View, String> lastSignatures = new WeakHashMap<>();
|
||||||
private final Map<View, String> lastOverlaySignatures = new WeakHashMap<>();
|
private final Map<View, String> lastOverlaySignatures = new WeakHashMap<>();
|
||||||
|
private final Map<View, Integer> lastRootTransformSignatures = new WeakHashMap<>();
|
||||||
private int systemBarAppearance;
|
private int systemBarAppearance;
|
||||||
private int systemBarBehavior;
|
private int systemBarBehavior;
|
||||||
private int systemBarRequestedVisibleTypes = WindowInsets.Type.statusBars();
|
private int systemBarRequestedVisibleTypes = WindowInsets.Type.statusBars();
|
||||||
@@ -171,6 +172,11 @@ final class BatteryBarController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void applyBatteryBarAfterRootTransform(View root) {
|
private void applyBatteryBarAfterRootTransform(View root) {
|
||||||
|
int transformSignature = rootTransformSignature(root);
|
||||||
|
Integer previousSignature = lastRootTransformSignatures.put(root, transformSignature);
|
||||||
|
if (previousSignature != null && previousSignature == transformSignature) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (isHiddenKeyguardRoot(root)) {
|
if (isHiddenKeyguardRoot(root)) {
|
||||||
removeBatteryBarView(root);
|
removeBatteryBarView(root);
|
||||||
return;
|
return;
|
||||||
@@ -255,9 +261,23 @@ final class BatteryBarController {
|
|||||||
}
|
}
|
||||||
roots.remove(root);
|
roots.remove(root);
|
||||||
pendingOverlayRetries.remove(root);
|
pendingOverlayRetries.remove(root);
|
||||||
|
lastRootTransformSignatures.remove(root);
|
||||||
removeBatteryBarView(root);
|
removeBatteryBarView(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int rootTransformSignature(View root) {
|
||||||
|
if (root == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int result = 17;
|
||||||
|
result = 31 * result + root.getVisibility();
|
||||||
|
result = 31 * result + Float.floatToIntBits(root.getY());
|
||||||
|
result = 31 * result + Float.floatToIntBits(root.getTranslationY());
|
||||||
|
result = 31 * result + root.getWidth();
|
||||||
|
result = 31 * result + root.getHeight();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
private void registerReceiverIfNeeded(Context context) {
|
private void registerReceiverIfNeeded(Context context) {
|
||||||
if (context == null || receiverRegistered) {
|
if (context == null || receiverRegistered) {
|
||||||
return;
|
return;
|
||||||
@@ -340,6 +360,10 @@ final class BatteryBarController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void applyBatteryBar(View root) {
|
private void applyBatteryBar(View root) {
|
||||||
|
applyBatteryBarInternal(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyBatteryBarInternal(View root) {
|
||||||
if (!(root instanceof ViewGroup rootGroup)) {
|
if (!(root instanceof ViewGroup rootGroup)) {
|
||||||
removeBatteryBarView(root);
|
removeBatteryBarView(root);
|
||||||
return;
|
return;
|
||||||
|
|||||||
+79
-3
@@ -24,6 +24,8 @@ import se.ajpanton.statusbartweak.runtime.ViewIdNames;
|
|||||||
import se.ajpanton.statusbartweak.runtime.features.RuntimeContext;
|
import se.ajpanton.statusbartweak.runtime.features.RuntimeContext;
|
||||||
import se.ajpanton.statusbartweak.runtime.hooks.ReflectionSupport;
|
import se.ajpanton.statusbartweak.runtime.hooks.ReflectionSupport;
|
||||||
import se.ajpanton.statusbartweak.runtime.hooks.XposedHookSupport;
|
import se.ajpanton.statusbartweak.runtime.hooks.XposedHookSupport;
|
||||||
|
import se.ajpanton.statusbartweak.runtime.mode.SceneKey;
|
||||||
|
import se.ajpanton.statusbartweak.runtime.mode.SurfaceMode;
|
||||||
import se.ajpanton.statusbartweak.runtime.settings.BroadcastReceiverSupport;
|
import se.ajpanton.statusbartweak.runtime.settings.BroadcastReceiverSupport;
|
||||||
import se.ajpanton.statusbartweak.runtime.settings.RuntimeSettingsCache;
|
import se.ajpanton.statusbartweak.runtime.settings.RuntimeSettingsCache;
|
||||||
import se.ajpanton.statusbartweak.shell.settings.SbtSettings;
|
import se.ajpanton.statusbartweak.shell.settings.SbtSettings;
|
||||||
@@ -83,6 +85,11 @@ final class DrawerClockTextController {
|
|||||||
|
|
||||||
private void scanAndApply(View root) {
|
private void scanAndApply(View root) {
|
||||||
SbtSettings settings = RuntimeSettingsCache.get(root.getContext());
|
SbtSettings settings = RuntimeSettingsCache.get(root.getContext());
|
||||||
|
SceneKey scene = runtimeContext.getModeStateRepository().getActiveScene();
|
||||||
|
if (scene != null && scene.isAod()) {
|
||||||
|
restoreTrackedDescendants(root);
|
||||||
|
return;
|
||||||
|
}
|
||||||
boolean clockEnabled = isEnabled(settings, Role.CLOCK);
|
boolean clockEnabled = isEnabled(settings, Role.CLOCK);
|
||||||
boolean dateEnabled = isEnabled(settings, Role.DATE);
|
boolean dateEnabled = isEnabled(settings, Role.DATE);
|
||||||
if (!clockEnabled && !dateEnabled) {
|
if (!clockEnabled && !dateEnabled) {
|
||||||
@@ -95,10 +102,16 @@ final class DrawerClockTextController {
|
|||||||
registerReceiverIfNeeded(root.getContext());
|
registerReceiverIfNeeded(root.getContext());
|
||||||
untrackDisabledRoles(clockEnabled, dateEnabled);
|
untrackDisabledRoles(clockEnabled, dateEnabled);
|
||||||
|
|
||||||
CandidateSelection candidates = cachedCandidates(root, clockEnabled, dateEnabled);
|
SurfaceMode surfaceMode = scene != null ? scene.surfaceMode() : null;
|
||||||
|
if (hasValidTrackedCandidates(root, clockEnabled, dateEnabled, surfaceMode)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CandidateSelection candidates = cachedCandidates(root, clockEnabled, dateEnabled, surfaceMode);
|
||||||
if (candidates == null) {
|
if (candidates == null) {
|
||||||
candidates = findCandidates(root);
|
candidates = findCandidates(root);
|
||||||
candidateCacheByRoot.put(root, new CandidateCache(
|
candidateCacheByRoot.put(root, new CandidateCache(
|
||||||
|
surfaceMode,
|
||||||
candidates.clock != null ? candidates.clock.view : null,
|
candidates.clock != null ? candidates.clock.view : null,
|
||||||
candidates.date != null ? candidates.date.view : null));
|
candidates.date != null ? candidates.date.view : null));
|
||||||
}
|
}
|
||||||
@@ -126,6 +139,18 @@ final class DrawerClockTextController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int restoreTrackedDescendants(View root) {
|
||||||
|
int restored = 0;
|
||||||
|
for (TextView textView : new ArrayList<>(trackedRoles.keySet())) {
|
||||||
|
if (textView == null || root == null || isDescendantOf(textView, root)) {
|
||||||
|
restore(textView);
|
||||||
|
untrack(textView);
|
||||||
|
restored++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return restored;
|
||||||
|
}
|
||||||
|
|
||||||
private void untrackDisabledRoles(boolean clockEnabled, boolean dateEnabled) {
|
private void untrackDisabledRoles(boolean clockEnabled, boolean dateEnabled) {
|
||||||
for (TextView textView : new ArrayList<>(trackedRoles.keySet())) {
|
for (TextView textView : new ArrayList<>(trackedRoles.keySet())) {
|
||||||
Role role = trackedRoles.get(textView);
|
Role role = trackedRoles.get(textView);
|
||||||
@@ -136,6 +161,44 @@ final class DrawerClockTextController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean hasValidTrackedCandidates(
|
||||||
|
View root,
|
||||||
|
boolean clockEnabled,
|
||||||
|
boolean dateEnabled,
|
||||||
|
SurfaceMode surfaceMode
|
||||||
|
) {
|
||||||
|
if (clockEnabled && !hasValidTrackedRole(root, Role.CLOCK, surfaceMode)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return !dateEnabled || hasValidTrackedRole(root, Role.DATE, surfaceMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasValidTrackedRole(View root, Role role, SurfaceMode surfaceMode) {
|
||||||
|
CandidateCache cache = candidateCacheByRoot.get(root);
|
||||||
|
if (cache == null || cache.surfaceMode != surfaceMode) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
WeakReference<TextView> expectedReference = role == Role.CLOCK
|
||||||
|
? cache.clockView
|
||||||
|
: cache.dateView;
|
||||||
|
TextView expectedView = expectedReference != null ? expectedReference.get() : null;
|
||||||
|
if (expectedView == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (Map.Entry<TextView, Role> entry : trackedRoles.entrySet()) {
|
||||||
|
TextView textView = entry.getKey();
|
||||||
|
if (entry.getValue() == role
|
||||||
|
&& textView == expectedView
|
||||||
|
&& textView.isAttachedToWindow()
|
||||||
|
&& isDescendantOf(textView, root)
|
||||||
|
&& !isStatusbarClock(textView)
|
||||||
|
&& ownedTexts.contains(textView)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private void track(TextView textView, Role role) {
|
private void track(TextView textView, Role role) {
|
||||||
if (textView == null || role == null) {
|
if (textView == null || role == null) {
|
||||||
return;
|
return;
|
||||||
@@ -159,6 +222,12 @@ final class DrawerClockTextController {
|
|||||||
if (role == null) {
|
if (role == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
SceneKey scene = runtimeContext.getModeStateRepository().getActiveScene();
|
||||||
|
if (scene != null && scene.isAod()) {
|
||||||
|
restore(textView);
|
||||||
|
untrack(textView);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (stockTextJustChanged) {
|
if (stockTextJustChanged) {
|
||||||
captureSnapshot(textView);
|
captureSnapshot(textView);
|
||||||
}
|
}
|
||||||
@@ -416,12 +485,17 @@ final class DrawerClockTextController {
|
|||||||
private CandidateSelection cachedCandidates(
|
private CandidateSelection cachedCandidates(
|
||||||
View root,
|
View root,
|
||||||
boolean clockEnabled,
|
boolean clockEnabled,
|
||||||
boolean dateEnabled
|
boolean dateEnabled,
|
||||||
|
SurfaceMode surfaceMode
|
||||||
) {
|
) {
|
||||||
CandidateCache cache = candidateCacheByRoot.get(root);
|
CandidateCache cache = candidateCacheByRoot.get(root);
|
||||||
if (cache == null) {
|
if (cache == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
if (cache.surfaceMode != surfaceMode) {
|
||||||
|
candidateCacheByRoot.remove(root);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
Candidate clock = candidateFromCache(root, cache.clockView, Role.CLOCK, clockEnabled);
|
Candidate clock = candidateFromCache(root, cache.clockView, Role.CLOCK, clockEnabled);
|
||||||
Candidate date = candidateFromCache(root, cache.dateView, Role.DATE, dateEnabled);
|
Candidate date = candidateFromCache(root, cache.dateView, Role.DATE, dateEnabled);
|
||||||
if (clockEnabled && clock == null || dateEnabled && date == null) {
|
if (clockEnabled && clock == null || dateEnabled && date == null) {
|
||||||
@@ -554,10 +628,12 @@ final class DrawerClockTextController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static final class CandidateCache {
|
private static final class CandidateCache {
|
||||||
|
final SurfaceMode surfaceMode;
|
||||||
final WeakReference<TextView> clockView;
|
final WeakReference<TextView> clockView;
|
||||||
final WeakReference<TextView> dateView;
|
final WeakReference<TextView> dateView;
|
||||||
|
|
||||||
CandidateCache(TextView clockView, TextView dateView) {
|
CandidateCache(SurfaceMode surfaceMode, TextView clockView, TextView dateView) {
|
||||||
|
this.surfaceMode = surfaceMode;
|
||||||
this.clockView = new WeakReference<>(clockView);
|
this.clockView = new WeakReference<>(clockView);
|
||||||
this.dateView = new WeakReference<>(dateView);
|
this.dateView = new WeakReference<>(dateView);
|
||||||
}
|
}
|
||||||
|
|||||||
+19
-7
@@ -153,7 +153,7 @@ final class StockClockController {
|
|||||||
}
|
}
|
||||||
runtimeContext.getModeStateRepository().addLayoutEnabledListener(enabled -> {
|
runtimeContext.getModeStateRepository().addLayoutEnabledListener(enabled -> {
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
removeAllRowOverlays();
|
restoreAllOwnedClocks();
|
||||||
} else {
|
} else {
|
||||||
refreshAllClocks();
|
refreshAllClocks();
|
||||||
}
|
}
|
||||||
@@ -218,14 +218,18 @@ final class StockClockController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void restoreAllOwnedClocks() {
|
||||||
|
for (TextView clockView : new ArrayList<>(trackedClocks)) {
|
||||||
|
restoreOwnedClock(clockView);
|
||||||
|
}
|
||||||
|
removeAllRowOverlays();
|
||||||
|
}
|
||||||
|
|
||||||
private void applyClockText(TextView clockView) {
|
private void applyClockText(TextView clockView) {
|
||||||
SbtSettings settings = RuntimeSettingsCache.get(clockView.getContext());
|
SbtSettings settings = RuntimeSettingsCache.get(clockView.getContext());
|
||||||
if (!hasCustomClockTextEnabled(settings)) {
|
boolean layoutEnabled = settings.clockEnabled;
|
||||||
stopTicker(clockView);
|
if (layoutEnabled || !hasCustomClockTextEnabled(settings)) {
|
||||||
if (ownedClocks.contains(clockView)) {
|
restoreOwnedClock(clockView);
|
||||||
restoreStockText(clockView);
|
|
||||||
ownedClocks.remove(clockView);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
captureCurrentStockSnapshot(clockView);
|
captureCurrentStockSnapshot(clockView);
|
||||||
@@ -255,6 +259,14 @@ final class StockClockController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void restoreOwnedClock(TextView clockView) {
|
||||||
|
stopTicker(clockView);
|
||||||
|
if (ownedClocks.contains(clockView)) {
|
||||||
|
restoreStockText(clockView);
|
||||||
|
ownedClocks.remove(clockView);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private ArrayList<ClockTextRenderer.LayoutRowResult> layoutRowsFromModel(
|
private ArrayList<ClockTextRenderer.LayoutRowResult> layoutRowsFromModel(
|
||||||
ClockLayoutTextFactory.Model model
|
ClockLayoutTextFactory.Model model
|
||||||
) {
|
) {
|
||||||
|
|||||||
+22
@@ -53,6 +53,28 @@ final class LockscreenCardsNotificationRowFilter {
|
|||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean applyRow(View row, boolean allowAfterKeyguardUnlock) {
|
||||||
|
if (!isNotificationRow(row)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Context context = row.getContext();
|
||||||
|
boolean active = isActive(context, allowAfterKeyguardUnlock);
|
||||||
|
boolean changed;
|
||||||
|
if (active && shouldHideRow(context, row, allowAfterKeyguardUnlock)) {
|
||||||
|
changed = hideRow(row);
|
||||||
|
} else {
|
||||||
|
changed = restoreRow(row);
|
||||||
|
}
|
||||||
|
if (changed) {
|
||||||
|
requestLayout(row);
|
||||||
|
}
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void restoreRemovedRow(View row) {
|
||||||
|
restoreRow(row);
|
||||||
|
}
|
||||||
|
|
||||||
void restoreAll() {
|
void restoreAll() {
|
||||||
if (hiddenRows.isEmpty()) {
|
if (hiddenRows.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
+224
-28
@@ -138,12 +138,15 @@ final class StockLayoutCanvasController {
|
|||||||
Collections.newSetFromMap(new WeakHashMap<>());
|
Collections.newSetFromMap(new WeakHashMap<>());
|
||||||
private final Set<View> pendingUnlockedAppearanceRefreshRoots =
|
private final Set<View> pendingUnlockedAppearanceRefreshRoots =
|
||||||
Collections.newSetFromMap(new WeakHashMap<>());
|
Collections.newSetFromMap(new WeakHashMap<>());
|
||||||
|
private final Set<View> pendingUnlockedClockTextRefreshRoots =
|
||||||
|
Collections.newSetFromMap(new WeakHashMap<>());
|
||||||
private final Set<View> pendingDrawerAppearanceRefreshRoots =
|
private final Set<View> pendingDrawerAppearanceRefreshRoots =
|
||||||
Collections.newSetFromMap(new WeakHashMap<>());
|
Collections.newSetFromMap(new WeakHashMap<>());
|
||||||
private final Set<View> dirtyUnlockedLayoutRoots =
|
private final Set<View> dirtyUnlockedLayoutRoots =
|
||||||
Collections.newSetFromMap(new WeakHashMap<>());
|
Collections.newSetFromMap(new WeakHashMap<>());
|
||||||
private final Set<View> pendingDrawerStatusChipRefreshRoots =
|
private final Set<View> pendingDrawerStatusChipRefreshRoots =
|
||||||
Collections.newSetFromMap(new WeakHashMap<>());
|
Collections.newSetFromMap(new WeakHashMap<>());
|
||||||
|
private final Map<View, Runnable> unlockedClockTickersByRoot = new WeakHashMap<>();
|
||||||
private final Set<ClassLoader> hookedPluginClassLoaders =
|
private final Set<ClassLoader> hookedPluginClassLoaders =
|
||||||
Collections.newSetFromMap(new IdentityHashMap<>());
|
Collections.newSetFromMap(new IdentityHashMap<>());
|
||||||
private final Set<ClassLoader> pendingPluginClassLoaders =
|
private final Set<ClassLoader> pendingPluginClassLoaders =
|
||||||
@@ -479,8 +482,9 @@ final class StockLayoutCanvasController {
|
|||||||
"onViewAdded",
|
"onViewAdded",
|
||||||
chain -> {
|
chain -> {
|
||||||
Object result = chain.proceed();
|
Object result = chain.proceed();
|
||||||
if (chain.getThisObject() instanceof ViewGroup stack) {
|
List<Object> args = chain.getArgs();
|
||||||
applyLockscreenCardsNotificationRowFilter(stack, false);
|
if (!args.isEmpty() && args.get(0) instanceof View row) {
|
||||||
|
applyLockscreenCardsNotificationRowFilterRow(row, false);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
@@ -490,8 +494,9 @@ final class StockLayoutCanvasController {
|
|||||||
"onViewRemoved",
|
"onViewRemoved",
|
||||||
chain -> {
|
chain -> {
|
||||||
Object result = chain.proceed();
|
Object result = chain.proceed();
|
||||||
if (chain.getThisObject() instanceof ViewGroup stack) {
|
List<Object> args = chain.getArgs();
|
||||||
applyLockscreenCardsNotificationRowFilter(stack, false);
|
if (!args.isEmpty() && args.get(0) instanceof View row) {
|
||||||
|
lockscreenCardsNotificationRowFilter.restoreRemovedRow(row);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
@@ -1780,6 +1785,7 @@ final class StockLayoutCanvasController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SceneKey activeScene = runtimeContext.getModeStateRepository().getActiveScene();
|
SceneKey activeScene = runtimeContext.getModeStateRepository().getActiveScene();
|
||||||
|
ensureUnlockedClockTickerState(root, settings, activeScene);
|
||||||
if (!clockTextRefreshEnabledForScene(settings, activeScene)) {
|
if (!clockTextRefreshEnabledForScene(settings, activeScene)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1804,6 +1810,80 @@ final class StockLayoutCanvasController {
|
|||||||
return System.currentTimeMillis() / divisor;
|
return System.currentTimeMillis() / divisor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ensureUnlockedClockTickerState(View root, SbtSettings settings, SceneKey scene) {
|
||||||
|
if (!clockNeedsSecondTicker(root, settings, scene)) {
|
||||||
|
stopUnlockedClockTicker(root);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Runnable existing = unlockedClockTickersByRoot.get(root);
|
||||||
|
if (existing != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Runnable ticker = new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (!clockNeedsSecondTicker(root, RuntimeSettingsCache.get(root.getContext()),
|
||||||
|
runtimeContext.getModeStateRepository().getActiveScene())) {
|
||||||
|
stopUnlockedClockTicker(root);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
scheduleUnlockedClockTextRefreshForRoot(root);
|
||||||
|
scheduleNextUnlockedClockTick(root, this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
unlockedClockTickersByRoot.put(root, ticker);
|
||||||
|
scheduleNextUnlockedClockTick(root, ticker);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean clockNeedsSecondTicker(View root, SbtSettings settings, SceneKey scene) {
|
||||||
|
if (root == null
|
||||||
|
|| !root.isAttachedToWindow()
|
||||||
|
|| !isUnlockedStatusBarRoot(root)
|
||||||
|
|| settings == null
|
||||||
|
|| !settings.clockEnabled
|
||||||
|
|| !clockTextRefreshEnabledForScene(settings, scene)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return clockUsesSeconds(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean clockUsesSeconds(SbtSettings settings) {
|
||||||
|
if (settings == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
String pattern = settings.clockCustomFormat != null ? settings.clockCustomFormat : "";
|
||||||
|
return settings.clockShowSeconds
|
||||||
|
|| (settings.clockCustomFormatEnabled && pattern.contains("s"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void scheduleNextUnlockedClockTick(View root, Runnable ticker) {
|
||||||
|
if (root == null || ticker == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
long next = now - (now % 1000L) + 1000L;
|
||||||
|
root.postDelayed(ticker, Math.max(1L, next - now));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stopUnlockedClockTicker(View root) {
|
||||||
|
if (root == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Runnable ticker = unlockedClockTickersByRoot.remove(root);
|
||||||
|
if (ticker != null) {
|
||||||
|
root.removeCallbacks(ticker);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearUnlockedClockRefreshState(View root) {
|
||||||
|
if (root == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
stopUnlockedClockTicker(root);
|
||||||
|
pendingUnlockedClockTextRefreshRoots.remove(root);
|
||||||
|
clockTimeBucketByRoot.remove(root);
|
||||||
|
}
|
||||||
|
|
||||||
private void scheduleUnlockedAppearanceRefreshForAllRoots() {
|
private void scheduleUnlockedAppearanceRefreshForAllRoots() {
|
||||||
scheduleUnlockedAppearanceRefreshForAllRoots(false);
|
scheduleUnlockedAppearanceRefreshForAllRoots(false);
|
||||||
}
|
}
|
||||||
@@ -1830,8 +1910,15 @@ final class StockLayoutCanvasController {
|
|||||||
if (previous == null || current == null || previous.equals(current)) {
|
if (previous == null || current == null || previous.equals(current)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (previous.isLockscreen() && !current.isLockscreen()) {
|
if (current.isUnlocked() && !previous.isUnlocked()) {
|
||||||
darkIconDispatcherGuard.restoreForcedStates();
|
darkIconDispatcherGuard.restoreForcedStates();
|
||||||
|
trackedLockedStatusBarIconSurfaces.clear();
|
||||||
|
} else if (previous.isLockscreen() && current.isAod()) {
|
||||||
|
darkIconDispatcherGuard.restoreForcedStates();
|
||||||
|
hideTrackedLockedStatusBarIconSurfaces(null);
|
||||||
|
} else if (previous.isLockscreen() && !current.isLockscreen()) {
|
||||||
|
darkIconDispatcherGuard.restoreForcedStates();
|
||||||
|
restoreTrackedLockedStatusBarIconSurfaces(null);
|
||||||
}
|
}
|
||||||
boolean lockscreenEntry = current.isLockscreen();
|
boolean lockscreenEntry = current.isLockscreen();
|
||||||
if (lockscreenEntry) {
|
if (lockscreenEntry) {
|
||||||
@@ -1847,6 +1934,7 @@ final class StockLayoutCanvasController {
|
|||||||
if (root == null || !root.isAttachedToWindow()) {
|
if (root == null || !root.isAttachedToWindow()) {
|
||||||
rootGeometries.remove(root);
|
rootGeometries.remove(root);
|
||||||
unlockedHostsByRoot.remove(root);
|
unlockedHostsByRoot.remove(root);
|
||||||
|
clearUnlockedClockRefreshState(root);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Runnable refresh = () -> refreshSceneRoot(root);
|
Runnable refresh = () -> refreshSceneRoot(root);
|
||||||
@@ -1866,6 +1954,7 @@ final class StockLayoutCanvasController {
|
|||||||
if (root == null || !root.isAttachedToWindow()) {
|
if (root == null || !root.isAttachedToWindow()) {
|
||||||
rootGeometries.remove(root);
|
rootGeometries.remove(root);
|
||||||
unlockedHostsByRoot.remove(root);
|
unlockedHostsByRoot.remove(root);
|
||||||
|
clearUnlockedClockRefreshState(root);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
unlockedIconRenderController.clearRoot(root);
|
unlockedIconRenderController.clearRoot(root);
|
||||||
@@ -1926,11 +2015,11 @@ final class StockLayoutCanvasController {
|
|||||||
if (root == null
|
if (root == null
|
||||||
|| !root.isAttachedToWindow()
|
|| !root.isAttachedToWindow()
|
||||||
|| !isUnlockedStatusBarRoot(root)
|
|| !isUnlockedStatusBarRoot(root)
|
||||||
|| !pendingUnlockedAppearanceRefreshRoots.add(root)) {
|
|| !pendingUnlockedClockTextRefreshRoots.add(root)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
root.post(() -> {
|
root.post(() -> {
|
||||||
pendingUnlockedAppearanceRefreshRoots.remove(root);
|
pendingUnlockedClockTextRefreshRoots.remove(root);
|
||||||
refreshUnlockedClockTextNow(root);
|
refreshUnlockedClockTextNow(root);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -2077,11 +2166,19 @@ final class StockLayoutCanvasController {
|
|||||||
}
|
}
|
||||||
if (!layoutRoot) {
|
if (!layoutRoot) {
|
||||||
if (activeScene != null
|
if (activeScene != null
|
||||||
|
&& activeScene.isUnlocked()
|
||||||
|
&& isNotificationShadeWindowRoot(root)) {
|
||||||
|
hideUnlockedShadeShelfIconSurfaces(root);
|
||||||
|
removeSharedLayoutHosts(root);
|
||||||
|
} else if (activeScene != null
|
||||||
&& activeScene.isLockscreen()
|
&& activeScene.isLockscreen()
|
||||||
&& canContainLockedStatusBarIconSurfaces(root)) {
|
&& canContainLockedStatusBarIconSurfaces(root)) {
|
||||||
removeUnlockedLayoutHosts(root);
|
removeUnlockedLayoutHosts(root);
|
||||||
removeAodCardsNotificationHost(root);
|
removeAodCardsNotificationHost(root);
|
||||||
renderLockscreenCardsNotificationStripIfNeeded(root, settings, activeScene);
|
if (activeScene.notificationDisplayStyle() != NotificationDisplayStyle.CARDS
|
||||||
|
&& hasLockscreenCardsNotificationHost(root)) {
|
||||||
|
removeLockscreenCardsNotificationHost(root);
|
||||||
|
}
|
||||||
hideOrDiscoverLockedStatusBarIconSurfaces(root);
|
hideOrDiscoverLockedStatusBarIconSurfaces(root);
|
||||||
} else {
|
} else {
|
||||||
removeSharedLayoutHosts(root);
|
removeSharedLayoutHosts(root);
|
||||||
@@ -2100,9 +2197,6 @@ final class StockLayoutCanvasController {
|
|||||||
&& (unlockedScene
|
&& (unlockedScene
|
||||||
|| activeScene != null && activeScene.isLockscreen()
|
|| activeScene != null && activeScene.isLockscreen()
|
||||||
|| aodScene)) {
|
|| aodScene)) {
|
||||||
if (!unlockedScene) {
|
|
||||||
restoreTrackedLockedStatusBarIconSurfaces(root);
|
|
||||||
}
|
|
||||||
boolean shouldRender = !unlockedIconRenderController.hasLayoutPlan(root)
|
boolean shouldRender = !unlockedIconRenderController.hasLayoutPlan(root)
|
||||||
|| rootDirty;
|
|| rootDirty;
|
||||||
if (shouldRender && shouldDeferUnlockedRenderForDrawer(root)) {
|
if (shouldRender && shouldDeferUnlockedRenderForDrawer(root)) {
|
||||||
@@ -2225,6 +2319,13 @@ final class StockLayoutCanvasController {
|
|||||||
|| findDirectOwnedHost(group, OwnedIconHostManager.TAG_AOD_CARDS_NOTIFICATION_HOST) != null;
|
|| findDirectOwnedHost(group, OwnedIconHostManager.TAG_AOD_CARDS_NOTIFICATION_HOST) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean hasLockscreenCardsNotificationHost(View root) {
|
||||||
|
return root instanceof ViewGroup group
|
||||||
|
&& findDirectOwnedHost(
|
||||||
|
group,
|
||||||
|
OwnedIconHostManager.TAG_LOCKSCREEN_CARDS_NOTIFICATION_HOST) != null;
|
||||||
|
}
|
||||||
|
|
||||||
private void applyDebugOverlay(
|
private void applyDebugOverlay(
|
||||||
View root,
|
View root,
|
||||||
boolean layoutEnabled,
|
boolean layoutEnabled,
|
||||||
@@ -2346,6 +2447,51 @@ final class StockLayoutCanvasController {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void hideUnlockedShadeShelfIconSurfaces(View root) {
|
||||||
|
if (root == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
boolean foundTracked = hideTrackedUnlockedShadeShelfIconSurfaces(root);
|
||||||
|
if (foundTracked) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
walkTree(root, view -> {
|
||||||
|
if (isUnlockedShadeShelfIconSurface(view)) {
|
||||||
|
trackedUnlockedStockSurfaces.add(view);
|
||||||
|
hideView(view, false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hideTrackedUnlockedShadeShelfIconSurfaces(View root) {
|
||||||
|
if (trackedUnlockedStockSurfaces.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
boolean foundIconSurfaceInRoot = false;
|
||||||
|
ArrayDeque<View> staleViews = new ArrayDeque<>();
|
||||||
|
for (View view : trackedUnlockedStockSurfaces) {
|
||||||
|
if (view == null || !view.isAttachedToWindow()) {
|
||||||
|
staleViews.add(view);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!isDescendantOf(view, root)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!isUnlockedShadeShelfIconSurface(view)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
foundIconSurfaceInRoot |= isCardsNotificationIconSurface(view);
|
||||||
|
hideView(view, false);
|
||||||
|
}
|
||||||
|
removeStaleViews(trackedUnlockedStockSurfaces, staleViews);
|
||||||
|
return foundIconSurfaceInRoot;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isUnlockedShadeShelfIconSurface(View view) {
|
||||||
|
return isCardsNotificationIconSurface(view)
|
||||||
|
|| isCardsNotificationShelfBackgroundSurface(view);
|
||||||
|
}
|
||||||
|
|
||||||
private boolean hasTrackedUnlockedStockSurfaces(View root) {
|
private boolean hasTrackedUnlockedStockSurfaces(View root) {
|
||||||
if (trackedUnlockedStockSurfaces.isEmpty()) {
|
if (trackedUnlockedStockSurfaces.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
@@ -2748,14 +2894,17 @@ final class StockLayoutCanvasController {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void trackAndHideLockedStatusBarIconSurfaces(View root) {
|
private int trackAndHideLockedStatusBarIconSurfaces(View root) {
|
||||||
|
final int[] found = {0};
|
||||||
walkTree(root, view -> {
|
walkTree(root, view -> {
|
||||||
if (isLockedStatusBarIconSurface(view)) {
|
if (isLockedStatusBarIconSurface(view)) {
|
||||||
rememberLockedCarrierTextSource(view);
|
rememberLockedCarrierTextSource(view);
|
||||||
trackedLockedStatusBarIconSurfaces.add(view);
|
trackedLockedStatusBarIconSurfaces.add(view);
|
||||||
hideView(view, isCarrierView(view));
|
hideView(view, isCarrierView(view));
|
||||||
|
found[0]++;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
return found[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
private void hideOrDiscoverLockedStatusBarIconSurfaces(View root) {
|
private void hideOrDiscoverLockedStatusBarIconSurfaces(View root) {
|
||||||
@@ -2776,13 +2925,18 @@ final class StockLayoutCanvasController {
|
|||||||
staleViews.add(view);
|
staleViews.add(view);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (root == null || isDescendantOf(view, root)) {
|
||||||
|
foundInRoot = true;
|
||||||
|
if (isAlreadySuppressedHiddenView(view)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!isLockedStatusBarIconSurface(view)) {
|
if (!isLockedStatusBarIconSurface(view)) {
|
||||||
restoreView(view);
|
restoreView(view);
|
||||||
staleViews.add(view);
|
staleViews.add(view);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (root == null || isDescendantOf(view, root)) {
|
if (root == null || isDescendantOf(view, root)) {
|
||||||
foundInRoot = true;
|
|
||||||
hideView(view, isCarrierView(view));
|
hideView(view, isCarrierView(view));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2790,6 +2944,13 @@ final class StockLayoutCanvasController {
|
|||||||
return foundInRoot;
|
return foundInRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isAlreadySuppressedHiddenView(View view) {
|
||||||
|
return view != null
|
||||||
|
&& hiddenViewStates.containsKey(view)
|
||||||
|
&& view.getAlpha() == 0f
|
||||||
|
&& (view.getVisibility() == View.GONE || view.getVisibility() == View.VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
private boolean shouldSuppressConflictingShadeHeaderAlpha(View view, float alpha) {
|
private boolean shouldSuppressConflictingShadeHeaderAlpha(View view, float alpha) {
|
||||||
return view != null
|
return view != null
|
||||||
&& alpha != view.getAlpha()
|
&& alpha != view.getAlpha()
|
||||||
@@ -2928,11 +3089,18 @@ final class StockLayoutCanvasController {
|
|||||||
if (trackedLockedStatusBarIconSurfaces.isEmpty()) {
|
if (trackedLockedStatusBarIconSurfaces.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
ArrayDeque<View> restoredViews = new ArrayDeque<>();
|
||||||
for (View view : trackedLockedStatusBarIconSurfaces) {
|
for (View view : trackedLockedStatusBarIconSurfaces) {
|
||||||
if (view != null && view.isAttachedToWindow() && (root == null || isDescendantOf(view, root))) {
|
if (view == null || !view.isAttachedToWindow()) {
|
||||||
|
restoredViews.add(view);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (root == null || isDescendantOf(view, root)) {
|
||||||
restoreView(view);
|
restoreView(view);
|
||||||
|
restoredViews.add(view);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
removeStaleViews(trackedLockedStatusBarIconSurfaces, restoredViews);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasTrackedStatusChipSources(View root) {
|
private boolean hasTrackedStatusChipSources(View root) {
|
||||||
@@ -3297,7 +3465,7 @@ final class StockLayoutCanvasController {
|
|||||||
aodBeforeDrawSignatureByRoot.remove(root);
|
aodBeforeDrawSignatureByRoot.remove(root);
|
||||||
lockscreenCardsRowFilterSignatures.remove(root);
|
lockscreenCardsRowFilterSignatures.remove(root);
|
||||||
lockscreenCardsNotificationRenderGenerationByRoot.remove(root);
|
lockscreenCardsNotificationRenderGenerationByRoot.remove(root);
|
||||||
clockTimeBucketByRoot.remove(root);
|
clearUnlockedClockRefreshState(root);
|
||||||
removeDebugOverlay(root);
|
removeDebugOverlay(root);
|
||||||
root.requestLayout();
|
root.requestLayout();
|
||||||
root.invalidate();
|
root.invalidate();
|
||||||
@@ -4046,7 +4214,7 @@ final class StockLayoutCanvasController {
|
|||||||
dirtyUnlockedLayoutRoots.remove(root);
|
dirtyUnlockedLayoutRoots.remove(root);
|
||||||
settingsIdentityByRoot.remove(root);
|
settingsIdentityByRoot.remove(root);
|
||||||
lockscreenCardsRowFilterSignatures.remove(root);
|
lockscreenCardsRowFilterSignatures.remove(root);
|
||||||
clockTimeBucketByRoot.remove(root);
|
clearUnlockedClockRefreshState(root);
|
||||||
if (!isUnlockedStatusBarRoot(root) || !layoutOffCleanedRoots.add(root)) {
|
if (!isUnlockedStatusBarRoot(root) || !layoutOffCleanedRoots.add(root)) {
|
||||||
unlockedHostsByRoot.remove(root);
|
unlockedHostsByRoot.remove(root);
|
||||||
rootGeometries.remove(root);
|
rootGeometries.remove(root);
|
||||||
@@ -4117,7 +4285,7 @@ final class StockLayoutCanvasController {
|
|||||||
pendingUnlockedAppearanceRefreshRoots.remove(root);
|
pendingUnlockedAppearanceRefreshRoots.remove(root);
|
||||||
dirtyUnlockedLayoutRoots.remove(root);
|
dirtyUnlockedLayoutRoots.remove(root);
|
||||||
settingsIdentityByRoot.remove(root);
|
settingsIdentityByRoot.remove(root);
|
||||||
clockTimeBucketByRoot.remove(root);
|
clearUnlockedClockRefreshState(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeUnlockedLayoutHosts(View root) {
|
private void removeUnlockedLayoutHosts(View root) {
|
||||||
@@ -4130,7 +4298,7 @@ final class StockLayoutCanvasController {
|
|||||||
pendingUnlockedAppearanceRefreshRoots.remove(root);
|
pendingUnlockedAppearanceRefreshRoots.remove(root);
|
||||||
dirtyUnlockedLayoutRoots.remove(root);
|
dirtyUnlockedLayoutRoots.remove(root);
|
||||||
settingsIdentityByRoot.remove(root);
|
settingsIdentityByRoot.remove(root);
|
||||||
clockTimeBucketByRoot.remove(root);
|
clearUnlockedClockRefreshState(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isDescendantOfNotificationShadeWindow(View view) {
|
private boolean isDescendantOfNotificationShadeWindow(View view) {
|
||||||
@@ -4185,16 +4353,23 @@ final class StockLayoutCanvasController {
|
|||||||
SbtSettings settings,
|
SbtSettings settings,
|
||||||
SceneKey activeScene
|
SceneKey activeScene
|
||||||
) {
|
) {
|
||||||
View visibleBouncerSurface = findVisibleBouncerSurface(root);
|
|
||||||
boolean suppressForTransition = runtimeContext.getModeStateRepository().isSystemUiShadeLocked()
|
|
||||||
|| visibleBouncerSurface != null;
|
|
||||||
if (root == null
|
if (root == null
|
||||||
|| settings == null
|
|| settings == null
|
||||||
|| activeScene == null
|
|| activeScene == null
|
||||||
|| !activeScene.isLockscreen()
|
|| !activeScene.isLockscreen()
|
||||||
|| activeScene.notificationDisplayStyle() != NotificationDisplayStyle.CARDS
|
|| activeScene.notificationDisplayStyle() != NotificationDisplayStyle.CARDS
|
||||||
|| !isNotificationShadeWindowRoot(root)
|
|| !isNotificationShadeWindowRoot(root)) {
|
||||||
|| suppressForTransition) {
|
removeLockscreenCardsNotificationHost(root);
|
||||||
|
lockscreenCardsNotificationRenderGenerationByRoot.remove(root);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (runtimeContext.getModeStateRepository().isSystemUiShadeLocked()) {
|
||||||
|
removeLockscreenCardsNotificationHost(root);
|
||||||
|
lockscreenCardsNotificationRenderGenerationByRoot.remove(root);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
View visibleBouncerSurface = findVisibleBouncerSurface(root);
|
||||||
|
if (visibleBouncerSurface != null) {
|
||||||
removeLockscreenCardsNotificationHost(root);
|
removeLockscreenCardsNotificationHost(root);
|
||||||
lockscreenCardsNotificationRenderGenerationByRoot.remove(root);
|
lockscreenCardsNotificationRenderGenerationByRoot.remove(root);
|
||||||
return;
|
return;
|
||||||
@@ -4210,7 +4385,7 @@ final class StockLayoutCanvasController {
|
|||||||
int rootHeight = root.getHeight();
|
int rootHeight = root.getHeight();
|
||||||
int activeKeyGeneration = NotificationActiveKeyStore.generation();
|
int activeKeyGeneration = NotificationActiveKeyStore.generation();
|
||||||
int sourceSignature =
|
int sourceSignature =
|
||||||
LockscreenCardsNotificationIconSourceStore.snapshotSourceSignatureForRoot(root);
|
LockscreenCardsNotificationIconSourceStore.lightweightSourceSignatureForRoot(root);
|
||||||
int generation = settingsId;
|
int generation = settingsId;
|
||||||
generation = 31 * generation + rootWidth;
|
generation = 31 * generation + rootWidth;
|
||||||
generation = 31 * generation + rootHeight;
|
generation = 31 * generation + rootHeight;
|
||||||
@@ -4224,7 +4399,7 @@ final class StockLayoutCanvasController {
|
|||||||
lockscreenCardsNotificationRenderGenerationByRoot.put(root, generation);
|
lockscreenCardsNotificationRenderGenerationByRoot.put(root, generation);
|
||||||
lockscreenCardsNotificationStripRenderer.render(root, hostGroup, settings, activeScene);
|
lockscreenCardsNotificationStripRenderer.render(root, hostGroup, settings, activeScene);
|
||||||
}
|
}
|
||||||
host.bringToFront();
|
bringToFrontIfNeeded(host);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4271,10 +4446,21 @@ final class StockLayoutCanvasController {
|
|||||||
lockscreenCardsNotificationStripRenderer.render(root, hostGroup, settings, activeScene);
|
lockscreenCardsNotificationStripRenderer.render(root, hostGroup, settings, activeScene);
|
||||||
}
|
}
|
||||||
setHostAlpha(host, aodVisualAlphaForRoot(root));
|
setHostAlpha(host, aodVisualAlphaForRoot(root));
|
||||||
host.bringToFront();
|
bringToFrontIfNeeded(host);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void bringToFrontIfNeeded(View view) {
|
||||||
|
if (view == null || !(view.getParent() instanceof ViewGroup group)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int childCount = group.getChildCount();
|
||||||
|
if (childCount <= 0 || group.getChildAt(childCount - 1) == view) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
view.bringToFront();
|
||||||
|
}
|
||||||
|
|
||||||
private void applyLockscreenCardsNotificationRowFilter(ViewGroup stack, boolean allowAfterKeyguardUnlock) {
|
private void applyLockscreenCardsNotificationRowFilter(ViewGroup stack, boolean allowAfterKeyguardUnlock) {
|
||||||
if (stack == null) {
|
if (stack == null) {
|
||||||
return;
|
return;
|
||||||
@@ -4286,6 +4472,17 @@ final class StockLayoutCanvasController {
|
|||||||
lockscreenCardsNotificationRowFilter.apply(stack, allowAfterKeyguardUnlock);
|
lockscreenCardsNotificationRowFilter.apply(stack, allowAfterKeyguardUnlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void applyLockscreenCardsNotificationRowFilterRow(View row, boolean allowAfterKeyguardUnlock) {
|
||||||
|
if (row == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (runtimeContext.getModeStateRepository().isSystemUiShadeLocked()) {
|
||||||
|
lockscreenCardsNotificationRowFilter.restoreRemovedRow(row);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lockscreenCardsNotificationRowFilter.applyRow(row, allowAfterKeyguardUnlock);
|
||||||
|
}
|
||||||
|
|
||||||
private boolean applyLockscreenCardsNotificationRowFilterInTreeIfNeeded(
|
private boolean applyLockscreenCardsNotificationRowFilterInTreeIfNeeded(
|
||||||
View root,
|
View root,
|
||||||
SbtSettings settings,
|
SbtSettings settings,
|
||||||
@@ -4311,7 +4508,6 @@ final class StockLayoutCanvasController {
|
|||||||
+ (runtimeContext.getModeStateRepository().isSystemUiShadeLocked() ? 1 : 0);
|
+ (runtimeContext.getModeStateRepository().isSystemUiShadeLocked() ? 1 : 0);
|
||||||
result = 31 * result + root.getWidth();
|
result = 31 * result + root.getWidth();
|
||||||
result = 31 * result + root.getHeight();
|
result = 31 * result + root.getHeight();
|
||||||
result = 31 * result + (root instanceof ViewGroup group ? group.getChildCount() : 0);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4471,7 +4667,7 @@ final class StockLayoutCanvasController {
|
|||||||
dirtyUnlockedLayoutRoots.remove(root);
|
dirtyUnlockedLayoutRoots.remove(root);
|
||||||
settingsIdentityByRoot.remove(root);
|
settingsIdentityByRoot.remove(root);
|
||||||
lockscreenCardsRowFilterSignatures.remove(root);
|
lockscreenCardsRowFilterSignatures.remove(root);
|
||||||
clockTimeBucketByRoot.remove(root);
|
clearUnlockedClockRefreshState(root);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -63,7 +63,6 @@ final class ClockLayout {
|
|||||||
int baseHeightSteps,
|
int baseHeightSteps,
|
||||||
int autoGapSteps,
|
int autoGapSteps,
|
||||||
int statusbarHeight,
|
int statusbarHeight,
|
||||||
int visualBaselineY,
|
|
||||||
int verticalOffsetSteps
|
int verticalOffsetSteps
|
||||||
) {
|
) {
|
||||||
if (source == null || model == null || model.rows.isEmpty()) {
|
if (source == null || model == null || model.rows.isEmpty()) {
|
||||||
@@ -102,10 +101,8 @@ final class ClockLayout {
|
|||||||
}
|
}
|
||||||
measuredRows = positionRowsFromLogicalSteps(
|
measuredRows = positionRowsFromLogicalSteps(
|
||||||
measuredRows,
|
measuredRows,
|
||||||
Math.max(1, baseHeightSteps),
|
|
||||||
Math.max(1, autoGapSteps),
|
Math.max(1, autoGapSteps),
|
||||||
Math.max(1, statusbarHeight),
|
Math.max(1, statusbarHeight),
|
||||||
visualBaselineY,
|
|
||||||
verticalOffsetSteps);
|
verticalOffsetSteps);
|
||||||
|
|
||||||
RowAlignment alignment = alignRows(measuredRows, position);
|
RowAlignment alignment = alignRows(measuredRows, position);
|
||||||
@@ -216,10 +213,8 @@ final class ClockLayout {
|
|||||||
|
|
||||||
private static ArrayList<MeasuredClockRow> positionRowsFromLogicalSteps(
|
private static ArrayList<MeasuredClockRow> positionRowsFromLogicalSteps(
|
||||||
ArrayList<MeasuredClockRow> measuredRows,
|
ArrayList<MeasuredClockRow> measuredRows,
|
||||||
int baseHeightSteps,
|
|
||||||
int autoGapSteps,
|
int autoGapSteps,
|
||||||
int statusbarHeight,
|
int statusbarHeight,
|
||||||
int visualBaselineY,
|
|
||||||
int verticalOffsetSteps
|
int verticalOffsetSteps
|
||||||
) {
|
) {
|
||||||
ArrayList<MeasuredClockRow> positionedRows = new ArrayList<>(measuredRows);
|
ArrayList<MeasuredClockRow> positionedRows = new ArrayList<>(measuredRows);
|
||||||
@@ -232,8 +227,7 @@ final class ClockLayout {
|
|||||||
if (rowIndex == measuredRows.size() - 1) {
|
if (rowIndex == measuredRows.size() - 1) {
|
||||||
topSteps = 100 - Math.max(1, row.logicalHeightSteps) - verticalOffsetSteps;
|
topSteps = 100 - Math.max(1, row.logicalHeightSteps) - verticalOffsetSteps;
|
||||||
int heightPx = Math.max(1, stepsToPx(Math.max(1, row.logicalHeightSteps), statusbarHeight));
|
int heightPx = Math.max(1, stepsToPx(Math.max(1, row.logicalHeightSteps), statusbarHeight));
|
||||||
int baselineY = visualBaselineY - stepsToPx(verticalOffsetSteps, statusbarHeight);
|
bottomPx = Math.max(1, statusbarHeight) - stepsToPx(verticalOffsetSteps, statusbarHeight);
|
||||||
bottomPx = baselineY - row.baseline + heightPx;
|
|
||||||
} else {
|
} else {
|
||||||
MeasuredClockRow nextRow = measuredRows.get(rowIndex + 1);
|
MeasuredClockRow nextRow = measuredRows.get(rowIndex + 1);
|
||||||
int gapSteps = resolveGapSteps(nextRow.source.gapBeforePx, autoGapSteps);
|
int gapSteps = resolveGapSteps(nextRow.source.gapBeforePx, autoGapSteps);
|
||||||
|
|||||||
+105
-14
@@ -27,6 +27,7 @@ public final class LockscreenCardsNotificationIconSourceStore {
|
|||||||
new WeakHashMap<>();
|
new WeakHashMap<>();
|
||||||
private static final ArrayList<String> AOD_NOTIFICATION_PACKAGES = new ArrayList<>();
|
private static final ArrayList<String> AOD_NOTIFICATION_PACKAGES = new ArrayList<>();
|
||||||
private static final int VIRTUAL_ICON_SIZE_PX = 39;
|
private static final int VIRTUAL_ICON_SIZE_PX = 39;
|
||||||
|
private static int generation;
|
||||||
|
|
||||||
private LockscreenCardsNotificationIconSourceStore() {
|
private LockscreenCardsNotificationIconSourceStore() {
|
||||||
}
|
}
|
||||||
@@ -34,7 +35,9 @@ public final class LockscreenCardsNotificationIconSourceStore {
|
|||||||
public static void put(ViewGroup container, ArrayList<SourceEntry> sources) {
|
public static void put(ViewGroup container, ArrayList<SourceEntry> sources) {
|
||||||
if (container == null || sources == null || sources.isEmpty()) {
|
if (container == null || sources == null || sources.isEmpty()) {
|
||||||
if (container != null) {
|
if (container != null) {
|
||||||
SOURCES_BY_CONTAINER.remove(container);
|
if (SOURCES_BY_CONTAINER.remove(container) != null) {
|
||||||
|
bumpGeneration();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -47,7 +50,12 @@ public final class LockscreenCardsNotificationIconSourceStore {
|
|||||||
attached.add(source);
|
attached.add(source);
|
||||||
}
|
}
|
||||||
if (attached.isEmpty()) {
|
if (attached.isEmpty()) {
|
||||||
SOURCES_BY_CONTAINER.remove(container);
|
if (SOURCES_BY_CONTAINER.remove(container) != null) {
|
||||||
|
bumpGeneration();
|
||||||
|
}
|
||||||
|
} else if (!sameSourceEntries(SOURCES_BY_CONTAINER.get(container), attached)) {
|
||||||
|
SOURCES_BY_CONTAINER.put(container, attached);
|
||||||
|
bumpGeneration();
|
||||||
} else {
|
} else {
|
||||||
SOURCES_BY_CONTAINER.put(container, attached);
|
SOURCES_BY_CONTAINER.put(container, attached);
|
||||||
}
|
}
|
||||||
@@ -56,7 +64,11 @@ public final class LockscreenCardsNotificationIconSourceStore {
|
|||||||
public static boolean putPackages(ViewGroup container, ArrayList<String> packages) {
|
public static boolean putPackages(ViewGroup container, ArrayList<String> packages) {
|
||||||
if (container == null || packages == null || packages.isEmpty()) {
|
if (container == null || packages == null || packages.isEmpty()) {
|
||||||
if (container != null) {
|
if (container != null) {
|
||||||
return PACKAGES_BY_CONTAINER.remove(container) != null;
|
boolean changed = PACKAGES_BY_CONTAINER.remove(container) != null;
|
||||||
|
if (changed) {
|
||||||
|
bumpGeneration();
|
||||||
|
}
|
||||||
|
return changed;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -71,13 +83,18 @@ public final class LockscreenCardsNotificationIconSourceStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!hasValid) {
|
if (!hasValid) {
|
||||||
return PACKAGES_BY_CONTAINER.remove(container) != null;
|
boolean changed = PACKAGES_BY_CONTAINER.remove(container) != null;
|
||||||
|
if (changed) {
|
||||||
|
bumpGeneration();
|
||||||
|
}
|
||||||
|
return changed;
|
||||||
} else {
|
} else {
|
||||||
ArrayList<String> previous = PACKAGES_BY_CONTAINER.get(container);
|
ArrayList<String> previous = PACKAGES_BY_CONTAINER.get(container);
|
||||||
if (previous != null && previous.equals(valid)) {
|
if (previous != null && previous.equals(valid)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
PACKAGES_BY_CONTAINER.put(container, valid);
|
PACKAGES_BY_CONTAINER.put(container, valid);
|
||||||
|
bumpGeneration();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -85,7 +102,11 @@ public final class LockscreenCardsNotificationIconSourceStore {
|
|||||||
public static boolean putAodDrawables(ViewGroup container, ArrayList<? extends View> views) {
|
public static boolean putAodDrawables(ViewGroup container, ArrayList<? extends View> views) {
|
||||||
if (container == null || views == null || views.isEmpty()) {
|
if (container == null || views == null || views.isEmpty()) {
|
||||||
if (container != null) {
|
if (container != null) {
|
||||||
return AOD_DRAWABLES_BY_CONTAINER.remove(container) != null;
|
boolean changed = AOD_DRAWABLES_BY_CONTAINER.remove(container) != null;
|
||||||
|
if (changed) {
|
||||||
|
bumpGeneration();
|
||||||
|
}
|
||||||
|
return changed;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -100,18 +121,28 @@ public final class LockscreenCardsNotificationIconSourceStore {
|
|||||||
valid.add(view);
|
valid.add(view);
|
||||||
}
|
}
|
||||||
if (valid.isEmpty()) {
|
if (valid.isEmpty()) {
|
||||||
return AOD_DRAWABLES_BY_CONTAINER.remove(container) != null;
|
boolean changed = AOD_DRAWABLES_BY_CONTAINER.remove(container) != null;
|
||||||
|
if (changed) {
|
||||||
|
bumpGeneration();
|
||||||
|
}
|
||||||
|
return changed;
|
||||||
} else {
|
} else {
|
||||||
ArrayList<View> previous = AOD_DRAWABLES_BY_CONTAINER.get(container);
|
ArrayList<View> previous = AOD_DRAWABLES_BY_CONTAINER.get(container);
|
||||||
if (sameViews(previous, valid)) {
|
if (sameViews(previous, valid)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
AOD_DRAWABLES_BY_CONTAINER.put(container, valid);
|
AOD_DRAWABLES_BY_CONTAINER.put(container, valid);
|
||||||
|
bumpGeneration();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void clearAodSources() {
|
public static void clearAodSources() {
|
||||||
|
if (!PACKAGES_BY_CONTAINER.isEmpty()
|
||||||
|
|| !AOD_DRAWABLES_BY_CONTAINER.isEmpty()
|
||||||
|
|| !AOD_NOTIFICATION_PACKAGES.isEmpty()) {
|
||||||
|
bumpGeneration();
|
||||||
|
}
|
||||||
PACKAGES_BY_CONTAINER.clear();
|
PACKAGES_BY_CONTAINER.clear();
|
||||||
AOD_DRAWABLES_BY_CONTAINER.clear();
|
AOD_DRAWABLES_BY_CONTAINER.clear();
|
||||||
AOD_NOTIFICATION_PACKAGES.clear();
|
AOD_NOTIFICATION_PACKAGES.clear();
|
||||||
@@ -121,20 +152,76 @@ public final class LockscreenCardsNotificationIconSourceStore {
|
|||||||
if (container == null) {
|
if (container == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PACKAGES_BY_CONTAINER.remove(container);
|
boolean changed = PACKAGES_BY_CONTAINER.remove(container) != null;
|
||||||
AOD_DRAWABLES_BY_CONTAINER.remove(container);
|
changed |= AOD_DRAWABLES_BY_CONTAINER.remove(container) != null;
|
||||||
|
if (changed) {
|
||||||
|
bumpGeneration();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void putAodNotificationPackages(ArrayList<String> packages) {
|
public static void putAodNotificationPackages(ArrayList<String> packages) {
|
||||||
|
ArrayList<String> previous = new ArrayList<>(AOD_NOTIFICATION_PACKAGES);
|
||||||
AOD_NOTIFICATION_PACKAGES.clear();
|
AOD_NOTIFICATION_PACKAGES.clear();
|
||||||
if (packages == null || packages.isEmpty()) {
|
if (packages != null && !packages.isEmpty()) {
|
||||||
return;
|
for (String pkg : packages) {
|
||||||
}
|
if (AppIconRules.isValidPackageName(pkg) && !AOD_NOTIFICATION_PACKAGES.contains(pkg)) {
|
||||||
for (String pkg : packages) {
|
AOD_NOTIFICATION_PACKAGES.add(pkg);
|
||||||
if (AppIconRules.isValidPackageName(pkg) && !AOD_NOTIFICATION_PACKAGES.contains(pkg)) {
|
}
|
||||||
AOD_NOTIFICATION_PACKAGES.add(pkg);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!previous.equals(AOD_NOTIFICATION_PACKAGES)) {
|
||||||
|
bumpGeneration();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int generation() {
|
||||||
|
return generation;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void bumpGeneration() {
|
||||||
|
generation++;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean sameSourceEntries(
|
||||||
|
ArrayList<SourceEntry> previous,
|
||||||
|
ArrayList<SourceEntry> current
|
||||||
|
) {
|
||||||
|
if (previous == current) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (previous == null || current == null || previous.size() != current.size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < previous.size(); i++) {
|
||||||
|
SourceEntry oldEntry = previous.get(i);
|
||||||
|
SourceEntry newEntry = current.get(i);
|
||||||
|
if (oldEntry == newEntry) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (oldEntry == null || newEntry == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (oldEntry.view != newEntry.view) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (oldEntry.key == null ? newEntry.key != null : !oldEntry.key.equals(newEntry.key)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int lightweightSourceSignatureForRoot(View root) {
|
||||||
|
int result = 17;
|
||||||
|
result = 31 * result + generation();
|
||||||
|
ViewGroup container = sourceContainerForRoot(root);
|
||||||
|
Bounds bounds = sourceBoundsRelativeTo(root, container);
|
||||||
|
if (isZeroSizeDotContainer(container, bounds)) {
|
||||||
|
bounds = new Bounds(bounds.left, bounds.top, VIRTUAL_ICON_SIZE_PX, VIRTUAL_ICON_SIZE_PX);
|
||||||
|
}
|
||||||
|
result = 31 * result + (bounds != null ? bounds.signature() : 0);
|
||||||
|
result = 31 * result + (sourceContainerHasHiddenAncestor(root, container) ? 1 : 0);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean sameViews(ArrayList<View> previous, ArrayList<View> current) {
|
private static boolean sameViews(ArrayList<View> previous, ArrayList<View> current) {
|
||||||
@@ -348,6 +435,10 @@ public final class LockscreenCardsNotificationIconSourceStore {
|
|||||||
|
|
||||||
public static boolean sourceContainerHasHiddenAncestorForRoot(View root) {
|
public static boolean sourceContainerHasHiddenAncestorForRoot(View root) {
|
||||||
ViewGroup container = sourceContainerForRoot(root);
|
ViewGroup container = sourceContainerForRoot(root);
|
||||||
|
return sourceContainerHasHiddenAncestor(root, container);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean sourceContainerHasHiddenAncestor(View root, ViewGroup container) {
|
||||||
if (container == null) {
|
if (container == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -579,11 +579,21 @@ final class SnapshotRenderer {
|
|||||||
int result = 17;
|
int result = 17;
|
||||||
result = 31 * result + sourceTreeSignature(source.view());
|
result = 31 * result + sourceTreeSignature(source.view());
|
||||||
Bounds boundsOverride = source.boundsOverride();
|
Bounds boundsOverride = source.boundsOverride();
|
||||||
result = 31 * result + (boundsOverride != null ? boundsOverride.signature() : 0);
|
result = 31 * result + boundsSizeSignature(boundsOverride);
|
||||||
result = 31 * result + tintSignatureFor(source);
|
result = 31 * result + tintSignatureFor(source);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int boundsSizeSignature(Bounds bounds) {
|
||||||
|
if (bounds == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int result = 17;
|
||||||
|
result = 31 * result + bounds.width;
|
||||||
|
result = 31 * result + bounds.height;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
private int tintSignatureFor(SnapshotSource source) {
|
private int tintSignatureFor(SnapshotSource source) {
|
||||||
return shouldApplyStatusBarTintTarget(source) ? StatusBarTintTarget.signature() : 0;
|
return shouldApplyStatusBarTintTarget(source) ? StatusBarTintTarget.signature() : 0;
|
||||||
}
|
}
|
||||||
|
|||||||
+147
-18
@@ -113,7 +113,14 @@ public final class UnlockedIconSnapshotRenderController {
|
|||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
!scene.isLockscreen() || lastLayoutPlanByRoot.get(root) != null);
|
!scene.isLockscreen() || lastLayoutPlanByRoot.get(root) != null,
|
||||||
|
lockscreenIconDebugSummary(
|
||||||
|
root,
|
||||||
|
notificationHost,
|
||||||
|
scene,
|
||||||
|
cachedPlan,
|
||||||
|
lastCollectedIconsByRoot.get(root),
|
||||||
|
"cacheHit"));
|
||||||
}
|
}
|
||||||
lastLayoutSignatureByRoot.put(root, signature);
|
lastLayoutSignatureByRoot.put(root, signature);
|
||||||
Integer currentClockSourceGeometry = clockSourceGeometrySignature(
|
Integer currentClockSourceGeometry = clockSourceGeometrySignature(
|
||||||
@@ -191,7 +198,18 @@ public final class UnlockedIconSnapshotRenderController {
|
|||||||
if (scene.isLockscreen() && clockEnabledForScene(settings, scene) && currentClockLayout == null) {
|
if (scene.isLockscreen() && clockEnabledForScene(settings, scene) && currentClockLayout == null) {
|
||||||
clearLockscreenHosts(clockHost, carrierHost, chipHost, statusHost, notificationHost);
|
clearLockscreenHosts(clockHost, carrierHost, chipHost, statusHost, notificationHost);
|
||||||
lastLayoutPlanByRoot.remove(root);
|
lastLayoutPlanByRoot.remove(root);
|
||||||
return new RenderResult(false, stockSourcesChanged, chipSourcesChanged, false);
|
return new RenderResult(
|
||||||
|
false,
|
||||||
|
stockSourcesChanged,
|
||||||
|
chipSourcesChanged,
|
||||||
|
false,
|
||||||
|
lockscreenIconDebugSummary(
|
||||||
|
root,
|
||||||
|
notificationHost,
|
||||||
|
scene,
|
||||||
|
null,
|
||||||
|
collectedIcons,
|
||||||
|
"missingClock"));
|
||||||
}
|
}
|
||||||
LayoutPlan layoutPlan = layoutPlanner.solve(
|
LayoutPlan layoutPlan = layoutPlanner.solve(
|
||||||
root,
|
root,
|
||||||
@@ -237,7 +255,18 @@ public final class UnlockedIconSnapshotRenderController {
|
|||||||
} else {
|
} else {
|
||||||
notificationRenderer.clear(notificationHost);
|
notificationRenderer.clear(notificationHost);
|
||||||
}
|
}
|
||||||
return new RenderResult(true, stockSourcesChanged, chipSourcesChanged);
|
return new RenderResult(
|
||||||
|
true,
|
||||||
|
stockSourcesChanged,
|
||||||
|
chipSourcesChanged,
|
||||||
|
true,
|
||||||
|
lockscreenIconDebugSummary(
|
||||||
|
root,
|
||||||
|
notificationHost,
|
||||||
|
scene,
|
||||||
|
layoutPlan,
|
||||||
|
collectedIcons,
|
||||||
|
"solved"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void refreshUnlockedAppearance(
|
public void refreshUnlockedAppearance(
|
||||||
@@ -722,7 +751,6 @@ public final class UnlockedIconSnapshotRenderController {
|
|||||||
int textSizeSteps = clockTextSizeSteps(settings, scene);
|
int textSizeSteps = clockTextSizeSteps(settings, scene);
|
||||||
float textSizePx = clockTextSizePx(statusbarHeight, textSizeSteps);
|
float textSizePx = clockTextSizePx(statusbarHeight, textSizeSteps);
|
||||||
int autoGapSteps = clockAutoGapSteps(source, statusbarHeight, textSizeSteps);
|
int autoGapSteps = clockAutoGapSteps(source, statusbarHeight, textSizeSteps);
|
||||||
int visualBaselineY = clockVisualBaselineY(source, sourceBounds, statusbarHeight);
|
|
||||||
ClockLayout layout = ClockLayout.measure(
|
ClockLayout layout = ClockLayout.measure(
|
||||||
source,
|
source,
|
||||||
model,
|
model,
|
||||||
@@ -735,7 +763,6 @@ public final class UnlockedIconSnapshotRenderController {
|
|||||||
textSizeSteps,
|
textSizeSteps,
|
||||||
autoGapSteps,
|
autoGapSteps,
|
||||||
statusbarHeight,
|
statusbarHeight,
|
||||||
visualBaselineY,
|
|
||||||
settings.clockVerticalOffsetPx);
|
settings.clockVerticalOffsetPx);
|
||||||
return layout;
|
return layout;
|
||||||
}
|
}
|
||||||
@@ -748,17 +775,6 @@ public final class UnlockedIconSnapshotRenderController {
|
|||||||
return Math.max(1, Math.round(lineHeight * 100f / statusbarHeight));
|
return Math.max(1, Math.round(lineHeight * 100f / statusbarHeight));
|
||||||
}
|
}
|
||||||
|
|
||||||
private int clockVisualBaselineY(TextView source, Bounds sourceBounds, int fallbackBaselineY) {
|
|
||||||
if (source == null || sourceBounds == null) {
|
|
||||||
return Math.max(1, fallbackBaselineY);
|
|
||||||
}
|
|
||||||
int baseline = source.getBaseline();
|
|
||||||
if (baseline <= 0) {
|
|
||||||
return Math.max(1, sourceBounds.top + sourceBounds.height);
|
|
||||||
}
|
|
||||||
return Math.max(1, sourceBounds.top + baseline);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int clockTextSizeSteps(SbtSettings settings, SceneKey scene) {
|
private int clockTextSizeSteps(SbtSettings settings, SceneKey scene) {
|
||||||
return scene != null && scene.isLockscreen()
|
return scene != null && scene.isLockscreen()
|
||||||
? settings.clockLockTextSizeSteps
|
? settings.clockLockTextSizeSteps
|
||||||
@@ -1039,14 +1055,127 @@ public final class UnlockedIconSnapshotRenderController {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String lockscreenIconDebugSummary(
|
||||||
|
View root,
|
||||||
|
ViewGroup notificationHost,
|
||||||
|
SceneKey scene,
|
||||||
|
LayoutPlan plan,
|
||||||
|
CollectedIcons icons,
|
||||||
|
String phase
|
||||||
|
) {
|
||||||
|
if (scene == null
|
||||||
|
|| !scene.isLockscreen()
|
||||||
|
|| scene.notificationDisplayStyle() != NotificationDisplayStyle.ICONS) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
ArrayList<SnapshotPlacement> notificationPlacements =
|
||||||
|
plan != null ? plan.notificationPlacements : null;
|
||||||
|
return "phase=" + phase
|
||||||
|
+ " root=" + viewBounds(root)
|
||||||
|
+ " hostChildren=" + (notificationHost != null ? notificationHost.getChildCount() : -1)
|
||||||
|
+ " sourceNotifs=" + sizeOf(icons != null ? icons.notificationIcons : null)
|
||||||
|
+ " placementCount=" + sizeOf(notificationPlacements)
|
||||||
|
+ " renderableCount=" + renderablePlacementCount(notificationPlacements)
|
||||||
|
+ " clock=" + boundsText(plan != null && plan.clockPlacement != null
|
||||||
|
? plan.clockPlacement.bounds
|
||||||
|
: null)
|
||||||
|
+ " carrier=" + boundsText(plan != null && plan.carrierPlacement != null
|
||||||
|
? plan.carrierPlacement.bounds
|
||||||
|
: null)
|
||||||
|
+ " notifs=" + placementSummary(notificationPlacements);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int sizeOf(ArrayList<?> values) {
|
||||||
|
return values != null ? values.size() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int renderablePlacementCount(ArrayList<SnapshotPlacement> placements) {
|
||||||
|
if (placements == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int count = 0;
|
||||||
|
for (SnapshotPlacement placement : placements) {
|
||||||
|
if (isRenderablePlacement(placement)) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isRenderablePlacement(SnapshotPlacement placement) {
|
||||||
|
return placement != null
|
||||||
|
&& (placement.source != null
|
||||||
|
|| placement.overflowDot
|
||||||
|
|| placement.heldSignal != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String placementSummary(ArrayList<SnapshotPlacement> placements) {
|
||||||
|
if (placements == null || placements.isEmpty()) {
|
||||||
|
return "[]";
|
||||||
|
}
|
||||||
|
StringBuilder out = new StringBuilder("[");
|
||||||
|
int limit = Math.min(placements.size(), 8);
|
||||||
|
for (int i = 0; i < limit; i++) {
|
||||||
|
if (i > 0) {
|
||||||
|
out.append(';');
|
||||||
|
}
|
||||||
|
SnapshotPlacement placement = placements.get(i);
|
||||||
|
out.append(i).append('{');
|
||||||
|
if (placement == null) {
|
||||||
|
out.append("null");
|
||||||
|
} else {
|
||||||
|
out.append("key=").append(placement.key)
|
||||||
|
.append(",b=").append(boundsText(placement.bounds))
|
||||||
|
.append(",source=").append(placement.source != null)
|
||||||
|
.append(",dot=").append(placement.overflowDot)
|
||||||
|
.append(",held=").append(placement.heldSignal != null)
|
||||||
|
.append(",renderable=").append(isRenderablePlacement(placement));
|
||||||
|
}
|
||||||
|
out.append('}');
|
||||||
|
}
|
||||||
|
if (placements.size() > limit) {
|
||||||
|
out.append(";...");
|
||||||
|
}
|
||||||
|
out.append(']');
|
||||||
|
return out.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String viewBounds(View view) {
|
||||||
|
if (view == null) {
|
||||||
|
return "null";
|
||||||
|
}
|
||||||
|
return view.getWidth() + "x" + view.getHeight()
|
||||||
|
+ "+" + view.getLeft()
|
||||||
|
+ "," + view.getTop();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String boundsText(Bounds bounds) {
|
||||||
|
if (bounds == null) {
|
||||||
|
return "null";
|
||||||
|
}
|
||||||
|
return bounds.width + "x" + bounds.height
|
||||||
|
+ "+" + bounds.left
|
||||||
|
+ "," + bounds.top;
|
||||||
|
}
|
||||||
|
|
||||||
public record RenderResult(
|
public record RenderResult(
|
||||||
boolean layoutChanged,
|
boolean layoutChanged,
|
||||||
boolean stockSourcesChanged,
|
boolean stockSourcesChanged,
|
||||||
boolean chipSourcesChanged,
|
boolean chipSourcesChanged,
|
||||||
boolean shouldOwnLockscreen
|
boolean shouldOwnLockscreen,
|
||||||
|
String debugSummary
|
||||||
) {
|
) {
|
||||||
public RenderResult(boolean layoutChanged, boolean stockSourcesChanged, boolean chipSourcesChanged) {
|
public RenderResult(boolean layoutChanged, boolean stockSourcesChanged, boolean chipSourcesChanged) {
|
||||||
this(layoutChanged, stockSourcesChanged, chipSourcesChanged, true);
|
this(layoutChanged, stockSourcesChanged, chipSourcesChanged, true, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RenderResult(
|
||||||
|
boolean layoutChanged,
|
||||||
|
boolean stockSourcesChanged,
|
||||||
|
boolean chipSourcesChanged,
|
||||||
|
boolean shouldOwnLockscreen
|
||||||
|
) {
|
||||||
|
this(layoutChanged, stockSourcesChanged, chipSourcesChanged, shouldOwnLockscreen, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+63
-13
@@ -103,7 +103,8 @@ final class UnlockedLayoutPlanner {
|
|||||||
scene,
|
scene,
|
||||||
edges,
|
edges,
|
||||||
layoutCutoutBounds,
|
layoutCutoutBounds,
|
||||||
clockLayout);
|
clockLayout,
|
||||||
|
statusbarHeight);
|
||||||
if (carrierLayout != null && carrierLayout.width() > 0) {
|
if (carrierLayout != null && carrierLayout.width() > 0) {
|
||||||
bands.add(UnlockedLayoutBand.carrier(
|
bands.add(UnlockedLayoutBand.carrier(
|
||||||
carrierHost,
|
carrierHost,
|
||||||
@@ -649,7 +650,8 @@ final class UnlockedLayoutPlanner {
|
|||||||
SceneKey scene,
|
SceneKey scene,
|
||||||
LayoutEdges edges,
|
LayoutEdges edges,
|
||||||
Bounds cutoutBounds,
|
Bounds cutoutBounds,
|
||||||
ClockLayout clockLayout
|
ClockLayout clockLayout,
|
||||||
|
int statusbarHeight
|
||||||
) {
|
) {
|
||||||
if (root == null
|
if (root == null
|
||||||
|| collectedIcons == null
|
|| collectedIcons == null
|
||||||
@@ -687,9 +689,11 @@ final class UnlockedLayoutPlanner {
|
|||||||
settings,
|
settings,
|
||||||
edges,
|
edges,
|
||||||
cutoutBounds,
|
cutoutBounds,
|
||||||
|
scene,
|
||||||
positionFor(settings.layoutCarrierPosition),
|
positionFor(settings.layoutCarrierPosition),
|
||||||
sideFor(settings.layoutCarrierMiddleSide),
|
sideFor(settings.layoutCarrierMiddleSide),
|
||||||
clockLayout));
|
clockLayout,
|
||||||
|
statusbarHeight));
|
||||||
}
|
}
|
||||||
|
|
||||||
private int carrierMaxWidth(
|
private int carrierMaxWidth(
|
||||||
@@ -697,9 +701,11 @@ final class UnlockedLayoutPlanner {
|
|||||||
SbtSettings settings,
|
SbtSettings settings,
|
||||||
LayoutEdges edges,
|
LayoutEdges edges,
|
||||||
Bounds cutoutBounds,
|
Bounds cutoutBounds,
|
||||||
|
SceneKey scene,
|
||||||
LayoutPosition position,
|
LayoutPosition position,
|
||||||
AnchorSide middleSide,
|
AnchorSide middleSide,
|
||||||
ClockLayout clockLayout
|
ClockLayout clockLayout,
|
||||||
|
int statusbarHeight
|
||||||
) {
|
) {
|
||||||
int rootWidth = root != null ? root.getWidth() : 0;
|
int rootWidth = root != null ? root.getWidth() : 0;
|
||||||
if (rootWidth <= 0 || edges == null) {
|
if (rootWidth <= 0 || edges == null) {
|
||||||
@@ -723,42 +729,86 @@ final class UnlockedLayoutPlanner {
|
|||||||
return carrierMaxWidthWithClockReserve(
|
return carrierMaxWidthWithClockReserve(
|
||||||
Math.max(1, right - minLeft),
|
Math.max(1, right - minLeft),
|
||||||
settings,
|
settings,
|
||||||
|
scene,
|
||||||
position,
|
position,
|
||||||
middleSide,
|
middleSide,
|
||||||
clockLayout,
|
clockLayout,
|
||||||
AnchorSide.RIGHT);
|
AnchorSide.RIGHT,
|
||||||
|
statusbarHeight);
|
||||||
}
|
}
|
||||||
int maxRight = usableCutout ? Math.max(left, cutoutBounds.left) : right;
|
int maxRight = usableCutout ? Math.max(left, cutoutBounds.left) : right;
|
||||||
return carrierMaxWidthWithClockReserve(
|
return carrierMaxWidthWithClockReserve(
|
||||||
Math.max(1, maxRight - left),
|
Math.max(1, maxRight - left),
|
||||||
settings,
|
settings,
|
||||||
|
scene,
|
||||||
position,
|
position,
|
||||||
middleSide,
|
middleSide,
|
||||||
clockLayout,
|
clockLayout,
|
||||||
AnchorSide.LEFT);
|
AnchorSide.LEFT,
|
||||||
|
statusbarHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int carrierMaxWidthWithClockReserve(
|
private int carrierMaxWidthWithClockReserve(
|
||||||
int sideWidth,
|
int sideWidth,
|
||||||
SbtSettings settings,
|
SbtSettings settings,
|
||||||
|
SceneKey scene,
|
||||||
LayoutPosition carrierPosition,
|
LayoutPosition carrierPosition,
|
||||||
AnchorSide carrierMiddleSide,
|
AnchorSide carrierMiddleSide,
|
||||||
ClockLayout clockLayout,
|
ClockLayout clockLayout,
|
||||||
AnchorSide side
|
AnchorSide side,
|
||||||
|
int statusbarHeight
|
||||||
) {
|
) {
|
||||||
if (sideWidth <= 0 || settings == null || clockLayout == null || clockLayout.width() <= 0) {
|
if (sideWidth <= 0 || settings == null) {
|
||||||
return Math.max(1, sideWidth);
|
return Math.max(1, sideWidth);
|
||||||
}
|
}
|
||||||
LayoutPosition clockPosition = positionFor(settings.clockPosition);
|
if (!occupiesSide(carrierPosition, carrierMiddleSide, side)) {
|
||||||
AnchorSide clockMiddleSide = sideFor(settings.clockMiddleCutoutSide);
|
|
||||||
if (!occupiesSide(clockPosition, clockMiddleSide, side)
|
|
||||||
|| !occupiesSide(carrierPosition, carrierMiddleSide, side)) {
|
|
||||||
return Math.max(1, sideWidth);
|
return Math.max(1, sideWidth);
|
||||||
}
|
}
|
||||||
int reserved = clockLayout.width() + Math.max(0, settings.layoutItemPaddingPx);
|
int reserved = notificationDotReserveForSide(settings, scene, side, statusbarHeight);
|
||||||
|
if (clockLayout != null && clockLayout.width() > 0) {
|
||||||
|
LayoutPosition clockPosition = positionFor(settings.clockPosition);
|
||||||
|
AnchorSide clockMiddleSide = sideFor(settings.clockMiddleCutoutSide);
|
||||||
|
if (occupiesSide(clockPosition, clockMiddleSide, side)) {
|
||||||
|
reserved += clockLayout.width() + Math.max(0, settings.layoutItemPaddingPx);
|
||||||
|
}
|
||||||
|
}
|
||||||
return Math.max(1, sideWidth - reserved);
|
return Math.max(1, sideWidth - reserved);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int notificationDotReserveForSide(
|
||||||
|
SbtSettings settings,
|
||||||
|
SceneKey scene,
|
||||||
|
AnchorSide side,
|
||||||
|
int statusbarHeight
|
||||||
|
) {
|
||||||
|
if (settings == null
|
||||||
|
|| scene == null
|
||||||
|
|| !scene.isLockscreen()
|
||||||
|
|| !settings.layoutNotifEnabledLockscreen
|
||||||
|
|| (scene.notificationDisplayStyle() != NotificationDisplayStyle.ICONS
|
||||||
|
&& scene.notificationDisplayStyle() != NotificationDisplayStyle.DOT)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int count = notificationCountForScene(settings, scene);
|
||||||
|
if (count <= 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
String[] positions = notificationPositionsForScene(settings, scene);
|
||||||
|
String[] middleSides = notificationMiddleSidesForScene(settings, scene);
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
LayoutPosition position = positionFor(stringAt(positions, i, settings.layoutNotifPosition));
|
||||||
|
AnchorSide middleSide = sideFor(stringAt(middleSides, i, settings.layoutNotifMiddleSide));
|
||||||
|
if (occupiesSide(position, middleSide, side)) {
|
||||||
|
int iconHeight = iconHeightPx(
|
||||||
|
statusbarHeight,
|
||||||
|
notificationIconHeightSteps(settings, scene));
|
||||||
|
int dotWidth = Math.max(1, Math.round(Math.max(1, iconHeight) * 0.75f));
|
||||||
|
return dotWidth + Math.max(0, settings.layoutItemPaddingPx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
private boolean occupiesSide(
|
private boolean occupiesSide(
|
||||||
LayoutPosition position,
|
LayoutPosition position,
|
||||||
AnchorSide middleSide,
|
AnchorSide middleSide,
|
||||||
|
|||||||
Reference in New Issue
Block a user