Loading core/java/android/util/LocalLog.java +5 −0 Original line number Diff line number Diff line Loading @@ -112,6 +112,11 @@ public final class LocalLog { } } // @VisibleForTesting(otherwise = VisibleForTesting.NONE) public synchronized void clear() { mLog.clear(); } public static class ReadOnlyLocalLog { private final LocalLog mLog; ReadOnlyLocalLog(LocalLog log) { Loading services/core/java/com/android/server/notification/DefaultDeviceEffectsApplier.java +10 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,9 @@ package com.android.server.notification; import static android.app.UiModeManager.MODE_ATTENTION_THEME_OVERLAY_NIGHT; import static android.app.UiModeManager.MODE_ATTENTION_THEME_OVERLAY_OFF; import static com.android.server.notification.ZenLog.traceApplyDeviceEffect; import static com.android.server.notification.ZenLog.traceScheduleApplyDeviceEffect; import android.app.UiModeManager; import android.app.WallpaperManager; import android.content.BroadcastReceiver; Loading Loading @@ -77,6 +80,8 @@ class DefaultDeviceEffectsApplier implements DeviceEffectsApplier { if (mLastAppliedEffects.shouldSuppressAmbientDisplay() != effects.shouldSuppressAmbientDisplay()) { try { traceApplyDeviceEffect("suppressAmbientDisplay", effects.shouldSuppressAmbientDisplay()); mPowerManager.suppressAmbientDisplay(SUPPRESS_AMBIENT_DISPLAY_TOKEN, effects.shouldSuppressAmbientDisplay()); } catch (Exception e) { Loading @@ -87,6 +92,8 @@ class DefaultDeviceEffectsApplier implements DeviceEffectsApplier { if (mLastAppliedEffects.shouldDisplayGrayscale() != effects.shouldDisplayGrayscale()) { if (mColorDisplayManager != null) { try { traceApplyDeviceEffect("displayGrayscale", effects.shouldDisplayGrayscale()); mColorDisplayManager.setSaturationLevel( effects.shouldDisplayGrayscale() ? SATURATION_LEVEL_GRAYSCALE : SATURATION_LEVEL_FULL_COLOR); Loading @@ -99,6 +106,7 @@ class DefaultDeviceEffectsApplier implements DeviceEffectsApplier { if (mLastAppliedEffects.shouldDimWallpaper() != effects.shouldDimWallpaper()) { if (mWallpaperManager != null) { try { traceApplyDeviceEffect("dimWallpaper", effects.shouldDimWallpaper()); mWallpaperManager.setWallpaperDimAmount( effects.shouldDimWallpaper() ? WALLPAPER_DIM_AMOUNT_DIMMED : WALLPAPER_DIM_AMOUNT_NORMAL); Loading Loading @@ -134,6 +142,7 @@ class DefaultDeviceEffectsApplier implements DeviceEffectsApplier { unregisterScreenOffReceiver(); updateNightModeImmediately(useNightMode); } else { traceScheduleApplyDeviceEffect("nightMode", useNightMode); registerScreenOffReceiver(); } } Loading @@ -150,6 +159,7 @@ class DefaultDeviceEffectsApplier implements DeviceEffectsApplier { private void updateNightModeImmediately(boolean useNightMode) { Binder.withCleanCallingIdentity(() -> { try { traceApplyDeviceEffect("nightMode", useNightMode); mUiModeManager.setAttentionModeThemeOverlay( useNightMode ? MODE_ATTENTION_THEME_OVERLAY_NIGHT : MODE_ATTENTION_THEME_OVERLAY_OFF); Loading services/core/java/com/android/server/notification/ZenLog.java +24 −5 Original line number Diff line number Diff line Loading @@ -23,18 +23,15 @@ import android.net.Uri; import android.os.Build; import android.os.RemoteException; import android.provider.Settings.Global; import android.service.notification.Condition; import android.service.notification.IConditionProvider; import android.service.notification.NotificationListenerService; import android.service.notification.ZenModeConfig; import android.service.notification.ZenModeDiff; import android.util.LocalLog; import android.util.Log; import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; import java.io.PrintWriter; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; public class ZenLog { Loading @@ -61,6 +58,8 @@ public class ZenLog { private static final int TYPE_RECORD_CALLER = 19; private static final int TYPE_CHECK_REPEAT_CALLER = 20; private static final int TYPE_ALERT_ON_UPDATED_INTERCEPT = 21; private static final int TYPE_APPLY_DEVICE_EFFECT = 22; private static final int TYPE_SCHEDULE_APPLY_DEVICE_EFFECT = 23; public static void traceIntercepted(NotificationRecord record, String reason) { append(TYPE_INTERCEPTED, record.getKey() + "," + reason); Loading Loading @@ -173,6 +172,14 @@ public class ZenLog { + ", given uri=" + hasUri); } public static void traceApplyDeviceEffect(String effect, boolean newValue) { append(TYPE_APPLY_DEVICE_EFFECT, effect + " -> " + newValue); } public static void traceScheduleApplyDeviceEffect(String effect, boolean scheduledValue) { append(TYPE_SCHEDULE_APPLY_DEVICE_EFFECT, effect + " -> " + scheduledValue); } private static String subscribeResult(IConditionProvider provider, RemoteException e) { return provider == null ? "no provider" : e != null ? e.getMessage() : "ok"; } Loading @@ -196,6 +203,8 @@ public class ZenLog { case TYPE_RECORD_CALLER: return "record_caller"; case TYPE_CHECK_REPEAT_CALLER: return "check_repeat_caller"; case TYPE_ALERT_ON_UPDATED_INTERCEPT: return "alert_on_updated_intercept"; case TYPE_APPLY_DEVICE_EFFECT: return "apply_device_effect"; case TYPE_SCHEDULE_APPLY_DEVICE_EFFECT: return "schedule_device_effect"; default: return "unknown"; } } Loading Loading @@ -273,4 +282,14 @@ public class ZenLog { STATE_CHANGES.dump(prefix, pw); } } @VisibleForTesting(/* otherwise = VisibleForTesting.NONE */) public static void clear() { synchronized (INTERCEPTION_EVENTS) { INTERCEPTION_EVENTS.clear(); } synchronized (STATE_CHANGES) { STATE_CHANGES.clear(); } } } services/tests/uiservicestests/src/com/android/server/notification/DefaultDeviceEffectsApplierTest.java +41 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.hardware.display.ColorDisplayManager; import android.os.PowerManager; import android.platform.test.annotations.EnableFlags; import android.platform.test.flag.junit.SetFlagsRule; import android.service.notification.ZenDeviceEffects; import android.testing.TestableContext; Loading @@ -64,6 +65,9 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.io.PrintWriter; import java.io.StringWriter; @RunWith(TestParameterInjector.class) public class DefaultDeviceEffectsApplierTest { Loading @@ -89,6 +93,8 @@ public class DefaultDeviceEffectsApplierTest { mApplier = new DefaultDeviceEffectsApplier(mContext); verify(mWallpaperManager).isWallpaperSupported(); ZenLog.clear(); } @Test Loading @@ -109,6 +115,41 @@ public class DefaultDeviceEffectsApplierTest { verify(mUiModeManager).setAttentionModeThemeOverlay(eq(MODE_ATTENTION_THEME_OVERLAY_NIGHT)); } @Test @EnableFlags(android.app.Flags.FLAG_MODES_API) public void apply_logsToZenLog() { when(mPowerManager.isInteractive()).thenReturn(true); ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor = ArgumentCaptor.forClass(BroadcastReceiver.class); ArgumentCaptor<IntentFilter> intentFilterCaptor = ArgumentCaptor.forClass(IntentFilter.class); ZenDeviceEffects effects = new ZenDeviceEffects.Builder() .setShouldDisplayGrayscale(true) .setShouldUseNightMode(true) .build(); mApplier.apply(effects, ORIGIN_APP); String zenLog = getZenLog(); assertThat(zenLog).contains("apply_device_effect: displayGrayscale -> true"); assertThat(zenLog).contains("schedule_device_effect: nightMode -> true"); assertThat(zenLog).doesNotContain("apply_device_effect: nightMode"); verify(mContext).registerReceiver(broadcastReceiverCaptor.capture(), intentFilterCaptor.capture(), anyInt()); BroadcastReceiver screenOffReceiver = broadcastReceiverCaptor.getValue(); screenOffReceiver.onReceive(mContext, new Intent(Intent.ACTION_SCREEN_OFF)); zenLog = getZenLog(); assertThat(zenLog).contains("apply_device_effect: nightMode -> true"); } private static String getZenLog() { StringWriter zenLogWriter = new StringWriter(); ZenLog.dump(new PrintWriter(zenLogWriter), ""); return zenLogWriter.toString(); } @Test public void apply_removesEffects() { mSetFlagsRule.enableFlags(android.app.Flags.FLAG_MODES_API); Loading Loading
core/java/android/util/LocalLog.java +5 −0 Original line number Diff line number Diff line Loading @@ -112,6 +112,11 @@ public final class LocalLog { } } // @VisibleForTesting(otherwise = VisibleForTesting.NONE) public synchronized void clear() { mLog.clear(); } public static class ReadOnlyLocalLog { private final LocalLog mLog; ReadOnlyLocalLog(LocalLog log) { Loading
services/core/java/com/android/server/notification/DefaultDeviceEffectsApplier.java +10 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,9 @@ package com.android.server.notification; import static android.app.UiModeManager.MODE_ATTENTION_THEME_OVERLAY_NIGHT; import static android.app.UiModeManager.MODE_ATTENTION_THEME_OVERLAY_OFF; import static com.android.server.notification.ZenLog.traceApplyDeviceEffect; import static com.android.server.notification.ZenLog.traceScheduleApplyDeviceEffect; import android.app.UiModeManager; import android.app.WallpaperManager; import android.content.BroadcastReceiver; Loading Loading @@ -77,6 +80,8 @@ class DefaultDeviceEffectsApplier implements DeviceEffectsApplier { if (mLastAppliedEffects.shouldSuppressAmbientDisplay() != effects.shouldSuppressAmbientDisplay()) { try { traceApplyDeviceEffect("suppressAmbientDisplay", effects.shouldSuppressAmbientDisplay()); mPowerManager.suppressAmbientDisplay(SUPPRESS_AMBIENT_DISPLAY_TOKEN, effects.shouldSuppressAmbientDisplay()); } catch (Exception e) { Loading @@ -87,6 +92,8 @@ class DefaultDeviceEffectsApplier implements DeviceEffectsApplier { if (mLastAppliedEffects.shouldDisplayGrayscale() != effects.shouldDisplayGrayscale()) { if (mColorDisplayManager != null) { try { traceApplyDeviceEffect("displayGrayscale", effects.shouldDisplayGrayscale()); mColorDisplayManager.setSaturationLevel( effects.shouldDisplayGrayscale() ? SATURATION_LEVEL_GRAYSCALE : SATURATION_LEVEL_FULL_COLOR); Loading @@ -99,6 +106,7 @@ class DefaultDeviceEffectsApplier implements DeviceEffectsApplier { if (mLastAppliedEffects.shouldDimWallpaper() != effects.shouldDimWallpaper()) { if (mWallpaperManager != null) { try { traceApplyDeviceEffect("dimWallpaper", effects.shouldDimWallpaper()); mWallpaperManager.setWallpaperDimAmount( effects.shouldDimWallpaper() ? WALLPAPER_DIM_AMOUNT_DIMMED : WALLPAPER_DIM_AMOUNT_NORMAL); Loading Loading @@ -134,6 +142,7 @@ class DefaultDeviceEffectsApplier implements DeviceEffectsApplier { unregisterScreenOffReceiver(); updateNightModeImmediately(useNightMode); } else { traceScheduleApplyDeviceEffect("nightMode", useNightMode); registerScreenOffReceiver(); } } Loading @@ -150,6 +159,7 @@ class DefaultDeviceEffectsApplier implements DeviceEffectsApplier { private void updateNightModeImmediately(boolean useNightMode) { Binder.withCleanCallingIdentity(() -> { try { traceApplyDeviceEffect("nightMode", useNightMode); mUiModeManager.setAttentionModeThemeOverlay( useNightMode ? MODE_ATTENTION_THEME_OVERLAY_NIGHT : MODE_ATTENTION_THEME_OVERLAY_OFF); Loading
services/core/java/com/android/server/notification/ZenLog.java +24 −5 Original line number Diff line number Diff line Loading @@ -23,18 +23,15 @@ import android.net.Uri; import android.os.Build; import android.os.RemoteException; import android.provider.Settings.Global; import android.service.notification.Condition; import android.service.notification.IConditionProvider; import android.service.notification.NotificationListenerService; import android.service.notification.ZenModeConfig; import android.service.notification.ZenModeDiff; import android.util.LocalLog; import android.util.Log; import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; import java.io.PrintWriter; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; public class ZenLog { Loading @@ -61,6 +58,8 @@ public class ZenLog { private static final int TYPE_RECORD_CALLER = 19; private static final int TYPE_CHECK_REPEAT_CALLER = 20; private static final int TYPE_ALERT_ON_UPDATED_INTERCEPT = 21; private static final int TYPE_APPLY_DEVICE_EFFECT = 22; private static final int TYPE_SCHEDULE_APPLY_DEVICE_EFFECT = 23; public static void traceIntercepted(NotificationRecord record, String reason) { append(TYPE_INTERCEPTED, record.getKey() + "," + reason); Loading Loading @@ -173,6 +172,14 @@ public class ZenLog { + ", given uri=" + hasUri); } public static void traceApplyDeviceEffect(String effect, boolean newValue) { append(TYPE_APPLY_DEVICE_EFFECT, effect + " -> " + newValue); } public static void traceScheduleApplyDeviceEffect(String effect, boolean scheduledValue) { append(TYPE_SCHEDULE_APPLY_DEVICE_EFFECT, effect + " -> " + scheduledValue); } private static String subscribeResult(IConditionProvider provider, RemoteException e) { return provider == null ? "no provider" : e != null ? e.getMessage() : "ok"; } Loading @@ -196,6 +203,8 @@ public class ZenLog { case TYPE_RECORD_CALLER: return "record_caller"; case TYPE_CHECK_REPEAT_CALLER: return "check_repeat_caller"; case TYPE_ALERT_ON_UPDATED_INTERCEPT: return "alert_on_updated_intercept"; case TYPE_APPLY_DEVICE_EFFECT: return "apply_device_effect"; case TYPE_SCHEDULE_APPLY_DEVICE_EFFECT: return "schedule_device_effect"; default: return "unknown"; } } Loading Loading @@ -273,4 +282,14 @@ public class ZenLog { STATE_CHANGES.dump(prefix, pw); } } @VisibleForTesting(/* otherwise = VisibleForTesting.NONE */) public static void clear() { synchronized (INTERCEPTION_EVENTS) { INTERCEPTION_EVENTS.clear(); } synchronized (STATE_CHANGES) { STATE_CHANGES.clear(); } } }
services/tests/uiservicestests/src/com/android/server/notification/DefaultDeviceEffectsApplierTest.java +41 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.hardware.display.ColorDisplayManager; import android.os.PowerManager; import android.platform.test.annotations.EnableFlags; import android.platform.test.flag.junit.SetFlagsRule; import android.service.notification.ZenDeviceEffects; import android.testing.TestableContext; Loading @@ -64,6 +65,9 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.io.PrintWriter; import java.io.StringWriter; @RunWith(TestParameterInjector.class) public class DefaultDeviceEffectsApplierTest { Loading @@ -89,6 +93,8 @@ public class DefaultDeviceEffectsApplierTest { mApplier = new DefaultDeviceEffectsApplier(mContext); verify(mWallpaperManager).isWallpaperSupported(); ZenLog.clear(); } @Test Loading @@ -109,6 +115,41 @@ public class DefaultDeviceEffectsApplierTest { verify(mUiModeManager).setAttentionModeThemeOverlay(eq(MODE_ATTENTION_THEME_OVERLAY_NIGHT)); } @Test @EnableFlags(android.app.Flags.FLAG_MODES_API) public void apply_logsToZenLog() { when(mPowerManager.isInteractive()).thenReturn(true); ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor = ArgumentCaptor.forClass(BroadcastReceiver.class); ArgumentCaptor<IntentFilter> intentFilterCaptor = ArgumentCaptor.forClass(IntentFilter.class); ZenDeviceEffects effects = new ZenDeviceEffects.Builder() .setShouldDisplayGrayscale(true) .setShouldUseNightMode(true) .build(); mApplier.apply(effects, ORIGIN_APP); String zenLog = getZenLog(); assertThat(zenLog).contains("apply_device_effect: displayGrayscale -> true"); assertThat(zenLog).contains("schedule_device_effect: nightMode -> true"); assertThat(zenLog).doesNotContain("apply_device_effect: nightMode"); verify(mContext).registerReceiver(broadcastReceiverCaptor.capture(), intentFilterCaptor.capture(), anyInt()); BroadcastReceiver screenOffReceiver = broadcastReceiverCaptor.getValue(); screenOffReceiver.onReceive(mContext, new Intent(Intent.ACTION_SCREEN_OFF)); zenLog = getZenLog(); assertThat(zenLog).contains("apply_device_effect: nightMode -> true"); } private static String getZenLog() { StringWriter zenLogWriter = new StringWriter(); ZenLog.dump(new PrintWriter(zenLogWriter), ""); return zenLogWriter.toString(); } @Test public void apply_removesEffects() { mSetFlagsRule.enableFlags(android.app.Flags.FLAG_MODES_API); Loading